From 5a303f878ecd597c1524f7cb0b844d17cb9da266 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Thu, 22 Aug 2002 22:43:14 +0000 Subject: [PATCH] Remove all traces of the ODBC driver, which is now on GBorg as the psqlodbc project ... --- GNUmakefile.in | 4 +- INSTALL | 33 - README | 7 +- configure | 164 - configure.in | 46 +- src/Makefile.global.in | 7 +- src/interfaces/Makefile | 8 +- src/interfaces/odbc/GNUmakefile | 72 - src/interfaces/odbc/bind.c | 638 ---- src/interfaces/odbc/bind.h | 62 - src/interfaces/odbc/columninfo.c | 191 - src/interfaces/odbc/columninfo.h | 42 - src/interfaces/odbc/connection.c | 2154 ----------- src/interfaces/odbc/connection.h | 359 -- src/interfaces/odbc/convert.c | 3578 ------------------ src/interfaces/odbc/convert.h | 56 - src/interfaces/odbc/descriptor.h | 104 - src/interfaces/odbc/dlg_specific.c | 971 ----- src/interfaces/odbc/dlg_specific.h | 200 - src/interfaces/odbc/dlg_wingui.c | 523 --- src/interfaces/odbc/drvconn.c | 435 --- src/interfaces/odbc/environ.c | 661 ---- src/interfaces/odbc/environ.h | 38 - src/interfaces/odbc/execute.c | 1090 ------ src/interfaces/odbc/gpps.c | 454 --- src/interfaces/odbc/gpps.h | 48 - src/interfaces/odbc/info.c | 4509 ----------------------- src/interfaces/odbc/info30.c | 396 -- src/interfaces/odbc/iodbc.h | 68 - src/interfaces/odbc/isql.h | 246 -- src/interfaces/odbc/isqlext.h | 1560 -------- src/interfaces/odbc/license.txt | 962 ----- src/interfaces/odbc/lobj.c | 186 - src/interfaces/odbc/lobj.h | 47 - src/interfaces/odbc/md5.c | 351 -- src/interfaces/odbc/md5.h | 49 - src/interfaces/odbc/misc.c | 329 -- src/interfaces/odbc/misc.h | 107 - src/interfaces/odbc/multibyte.c | 454 --- src/interfaces/odbc/multibyte.h | 90 - src/interfaces/odbc/notice.txt | 38 - src/interfaces/odbc/odbc.sql | 228 -- src/interfaces/odbc/odbcapi.c | 716 ---- src/interfaces/odbc/odbcapi25w.c | 81 - src/interfaces/odbc/odbcapi30.c | 550 --- src/interfaces/odbc/odbcapi30w.c | 282 -- src/interfaces/odbc/odbcapiw.c | 626 ---- src/interfaces/odbc/odbcinst.ini | 3 - src/interfaces/odbc/options.c | 728 ---- src/interfaces/odbc/parse.c | 1229 ------ src/interfaces/odbc/pgapi30.c | 1656 --------- src/interfaces/odbc/pgapifunc.h | 294 -- src/interfaces/odbc/pgtypes.c | 1475 -------- src/interfaces/odbc/pgtypes.h | 106 - src/interfaces/odbc/psqlodbc.c | 132 - src/interfaces/odbc/psqlodbc.h | 279 -- src/interfaces/odbc/psqlodbc.rc | 321 -- src/interfaces/odbc/psqlodbc.reg | 16 - src/interfaces/odbc/psqlodbc30.reg | 16 - src/interfaces/odbc/psqlodbc30w.reg | 16 - src/interfaces/odbc/psqlodbc_api30.def | 82 - src/interfaces/odbc/psqlodbc_api30w.def | 107 - src/interfaces/odbc/psqlodbc_apiw.def | 84 - src/interfaces/odbc/psqlodbc_win32.def | 60 - src/interfaces/odbc/qresult.c | 846 ----- src/interfaces/odbc/qresult.h | 146 - src/interfaces/odbc/readme.txt | 84 - src/interfaces/odbc/resource.h | 79 - src/interfaces/odbc/results.c | 2999 --------------- src/interfaces/odbc/setup.c | 409 -- src/interfaces/odbc/setup.rul | 495 --- src/interfaces/odbc/socket.c | 354 -- src/interfaces/odbc/socket.h | 95 - src/interfaces/odbc/statement.c | 1197 ------ src/interfaces/odbc/statement.h | 248 -- src/interfaces/odbc/tuple.c | 66 - src/interfaces/odbc/tuple.h | 72 - src/interfaces/odbc/tuplelist.c | 216 -- src/interfaces/odbc/tuplelist.h | 35 - src/interfaces/odbc/version.h | 16 - src/interfaces/odbc/win32.mak | 511 --- src/interfaces/odbc/win32_30.mak | 537 --- src/interfaces/odbc/win32_30w.mak | 520 --- src/interfaces/odbc/win32w.mak | 478 --- src/interfaces/odbc/win_md5.c | 15 - src/interfaces/odbc/win_setup.h | 27 - src/interfaces/odbc/win_unicode.c | 149 - 87 files changed, 11 insertions(+), 40007 deletions(-) delete mode 100644 src/interfaces/odbc/GNUmakefile delete mode 100644 src/interfaces/odbc/bind.c delete mode 100644 src/interfaces/odbc/bind.h delete mode 100644 src/interfaces/odbc/columninfo.c delete mode 100644 src/interfaces/odbc/columninfo.h delete mode 100644 src/interfaces/odbc/connection.c delete mode 100644 src/interfaces/odbc/connection.h delete mode 100644 src/interfaces/odbc/convert.c delete mode 100644 src/interfaces/odbc/convert.h delete mode 100644 src/interfaces/odbc/descriptor.h delete mode 100644 src/interfaces/odbc/dlg_specific.c delete mode 100644 src/interfaces/odbc/dlg_specific.h delete mode 100644 src/interfaces/odbc/dlg_wingui.c delete mode 100644 src/interfaces/odbc/drvconn.c delete mode 100644 src/interfaces/odbc/environ.c delete mode 100644 src/interfaces/odbc/environ.h delete mode 100644 src/interfaces/odbc/execute.c delete mode 100644 src/interfaces/odbc/gpps.c delete mode 100644 src/interfaces/odbc/gpps.h delete mode 100644 src/interfaces/odbc/info.c delete mode 100644 src/interfaces/odbc/info30.c delete mode 100644 src/interfaces/odbc/iodbc.h delete mode 100644 src/interfaces/odbc/isql.h delete mode 100644 src/interfaces/odbc/isqlext.h delete mode 100644 src/interfaces/odbc/license.txt delete mode 100644 src/interfaces/odbc/lobj.c delete mode 100644 src/interfaces/odbc/lobj.h delete mode 100644 src/interfaces/odbc/md5.c delete mode 100644 src/interfaces/odbc/md5.h delete mode 100644 src/interfaces/odbc/misc.c delete mode 100644 src/interfaces/odbc/misc.h delete mode 100644 src/interfaces/odbc/multibyte.c delete mode 100644 src/interfaces/odbc/multibyte.h delete mode 100644 src/interfaces/odbc/notice.txt delete mode 100644 src/interfaces/odbc/odbc.sql delete mode 100644 src/interfaces/odbc/odbcapi.c delete mode 100644 src/interfaces/odbc/odbcapi25w.c delete mode 100644 src/interfaces/odbc/odbcapi30.c delete mode 100644 src/interfaces/odbc/odbcapi30w.c delete mode 100755 src/interfaces/odbc/odbcapiw.c delete mode 100644 src/interfaces/odbc/odbcinst.ini delete mode 100644 src/interfaces/odbc/options.c delete mode 100644 src/interfaces/odbc/parse.c delete mode 100644 src/interfaces/odbc/pgapi30.c delete mode 100644 src/interfaces/odbc/pgapifunc.h delete mode 100644 src/interfaces/odbc/pgtypes.c delete mode 100644 src/interfaces/odbc/pgtypes.h delete mode 100644 src/interfaces/odbc/psqlodbc.c delete mode 100644 src/interfaces/odbc/psqlodbc.h delete mode 100644 src/interfaces/odbc/psqlodbc.rc delete mode 100644 src/interfaces/odbc/psqlodbc.reg delete mode 100644 src/interfaces/odbc/psqlodbc30.reg delete mode 100644 src/interfaces/odbc/psqlodbc30w.reg delete mode 100755 src/interfaces/odbc/psqlodbc_api30.def delete mode 100644 src/interfaces/odbc/psqlodbc_api30w.def delete mode 100644 src/interfaces/odbc/psqlodbc_apiw.def delete mode 100644 src/interfaces/odbc/psqlodbc_win32.def delete mode 100644 src/interfaces/odbc/qresult.c delete mode 100644 src/interfaces/odbc/qresult.h delete mode 100644 src/interfaces/odbc/readme.txt delete mode 100644 src/interfaces/odbc/resource.h delete mode 100644 src/interfaces/odbc/results.c delete mode 100644 src/interfaces/odbc/setup.c delete mode 100644 src/interfaces/odbc/setup.rul delete mode 100644 src/interfaces/odbc/socket.c delete mode 100644 src/interfaces/odbc/socket.h delete mode 100644 src/interfaces/odbc/statement.c delete mode 100644 src/interfaces/odbc/statement.h delete mode 100644 src/interfaces/odbc/tuple.c delete mode 100644 src/interfaces/odbc/tuple.h delete mode 100644 src/interfaces/odbc/tuplelist.c delete mode 100644 src/interfaces/odbc/tuplelist.h delete mode 100644 src/interfaces/odbc/version.h delete mode 100644 src/interfaces/odbc/win32.mak delete mode 100755 src/interfaces/odbc/win32_30.mak delete mode 100644 src/interfaces/odbc/win32_30w.mak delete mode 100644 src/interfaces/odbc/win32w.mak delete mode 100644 src/interfaces/odbc/win_md5.c delete mode 100644 src/interfaces/odbc/win_setup.h delete mode 100644 src/interfaces/odbc/win_unicode.c diff --git a/GNUmakefile.in b/GNUmakefile.in index 70151c0324..71219e261e 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -1,7 +1,7 @@ # # PostgreSQL top level makefile # -# $Header: /cvsroot/pgsql/GNUmakefile.in,v 1.25 2002/08/22 00:15:04 scrappy Exp $ +# $Header: /cvsroot/pgsql/GNUmakefile.in,v 1.26 2002/08/22 22:43:08 scrappy Exp $ # subdir = @@ -72,7 +72,7 @@ $(distdir).tar: distdir opt_files := src/backend/utils/mb contrib/retep/build.xml \ src/tools src/corba src/data src/tutorial \ $(addprefix src/bin/, pgaccess pgtclsh pg_encoding) \ - $(addprefix src/interfaces/, odbc libpgtcl perl5 python jdbc) \ + $(addprefix src/interfaces/, libpgtcl perl5 python jdbc) \ $(addprefix src/pl/, plperl tcl) docs_files := doc/postgres.tar.gz doc/src doc/TODO.detail diff --git a/INSTALL b/INSTALL index 1288a9da4a..ac8338a0e1 100644 --- a/INSTALL +++ b/INSTALL @@ -321,10 +321,6 @@ Installation Procedure the only good reason to select a non-default value is if you intend to run multiple PostgreSQL servers on the same machine. - --with-CXX - - Build the C++ interface library. - --with-perl Build the Perl interface module. The Perl interface will be @@ -362,35 +358,6 @@ Installation Procedure use a different version of Tcl or Tk you can specify the directory in which to find them. - --enable-odbc - - Build the ODBC driver. By default, the driver will be independent - of a driver manager. To work better with a driver manager already - installed on your system, use one of the following options in - addition to this one. More information can be found in the - Programmer's Guide. - - --with-iodbc - - Build the ODBC driver for use with iODBC. - - --with-unixodbc - - Build the ODBC driver for use with unixODBC. - - --with-odbcinst=DIRECTORY - - Specifies the directory where the ODBC driver will expect its - "odbcinst.ini" configuration file. The default is - "/usr/local/pgsql/etc" or whatever you specified as - "--sysconfdir". It should be arranged that the driver reads the - same file as the driver manager. - - If either the option "--with-iodbc" or the option - "--with-unixodbc" is used, this option will be ignored because in - that case the driver manager handles the location of the - configuration file. - --with-java Build the JDBC driver and associated Java packages. This option diff --git a/README b/README index a02403b8b8..ec7d3ec26b 100644 --- a/README +++ b/README @@ -8,8 +8,11 @@ PostgreSQL is an advanced object-relational database management system that supports an extended subset of the SQL standard, including transactions, foreign keys, subqueries, triggers, user-defined types and functions. This distribution also contains several language -bindings, including C, C++, Perl, Python, and Tcl, as well as drivers -for JDBC and ODBC. +bindings, including C, Perl, Python, and Tcl, as well as drivers +for JDBC. + +As of v7.3, the ODBC and C++ interfaces have been moved over to the +PostgreSQL Projects WebSite @ http://gborg.postgresql.org. See the file INSTALL for instructions on how to build and install PostgreSQL. That file also lists supported operating systems and diff --git a/configure b/configure index f119371da8..01249797cb 100755 --- a/configure +++ b/configure @@ -845,7 +845,6 @@ Optional Features: --enable-debug build with debugging symbols (-g) --enable-depend turn on automatic dependency tracking --enable-cassert enable assertion checks (for debugging) - --enable-odbc build the ODBC driver package --disable-largefile omit support for large files Optional Packages: @@ -871,9 +870,6 @@ Optional Packages: --with-openssl[=DIR] build with OpenSSL support [/usr/local/ssl] --without-readline do not use Readline --without-zlib do not use Zlib - --with-unixodbc build ODBC driver for unixODBC - --with-iodbc build ODBC driver for iODBC - --with-odbcinst=DIR default directory for odbcinst.ini sysconfdir --with-gnu-ld assume the C compiler uses GNU ld default=no Some influential environment variables: @@ -3476,162 +3472,6 @@ fi; -# -# Optionally enable the building of the ODBC driver -# - -# Old option name -if test "${with_odbc+set}" = set && test "${enable_odbc+set}" != set; then - enable_odbc=$with_odbc -fi - -echo "$as_me:$LINENO: checking whether to build the ODBC driver" >&5 -echo $ECHO_N "checking whether to build the ODBC driver... $ECHO_C" >&6 - - -# Check whether --enable-odbc or --disable-odbc was given. -if test "${enable_odbc+set}" = set; then - enableval="$enable_odbc" - - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-odbc option" >&5 -echo "$as_me: error: no argument expected for --enable-odbc option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_odbc=no - -fi; - - - - -# Check whether --with-unixodbc or --without-unixodbc was given. -if test "${with_unixodbc+set}" = set; then - withval="$with_unixodbc" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-unixodbc option" >&5 -echo "$as_me: error: no argument expected for --with-unixodbc option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_unixodbc=no - -fi; - - - - -# Check whether --with-iodbc or --without-iodbc was given. -if test "${with_iodbc+set}" = set; then - withval="$with_iodbc" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-iodbc option" >&5 -echo "$as_me: error: no argument expected for --with-iodbc option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_iodbc=no - -fi; - -if test "$with_unixodbc" = yes && test "$with_iodbc" = yes; then - { { echo "$as_me:$LINENO: error: ODBC driver cannot be built for both unixODBC and iODBC" >&5 -echo "$as_me: error: ODBC driver cannot be built for both unixODBC and iODBC" >&2;} - { (exit 1); exit 1; }; } -fi -if test "$with_unixodbc" = yes || test "$with_iodbc" = yes; then - enable_odbc=yes -fi -case $enable_odbc:$with_unixodbc:$with_iodbc in - yes:no:no) echo "$as_me:$LINENO: result: yes (stand-alone)" >&5 -echo "${ECHO_T}yes (stand-alone)" >&6;; - yes:yes:no) echo "$as_me:$LINENO: result: yes (unixODBC)" >&5 -echo "${ECHO_T}yes (unixODBC)" >&6 - -cat >>confdefs.h <<\_ACEOF -#define WITH_UNIXODBC 1 -_ACEOF - - ;; - yes:no:yes) echo "$as_me:$LINENO: result: yes (iODBC)" >&5 -echo "${ECHO_T}yes (iODBC)" >&6 - -cat >>confdefs.h <<\_ACEOF -#define WITH_IODBC 1 -_ACEOF - - ;; - no:*) echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6;; -esac - - - - - -# Allow for overriding the default location of the odbcinst.ini -# file which is normally ${sysconfdir} (i.e., ${prefix}/etc). - - - -# Check whether --with-odbcinst or --without-odbcinst was given. -if test "${with_odbcinst+set}" = set; then - withval="$with_odbcinst" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-odbcinst option" >&5 -echo "$as_me: error: argument required for --with-odbcinst option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-odbcinst option" >&5 -echo "$as_me: error: argument required for --with-odbcinst option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - odbcinst_ini_dir=$withval - ;; - esac - -else - odbcinst_ini_dir="\${sysconfdir}" -fi; - - - - - # Assume system is ELF if it predefines __ELF__ as 1, # otherwise believe host_os based default. case $host_os in @@ -16459,10 +16299,6 @@ s,@with_krb5@,$with_krb5,;t t s,@krb_srvtab@,$krb_srvtab,;t t s,@with_pam@,$with_pam,;t t s,@with_openssl@,$with_openssl,;t t -s,@enable_odbc@,$enable_odbc,;t t -s,@with_unixodbc@,$with_unixodbc,;t t -s,@with_iodbc@,$with_iodbc,;t t -s,@odbcinst_ini_dir@,$odbcinst_ini_dir,;t t s,@ELF_SYS@,$ELF_SYS,;t t s,@AWK@,$AWK,;t t s,@FLEX@,$FLEX,;t t diff --git a/configure.in b/configure.in index a919b1a949..51d28c37cf 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.196 2002/08/22 00:15:06 scrappy Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.197 2002/08/22 22:43:08 scrappy Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -511,50 +511,6 @@ PGAC_ARG_BOOL(with, zlib, yes, -# -# Optionally enable the building of the ODBC driver -# - -# Old option name -if test "${with_odbc+set}" = set && test "${enable_odbc+set}" != set; then - enable_odbc=$with_odbc -fi - -AC_MSG_CHECKING([whether to build the ODBC driver]) -PGAC_ARG_BOOL(enable, odbc, no, [ --enable-odbc build the ODBC driver package]) -PGAC_ARG_BOOL(with, unixodbc, no, [ --with-unixodbc build ODBC driver for unixODBC]) -PGAC_ARG_BOOL(with, iodbc, no, [ --with-iodbc build ODBC driver for iODBC]) -if test "$with_unixodbc" = yes && test "$with_iodbc" = yes; then - AC_MSG_ERROR([ODBC driver cannot be built for both unixODBC and iODBC]) -fi -if test "$with_unixodbc" = yes || test "$with_iodbc" = yes; then - enable_odbc=yes -fi -case $enable_odbc:$with_unixodbc:$with_iodbc in - yes:no:no) AC_MSG_RESULT([yes (stand-alone)]);; - yes:yes:no) AC_MSG_RESULT([yes (unixODBC)]) - AC_DEFINE(WITH_UNIXODBC, 1, [Define to 1 to build with unixODBC support (--with-unixodbc)]) - ;; - yes:no:yes) AC_MSG_RESULT([yes (iODBC)]) - AC_DEFINE(WITH_IODBC, 1, [Define to 1 to build with iODBC support (--with-iodbc)]) - ;; - no:*) AC_MSG_RESULT(no);; -esac -AC_SUBST([enable_odbc]) -AC_SUBST([with_unixodbc]) -AC_SUBST([with_iodbc]) - - -# Allow for overriding the default location of the odbcinst.ini -# file which is normally ${sysconfdir} (i.e., ${prefix}/etc). -PGAC_ARG_REQ(with, odbcinst, - [ --with-odbcinst=DIR default directory for odbcinst.ini [sysconfdir]], - [odbcinst_ini_dir=$withval], - [odbcinst_ini_dir="\${sysconfdir}"]) -AC_SUBST([odbcinst_ini_dir]) - - - # Assume system is ELF if it predefines __ELF__ as 1, # otherwise believe host_os based default. case $host_os in diff --git a/src/Makefile.global.in b/src/Makefile.global.in index a7370bcc84..cdbedb5b06 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -1,5 +1,5 @@ # -*-makefile-*- -# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.152 2002/07/27 20:10:04 petere Exp $ +# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.153 2002/08/22 22:43:10 scrappy Exp $ #------------------------------------------------------------------------------ # All PostgreSQL makefiles include this file and use the variables it sets, @@ -111,8 +111,6 @@ override docdir := $(docdir)/postgresql endif endif -odbcinst_ini_dir = @odbcinst_ini_dir@ - javadir := $(DESTDIR)$(datadir)/java localedir := @localedir@ @@ -129,9 +127,6 @@ with_perl = @with_perl@ with_python = @with_python@ with_tcl = @with_tcl@ with_tk = @with_tk@ -enable_odbc = @enable_odbc@ -with_iodbc = @with_iodbc@ -with_unixodbc = @with_unixodbc@ MULTIBYTE = @MULTIBYTE@ enable_shared = @enable_shared@ enable_rpath = @enable_rpath@ diff --git a/src/interfaces/Makefile b/src/interfaces/Makefile index 8fa11e0aff..113670bbeb 100644 --- a/src/interfaces/Makefile +++ b/src/interfaces/Makefile @@ -4,7 +4,7 @@ # # Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/interfaces/Makefile,v 1.46 2002/08/22 00:15:10 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/Makefile,v 1.47 2002/08/22 22:43:11 scrappy Exp $ # #------------------------------------------------------------------------- @@ -14,11 +14,7 @@ include $(top_builddir)/src/Makefile.global DIRS := libpq ecpg libpgeasy -ALLDIRS := $(DIRS) odbc libpgtcl perl5 python jdbc - -ifeq ($(enable_odbc), yes) -DIRS += odbc -endif +ALLDIRS := $(DIRS) libpgtcl perl5 python jdbc ifeq ($(with_tcl), yes) DIRS += libpgtcl diff --git a/src/interfaces/odbc/GNUmakefile b/src/interfaces/odbc/GNUmakefile deleted file mode 100644 index 8d62f9079a..0000000000 --- a/src/interfaces/odbc/GNUmakefile +++ /dev/null @@ -1,72 +0,0 @@ -#------------------------------------------------------------------------- -# -# GNUMakefile for psqlodbc (Postgres ODBC driver) -# -# $Header: /cvsroot/pgsql/src/interfaces/odbc/Attic/GNUmakefile,v 1.23 2001/11/12 00:54:28 inoue Exp $ -# -#------------------------------------------------------------------------- - -subdir = src/interfaces/odbc -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global - -# Shared library parameters -ifeq ($(with_unixodbc),yes) -NAME = odbcpsql -else -NAME = psqlodbc -endif -SO_MAJOR_VERSION = 0 -SO_MINOR_VERSION = 27 - -override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DMD5_ODBC - - -OBJS = info.o bind.o columninfo.o connection.o convert.o drvconn.o \ - environ.o execute.o lobj.o md5.o misc.o options.o \ - pgtypes.o psqlodbc.o qresult.o results.o socket.o parse.o statement.o \ - tuple.o tuplelist.o dlg_specific.o odbcapi.o - -ifdef MULTIBYTE -OBJS += multibyte.o -endif - -SHLIB_LINK += $(filter -lm -lnsl -lsocket, $(LIBS)) -ifeq ($(with_unixodbc),yes) -SHLIB_LINK += -lodbcinst -endif -ifeq ($(with_iodbc),yes) -SHLIB_LINK += -liodbcinst -endif -ifeq ($(with_unixodbc)$(with_iodbc),nono) -OBJS += gpps.o -override CPPFLAGS += -DODBCINSTDIR='"$(odbcinst_ini_dir)"' -endif - -all: all-lib odbc-drop.sql - -# Shared library stuff -include $(top_srcdir)/src/Makefile.shlib - -# Symbols must be resolved to the version in the shared library because -# the driver manager (e.g., iodbc) provides some symbols with the same -# names and we don't want those. (This issue is probably ELF specific.) -LINK.shared += $(shlib_symbolic) - -odbc-drop.sql: odbc.sql - sed -n '/^CREATE OR REPLACE FUNCTION/s/CREATE OR REPLACE FUNCTION \([^ (][^ (]*([^)]*)\).*/DROP FUNCTION \1;/p' $< >$@ - -install: all installdirs - $(INSTALL_DATA) $(srcdir)/odbc.sql $(DESTDIR)$(datadir)/odbc.sql - $(INSTALL_DATA) odbc-drop.sql $(DESTDIR)$(datadir)/odbc-drop.sql - $(MAKE) install-lib - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(datadir) - -uninstall: uninstall-lib - rm -f $(DESTDIR)$(datadir)/odbc.sql $(DESTDIR)$(datadir)/odbc-drop.sql - -clean distclean maintainer-clean: clean-lib - rm -f $(OBJS) - rm -f odbc-drop.sql diff --git a/src/interfaces/odbc/bind.c b/src/interfaces/odbc/bind.c deleted file mode 100644 index e6deedaa8b..0000000000 --- a/src/interfaces/odbc/bind.c +++ /dev/null @@ -1,638 +0,0 @@ -/*------- - * Module: bind.c - * - * Description: This module contains routines related to binding - * columns and parameters. - * - * Classes: BindInfoClass, ParameterInfoClass - * - * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams, - * SQLParamOptions - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "bind.h" - -#include "environ.h" -#include "statement.h" -#include "descriptor.h" -#include "qresult.h" -#include "pgtypes.h" -#include -#include - -#include "pgapifunc.h" - - -/* Bind parameters on a statement handle */ -RETCODE SQL_API -PGAPI_BindParameter( - HSTMT hstmt, - UWORD ipar, - SWORD fParamType, - SWORD fCType, - SWORD fSqlType, - UDWORD cbColDef, - SWORD ibScale, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR * pcbValue) -{ - StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "PGAPI_BindParameter"; - APDFields *opts; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - SC_clear_error(stmt); - - opts = SC_get_APD(stmt); - if (opts->allocated < ipar) - extend_parameter_bindings(opts, ipar); - - /* use zero based column numbers for the below part */ - ipar--; - - /* store the given info */ - opts->parameters[ipar].buflen = cbValueMax; - opts->parameters[ipar].buffer = rgbValue; - opts->parameters[ipar].used = pcbValue; - opts->parameters[ipar].paramType = fParamType; - opts->parameters[ipar].CType = fCType; - opts->parameters[ipar].SQLType = fSqlType; - opts->parameters[ipar].column_size = cbColDef; - opts->parameters[ipar].decimal_digits = ibScale; - opts->parameters[ipar].precision = 0; - opts->parameters[ipar].scale = 0; -#if (ODBCVER >= 0x0300) - switch (fCType) - { - case SQL_C_NUMERIC: - if (cbColDef > 0) - opts->parameters[ipar].precision = (UInt2) cbColDef; - if (ibScale > 0) - opts->parameters[ipar].scale = ibScale; - break; - case SQL_C_TYPE_TIMESTAMP: - if (ibScale > 0) - opts->parameters[ipar].precision = ibScale; - break; - } -#endif /* ODBCVER */ - - /* - * If rebinding a parameter that had data-at-exec stuff in it, then - * free that stuff - */ - if (opts->parameters[ipar].EXEC_used) - { - free(opts->parameters[ipar].EXEC_used); - opts->parameters[ipar].EXEC_used = NULL; - } - - if (opts->parameters[ipar].EXEC_buffer) - { - if (opts->parameters[ipar].SQLType != SQL_LONGVARBINARY) - free(opts->parameters[ipar].EXEC_buffer); - opts->parameters[ipar].EXEC_buffer = NULL; - } - - if (pcbValue && opts->param_offset_ptr) - pcbValue += (*opts->param_offset_ptr >> 2); - /* Data at exec macro only valid for C char/binary data */ - if (pcbValue && (*pcbValue == SQL_DATA_AT_EXEC || - *pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET)) - opts->parameters[ipar].data_at_exec = TRUE; - else - opts->parameters[ipar].data_at_exec = FALSE; - - /* Clear premature result */ - if (stmt->status == STMT_PREMATURE) - SC_recycle_statement(stmt); - - mylog("PGAPI_BindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, opts->parameters[ipar].data_at_exec); - - return SQL_SUCCESS; -} - - -/* Associate a user-supplied buffer with a database column. */ -RETCODE SQL_API -PGAPI_BindCol( - HSTMT hstmt, - UWORD icol, - SWORD fCType, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR * pcbValue) -{ - StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "PGAPI_BindCol"; - ARDFields *opts; - - mylog("%s: entering...\n", func); - - mylog("**** PGAPI_BindCol: stmt = %u, icol = %d\n", stmt, icol); - mylog("**** : fCType=%d rgb=%x valusMax=%d pcb=%x\n", fCType, rgbValue, cbValueMax, pcbValue); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - - - opts = SC_get_ARD(stmt); - if (stmt->status == STMT_EXECUTING) - { - stmt->errormsg = "Can't bind columns while statement is still executing."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - SC_clear_error(stmt); - /* If the bookmark column is being bound, then just save it */ - if (icol == 0) - { - if (rgbValue == NULL) - { - opts->bookmark->buffer = NULL; - opts->bookmark->used = NULL; - } - else - { - /* Make sure it is the bookmark data type */ - if (fCType == SQL_C_BOOKMARK) - switch (fCType) - { - case SQL_C_BOOKMARK: -#if (ODBCVER >= 0x0300) - case SQL_C_VARBOOKMARK: -#endif /* ODBCVER */ - break; - default: - stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK"; -inolog("Column 0 is type %d not of type SQL_C_BOOKMARK", fCType); - stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - opts->bookmark->buffer = rgbValue; - opts->bookmark->used = pcbValue; - } - return SQL_SUCCESS; - } - - /* - * Allocate enough bindings if not already done. Most likely, - * execution of a statement would have setup the necessary bindings. - * But some apps call BindCol before any statement is executed. - */ - if (icol > opts->allocated) - extend_column_bindings(opts, icol); - - /* check to see if the bindings were allocated */ - if (!opts->bindings) - { - stmt->errormsg = "Could not allocate memory for bindings."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - /* use zero based col numbers from here out */ - icol--; - - /* Reset for SQLGetData */ - opts->bindings[icol].data_left = -1; - - if (rgbValue == NULL) - { - /* we have to unbind the column */ - opts->bindings[icol].buflen = 0; - opts->bindings[icol].buffer = NULL; - opts->bindings[icol].used = NULL; - opts->bindings[icol].returntype = SQL_C_CHAR; - if (opts->bindings[icol].ttlbuf) - free(opts->bindings[icol].ttlbuf); - opts->bindings[icol].ttlbuf = NULL; - opts->bindings[icol].ttlbuflen = 0; - opts->bindings[icol].precision = 0; - opts->bindings[icol].scale = 0; - } - else - { - /* ok, bind that column */ - opts->bindings[icol].buflen = cbValueMax; - opts->bindings[icol].buffer = rgbValue; - opts->bindings[icol].used = pcbValue; - opts->bindings[icol].returntype = fCType; -#if (ODBCVER >= 0x0300) - if (SQL_C_NUMERIC == fCType) - opts->bindings[icol].precision = 32; - else -#endif /* ODBCVER */ - opts->bindings[icol].precision = 0; - opts->bindings[icol].scale = 0; - - mylog(" bound buffer[%d] = %u\n", icol, opts->bindings[icol].buffer); - } - - return SQL_SUCCESS; -} - - -/* - * Returns the description of a parameter marker. - * This function is listed as not being supported by SQLGetFunctions() because it is - * used to describe "parameter markers" (not bound parameters), in which case, - * the dbms should return info on the markers. Since Postgres doesn't support that, - * it is best to say this function is not supported and let the application assume a - * data type (most likely varchar). - */ -RETCODE SQL_API -PGAPI_DescribeParam( - HSTMT hstmt, - UWORD ipar, - SWORD FAR * pfSqlType, - UDWORD FAR * pcbColDef, - SWORD FAR * pibScale, - SWORD FAR * pfNullable) -{ - StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "PGAPI_DescribeParam"; - APDFields *opts; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - SC_clear_error(stmt); - - opts = SC_get_APD(stmt); - if ((ipar < 1) || (ipar > opts->allocated)) - { - stmt->errormsg = "Invalid parameter number for PGAPI_DescribeParam."; - stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - ipar--; - - /* - * This implementation is not very good, since it is supposed to - * describe - */ - /* parameter markers, not bound parameters. */ - if (pfSqlType) - *pfSqlType = opts->parameters[ipar].SQLType; - - if (pcbColDef) - *pcbColDef = opts->parameters[ipar].column_size; - - if (pibScale) - *pibScale = opts->parameters[ipar].decimal_digits; - - if (pfNullable) - *pfNullable = pgtype_nullable(stmt, opts->parameters[ipar].paramType); - - return SQL_SUCCESS; -} - - -/* Sets multiple values (arrays) for the set of parameter markers. */ -RETCODE SQL_API -PGAPI_ParamOptions( - HSTMT hstmt, - UDWORD crow, - UDWORD FAR * pirow) -{ - static char *func = "PGAPI_ParamOptions"; - StatementClass *stmt = (StatementClass *) hstmt; - APDFields *opts; - - mylog("%s: entering... %d %x\n", func, crow, pirow); - - opts = SC_get_APD(stmt); - opts->paramset_size = crow; - SC_get_IPD(stmt)->param_processed_ptr = (UInt4 *) pirow; - return SQL_SUCCESS; -} - - -/* - * This function should really talk to the dbms to determine the number of - * "parameter markers" (not bound parameters) in the statement. But, since - * Postgres doesn't support that, the driver should just count the number of markers - * and return that. The reason the driver just can't say this function is unsupported - * like it does for SQLDescribeParam is that some applications don't care and try - * to call it anyway. - * If the statement does not have parameters, it should just return 0. - */ -RETCODE SQL_API -PGAPI_NumParams( - HSTMT hstmt, - SWORD FAR * pcpar) -{ - StatementClass *stmt = (StatementClass *) hstmt; - char in_quote = FALSE; - unsigned int i; - static char *func = "PGAPI_NumParams"; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - SC_clear_error(stmt); - - if (pcpar) - *pcpar = 0; - else - { - SC_log_error(func, "pcpar was null", stmt); - return SQL_ERROR; - } - - - if (!stmt->statement) - { - /* no statement has been allocated */ - stmt->errormsg = "PGAPI_NumParams called with no statement ready."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - else - { - for (i = 0; i < strlen(stmt->statement); i++) - { - if (stmt->statement[i] == '?' && !in_quote) - (*pcpar)++; - else - { - if (stmt->statement[i] == '\'') - in_quote = (in_quote ? FALSE : TRUE); - } - } - return SQL_SUCCESS; - } -} - - -/* - * Bindings Implementation - */ -BindInfoClass * -create_empty_bindings(int num_columns) -{ - BindInfoClass *new_bindings; - int i; - - new_bindings = (BindInfoClass *) malloc(num_columns * sizeof(BindInfoClass)); - if (!new_bindings) - return 0; - - for (i = 0; i < num_columns; i++) - { - new_bindings[i].buflen = 0; - new_bindings[i].buffer = NULL; - new_bindings[i].used = NULL; - new_bindings[i].data_left = -1; - new_bindings[i].ttlbuf = NULL; - new_bindings[i].ttlbuflen = 0; - } - - return new_bindings; -} - -void -extend_parameter_bindings(APDFields *self, int num_params) -{ - static char *func = "extend_parameter_bindings"; - ParameterInfoClass *new_bindings; - - mylog("%s: entering ... self=%u, parameters_allocated=%d, num_params=%d\n", func, self, self->allocated, num_params); - - /* - * if we have too few, allocate room for more, and copy the old - * entries into the new structure - */ - if (self->allocated < num_params) - { - new_bindings = (ParameterInfoClass *) realloc(self->parameters, sizeof(ParameterInfoClass) * num_params); - if (!new_bindings) - { - mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_params, self->allocated); - - self->parameters = NULL; - self->allocated = 0; - return; - } - memset(&new_bindings[self->allocated], 0, - sizeof(ParameterInfoClass) * (num_params - self->allocated)); - - self->parameters = new_bindings; - self->allocated = num_params; - } - - mylog("exit extend_parameter_bindings\n"); -} - -void -reset_a_parameter_binding(APDFields *self, int ipar) -{ - static char *func = "reset_a_parameter_binding"; - - mylog("%s: entering ... self=%u, parameters_allocated=%d, ipar=%d\n", func, self, self->allocated, ipar); - - if (ipar < 1 || ipar > self->allocated) - return; - - ipar--; - self->parameters[ipar].buflen = 0; - self->parameters[ipar].buffer = 0; - self->parameters[ipar].used = 0; - self->parameters[ipar].paramType = 0; - self->parameters[ipar].CType = 0; - if (self->parameters[ipar].EXEC_used) - { - free(self->parameters[ipar].EXEC_used); - self->parameters[ipar].EXEC_used = NULL; - } - - if (self->parameters[ipar].EXEC_buffer) - { - if (self->parameters[ipar].SQLType != SQL_LONGVARBINARY) - free(self->parameters[ipar].EXEC_buffer); - self->parameters[ipar].EXEC_buffer = NULL; - } - self->parameters[ipar].SQLType = 0; - self->parameters[ipar].column_size = 0; - self->parameters[ipar].decimal_digits = 0; - self->parameters[ipar].precision = 0; - self->parameters[ipar].scale = 0; - self->parameters[ipar].data_at_exec = FALSE; - self->parameters[ipar].lobj_oid = 0; -} - -/* - * Free parameters and free the memory. - */ -void -APD_free_params(APDFields *self, char option) -{ - int i; - - mylog("APD_free_params: ENTER, self=%d\n", self); - - if (!self->parameters) - return; - - for (i = 0; i < self->allocated; i++) - { - if (self->parameters[i].data_at_exec) - { - if (self->parameters[i].EXEC_used) - { - free(self->parameters[i].EXEC_used); - self->parameters[i].EXEC_used = NULL; - } - - if (self->parameters[i].EXEC_buffer) - { - if (self->parameters[i].SQLType != SQL_LONGVARBINARY) - free(self->parameters[i].EXEC_buffer); - self->parameters[i].EXEC_buffer = NULL; - } - } - } - - if (option == STMT_FREE_PARAMS_ALL) - { - if (self->parameters); - free(self->parameters); - self->parameters = NULL; - self->allocated = 0; - } - - mylog("APD_free_params: EXIT\n"); -} - -void -extend_column_bindings(ARDFields *self, int num_columns) -{ - static char *func = "extend_column_bindings"; - BindInfoClass *new_bindings; - int i; - - mylog("%s: entering ... self=%u, bindings_allocated=%d, num_columns=%d\n", func, self, self->allocated, num_columns); - - /* - * if we have too few, allocate room for more, and copy the old - * entries into the new structure - */ - if (self->allocated < num_columns) - { - new_bindings = create_empty_bindings(num_columns); - if (!new_bindings) - { - mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, self->allocated); - - if (self->bindings) - { - free(self->bindings); - self->bindings = NULL; - } - self->allocated = 0; - return; - } - - if (self->bindings) - { - for (i = 0; i < self->allocated; i++) - new_bindings[i] = self->bindings[i]; - - free(self->bindings); - } - - self->bindings = new_bindings; - self->allocated = num_columns; - } - - /* - * There is no reason to zero out extra bindings if there are more - * than needed. If an app has allocated extra bindings, let it worry - * about it by unbinding those columns. - */ - - /* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */ - /* SQLExecDirect(...) # returns 5 cols */ - /* SQLExecDirect(...) # returns 10 cols (now OK) */ - - mylog("exit extend_column_bindings\n"); -} - -void -reset_a_column_binding(ARDFields *self, int icol) -{ - static char *func = "reset_a_column_binding"; - - mylog("%s: entering ... self=%u, bindings_allocated=%d, icol=%d\n", func, self, self->allocated, icol); - - if (icol > self->allocated) - return; - - /* use zero based col numbers from here out */ - if (0 == icol) - { - self->bookmark->buffer = NULL; - self->bookmark->used = NULL; - } - else - { - icol--; - - /* we have to unbind the column */ - self->bindings[icol].buflen = 0; - self->bindings[icol].buffer = NULL; - self->bindings[icol].used = NULL; - self->bindings[icol].data_left = -1; - self->bindings[icol].returntype = SQL_C_CHAR; - if (self->bindings[icol].ttlbuf) - free(self->bindings[icol].ttlbuf); - self->bindings[icol].ttlbuf = NULL; - self->bindings[icol].ttlbuflen = 0; - } -} - -void ARD_unbind_cols(ARDFields *self, BOOL freeall) -{ - Int2 lf; - - for (lf = 1; lf <= self->allocated; lf++) - reset_a_column_binding(self, lf); - if (freeall) - { - if (self->bindings) - free(self->bindings); - self->bindings = NULL; - self->allocated = 0; - } -} diff --git a/src/interfaces/odbc/bind.h b/src/interfaces/odbc/bind.h deleted file mode 100644 index f2467c7713..0000000000 --- a/src/interfaces/odbc/bind.h +++ /dev/null @@ -1,62 +0,0 @@ -/* File: bind.h - * - * Description: See "bind.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __BIND_H__ -#define __BIND_H__ - -#include "psqlodbc.h" - -/* - * BindInfoClass -- stores information about a bound column - */ -struct BindInfoClass_ -{ - Int4 buflen; /* size of buffer */ - Int4 data_left; /* amount of data left to read - * (SQLGetData) */ - char *buffer; /* pointer to the buffer */ - Int4 *used; /* used space in the buffer (for strings - * not counting the '\0') */ - char *ttlbuf; /* to save the large result */ - Int4 ttlbuflen; /* the buffer length */ - Int2 returntype; /* kind of conversion to be applied when - * returning (SQL_C_DEFAULT, - * SQL_C_CHAR...) */ - Int2 precision; /* the precision for numeric or timestamp type */ - Int2 scale; /* the scale for numeric type */ -}; - -/* - * ParameterInfoClass -- stores information about a bound parameter - */ -struct ParameterInfoClass_ -{ - Int4 buflen; - char *buffer; - Int4 *used; - Int2 paramType; - Int2 CType; - Int2 SQLType; - Int2 decimal_digits; - UInt4 column_size; - Oid lobj_oid; - Int4 *EXEC_used; /* amount of data OR the oid of the large - * object */ - char *EXEC_buffer; /* the data or the FD of the large object */ - Int2 precision; /* the precision for numeric or timestamp type */ - Int2 scale; /* the scale for numeric type */ - char data_at_exec; -}; - -BindInfoClass *create_empty_bindings(int num_columns); -void extend_column_bindings(ARDFields *opts, int num_columns); -void reset_a_column_binding(ARDFields *opts, int icol); -void extend_parameter_bindings(APDFields *opts, int num_columns); -void reset_a_parameter_binding(APDFields *opts, int ipar); - -#endif diff --git a/src/interfaces/odbc/columninfo.c b/src/interfaces/odbc/columninfo.c deleted file mode 100644 index 7fe72d3f6d..0000000000 --- a/src/interfaces/odbc/columninfo.c +++ /dev/null @@ -1,191 +0,0 @@ -/*------- - * Module: columninfo.c - * - * Description: This module contains routines related to - * reading and storing the field information from a query. - * - * Classes: ColumnInfoClass (Functions prefix: "CI_") - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "pgtypes.h" -#include "columninfo.h" - -#include "connection.h" -#include "socket.h" -#include -#include -#include "pgapifunc.h" - -ColumnInfoClass * -CI_Constructor() -{ - ColumnInfoClass *rv; - - rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass)); - - if (rv) - { - rv->num_fields = 0; - rv->name = NULL; - rv->adtid = NULL; - rv->adtsize = NULL; - rv->display_size = NULL; - rv->atttypmod = NULL; - } - - return rv; -} - - -void -CI_Destructor(ColumnInfoClass *self) -{ - CI_free_memory(self); - - free(self); -} - - -/* - * Read in field descriptions. - * If self is not null, then also store the information. - * If self is null, then just read, don't store. - */ -char -CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn) -{ - Int2 lf; - int new_num_fields; - Oid new_adtid; - Int2 new_adtsize; - Int4 new_atttypmod = -1; - - /* MAX_COLUMN_LEN may be sufficient but for safety */ - char new_field_name[2 * MAX_COLUMN_LEN + 1]; - SocketClass *sock; - ConnInfo *ci; - - sock = CC_get_socket(conn); - ci = &conn->connInfo; - - /* at first read in the number of fields that are in the query */ - new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2)); - - mylog("num_fields = %d\n", new_num_fields); - - if (self) - /* according to that allocate memory */ - CI_set_num_fields(self, new_num_fields); - - /* now read in the descriptions */ - for (lf = 0; lf < new_num_fields; lf++) - { - SOCK_get_string(sock, new_field_name, 2 * MAX_COLUMN_LEN); - new_adtid = (Oid) SOCK_get_int(sock, 4); - new_adtsize = (Int2) SOCK_get_int(sock, 2); - - /* If 6.4 protocol, then read the atttypmod field */ - if (PG_VERSION_GE(conn, 6.4)) - { - mylog("READING ATTTYPMOD\n"); - new_atttypmod = (Int4) SOCK_get_int(sock, 4); - - /* Subtract the header length */ - switch (new_adtid) - { - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIME: - case PG_TYPE_TIME_WITH_TMZONE: - break; - default: - new_atttypmod -= 4; - } - if (new_atttypmod < 0) - new_atttypmod = -1; - - } - - mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod); - - if (self) - CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod); - } - - return (SOCK_get_errcode(sock) == 0); -} - - -void -CI_free_memory(ColumnInfoClass *self) -{ - register Int2 lf; - int num_fields = self->num_fields; - - for (lf = 0; lf < num_fields; lf++) - { - if (self->name[lf]) - { - free(self->name[lf]); - self->name[lf] = NULL; - } - } - - /* Safe to call even if null */ - self->num_fields = 0; - if (self->name) - free(self->name); - self->name = NULL; - if (self->adtid) - free(self->adtid); - self->adtid = NULL; - if (self->adtsize) - free(self->adtsize); - self->adtsize = NULL; - if (self->display_size) - free(self->display_size); - self->display_size = NULL; - - if (self->atttypmod) - free(self->atttypmod); - self->atttypmod = NULL; -} - - -void -CI_set_num_fields(ColumnInfoClass *self, int new_num_fields) -{ - CI_free_memory(self); /* always safe to call */ - - self->num_fields = new_num_fields; - - self->name = (char **) malloc(sizeof(char *) * self->num_fields); - memset(self->name, 0, sizeof(char *) * self->num_fields); - self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields); - self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields); - self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields); - self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields); -} - - -void -CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, - Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod) -{ - /* check bounds */ - if ((field_num < 0) || (field_num >= self->num_fields)) - return; - - /* store the info */ - self->name[field_num] = strdup(new_name); - self->adtid[field_num] = new_adtid; - self->adtsize[field_num] = new_adtsize; - self->atttypmod[field_num] = new_atttypmod; - - self->display_size[field_num] = 0; -} diff --git a/src/interfaces/odbc/columninfo.h b/src/interfaces/odbc/columninfo.h deleted file mode 100644 index 41e9400dce..0000000000 --- a/src/interfaces/odbc/columninfo.h +++ /dev/null @@ -1,42 +0,0 @@ -/* File: columninfo.h - * - * Description: See "columninfo.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __COLUMNINFO_H__ -#define __COLUMNINFO_H__ - -#include "psqlodbc.h" - -struct ColumnInfoClass_ -{ - Int2 num_fields; - char **name; /* list of type names */ - Oid *adtid; /* list of type ids */ - Int2 *adtsize; /* list type sizes */ - Int2 *display_size; /* the display size (longest row) */ - Int4 *atttypmod; /* the length of bpchar/varchar */ -}; - -#define CI_get_num_fields(self) (self->num_fields) -#define CI_get_oid(self, col) (self->adtid[col]) -#define CI_get_fieldname(self, col) (self->name[col]) -#define CI_get_fieldsize(self, col) (self->adtsize[col]) -#define CI_get_display_size(self, col) (self->display_size[col]) -#define CI_get_atttypmod(self, col) (self->atttypmod[col]) - -ColumnInfoClass *CI_Constructor(void); -void CI_Destructor(ColumnInfoClass *self); -void CI_free_memory(ColumnInfoClass *self); -char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn); - -/* functions for setting up the fields from within the program, */ -/* without reading from a socket */ -void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields); -void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, - Oid new_adtid, Int2 new_adtsize, Int4 atttypmod); - -#endif diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c deleted file mode 100644 index e3c0563ec2..0000000000 --- a/src/interfaces/odbc/connection.c +++ /dev/null @@ -1,2154 +0,0 @@ -/*------ - * Module: connection.c - * - * Description: This module contains routines related to - * connecting to and disconnecting from the Postgres DBMS. - * - * Classes: ConnectionClass (Functions prefix: "CC_") - * - * API functions: SQLAllocConnect, SQLConnect, SQLDisconnect, SQLFreeConnect, - * SQLBrowseConnect(NI) - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ -/* Multibyte support Eiji Tokuya 2001-03-15 */ - -#include "connection.h" - -#include -#include -#include -#ifndef WIN32 -#include -#endif /* WIN32 */ - -#include "environ.h" -#include "socket.h" -#include "statement.h" -#include "qresult.h" -#include "lobj.h" -#include "dlg_specific.h" - -#ifdef MULTIBYTE -#include "multibyte.h" -#endif - -#include "pgapifunc.h" -#include "md5.h" - -#define STMT_INCREMENT 16 /* how many statement holders to allocate - * at a time */ - -#define PRN_NULLCHECK - -extern GLOBAL_VALUES globals; - - -RETCODE SQL_API -PGAPI_AllocConnect( - HENV henv, - HDBC FAR * phdbc) -{ - EnvironmentClass *env = (EnvironmentClass *) henv; - ConnectionClass *conn; - static char *func = "PGAPI_AllocConnect"; - - mylog("%s: entering...\n", func); - - conn = CC_Constructor(); - mylog("**** %s: henv = %u, conn = %u\n", func, henv, conn); - - if (!conn) - { - env->errormsg = "Couldn't allocate memory for Connection object."; - env->errornumber = ENV_ALLOC_ERROR; - *phdbc = SQL_NULL_HDBC; - EN_log_error(func, "", env); - return SQL_ERROR; - } - - if (!EN_add_connection(env, conn)) - { - env->errormsg = "Maximum number of connections exceeded."; - env->errornumber = ENV_ALLOC_ERROR; - CC_Destructor(conn); - *phdbc = SQL_NULL_HDBC; - EN_log_error(func, "", env); - return SQL_ERROR; - } - - if (phdbc) - *phdbc = (HDBC) conn; - - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_Connect( - HDBC hdbc, - UCHAR FAR * szDSN, - SWORD cbDSN, - UCHAR FAR * szUID, - SWORD cbUID, - UCHAR FAR * szAuthStr, - SWORD cbAuthStr) -{ - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci; - static char *func = "PGAPI_Connect"; - - mylog("%s: entering...\n", func); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - ci = &conn->connInfo; - - make_string(szDSN, cbDSN, ci->dsn); - - /* get the values for the DSN from the registry */ - memcpy(&ci->drivers, &globals, sizeof(globals)); - getDSNinfo(ci, CONN_OVERWRITE); - logs_on_off(1, ci->drivers.debug, ci->drivers.commlog); - /* initialize pg_version from connInfo.protocol */ - CC_initialize_pg_version(conn); - - /* - * override values from DSN info with UID and authStr(pwd) This only - * occurs if the values are actually there. - */ - make_string(szUID, cbUID, ci->username); - make_string(szAuthStr, cbAuthStr, ci->password); - - /* fill in any defaults */ - getDSNdefaults(ci); - - qlog("conn = %u, %s(DSN='%s', UID='%s', PWD='%s')\n", conn, func, ci->dsn, ci->username, ci->password); - - if (CC_connect(conn, AUTH_REQ_OK, NULL) <= 0) - { - /* Error messages are filled in */ - CC_log_error(func, "Error on CC_connect", conn); - return SQL_ERROR; - } - - mylog("%s: returning...\n", func); - - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_BrowseConnect( - HDBC hdbc, - UCHAR FAR * szConnStrIn, - SWORD cbConnStrIn, - UCHAR FAR * szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR * pcbConnStrOut) -{ - static char *func = "PGAPI_BrowseConnect"; - - mylog("%s: entering...\n", func); - - return SQL_SUCCESS; -} - - -/* Drop any hstmts open on hdbc and disconnect from database */ -RETCODE SQL_API -PGAPI_Disconnect( - HDBC hdbc) -{ - ConnectionClass *conn = (ConnectionClass *) hdbc; - static char *func = "PGAPI_Disconnect"; - - - mylog("%s: entering...\n", func); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - qlog("conn=%u, %s\n", conn, func); - - if (conn->status == CONN_EXECUTING) - { - conn->errornumber = CONN_IN_USE; - conn->errormsg = "A transaction is currently being executed"; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - - logs_on_off(-1, conn->connInfo.drivers.debug, conn->connInfo.drivers.commlog); - mylog("%s: about to CC_cleanup\n", func); - - /* Close the connection and free statements */ - CC_cleanup(conn); - - mylog("%s: done CC_cleanup\n", func); - mylog("%s: returning...\n", func); - - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_FreeConnect( - HDBC hdbc) -{ - ConnectionClass *conn = (ConnectionClass *) hdbc; - static char *func = "PGAPI_FreeConnect"; - - mylog("%s: entering...\n", func); - mylog("**** in %s: hdbc=%u\n", func, hdbc); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - /* Remove the connection from the environment */ - if (!EN_remove_connection(conn->henv, conn)) - { - conn->errornumber = CONN_IN_USE; - conn->errormsg = "A transaction is currently being executed"; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - - CC_Destructor(conn); - - mylog("%s: returning...\n", func); - - return SQL_SUCCESS; -} - - -void -CC_conninfo_init(ConnInfo *conninfo) -{ - memset(conninfo, 0, sizeof(ConnInfo)); - conninfo->disallow_premature = -1; - conninfo->allow_keyset = -1; - conninfo->lf_conversion = -1; - conninfo->true_is_minus1 = -1; - conninfo->int8_as = -101; - memcpy(&(conninfo->drivers), &globals, sizeof(globals)); -} -/* - * IMPLEMENTATION CONNECTION CLASS - */ -ConnectionClass * -CC_Constructor() -{ - ConnectionClass *rv; - - rv = (ConnectionClass *) malloc(sizeof(ConnectionClass)); - - if (rv != NULL) - { - rv->henv = NULL; /* not yet associated with an environment */ - - rv->errormsg = NULL; - rv->errornumber = 0; - rv->errormsg_created = FALSE; - - rv->status = CONN_NOT_CONNECTED; - rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */ - - CC_conninfo_init(&(rv->connInfo)); - rv->sock = SOCK_Constructor(rv); - if (!rv->sock) - return NULL; - - rv->stmts = (StatementClass **) malloc(sizeof(StatementClass *) * STMT_INCREMENT); - if (!rv->stmts) - return NULL; - memset(rv->stmts, 0, sizeof(StatementClass *) * STMT_INCREMENT); - - rv->num_stmts = STMT_INCREMENT; - - rv->lobj_type = PG_TYPE_LO; - - rv->ntables = 0; - rv->col_info = NULL; - - rv->translation_option = 0; - rv->translation_handle = NULL; - rv->DataSourceToDriver = NULL; - rv->DriverToDataSource = NULL; - rv->driver_version = ODBCVER; - memset(rv->pg_version, 0, sizeof(rv->pg_version)); - rv->pg_version_number = .0; - rv->pg_version_major = 0; - rv->pg_version_minor = 0; - rv->ms_jet = 0; - rv->unicode = 0; - rv->result_uncommitted = 0; - rv->schema_support = 0; - rv->isolation = SQL_TXN_READ_COMMITTED; -#ifdef MULTIBYTE - rv->client_encoding = NULL; - rv->server_encoding = NULL; -#endif /* MULTIBYTE */ - rv->current_schema = NULL; - - - /* Initialize statement options to defaults */ - /* Statements under this conn will inherit these options */ - - InitializeStatementOptions(&rv->stmtOptions); - InitializeARDFields(&rv->ardOptions); - InitializeAPDFields(&rv->apdOptions); - } - return rv; -} - - -char -CC_Destructor(ConnectionClass *self) -{ - mylog("enter CC_Destructor, self=%u\n", self); - - if (self->status == CONN_EXECUTING) - return 0; - - CC_cleanup(self); /* cleanup socket and statements */ - - mylog("after CC_Cleanup\n"); - - /* Free up statement holders */ - if (self->stmts) - { - free(self->stmts); - self->stmts = NULL; - } - mylog("after free statement holders\n"); - - free(self); - - mylog("exit CC_Destructor\n"); - - return 1; -} - - -/* Return how many cursors are opened on this connection */ -int -CC_cursor_count(ConnectionClass *self) -{ - StatementClass *stmt; - int i, - count = 0; - - mylog("CC_cursor_count: self=%u, num_stmts=%d\n", self, self->num_stmts); - - for (i = 0; i < self->num_stmts; i++) - { - stmt = self->stmts[i]; - if (stmt && SC_get_Result(stmt) && SC_get_Result(stmt)->cursor) - count++; - } - - mylog("CC_cursor_count: returning %d\n", count); - - return count; -} - - -void -CC_clear_error(ConnectionClass *self) -{ - self->errornumber = 0; - self->errormsg = NULL; - self->errormsg_created = FALSE; -} - - -/* - * Used to begin a transaction. - */ -char -CC_begin(ConnectionClass *self) -{ - char ret = TRUE; - if (!CC_is_in_trans(self)) - { - QResultClass *res = CC_send_query(self, "BEGIN", NULL, CLEAR_RESULT_ON_ABORT); - mylog("CC_begin: sending BEGIN!\n"); - - if (res != NULL) - { - ret = QR_command_maybe_successful(res); - QR_Destructor(res); - } - else - return FALSE; - } - - return ret; -} - -/* - * Used to commit a transaction. - * We are almost always in the middle of a transaction. - */ -char -CC_commit(ConnectionClass *self) -{ - char ret = FALSE; - if (CC_is_in_trans(self)) - { - QResultClass *res = CC_send_query(self, "COMMIT", NULL, CLEAR_RESULT_ON_ABORT); - mylog("CC_commit: sending COMMIT!\n"); - if (res != NULL) - { - ret = QR_command_maybe_successful(res); - QR_Destructor(res); - } - else - return FALSE; - } - - return ret; -} - -/* - * Used to cancel a transaction. - * We are almost always in the middle of a transaction. - */ -char -CC_abort(ConnectionClass *self) -{ - if (CC_is_in_trans(self)) - { - QResultClass *res = CC_send_query(self, "ROLLBACK", NULL, CLEAR_RESULT_ON_ABORT); - mylog("CC_abort: sending ABORT!\n"); - if (res != NULL) - QR_Destructor(res); - else - return FALSE; - } - - return TRUE; -} - - -/* This is called by SQLDisconnect also */ -char -CC_cleanup(ConnectionClass *self) -{ - int i; - StatementClass *stmt; - - if (self->status == CONN_EXECUTING) - return FALSE; - - mylog("in CC_Cleanup, self=%u\n", self); - - /* Cancel an ongoing transaction */ - /* We are always in the middle of a transaction, */ - /* even if we are in auto commit. */ - if (self->sock) - CC_abort(self); - - mylog("after CC_abort\n"); - - /* This actually closes the connection to the dbase */ - if (self->sock) - { - SOCK_Destructor(self->sock); - self->sock = NULL; - } - - mylog("after SOCK destructor\n"); - - /* Free all the stmts on this connection */ - for (i = 0; i < self->num_stmts; i++) - { - stmt = self->stmts[i]; - if (stmt) - { - stmt->hdbc = NULL; /* prevent any more dbase interactions */ - - SC_Destructor(stmt); - - self->stmts[i] = NULL; - } - } - - /* Check for translation dll */ -#ifdef WIN32 - if (self->translation_handle) - { - FreeLibrary(self->translation_handle); - self->translation_handle = NULL; - } -#endif - - self->status = CONN_NOT_CONNECTED; - self->transact_status = CONN_IN_AUTOCOMMIT; - CC_conninfo_init(&(self->connInfo)); -#ifdef MULTIBYTE - if (self->client_encoding) - free(self->client_encoding); - self->client_encoding = NULL; - if (self->server_encoding) - free(self->server_encoding); - self->server_encoding = NULL; -#endif /* MULTIBYTE */ - if (self->current_schema) - free(self->current_schema); - self->current_schema = NULL; - /* Free cached table info */ - if (self->col_info) - { - int i; - - for (i = 0; i < self->ntables; i++) - { - if (self->col_info[i]->result) /* Free the SQLColumns result structure */ - QR_Destructor(self->col_info[i]->result); - - if (self->col_info[i]->schema) - free(self->col_info[i]->schema); - free(self->col_info[i]); - } - free(self->col_info); - self->col_info = NULL; - } - self->ntables = 0; - mylog("exit CC_Cleanup\n"); - return TRUE; -} - - -int -CC_set_translation(ConnectionClass *self) -{ - -#ifdef WIN32 - - if (self->translation_handle != NULL) - { - FreeLibrary(self->translation_handle); - self->translation_handle = NULL; - } - - if (self->connInfo.translation_dll[0] == 0) - return TRUE; - - self->translation_option = atoi(self->connInfo.translation_option); - self->translation_handle = LoadLibrary(self->connInfo.translation_dll); - - if (self->translation_handle == NULL) - { - self->errornumber = CONN_UNABLE_TO_LOAD_DLL; - self->errormsg = "Could not load the translation DLL."; - return FALSE; - } - - self->DataSourceToDriver - = (DataSourceToDriverProc) GetProcAddress(self->translation_handle, - "SQLDataSourceToDriver"); - - self->DriverToDataSource - = (DriverToDataSourceProc) GetProcAddress(self->translation_handle, - "SQLDriverToDataSource"); - - if (self->DataSourceToDriver == NULL || self->DriverToDataSource == NULL) - { - self->errornumber = CONN_UNABLE_TO_LOAD_DLL; - self->errormsg = "Could not find translation DLL functions."; - return FALSE; - } -#endif - return TRUE; -} - -static int -md5_auth_send(ConnectionClass *self, const char *salt) -{ - char *pwd1 = NULL, *pwd2 = NULL; - ConnInfo *ci = &(self->connInfo); - SocketClass *sock = self->sock; - - if (!(pwd1 = malloc(MD5_PASSWD_LEN + 1))) - return 1; - if (!EncryptMD5(ci->password, ci->username, strlen(ci->username), pwd1)) - { - free(pwd1); - return 1; - } - if (!(pwd2 = malloc(MD5_PASSWD_LEN + 1))) - { - free(pwd1); - return 1; - } - if (!EncryptMD5(pwd1 + strlen("md5"), salt, 4, pwd2)) - { - free(pwd2); - free(pwd1); - return 1; - } - free(pwd1); - SOCK_put_int(sock, 4 + strlen(pwd2) + 1, 4); - SOCK_put_n_char(sock, pwd2, strlen(pwd2) + 1); - SOCK_flush_output(sock); - free(pwd2); - return 0; -} - -char -CC_connect(ConnectionClass *self, char password_req, char *salt_para) -{ - StartupPacket sp; - StartupPacket6_2 sp62; - QResultClass *res; - SocketClass *sock; - ConnInfo *ci = &(self->connInfo); - int areq = -1; - int beresp; - static char msgbuffer[ERROR_MSG_LENGTH]; - char salt[5], notice[512]; - static char *func = "CC_connect"; - -#ifdef MULTIBYTE - char *encoding; -#endif /* MULTIBYTE */ - - mylog("%s: entering...\n", func); - - if (password_req != AUTH_REQ_OK) - - sock = self->sock; /* already connected, just authenticate */ - - else - { - qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d\n", - POSTGRESDRIVERVERSION, - ci->drivers.fetch_max, - ci->drivers.socket_buffersize, - ci->drivers.unknown_sizes, - ci->drivers.max_varchar_size, - ci->drivers.max_longvarchar_size); - qlog(" disable_optimizer=%d, ksqo=%d, unique_index=%d, use_declarefetch=%d\n", - ci->drivers.disable_optimizer, - ci->drivers.ksqo, - ci->drivers.unique_index, - ci->drivers.use_declarefetch); - qlog(" text_as_longvarchar=%d, unknowns_as_longvarchar=%d, bools_as_char=%d NAMEDATALEN=%d\n", - ci->drivers.text_as_longvarchar, - ci->drivers.unknowns_as_longvarchar, - ci->drivers.bools_as_char, - MAX_TABLE_LEN); - -#ifdef MULTIBYTE - encoding = check_client_encoding(ci->conn_settings); - if (encoding && strcmp(encoding, "OTHER")) - self->client_encoding = strdup(encoding); - else - { - encoding = check_client_encoding(ci->drivers.conn_settings); - if (encoding && strcmp(encoding, "OTHER")) - self->client_encoding = strdup(encoding); - } - if (self->client_encoding) - self->ccsc = pg_CS_code(self->client_encoding); - qlog(" extra_systable_prefixes='%s', conn_settings='%s' conn_encoding='%s'\n", - ci->drivers.extra_systable_prefixes, - ci->drivers.conn_settings, - encoding ? encoding : ""); -#else - qlog(" extra_systable_prefixes='%s', conn_settings='%s'\n", - ci->drivers.extra_systable_prefixes, - ci->drivers.conn_settings); -#endif - - if (self->status != CONN_NOT_CONNECTED) - { - self->errormsg = "Already connected."; - self->errornumber = CONN_OPENDB_ERROR; - return 0; - } - - if (ci->server[0] == '\0' || ci->port[0] == '\0' || ci->database[0] == '\0') - { - self->errornumber = CONN_INIREAD_ERROR; - self->errormsg = "Missing server name, port, or database name in call to CC_connect."; - return 0; - } - - mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', database = '%s', username = '%s', password='%s'\n", ci->dsn, ci->server, ci->port, ci->database, ci->username, ci->password); - -another_version_retry: - - /* - * If the socket was closed for some reason (like a SQLDisconnect, - * but no SQLFreeConnect then create a socket now. - */ - if (!self->sock) - { - self->sock = SOCK_Constructor(self); - if (!self->sock) - { - self->errornumber = CONNECTION_SERVER_NOT_REACHED; - self->errormsg = "Could not open a socket to the server"; - return 0; - } - } - - sock = self->sock; - - mylog("connecting to the server socket...\n"); - - SOCK_connect_to(sock, (short) atoi(ci->port), ci->server); - if (SOCK_get_errcode(sock) != 0) - { - mylog("connection to the server socket failed.\n"); - self->errornumber = CONNECTION_SERVER_NOT_REACHED; - self->errormsg = "Could not connect to the server"; - return 0; - } - mylog("connection to the server socket succeeded.\n"); - - if (PROTOCOL_62(ci)) - { - sock->reverse = TRUE; /* make put_int and get_int work - * for 6.2 */ - - memset(&sp62, 0, sizeof(StartupPacket6_2)); - SOCK_put_int(sock, htonl(4 + sizeof(StartupPacket6_2)), 4); - sp62.authtype = htonl(NO_AUTHENTICATION); - strncpy(sp62.database, ci->database, PATH_SIZE); - strncpy(sp62.user, ci->username, USRNAMEDATALEN); - SOCK_put_n_char(sock, (char *) &sp62, sizeof(StartupPacket6_2)); - SOCK_flush_output(sock); - } - else - { - memset(&sp, 0, sizeof(StartupPacket)); - - mylog("sizeof startup packet = %d\n", sizeof(StartupPacket)); - - /* Send length of Authentication Block */ - SOCK_put_int(sock, 4 + sizeof(StartupPacket), 4); - - if (PROTOCOL_63(ci)) - sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_63); - else - sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST); - - strncpy(sp.database, ci->database, SM_DATABASE); - strncpy(sp.user, ci->username, SM_USER); - - SOCK_put_n_char(sock, (char *) &sp, sizeof(StartupPacket)); - SOCK_flush_output(sock); - } - - mylog("sent the authentication block.\n"); - - if (sock->errornumber != 0) - { - mylog("couldn't send the authentication block properly.\n"); - self->errornumber = CONN_INVALID_AUTHENTICATION; - self->errormsg = "Sending the authentication packet failed"; - return 0; - } - mylog("sent the authentication block successfully.\n"); - } - - - mylog("gonna do authentication\n"); - - - /* - * Now get the authentication request from backend - */ - - if (!PROTOCOL_62(ci)) - { - BOOL before_64 = PG_VERSION_LT(self, 6.4), - ReadyForQuery = FALSE; - - do - { - if (password_req != AUTH_REQ_OK) - beresp = 'R'; - else - { - beresp = SOCK_get_char(sock); - mylog("auth got '%c'\n", beresp); - } - - switch (beresp) - { - case 'E': - - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - self->errornumber = CONN_INVALID_AUTHENTICATION; - self->errormsg = msgbuffer; - qlog("ERROR from backend during authentication: '%s'\n", self->errormsg); - if (strncmp(msgbuffer, "Unsupported frontend protocol", 29) == 0) - { /* retry older version */ - if (PROTOCOL_63(ci)) - strcpy(ci->protocol, PG62); - else - strcpy(ci->protocol, PG63); - SOCK_Destructor(sock); - self->sock = (SocketClass *) 0; - CC_initialize_pg_version(self); - goto another_version_retry; - } - - return 0; - case 'R': - - if (password_req != AUTH_REQ_OK) - { - mylog("in 'R' password_req=%s\n", ci->password); - areq = password_req; - if (salt_para) - memcpy(salt, salt_para, sizeof(salt)); - password_req = AUTH_REQ_OK; - } - else - { - - areq = SOCK_get_int(sock, 4); - if (areq == AUTH_REQ_MD5) - SOCK_get_n_char(sock, salt, 4); - else if (areq == AUTH_REQ_CRYPT) - SOCK_get_n_char(sock, salt, 2); - - mylog("areq = %d\n", areq); - } - switch (areq) - { - case AUTH_REQ_OK: - break; - - case AUTH_REQ_KRB4: - self->errormsg = "Kerberos 4 authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - - case AUTH_REQ_KRB5: - self->errormsg = "Kerberos 5 authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - - case AUTH_REQ_PASSWORD: - mylog("in AUTH_REQ_PASSWORD\n"); - - if (ci->password[0] == '\0') - { - self->errornumber = CONNECTION_NEED_PASSWORD; - self->errormsg = "A password is required for this connection."; - return -areq; /* need password */ - } - - mylog("past need password\n"); - - SOCK_put_int(sock, 4 + strlen(ci->password) + 1, 4); - SOCK_put_n_char(sock, ci->password, strlen(ci->password) + 1); - SOCK_flush_output(sock); - - mylog("past flush\n"); - break; - - case AUTH_REQ_CRYPT: - self->errormsg = "Password crypt authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - case AUTH_REQ_MD5: - mylog("in AUTH_REQ_MD5\n"); - if (ci->password[0] == '\0') - { - self->errornumber = CONNECTION_NEED_PASSWORD; - self->errormsg = "A password is required for this connection."; - if (salt_para) - memcpy(salt_para, salt, sizeof(salt)); - return -areq; /* need password */ - } - if (md5_auth_send(self, salt)) - { - self->errormsg = "md5 hashing failed"; - self->errornumber = CONN_INVALID_AUTHENTICATION; - return 0; - } - break; - - case AUTH_REQ_SCM_CREDS: - self->errormsg = "Unix socket credential authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - - default: - self->errormsg = "Unknown authentication type"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - } - break; - case 'K': /* Secret key (6.4 protocol) */ - self->be_pid = SOCK_get_int(sock, 4); /* pid */ - self->be_key = SOCK_get_int(sock, 4); /* key */ - - break; - case 'Z': /* Backend is ready for new query (6.4) */ - ReadyForQuery = TRUE; - break; - case 'N': /* Notices may come */ - while (SOCK_get_string(sock, notice, sizeof(notice) - 1)) ; - break; - default: - self->errormsg = "Unexpected protocol character during authentication"; - self->errornumber = CONN_INVALID_AUTHENTICATION; - return 0; - } - - /* - * There were no ReadyForQuery responce before 6.4. - */ - if (before_64 && areq == AUTH_REQ_OK) - ReadyForQuery = TRUE; - } while (!ReadyForQuery); - } - - - CC_clear_error(self); /* clear any password error */ - - /* - * send an empty query in order to find out whether the specified - * database really exists on the server machine - */ - mylog("sending an empty query...\n"); - - res = CC_send_query(self, " ", NULL, CLEAR_RESULT_ON_ABORT); - if (res == NULL || QR_get_status(res) != PGRES_EMPTY_QUERY) - { - mylog("got no result from the empty query. (probably database does not exist)\n"); - self->errornumber = CONNECTION_NO_SUCH_DATABASE; - self->errormsg = "The database does not exist on the server\nor user authentication failed."; - if (res != NULL) - QR_Destructor(res); - return 0; - } - if (res) - QR_Destructor(res); - - mylog("empty query seems to be OK.\n"); - - CC_set_translation(self); - - /* - * Send any initial settings - */ - - /* - * Get the version number first so we can check it before sending options - * that are now obsolete. DJP 21/06/2002 - */ - - CC_lookup_pg_version(self); /* Get PostgreSQL version for - SQLGetInfo use */ - /* - * Since these functions allocate statements, and since the connection - * is not established yet, it would violate odbc state transition - * rules. Therefore, these functions call the corresponding local - * function instead. - */ - CC_send_settings(self); - CC_lookup_lo(self); /* a hack to get the oid of - our large object oid type */ - - /* - * Multibyte handling is available ? - */ -#ifdef MULTIBYTE - if (PG_VERSION_GE(self, 6.4)) - { - CC_lookup_characterset(self); - if (self->errornumber != 0) - return 0; -#ifdef UNICODE_SUPPORT - if (self->unicode) - { - if (!self->client_encoding || - stricmp(self->client_encoding, "UNICODE")) - { - QResultClass *res; - if (PG_VERSION_LT(self, 7.1)) - { - self->errornumber = CONN_NOT_IMPLEMENTED_ERROR; - self->errormsg = "UTF-8 conversion isn't implemented before 7.1"; - return 0; - } - if (self->client_encoding) - free(self->client_encoding); - self->client_encoding = NULL; - if (res = CC_send_query(self, "set client_encoding to 'UTF8'", NULL, CLEAR_RESULT_ON_ABORT), res) - { - self->client_encoding = strdup("UNICODE"); - self->ccsc = pg_CS_code(self->client_encoding); - QR_Destructor(res); - - } - } - } -#else - { - } -#endif /* UNICODE_SUPPORT */ - } -#ifdef UNICODE_SUPPORT - else if (self->unicode) - { - self->errornumber = CONN_NOT_IMPLEMENTED_ERROR; - self->errormsg = "Unicode isn't supported before 6.4"; - return 0; - } -#endif /* UNICODE_SUPPORT */ -#endif /* MULTIBYTE */ - ci->updatable_cursors = 0; -#ifdef DRIVER_CURSOR_IMPLEMENT - if (!ci->drivers.use_declarefetch && - PG_VERSION_GE(self, 7.0)) /* Tid scan since 7.0 */ - ci->updatable_cursors = ci->allow_keyset; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - CC_clear_error(self); /* clear any initial command errors */ - self->status = CONN_CONNECTED; - - mylog("%s: returning...\n", func); - - return 1; - -} - - -char -CC_add_statement(ConnectionClass *self, StatementClass *stmt) -{ - int i; - - mylog("CC_add_statement: self=%u, stmt=%u\n", self, stmt); - - for (i = 0; i < self->num_stmts; i++) - { - if (!self->stmts[i]) - { - stmt->hdbc = self; - self->stmts[i] = stmt; - return TRUE; - } - } - - /* no more room -- allocate more memory */ - self->stmts = (StatementClass **) realloc(self->stmts, sizeof(StatementClass *) * (STMT_INCREMENT + self->num_stmts)); - if (!self->stmts) - return FALSE; - - memset(&self->stmts[self->num_stmts], 0, sizeof(StatementClass *) * STMT_INCREMENT); - - stmt->hdbc = self; - self->stmts[self->num_stmts] = stmt; - - self->num_stmts += STMT_INCREMENT; - - return TRUE; -} - - -char -CC_remove_statement(ConnectionClass *self, StatementClass *stmt) -{ - int i; - - for (i = 0; i < self->num_stmts; i++) - { - if (self->stmts[i] == stmt && stmt->status != STMT_EXECUTING) - { - self->stmts[i] = NULL; - return TRUE; - } - } - - return FALSE; -} - - -/* - * Create a more informative error message by concatenating the connection - * error message with its socket error message. - */ -char * -CC_create_errormsg(ConnectionClass *self) -{ - SocketClass *sock = self->sock; - int pos; - static char msg[4096]; - - mylog("enter CC_create_errormsg\n"); - - msg[0] = '\0'; - - if (self->errormsg) - strcpy(msg, self->errormsg); - - mylog("msg = '%s'\n", msg); - - if (sock && sock->errormsg && sock->errormsg[0] != '\0') - { - pos = strlen(msg); - sprintf(&msg[pos], ";\n%s", sock->errormsg); - } - - mylog("exit CC_create_errormsg\n"); - return msg; -} - - -char -CC_get_error(ConnectionClass *self, int *number, char **message) -{ - int rv; - - mylog("enter CC_get_error\n"); - - /* Create a very informative errormsg if it hasn't been done yet. */ - if (!self->errormsg_created) - { - self->errormsg = CC_create_errormsg(self); - self->errormsg_created = TRUE; - } - - if (self->errornumber) - { - *number = self->errornumber; - *message = self->errormsg; - } - rv = (self->errornumber != 0); - - self->errornumber = 0; /* clear the error */ - - mylog("exit CC_get_error\n"); - - return rv; -} - - -void CC_on_commit(ConnectionClass *conn) -{ - if (CC_is_in_trans(conn)) - { -#ifdef DRIVER_CURSOR_IMPLEMENT - if (conn->result_uncommitted) - ProcessRollback(conn, FALSE); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - CC_set_no_trans(conn); - } - conn->result_uncommitted = 0; -} -void CC_on_abort(ConnectionClass *conn, UDWORD opt) -{ - if (CC_is_in_trans(conn)) - { -#ifdef DRIVER_CURSOR_IMPLEMENT - if (conn->result_uncommitted) - ProcessRollback(conn, TRUE); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - if (0 != (opt & NO_TRANS)) - CC_set_no_trans(conn); - } - if (0 != (opt & CONN_DEAD)) - conn->status = CONN_DOWN; - conn->result_uncommitted = 0; -} - -/* - * The "result_in" is only used by QR_next_tuple() to fetch another group of rows into - * the same existing QResultClass (this occurs when the tuple cache is depleted and - * needs to be re-filled). - * - * The "cursor" is used by SQLExecute to associate a statement handle as the cursor name - * (i.e., C3326857) for SQL select statements. This cursor is then used in future - * 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements. - */ -QResultClass * -CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag) -{ - QResultClass *cmdres = NULL, - *retres = NULL, - *res = NULL; - BOOL clear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0), - create_keyset = ((flag & CREATE_KEYSET) != 0), - issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self)); - char swallow, *wq, *ptr; - int id; - SocketClass *sock = self->sock; - int maxlen, - empty_reqs; - BOOL msg_truncated, - ReadyToReturn, - query_completed = FALSE, - before_64 = PG_VERSION_LT(self, 6.4), - aborted = FALSE, - used_passed_result_object = FALSE; - UDWORD abort_opt; - - /* ERROR_MSG_LENGTH is suffcient */ - static char msgbuffer[ERROR_MSG_LENGTH + 1]; - - /* QR_set_command() dups this string so doesn't need static */ - char cmdbuffer[ERROR_MSG_LENGTH + 1]; - - mylog("send_query(): conn=%u, query='%s'\n", self, query); - qlog("conn=%u, query='%s'\n", self, query); - - /* Indicate that we are sending a query to the backend */ - maxlen = CC_get_max_query_len(self); - if (maxlen > 0 && maxlen < (int) strlen(query) + 1) - { - self->errornumber = CONNECTION_MSG_TOO_LONG; - self->errormsg = "Query string is too long"; - return NULL; - } - - if ((NULL == query) || (query[0] == '\0')) - return NULL; - - if (SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_COULD_NOT_SEND; - self->errormsg = "Could not send Query to backend"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - return NULL; - } - - SOCK_put_char(sock, 'Q'); - if (SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_COULD_NOT_SEND; - self->errormsg = "Could not send Query to backend"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - return NULL; - } - - if (issue_begin) - SOCK_put_n_char(sock, "begin;", 6); - SOCK_put_string(sock, query); - SOCK_flush_output(sock); - - if (SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_COULD_NOT_SEND; - self->errormsg = "Could not send Query to backend"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - return NULL; - } - - mylog("send_query: done sending query\n"); - - ReadyToReturn = FALSE; - empty_reqs = 0; - for (wq = query; isspace((unsigned char) *wq); wq++) - ; - if (*wq == '\0') - empty_reqs = 1; - cmdres = qi ? qi->result_in : NULL; - if (cmdres) - used_passed_result_object = TRUE; - else - { - cmdres = QR_Constructor(); - if (!cmdres) - { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = "Could not create result info in send_query."; - return NULL; - } - } - res = cmdres; - while (!ReadyToReturn) - { - /* what type of message is coming now ? */ - id = SOCK_get_char(sock); - - if ((SOCK_get_errcode(sock) != 0) || (id == EOF)) - { - self->errornumber = CONNECTION_NO_RESPONSE; - self->errormsg = "No response from the backend"; - - mylog("send_query: 'id' - %s\n", self->errormsg); - CC_on_abort(self, NO_TRANS | CONN_DEAD); - ReadyToReturn = TRUE; - retres = NULL; - break; - } - - mylog("send_query: got id = '%c'\n", id); - - switch (id) - { - case 'A': /* Asynchronous Messages are ignored */ - (void) SOCK_get_int(sock, 4); /* id of notification */ - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - /* name of the relation the message comes from */ - break; - case 'C': /* portal query command, no tuples - * returned */ - /* read in the return message from the backend */ - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - if (SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_NO_RESPONSE; - self->errormsg = "No response from backend while receiving a portal query command"; - mylog("send_query: 'C' - %s\n", self->errormsg); - CC_on_abort(self, NO_TRANS | CONN_DEAD); - ReadyToReturn = TRUE; - retres = NULL; - } - else - { - mylog("send_query: ok - 'C' - %s\n", cmdbuffer); - - if (query_completed) /* allow for "show" style notices */ - { - res->next = QR_Constructor(); - res = res->next; - } - - mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer); - - if (strnicmp(cmdbuffer, "BEGIN", 5) == 0) - { - CC_set_in_trans(self); - if (issue_begin) - { - issue_begin = FALSE; - continue; - } - } - else if (strnicmp(cmdbuffer, "COMMIT", 6) == 0) - CC_on_commit(self); - else if (strnicmp(cmdbuffer, "ROLLBACK", 8) == 0) - CC_on_abort(self, NO_TRANS); - else if (strnicmp(cmdbuffer, "END", 3) == 0) - CC_on_commit(self); - else if (strnicmp(cmdbuffer, "ABORT", 5) == 0) - CC_on_abort(self, NO_TRANS); - else - { - trim(cmdbuffer); /* get rid of trailing space */ - ptr = strrchr(cmdbuffer, ' '); - if (ptr) - res->recent_processed_row_count = atoi(ptr + 1); - else - res->recent_processed_row_count = -1; - } - - if (QR_command_successful(res)) - QR_set_status(res, PGRES_COMMAND_OK); - QR_set_command(res, cmdbuffer); - query_completed = TRUE; - mylog("send_query: returning res = %u\n", res); - if (!before_64) - break; - - /* - * (Quotation from the original comments) since - * backend may produce more than one result for some - * commands we need to poll until clear so we send an - * empty query, and keep reading out of the pipe until - * an 'I' is received - */ - - if (empty_reqs == 0) - { - SOCK_put_string(sock, "Q "); - SOCK_flush_output(sock); - empty_reqs++; - } - } - break; - case 'Z': /* Backend is ready for new query (6.4) */ - if (empty_reqs == 0) - { - ReadyToReturn = TRUE; - if (aborted || query_completed) - retres = cmdres; - else - ReadyToReturn = FALSE; - } - break; - case 'N': /* NOTICE: */ - msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - if (QR_command_successful(res)) - QR_set_status(res, PGRES_NONFATAL_ERROR); - QR_set_notice(res, cmdbuffer); /* will dup this string */ - mylog("~~~ NOTICE: '%s'\n", cmdbuffer); - qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer); - while (msg_truncated) - msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - - continue; /* dont return a result -- continue - * reading */ - - case 'I': /* The server sends an empty query */ - /* There is a closing '\0' following the 'I', so we eat it */ - swallow = SOCK_get_char(sock); - if ((swallow != '\0') || SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_BACKEND_CRAZY; - QR_set_message(res, "Unexpected protocol character from backend (send_query - I)"); - QR_set_status(res, PGRES_FATAL_ERROR); - ReadyToReturn = TRUE; - retres = cmdres; - break; - } - else - { - /* We return the empty query */ - QR_set_status(res, PGRES_EMPTY_QUERY); - } - if (empty_reqs > 0) - { - if (--empty_reqs == 0) - query_completed = TRUE; - } - break; - case 'E': - msg_truncated = SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - - /* Remove a newline */ - if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n') - msgbuffer[strlen(msgbuffer) - 1] = '\0'; - - - mylog("send_query: 'E' - %s\n", msgbuffer); - qlog("ERROR from backend during send_query: '%s'\n", msgbuffer); - - /* We should report that an error occured. Zoltan */ - abort_opt = 0; - if (!strncmp(msgbuffer, "FATAL", 5)) - { - self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; - abort_opt = NO_TRANS | CONN_DEAD; - } - else - self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; - CC_on_abort(self, abort_opt); - QR_set_status(res, PGRES_FATAL_ERROR); - QR_set_message(res, msgbuffer); - QR_set_aborted(res, TRUE); - aborted = TRUE; - while (msg_truncated) - msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - - query_completed = TRUE; - break; - - case 'P': /* get the Portal name */ - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - break; - case 'T': /* Tuple results start here */ - if (query_completed) - { - res->next = QR_Constructor(); - if (!res->next) - { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = "Could not create result info in send_query."; - ReadyToReturn = TRUE; - retres = NULL; - break; - } - if (create_keyset) - QR_set_haskeyset(res->next); - mylog("send_query: 'T' no result_in: res = %u\n", res->next); - res = res->next; - - if (qi) - QR_set_cache_size(res, qi->row_size); - } - if (!used_passed_result_object) - { - if (create_keyset) - QR_set_haskeyset(res); - if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL)) - { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = QR_get_message(res); - ReadyToReturn = TRUE; - if (PGRES_FATAL_ERROR == QR_get_status(res)) - retres = cmdres; - else - retres = NULL; - break; - } - query_completed = TRUE; - } - else - { /* next fetch, so reuse an existing result */ - - /* - * called from QR_next_tuple and must return - * immediately. - */ - ReadyToReturn = TRUE; - if (!QR_fetch_tuples(res, NULL, NULL)) - { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = QR_get_message(res); - retres = NULL; - break; - } - retres = cmdres; - } - break; - case 'D': /* Copy in command began successfully */ - if (query_completed) - { - res->next = QR_Constructor(); - res = res->next; - } - QR_set_status(res, PGRES_COPY_IN); - ReadyToReturn = TRUE; - retres = cmdres; - break; - case 'B': /* Copy out command began successfully */ - if (query_completed) - { - res->next = QR_Constructor(); - res = res->next; - } - QR_set_status(res, PGRES_COPY_OUT); - ReadyToReturn = TRUE; - retres = cmdres; - break; - default: - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_query)"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - - mylog("send_query: error - %s\n", self->errormsg); - ReadyToReturn = TRUE; - retres = NULL; - break; - } - - /* - * There were no ReadyForQuery response before 6.4. - */ - if (before_64) - { - if (empty_reqs == 0 && query_completed) - break; - } - } - - /* - * Break before being ready to return. - */ - if (!ReadyToReturn) - retres = cmdres; - - /* - * Cleanup garbage results before returning. - */ - if (cmdres && retres != cmdres && !used_passed_result_object) - QR_Destructor(cmdres); - /* - * Cleanup the aborted result if specified - */ - if (retres) - { - if (aborted) - { - if (clear_result_on_abort) - { - if (!used_passed_result_object) - { - QR_Destructor(retres); - retres = NULL; - } - } - if (retres) - { - /* - * discard results other than errors. - */ - QResultClass *qres; - for (qres = retres; qres->next; qres = retres) - { - if (QR_get_aborted(qres)) - break; - retres = qres->next; - qres->next = NULL; - QR_Destructor(qres); - } - /* - * If error message isn't set - */ - if (retres && (!self->errormsg || !self->errormsg[0])) - self->errormsg = QR_get_message(retres); - } - } - } - return retres; -} - - -int -CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *args, int nargs) -{ - char id, - c, - done; - SocketClass *sock = self->sock; - - /* ERROR_MSG_LENGTH is sufficient */ - static char msgbuffer[ERROR_MSG_LENGTH + 1]; - int i; - - mylog("send_function(): conn=%u, fnid=%d, result_is_int=%d, nargs=%d\n", self, fnid, result_is_int, nargs); - - if (SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_COULD_NOT_SEND; - self->errormsg = "Could not send function to backend"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - return FALSE; - } - - SOCK_put_string(sock, "F "); - if (SOCK_get_errcode(sock) != 0) - { - self->errornumber = CONNECTION_COULD_NOT_SEND; - self->errormsg = "Could not send function to backend"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - return FALSE; - } - - SOCK_put_int(sock, fnid, 4); - SOCK_put_int(sock, nargs, 4); - - - mylog("send_function: done sending function\n"); - - for (i = 0; i < nargs; ++i) - { - mylog(" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u\n", i, args[i].len, args[i].isint, args[i].u.integer, args[i].u.ptr); - - SOCK_put_int(sock, args[i].len, 4); - if (args[i].isint) - SOCK_put_int(sock, args[i].u.integer, 4); - else - SOCK_put_n_char(sock, (char *) args[i].u.ptr, args[i].len); - - - } - - mylog(" done sending args\n"); - - SOCK_flush_output(sock); - mylog(" after flush output\n"); - - done = FALSE; - while (!done) - { - id = SOCK_get_char(sock); - mylog(" got id = %c\n", id); - - switch (id) - { - case 'V': - done = TRUE; - break; /* ok */ - - case 'N': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - mylog("send_function(V): 'N' - %s\n", msgbuffer); - /* continue reading */ - break; - - case 'E': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - self->errormsg = msgbuffer; - CC_on_abort(self, 0); - - mylog("send_function(V): 'E' - %s\n", self->errormsg); - qlog("ERROR from backend during send_function: '%s'\n", self->errormsg); - - return FALSE; - - case 'Z': - break; - - default: - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_function, args)"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - - mylog("send_function: error - %s\n", self->errormsg); - return FALSE; - } - } - - id = SOCK_get_char(sock); - for (;;) - { - switch (id) - { - case 'G': /* function returned properly */ - mylog(" got G!\n"); - - *actual_result_len = SOCK_get_int(sock, 4); - mylog(" actual_result_len = %d\n", *actual_result_len); - - if (result_is_int) - *((int *) result_buf) = SOCK_get_int(sock, 4); - else - SOCK_get_n_char(sock, (char *) result_buf, *actual_result_len); - - mylog(" after get result\n"); - - c = SOCK_get_char(sock); /* get the last '0' */ - - mylog(" after get 0\n"); - - return TRUE; - - case 'E': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - self->errormsg = msgbuffer; - CC_on_abort(self, 0); - mylog("send_function(G): 'E' - %s\n", self->errormsg); - qlog("ERROR from backend during send_function: '%s'\n", self->errormsg); - - return FALSE; - - case 'N': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - - mylog("send_function(G): 'N' - %s\n", msgbuffer); - qlog("NOTICE from backend during send_function: '%s'\n", msgbuffer); - - continue; /* dont return a result -- continue - * reading */ - - case '0': /* empty result */ - return TRUE; - - default: - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_function, result)"; - CC_on_abort(self, NO_TRANS | CONN_DEAD); - - mylog("send_function: error - %s\n", self->errormsg); - return FALSE; - } - } -} - - -char -CC_send_settings(ConnectionClass *self) -{ - /* char ini_query[MAX_MESSAGE_LEN]; */ - ConnInfo *ci = &(self->connInfo); - -/* QResultClass *res; */ - HSTMT hstmt; - StatementClass *stmt; - RETCODE result; - char status = TRUE; - char *cs, - *ptr; - static char *func = "CC_send_settings"; - - - mylog("%s: entering...\n", func); - -/* - * This function must use the local odbc API functions since the odbc state - * has not transitioned to "connected" yet. - */ - - result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - return FALSE; - stmt = (StatementClass *) hstmt; - - stmt->internal = TRUE; /* ensure no BEGIN/COMMIT/ABORT stuff */ - - /* Set the Datestyle to the format the driver expects it to be in */ - result = PGAPI_ExecDirect(hstmt, "set DateStyle to 'ISO'", SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - status = FALSE; - - mylog("%s: result %d, status %d from set DateStyle\n", func, result, status); - - /* Disable genetic optimizer based on global flag */ - if (ci->drivers.disable_optimizer) - { - result = PGAPI_ExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - status = FALSE; - - mylog("%s: result %d, status %d from set geqo\n", func, result, status); - - } - - /* KSQO (not applicable to 7.1+ - DJP 21/06/2002) */ - if (ci->drivers.ksqo && PG_VERSION_LT(self, 7.1)) - { - result = PGAPI_ExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - status = FALSE; - - mylog("%s: result %d, status %d from set ksqo\n", func, result, status); - - } - - /* Global settings */ - if (ci->drivers.conn_settings[0] != '\0') - { - cs = strdup(ci->drivers.conn_settings); - ptr = strtok(cs, ";"); - while (ptr) - { - result = PGAPI_ExecDirect(hstmt, ptr, SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - status = FALSE; - - mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); - - ptr = strtok(NULL, ";"); - } - - free(cs); - } - - /* Per Datasource settings */ - if (ci->conn_settings[0] != '\0') - { - cs = strdup(ci->conn_settings); - ptr = strtok(cs, ";"); - while (ptr) - { - result = PGAPI_ExecDirect(hstmt, ptr, SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - status = FALSE; - - mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); - - ptr = strtok(NULL, ";"); - } - - free(cs); - } - - - PGAPI_FreeStmt(hstmt, SQL_DROP); - - return status; -} - - -/* - * This function is just a hack to get the oid of our Large Object oid type. - * If a real Large Object oid type is made part of Postgres, this function - * will go away and the define 'PG_TYPE_LO' will be updated. - */ -void -CC_lookup_lo(ConnectionClass *self) -{ - HSTMT hstmt; - StatementClass *stmt; - RETCODE result; - static char *func = "CC_lookup_lo"; - - mylog("%s: entering...\n", func); - -/* - * This function must use the local odbc API functions since the odbc state - * has not transitioned to "connected" yet. - */ - result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - return; - stmt = (StatementClass *) hstmt; - - result = PGAPI_ExecDirect(hstmt, "select oid from pg_type where typname='" PG_TYPE_LO_NAME "'", SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - PGAPI_FreeStmt(hstmt, SQL_DROP); - return; - } - - result = PGAPI_Fetch(hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - PGAPI_FreeStmt(hstmt, SQL_DROP); - return; - } - - result = PGAPI_GetData(hstmt, 1, SQL_C_SLONG, &self->lobj_type, sizeof(self->lobj_type), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - PGAPI_FreeStmt(hstmt, SQL_DROP); - return; - } - - mylog("Got the large object oid: %d\n", self->lobj_type); - qlog(" [ Large Object oid = %d ]\n", self->lobj_type); - - result = PGAPI_FreeStmt(hstmt, SQL_DROP); -} - - -/* - * This function initializes the version of PostgreSQL from - * connInfo.protocol that we're connected to. - * h-inoue 01-2-2001 - */ -void -CC_initialize_pg_version(ConnectionClass *self) -{ - strcpy(self->pg_version, self->connInfo.protocol); - if (PROTOCOL_62(&self->connInfo)) - { - self->pg_version_number = (float) 6.2; - self->pg_version_major = 6; - self->pg_version_minor = 2; - } - else if (PROTOCOL_63(&self->connInfo)) - { - self->pg_version_number = (float) 6.3; - self->pg_version_major = 6; - self->pg_version_minor = 3; - } - else - { - self->pg_version_number = (float) 6.4; - self->pg_version_major = 6; - self->pg_version_minor = 4; - } -} - - -/* - * This function gets the version of PostgreSQL that we're connected to. - * This is used to return the correct info in SQLGetInfo - * DJP - 25-1-2001 - */ -void -CC_lookup_pg_version(ConnectionClass *self) -{ - HSTMT hstmt; - StatementClass *stmt; - RETCODE result; - char szVersion[32]; - int major, - minor; - static char *func = "CC_lookup_pg_version"; - - mylog("%s: entering...\n", func); - -/* - * This function must use the local odbc API functions since the odbc state - * has not transitioned to "connected" yet. - */ - result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - return; - stmt = (StatementClass *) hstmt; - - /* get the server's version if possible */ - result = PGAPI_ExecDirect(hstmt, "select version()", SQL_NTS); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - PGAPI_FreeStmt(hstmt, SQL_DROP); - return; - } - - result = PGAPI_Fetch(hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - PGAPI_FreeStmt(hstmt, SQL_DROP); - return; - } - - result = PGAPI_GetData(hstmt, 1, SQL_C_CHAR, self->pg_version, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - PGAPI_FreeStmt(hstmt, SQL_DROP); - return; - } - - /* - * Extract the Major and Minor numbers from the string. This assumes - * the string starts 'Postgresql X.X' - */ - strcpy(szVersion, "0.0"); - if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2) - { - sprintf(szVersion, "%d.%d", major, minor); - self->pg_version_major = major; - self->pg_version_minor = minor; - } - self->pg_version_number = (float) atof(szVersion); - if (PG_VERSION_GE(self, 7.3)) - self->schema_support = 1; - - mylog("Got the PostgreSQL version string: '%s'\n", self->pg_version); - mylog("Extracted PostgreSQL version number: '%1.1f'\n", self->pg_version_number); - qlog(" [ PostgreSQL version string = '%s' ]\n", self->pg_version); - qlog(" [ PostgreSQL version number = '%1.1f' ]\n", self->pg_version_number); - - result = PGAPI_FreeStmt(hstmt, SQL_DROP); -} - - -void -CC_log_error(const char *func, const char *desc, const ConnectionClass *self) -{ -#ifdef PRN_NULLCHECK -#define nullcheck(a) (a ? a : "(NULL)") -#endif - - if (self) - { - qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg)); - mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg)); - qlog(" ------------------------------------------------------------\n"); - qlog(" henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts); - qlog(" sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type); - - qlog(" ---------------- Socket Info -------------------------------\n"); - if (self->sock) - { - SocketClass *sock = self->sock; - - qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, nullcheck(sock->errormsg)); - qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out); - qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in); - } - } - else -{ - qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc); - mylog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc); -} -#undef PRN_NULLCHECK -} - -int -CC_get_max_query_len(const ConnectionClass *conn) -{ - int value; - - /* Long Queries in 7.0+ */ - if (PG_VERSION_GE(conn, 7.0)) - value = 0 /* MAX_STATEMENT_LEN */ ; - /* Prior to 7.0 we used 2*BLCKSZ */ - else if (PG_VERSION_GE(conn, 6.5)) - value = (2 * BLCKSZ); - else - /* Prior to 6.5 we used BLCKSZ */ - value = BLCKSZ; - return value; -} - -/* - * This deosn't really return the CURRENT SCHEMA - * but there's no alternative. - */ -const char * -CC_get_current_schema(ConnectionClass *conn) -{ - if (!conn->current_schema && conn->schema_support) - { - QResultClass *res; - - if (res = CC_send_query(conn, "select current_schema()", NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_total_tuples(res) == 1) - conn->current_schema = strdup(QR_get_value_backend_row(res, 0, 0)); - QR_Destructor(res); - } - } - return (const char *) conn->current_schema; -} - -int -CC_send_cancel_request(const ConnectionClass *conn) -{ -#ifdef WIN32 - int save_errno = (WSAGetLastError()); -#else - int save_errno = errno; -#endif - int tmpsock = -1; - struct - { - uint32 packetlen; - CancelRequestPacket cp; - } crp; - - /* Check we have an open connection */ - if (!conn) - return FALSE; - - if (conn->sock == NULL ) - { - return FALSE; - } - - /* - * We need to open a temporary connection to the postmaster. Use the - * information saved by connectDB to do this with only kernel calls. - */ - if ((tmpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - return FALSE; - } - if (connect(tmpsock, (struct sockaddr *)&(conn->sock->sadr), - sizeof(conn->sock->sadr)) < 0) - { - return FALSE; - } - - /* - * We needn't set nonblocking I/O or NODELAY options here. - */ - crp.packetlen = htonl((uint32) sizeof(crp)); - crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE); - crp.cp.backendPID = htonl(conn->be_pid); - crp.cp.cancelAuthCode = htonl(conn->be_key); - - if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp)) - { - return FALSE; - } - - /* Sent it, done */ - closesocket(tmpsock); -#ifdef WIN32 - WSASetLastError(save_errno); -#else - errno = save_errno; -#endif - return TRUE; -} diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h deleted file mode 100644 index 133b4920c0..0000000000 --- a/src/interfaces/odbc/connection.h +++ /dev/null @@ -1,359 +0,0 @@ -/* File: connection.h - * - * Description: See "connection.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __CONNECTION_H__ -#define __CONNECTION_H__ - -#include "psqlodbc.h" - -#include -#include -#include "descriptor.h" - - -typedef enum -{ - CONN_NOT_CONNECTED, /* Connection has not been established */ - CONN_CONNECTED, /* Connection is up and has been - * established */ - CONN_DOWN, /* Connection is broken */ - CONN_EXECUTING /* the connection is currently executing a - * statement */ -} CONN_Status; - -/* These errors have general sql error state */ -#define CONNECTION_SERVER_NOT_REACHED 101 -#define CONNECTION_MSG_TOO_LONG 103 -#define CONNECTION_COULD_NOT_SEND 104 -#define CONNECTION_NO_SUCH_DATABASE 105 -#define CONNECTION_BACKEND_CRAZY 106 -#define CONNECTION_NO_RESPONSE 107 -#define CONNECTION_SERVER_REPORTED_ERROR 108 -#define CONNECTION_COULD_NOT_RECEIVE 109 -#define CONNECTION_SERVER_REPORTED_WARNING 110 -#define CONNECTION_NEED_PASSWORD 112 - -/* These errors correspond to specific SQL states */ -#define CONN_INIREAD_ERROR 201 -#define CONN_OPENDB_ERROR 202 -#define CONN_STMT_ALLOC_ERROR 203 -#define CONN_IN_USE 204 -#define CONN_UNSUPPORTED_OPTION 205 -/* Used by SetConnectoption to indicate unsupported options */ -#define CONN_INVALID_ARGUMENT_NO 206 -/* SetConnectOption: corresponds to ODBC--"S1009" */ -#define CONN_TRANSACT_IN_PROGRES 207 -#define CONN_NO_MEMORY_ERROR 208 -#define CONN_NOT_IMPLEMENTED_ERROR 209 -#define CONN_INVALID_AUTHENTICATION 210 -#define CONN_AUTH_TYPE_UNSUPPORTED 211 -#define CONN_UNABLE_TO_LOAD_DLL 212 - -#define CONN_OPTION_VALUE_CHANGED 213 -#define CONN_VALUE_OUT_OF_RANGE 214 - -#define CONN_TRUNCATED 215 - -/* Conn_status defines */ -#define CONN_IN_AUTOCOMMIT 0x01 -#define CONN_IN_TRANSACTION 0x02 - -/* AutoCommit functions */ -#define CC_set_autocommit_off(x) (x->transact_status &= ~CONN_IN_AUTOCOMMIT) -#define CC_set_autocommit_on(x) (x->transact_status |= CONN_IN_AUTOCOMMIT) -#define CC_is_in_autocommit(x) (x->transact_status & CONN_IN_AUTOCOMMIT) - -/* Transaction in/not functions */ -#define CC_set_in_trans(x) (x->transact_status |= CONN_IN_TRANSACTION) -#define CC_set_no_trans(x) (x->transact_status &= ~CONN_IN_TRANSACTION) -#define CC_is_in_trans(x) (x->transact_status & CONN_IN_TRANSACTION) - - -/* Authentication types */ -#define AUTH_REQ_OK 0 -#define AUTH_REQ_KRB4 1 -#define AUTH_REQ_KRB5 2 -#define AUTH_REQ_PASSWORD 3 -#define AUTH_REQ_CRYPT 4 -#define AUTH_REQ_MD5 5 -#define AUTH_REQ_SCM_CREDS 6 - -/* Startup Packet sizes */ -#define SM_DATABASE 64 -#define SM_USER 32 -#define SM_OPTIONS 64 -#define SM_UNUSED 64 -#define SM_TTY 64 - -/* Old 6.2 protocol defines */ -#define NO_AUTHENTICATION 7 -#define PATH_SIZE 64 -#define ARGV_SIZE 64 -#define USRNAMEDATALEN 16 - -typedef unsigned int ProtocolVersion; - -#define PG_PROTOCOL(major, minor) (((major) << 16) | (minor)) -#define PG_PROTOCOL_LATEST PG_PROTOCOL(2, 0) -#define PG_PROTOCOL_63 PG_PROTOCOL(1, 0) -#define PG_PROTOCOL_62 PG_PROTOCOL(0, 0) - -/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */ -typedef struct _StartupPacket -{ - ProtocolVersion protoVersion; - char database[SM_DATABASE]; - char user[SM_USER]; - char options[SM_OPTIONS]; - char unused[SM_UNUSED]; - char tty[SM_TTY]; -} StartupPacket; - - -/* This startup packet is to support pre-Postgres 6.3 protocol */ -typedef struct _StartupPacket6_2 -{ - unsigned int authtype; - char database[PATH_SIZE]; - char user[USRNAMEDATALEN]; - char options[ARGV_SIZE]; - char execfile[ARGV_SIZE]; - char tty[PATH_SIZE]; -} StartupPacket6_2; - -/* Transferred from pqcomm.h: */ - - -typedef ProtocolVersion MsgType; - -#define PG_PROTOCOL(m,n) (((m) << 16) | (n)) -#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) - -typedef struct CancelRequestPacket -{ - /* Note that each field is stored in network byte order! */ - MsgType cancelRequestCode; /* code to identify a cancel request */ - unsigned int backendPID; /* PID of client's backend */ - unsigned int cancelAuthCode; /* secret key to authorize cancel */ -} CancelRequestPacket; - -/* Structure to hold all the connection attributes for a specific - connection (used for both registry and file, DSN and DRIVER) -*/ -typedef struct -{ - char dsn[MEDIUM_REGISTRY_LEN]; - char desc[MEDIUM_REGISTRY_LEN]; - char driver[MEDIUM_REGISTRY_LEN]; - char server[MEDIUM_REGISTRY_LEN]; - char database[MEDIUM_REGISTRY_LEN]; - char username[MEDIUM_REGISTRY_LEN]; - char password[MEDIUM_REGISTRY_LEN]; - char conn_settings[LARGE_REGISTRY_LEN]; - char protocol[SMALL_REGISTRY_LEN]; - char port[SMALL_REGISTRY_LEN]; - char onlyread[SMALL_REGISTRY_LEN]; - char fake_oid_index[SMALL_REGISTRY_LEN]; - char show_oid_column[SMALL_REGISTRY_LEN]; - char row_versioning[SMALL_REGISTRY_LEN]; - char show_system_tables[SMALL_REGISTRY_LEN]; - char translation_dll[MEDIUM_REGISTRY_LEN]; - char translation_option[SMALL_REGISTRY_LEN]; - char focus_password; - char disallow_premature; - char allow_keyset; - char updatable_cursors; - char lf_conversion; - char true_is_minus1; - char int8_as; - GLOBAL_VALUES drivers; /* moved from driver's option */ -} ConnInfo; - -/* Macro to determine is the connection using 6.2 protocol? */ -#define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0) - -/* Macro to determine is the connection using 6.3 protocol? */ -#define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0) - -/* - * Macros to compare the server's version with a specified version - * 1st parameter: pointer to a ConnectionClass object - * 2nd parameter: major version number - * 3rd parameter: minor version number - */ -#define SERVER_VERSION_GT(conn, major, minor) \ - ((conn)->pg_version_major > major || \ - ((conn)->pg_version_major == major && (conn)->pg_version_minor > minor)) -#define SERVER_VERSION_GE(conn, major, minor) \ - ((conn)->pg_version_major > major || \ - ((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor)) -#define SERVER_VERSION_EQ(conn, major, minor) \ - ((conn)->pg_version_major == major && (conn)->pg_version_minor == minor) -#define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor)) -#define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor)) -/*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/ -#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1) -/*#else -#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1) -#endif*/ -/* - * Simplified macros to compare the server's version with a - * specified version - * Note: Never pass a variable as the second parameter. - * It must be a decimal constant of the form %d.%d . - */ -#define PG_VERSION_GT(conn, ver) \ - (SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) -#define PG_VERSION_GE(conn, ver) \ - (SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) -#define PG_VERSION_EQ(conn, ver) \ - (SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) -#define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver)) -#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver)) - -/* This is used to store cached table information in the connection */ -struct col_info -{ - QResultClass *result; - char *schema; - char name[MAX_TABLE_LEN + 1]; -}; - - /* Translation DLL entry points */ -#ifdef WIN32 -#define DLLHANDLE HINSTANCE -#else -#define WINAPI CALLBACK -#define DLLHANDLE void * -#define HINSTANCE void * -#endif - -typedef BOOL (FAR WINAPI * DataSourceToDriverProc) (UDWORD, - SWORD, - PTR, - SDWORD, - PTR, - SDWORD, - SDWORD FAR *, - UCHAR FAR *, - SWORD, - SWORD FAR *); - -typedef BOOL (FAR WINAPI * DriverToDataSourceProc) (UDWORD, - SWORD, - PTR, - SDWORD, - PTR, - SDWORD, - SDWORD FAR *, - UCHAR FAR *, - SWORD, - SWORD FAR *); - -/******* The Connection handle ************/ -struct ConnectionClass_ -{ - HENV henv; /* environment this connection was created - * on */ - StatementOptions stmtOptions; - ARDFields ardOptions; - APDFields apdOptions; - char *errormsg; - int errornumber; - CONN_Status status; - ConnInfo connInfo; - StatementClass **stmts; - int num_stmts; - SocketClass *sock; - int lobj_type; - int ntables; - COL_INFO **col_info; - long translation_option; - HINSTANCE translation_handle; - DataSourceToDriverProc DataSourceToDriver; - DriverToDataSourceProc DriverToDataSource; - Int2 driver_version; /* prepared for ODBC3.0 */ - char transact_status;/* Is a transaction is currently in - * progress */ - char errormsg_created; /* has an informative error msg - * been created? */ - char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL - * we're connected to - - * DJP 25-1-2001 */ - float pg_version_number; - Int2 pg_version_major; - Int2 pg_version_minor; - char ms_jet; - char unicode; - char result_uncommitted; - char schema_support; -#ifdef MULTIBYTE - char *client_encoding; - char *server_encoding; -#endif /* MULTIBYTE */ - int ccsc; - int be_pid; /* pid returned by backend */ - int be_key; /* auth code needed to send cancel */ - UInt4 isolation; - char *current_schema; -}; - - -/* Accessor functions */ -#define CC_get_socket(x) (x->sock) -#define CC_get_database(x) (x->connInfo.database) -#define CC_get_server(x) (x->connInfo.server) -#define CC_get_DSN(x) (x->connInfo.dsn) -#define CC_get_username(x) (x->connInfo.username) -#define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1') - - -/* for CC_DSN_info */ -#define CONN_DONT_OVERWRITE 0 -#define CONN_OVERWRITE 1 - - -/* prototypes */ -ConnectionClass *CC_Constructor(void); -void CC_conninfo_init(ConnInfo *conninfo); -char CC_Destructor(ConnectionClass *self); -int CC_cursor_count(ConnectionClass *self); -char CC_cleanup(ConnectionClass *self); -char CC_begin(ConnectionClass *self); -char CC_commit(ConnectionClass *self); -char CC_abort(ConnectionClass *self); -int CC_set_translation(ConnectionClass *self); -char CC_connect(ConnectionClass *self, char password_req, char *salt); -char CC_add_statement(ConnectionClass *self, StatementClass *stmt); -char CC_remove_statement(ConnectionClass *self, StatementClass *stmt); -char CC_get_error(ConnectionClass *self, int *number, char **message); -QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag); -void CC_clear_error(ConnectionClass *self); -char *CC_create_errormsg(ConnectionClass *self); -int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs); -char CC_send_settings(ConnectionClass *self); -void CC_lookup_lo(ConnectionClass *conn); -void CC_lookup_pg_version(ConnectionClass *conn); -void CC_initialize_pg_version(ConnectionClass *conn); -void CC_log_error(const char *func, const char *desc, const ConnectionClass *self); -int CC_get_max_query_len(const ConnectionClass *self); -int CC_send_cancel_request(const ConnectionClass *conn); -void CC_on_commit(ConnectionClass *conn); -void CC_on_abort(ConnectionClass *conn, UDWORD opt); -void ProcessRollback(ConnectionClass *conn, BOOL undo); -const char *CC_get_current_schema(ConnectionClass *conn); - -/* CC_send_query options */ -#define CLEAR_RESULT_ON_ABORT 1L -#define CREATE_KEYSET (1L << 1) /* create keyset for updatable curosrs */ -#define GO_INTO_TRANSACTION (1L << 2) /* issue begin in advance */ -/* CC_on_abort options */ -#define NO_TRANS 1L -#define CONN_DEAD (1L << 1) /* connection is no longer valid */ - -#endif /* __CONNECTION_H__ */ diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c deleted file mode 100644 index 2b58619232..0000000000 --- a/src/interfaces/odbc/convert.c +++ /dev/null @@ -1,3578 +0,0 @@ -/*------- - * Module: convert.c - * - * Description: This module contains routines related to - * converting parameters and columns into requested data types. - * Parameters are converted from their SQL_C data types into - * the appropriate postgres type. Columns are converted from - * their postgres type (SQL type) into the appropriate SQL_C - * data type. - * - * Classes: n/a - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ -/* Multibyte support Eiji Tokuya 2001-03-15 */ - -#include "convert.h" - -#include -#include -#include - -#ifdef MULTIBYTE -#include "multibyte.h" -#endif - -#include -#ifdef HAVE_LOCALE_H -#include -#endif -#include -#include -#include "statement.h" -#include "qresult.h" -#include "bind.h" -#include "pgtypes.h" -#include "lobj.h" -#include "connection.h" -#include "pgapifunc.h" - -#ifdef __CYGWIN__ -#define TIMEZONE_GLOBAL _timezone -#elif defined(WIN32) || defined(HAVE_INT_TIMEZONE) -#define TIMEZONE_GLOBAL timezone -#endif - -/* - * How to map ODBC scalar functions {fn func(args)} to Postgres. - * This is just a simple substitution. List augmented from: - * http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm - * - thomas 2000-04-03 - */ -char *mapFuncs[][2] = { -/* { "ASCII", "ascii" }, built_in */ - {"CHAR", "chr($*)" }, - {"CONCAT", "textcat($*)" }, -/* { "DIFFERENCE", "difference" }, how to ? */ - {"INSERT", "substring($1 from 1 for $2 - 1) || $4 || substring($1 from $2 + $3)" }, - {"LCASE", "lower($*)" }, - {"LEFT", "ltrunc($*)" }, - {"%2LOCATE", "strpos($2, $1)" }, /* 2 parameters */ - {"%3LOCATE", "strpos(substring($2 from $3), $1) + $3 - 1" }, /* 3 parameters */ - {"LENGTH", "char_length($*)"}, -/* { "LTRIM", "ltrim" }, built_in */ - {"RIGHT", "rtrunc($*)" }, - {"SPACE", "repeat('' '', $1)" }, -/* { "REPEAT", "repeat" }, built_in */ -/* { "REPLACE", "replace" }, ??? */ -/* { "RTRIM", "rtrim" }, built_in */ -/* { "SOUNDEX", "soundex" }, how to ? */ - {"SUBSTRING", "substr($*)" }, - {"UCASE", "upper($*)" }, - -/* { "ABS", "abs" }, built_in */ -/* { "ACOS", "acos" }, built_in */ -/* { "ASIN", "asin" }, built_in */ -/* { "ATAN", "atan" }, built_in */ -/* { "ATAN2", "atan2" }, bui;t_in */ - {"CEILING", "ceil($*)" }, -/* { "COS", "cos" }, built_in */ -/* { "COT", "cot" }, built_in */ -/* { "DEGREES", "degrees" }, built_in */ -/* { "EXP", "exp" }, built_in */ -/* { "FLOOR", "floor" }, built_in */ - {"LOG", "ln($*)" }, - {"LOG10", "log($*)" }, -/* { "MOD", "mod" }, built_in */ -/* { "PI", "pi" }, built_in */ - {"POWER", "pow($*)" }, -/* { "RADIANS", "radians" }, built_in */ - {"%0RAND", "random()" }, /* 0 parameters */ - {"%1RAND", "(setseed($1) * .0 + random())" }, /* 1 parameters */ -/* { "ROUND", "round" }, built_in */ -/* { "SIGN", "sign" }, built_in */ -/* { "SIN", "sin" }, built_in */ -/* { "SQRT", "sqrt" }, built_in */ -/* { "TAN", "tan" }, built_in */ - {"TRUNCATE", "trunc($*)" }, - - {"CURRENT_DATE", "current_date" }, - {"CURRENT_TIME", "current_time" }, - {"CURRENT_TIMESTAMP", "current_timestamp" }, - {"LOCALTIME", "localtime" }, - {"LOCALTIMESTAMP", "localtimestamp" }, - {"CURRENT_USER", "cast(current_user as text)" }, - {"SESSION_USER", "cast(session_user as text)" }, - {"CURDATE", "current_date" }, - {"CURTIME", "current_time" }, - {"DAYNAME", "to_char($1, 'Day')" }, - {"DAYOFMONTH", "cast(extract(day from $1) as integer)" }, - {"DAYOFWEEK", "(cast(extract(dow from $1) as integer) + 1)" }, - {"DAYOFYEAR", "cast(extract(doy from $1) as integer)" }, - {"HOUR", "cast(extract(hour from $1) as integer)" }, - {"MINUTE", "cast(extract(minute from $1) as integer)" }, - {"MONTH", "cast(extract(month from $1) as integer)" }, - {"MONTHNAME", " to_char($1, 'Month')" }, -/* { "NOW", "now" }, built_in */ - {"QUARTER", "cast(extract(quarter from $1) as integer)" }, - {"SECOND", "cast(extract(second from $1) as integer)" }, - {"WEEK", "cast(extract(week from $1) as integer)" }, - {"YEAR", "cast(extract(year from $1) as integer)" }, - -/* { "DATABASE", "database" }, */ - {"IFNULL", "coalesce($*)" }, - {"USER", "cast(current_user as text)" }, - {0, 0} -}; - -static const char *mapFunction(const char *func, int param_count); -static unsigned int conv_from_octal(const unsigned char *s); -static unsigned int conv_from_hex(const unsigned char *s); -static char *conv_to_octal(unsigned char val); - -/*--------- - * A Guide for date/time/timestamp conversions - * - * field_type fCType Output - * ---------- ------ ---------- - * PG_TYPE_DATE SQL_C_DEFAULT SQL_C_DATE - * PG_TYPE_DATE SQL_C_DATE SQL_C_DATE - * PG_TYPE_DATE SQL_C_TIMESTAMP SQL_C_TIMESTAMP (time = 0 (midnight)) - * PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME - * PG_TYPE_TIME SQL_C_TIME SQL_C_TIME - * PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date) - * PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP - * PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated) - * PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated) - * PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP - *--------- - */ - - - -/* - * TIMESTAMP <-----> SIMPLE_TIME - * precision support since 7.2. - * time zone support is unavailable(the stuff is unreliable) - */ -static BOOL -timestamp2stime(const char *str, SIMPLE_TIME *st, BOOL *bZone, int *zone) -{ - char rest[64], - *ptr; - int scnt, - i; -#if defined(WIN32) || defined(HAVE_INT_TIMEZONE) - long timediff; -#endif - BOOL withZone = *bZone; - - *bZone = FALSE; - *zone = 0; - st->fr = 0; - st->infinity = 0; - if ((scnt = sscanf(str, "%4d-%2d-%2d %2d:%2d:%2d%s", &st->y, &st->m, &st->d, &st->hh, &st->mm, &st->ss, rest)) < 6) - return FALSE; - else if (scnt == 6) - return TRUE; - switch (rest[0]) - { - case '+': - *bZone = TRUE; - *zone = atoi(&rest[1]); - break; - case '-': - *bZone = TRUE; - *zone = -atoi(&rest[1]); - break; - case '.': - if ((ptr = strchr(rest, '+')) != NULL) - { - *bZone = TRUE; - *zone = atoi(&ptr[1]); - *ptr = '\0'; - } - else if ((ptr = strchr(rest, '-')) != NULL) - { - *bZone = TRUE; - *zone = -atoi(&ptr[1]); - *ptr = '\0'; - } - for (i = 1; i < 10; i++) - { - if (!isdigit((unsigned char) rest[i])) - break; - } - for (; i < 10; i++) - rest[i] = '0'; - rest[i] = '\0'; - st->fr = atoi(&rest[1]); - break; - default: - return TRUE; - } - if (!withZone || !*bZone || st->y < 1970) - return TRUE; -#if defined(WIN32) || defined(HAVE_INT_TIMEZONE) - if (!tzname[0] || !tzname[0][0]) - { - *bZone = FALSE; - return TRUE; - } - timediff = TIMEZONE_GLOBAL + (*zone) * 3600; - if (!daylight && timediff == 0) /* the same timezone */ - return TRUE; - else - { - struct tm tm, - *tm2; - time_t time0; - - *bZone = FALSE; - tm.tm_year = st->y - 1900; - tm.tm_mon = st->m - 1; - tm.tm_mday = st->d; - tm.tm_hour = st->hh; - tm.tm_min = st->mm; - tm.tm_sec = st->ss; - tm.tm_isdst = -1; - time0 = mktime(&tm); - if (time0 < 0) - return TRUE; - if (tm.tm_isdst > 0) - timediff -= 3600; - if (timediff == 0) /* the same time zone */ - return TRUE; - time0 -= timediff; - if (time0 >= 0 && (tm2 = localtime(&time0)) != NULL) - { - st->y = tm2->tm_year + 1900; - st->m = tm2->tm_mon + 1; - st->d = tm2->tm_mday; - st->hh = tm2->tm_hour; - st->mm = tm2->tm_min; - st->ss = tm2->tm_sec; - *bZone = TRUE; - } - } -#endif /* WIN32 */ - return TRUE; -} - -static BOOL -stime2timestamp(const SIMPLE_TIME *st, char *str, BOOL bZone, BOOL precision) -{ - char precstr[16], - zonestr[16]; - int i; - - precstr[0] = '\0'; - if (st->infinity > 0) - { - strcpy(str, "Infinity"); - return TRUE; - } - else if (st->infinity < 0) - { - strcpy(str, "-Infinity"); - return TRUE; - } - if (precision && st->fr) - { - sprintf(precstr, ".%09d", st->fr); - for (i = 9; i > 0; i--) - { - if (precstr[i] != '0') - break; - precstr[i] = '\0'; - } - } - zonestr[0] = '\0'; -#if defined(WIN32) || defined(HAVE_INT_TIMEZONE) - if (bZone && tzname[0] && tzname[0][0] && st->y >= 1970) - { - long zoneint; - struct tm tm; - time_t time0; - - zoneint = TIMEZONE_GLOBAL; - if (daylight && st->y >= 1900) - { - tm.tm_year = st->y - 1900; - tm.tm_mon = st->m - 1; - tm.tm_mday = st->d; - tm.tm_hour = st->hh; - tm.tm_min = st->mm; - tm.tm_sec = st->ss; - tm.tm_isdst = -1; - time0 = mktime(&tm); - if (time0 >= 0 && tm.tm_isdst > 0) - zoneint -= 3600; - } - if (zoneint > 0) - sprintf(zonestr, "-%02d", (int) zoneint / 3600); - else - sprintf(zonestr, "+%02d", -(int) zoneint / 3600); - } -#endif /* WIN32 */ - sprintf(str, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d%s%s", st->y, st->m, st->d, st->hh, st->mm, st->ss, precstr, zonestr); - return TRUE; -} - -/* This is called by SQLFetch() */ -int -copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col) -{ - ARDFields *opts = SC_get_ARD(stmt); - BindInfoClass *bic = &(opts->bindings[col]); - UInt4 offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0; - - return copy_and_convert_field(stmt, field_type, value, (Int2) bic->returntype, (PTR) (bic->buffer + offset), - (SDWORD) bic->buflen, (SDWORD *) (bic->used + (offset >> 2))); -} - - -/* This is called by SQLGetData() */ -int -copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, - PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue) -{ - static char *func = "copy_and_convert_field"; - ARDFields *opts = SC_get_ARD(stmt); - Int4 len = 0, - copy_len = 0; - SIMPLE_TIME st; - time_t t = time(NULL); - struct tm *tim; - int pcbValueOffset, - rgbValueOffset; - char *rgbValueBindRow; - const char *ptr; - int bind_row = stmt->bind_row; - int bind_size = opts->bind_size; - int result = COPY_OK; -#ifdef HAVE_LOCALE_H - char saved_locale[256]; -#endif /* HAVE_LOCALE_H */ - BOOL changed, true_is_minus1 = FALSE; - const char *neut_str = value; - char midtemp[2][32]; - int mtemp_cnt = 0; - static BindInfoClass sbic; - BindInfoClass *pbic; -#ifdef UNICODE_SUPPORT - BOOL wchanged = FALSE; -#endif /* UNICODE_SUPPORT */ - - if (stmt->current_col >= 0) - { - pbic = &opts->bindings[stmt->current_col]; - if (pbic->data_left == -2) - pbic->data_left = (cbValueMax > 0) ? 0 : -1; /* This seems to be * - * needed by ADO ? */ - if (pbic->data_left == 0) - { - if (pbic->ttlbuf != NULL) - { - free(pbic->ttlbuf); - pbic->ttlbuf = NULL; - pbic->ttlbuflen = 0; - } - pbic->data_left = -2; /* needed by ADO ? */ - return COPY_NO_DATA_FOUND; - } - } - /*--------- - * rgbValueOffset is *ONLY* for character and binary data. - * pcbValueOffset is for computing any pcbValue location - *--------- - */ - - if (bind_size > 0) - pcbValueOffset = rgbValueOffset = (bind_size * bind_row); - else - { - pcbValueOffset = bind_row * sizeof(SDWORD); - rgbValueOffset = bind_row * cbValueMax; - - } - - memset(&st, 0, sizeof(SIMPLE_TIME)); - - /* Initialize current date */ - tim = localtime(&t); - st.m = tim->tm_mon + 1; - st.d = tim->tm_mday; - st.y = tim->tm_year + 1900; - - mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value == NULL) ? "" : value, cbValueMax); - - if (!value) - { - /* - * handle a null just by returning SQL_NULL_DATA in pcbValue, and - * doing nothing to the buffer. - */ - if (pcbValue) - { - *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA; - return COPY_OK; - } - else - { - stmt->errornumber = STMT_RETURN_NULL_WITHOUT_INDICATOR; - stmt->errormsg = "StrLen_or_IndPtr was a null pointer and NULL data was retrieved"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - - if (stmt->hdbc->DataSourceToDriver != NULL) - { - int length = strlen(value); - - stmt->hdbc->DataSourceToDriver(stmt->hdbc->translation_option, - SQL_CHAR, - value, length, - value, length, NULL, - NULL, 0, NULL); - } - - /* - * First convert any specific postgres types into more useable data. - * - * NOTE: Conversions from PG char/varchar of a date/time/timestamp value - * to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported - */ - switch (field_type) - { - /* - * $$$ need to add parsing for date/time/timestamp strings in - * PG_TYPE_CHAR,VARCHAR $$$ - */ - case PG_TYPE_DATE: - sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d); - break; - - case PG_TYPE_TIME: - sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss); - break; - - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIMESTAMP: - st.fr = 0; - st.infinity = 0; - if (strnicmp(value, "infinity", 8) == 0) - { - st.infinity = 1; - st.m = 12; - st.d = 31; - st.y = 9999; - st.hh = 23; - st.mm = 59; - st.ss = 59; - } - if (strnicmp(value, "-infinity", 9) == 0) - { - st.infinity = -1; - st.m = 0; - st.d = 0; - st.y = 0; - st.hh = 0; - st.mm = 0; - st.ss = 0; - } - if (strnicmp(value, "invalid", 7) != 0) - { - BOOL bZone = (field_type != PG_TYPE_TIMESTAMP_NO_TMZONE && PG_VERSION_GE(SC_get_conn(stmt), 7.2)); - int zone; - - /* - * sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, - * &st.d, &st.hh, &st.mm, &st.ss); - */ - bZone = FALSE; /* time zone stuff is unreliable */ - timestamp2stime(value, &st, &bZone, &zone); - } - else - { - /* - * The timestamp is invalid so set something conspicuous, - * like the epoch - */ - t = 0; - tim = localtime(&t); - st.m = tim->tm_mon + 1; - st.d = tim->tm_mday; - st.y = tim->tm_year + 1900; - st.hh = tim->tm_hour; - st.mm = tim->tm_min; - st.ss = tim->tm_sec; - } - break; - - case PG_TYPE_BOOL: - { /* change T/F to 1/0 */ - char *s; - - s = midtemp[mtemp_cnt]; - switch (((char *)value)[0]) - { - case 'f': - case 'F': - case 'n': - case 'N': - case '0': - strcpy(s, "0"); - break; - default: - if (true_is_minus1) - strcpy(s, "-1"); - else - strcpy(s, "1"); - } - neut_str = midtemp[mtemp_cnt]; - mtemp_cnt++; - } - break; - - /* This is for internal use by SQLStatistics() */ - case PG_TYPE_INT2VECTOR: - { - int nval, - i; - const char *vp; - - /* this is an array of eight integers */ - short *short_array = (short *) ((char *) rgbValue + rgbValueOffset); - - len = 32; - vp = value; - nval = 0; - mylog("index=("); - for (i = 0; i < 16; i++) - { - if (sscanf(vp, "%hd", &short_array[i]) != 1) - break; - - mylog(" %d", short_array[i]); - nval++; - - /* skip the current token */ - while ((*vp != '\0') && (!isspace((unsigned char) *vp))) - vp++; - /* and skip the space to the next token */ - while ((*vp != '\0') && (isspace((unsigned char) *vp))) - vp++; - if (*vp == '\0') - break; - } - mylog(") nval = %d\n", nval); - - for (i = nval; i < 16; i++) - short_array[i] = 0; - -#if 0 - sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd", - &short_array[0], - &short_array[1], - &short_array[2], - &short_array[3], - &short_array[4], - &short_array[5], - &short_array[6], - &short_array[7]); -#endif - - /* There is no corresponding fCType for this. */ - if (pcbValue) - *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len; - - return COPY_OK; /* dont go any further or the data will be - * trashed */ - } - - /* - * This is a large object OID, which is used to store - * LONGVARBINARY objects. - */ - case PG_TYPE_LO: - - return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); - - default: - - if (field_type == stmt->hdbc->lobj_type) /* hack until permanent - * type available */ - return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); - } - - /* Change default into something useable */ - if (fCType == SQL_C_DEFAULT) - { - fCType = pgtype_to_ctype(stmt, field_type); - - mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType); - } - - rgbValueBindRow = (char *) rgbValue + rgbValueOffset; - -#ifdef UNICODE_SUPPORT - if (fCType == SQL_C_CHAR || fCType == SQL_C_WCHAR) -#else - if (fCType == SQL_C_CHAR) -#endif /* UNICODE_SUPPORT */ - { - /* Special character formatting as required */ - - /* - * These really should return error if cbValueMax is not big - * enough. - */ - switch (field_type) - { - case PG_TYPE_DATE: - len = 10; - if (cbValueMax > len) - sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d", st.y, st.m, st.d); - break; - - case PG_TYPE_TIME: - len = 8; - if (cbValueMax > len) - sprintf(rgbValueBindRow, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss); - break; - - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIMESTAMP: - len = 19; - if (cbValueMax > len) - sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", - st.y, st.m, st.d, st.hh, st.mm, st.ss); - break; - - case PG_TYPE_BOOL: - len = strlen(neut_str); - if (cbValueMax > len) - { - strcpy(rgbValueBindRow, neut_str); - mylog("PG_TYPE_BOOL: rgbValueBindRow = '%s'\n", rgbValueBindRow); - } - break; - - /* - * Currently, data is SILENTLY TRUNCATED for BYTEA and - * character data types if there is not enough room in - * cbValueMax because the driver can't handle multiple - * calls to SQLGetData for these, yet. Most likely, the - * buffer passed in will be big enough to handle the - * maximum limit of postgres, anyway. - * - * LongVarBinary types are handled correctly above, observing - * truncation and all that stuff since there is - * essentially no limit on the large object used to store - * those. - */ - case PG_TYPE_BYTEA:/* convert binary data to hex strings - * (i.e, 255 = "FF") */ - len = convert_pgbinary_to_char(neut_str, rgbValueBindRow, cbValueMax); - - /***** THIS IS NOT PROPERLY IMPLEMENTED *****/ - break; - - default: - if (stmt->current_col < 0) - { - pbic = &sbic; - pbic->data_left = -1; - } - else - pbic = &opts->bindings[stmt->current_col]; - if (pbic->data_left < 0) - { - BOOL lf_conv = SC_get_conn(stmt)->connInfo.lf_conversion; -#ifdef UNICODE_SUPPORT - if (fCType == SQL_C_WCHAR) - { - len = utf8_to_ucs2_lf(neut_str, -1, lf_conv, NULL, 0); - len *= 2; - wchanged = changed = TRUE; - } - else -#endif /* UNICODE_SUPPORT */ - /* convert linefeeds to carriage-return/linefeed */ - len = convert_linefeeds(neut_str, NULL, 0, lf_conv, &changed); - if (cbValueMax == 0) /* just returns length - * info */ - { - result = COPY_RESULT_TRUNCATED; - break; - } - if (!pbic->ttlbuf) - pbic->ttlbuflen = 0; - if (changed || len >= cbValueMax) - { - if (len >= (int) pbic->ttlbuflen) - { - pbic->ttlbuf = realloc(pbic->ttlbuf, len + 1); - pbic->ttlbuflen = len + 1; - } -#ifdef UNICODE_SUPPORT - if (fCType == SQL_C_WCHAR) - { - utf8_to_ucs2_lf(neut_str, -1, lf_conv, (SQLWCHAR *) pbic->ttlbuf, len / 2); - } - else -#endif /* UNICODE_SUPPORT */ - convert_linefeeds(neut_str, pbic->ttlbuf, pbic->ttlbuflen, lf_conv, &changed); - ptr = pbic->ttlbuf; - } - else - { - if (pbic->ttlbuf) - { - free(pbic->ttlbuf); - pbic->ttlbuf = NULL; - } - ptr = neut_str; - } - } - else - ptr = pbic->ttlbuf; - - mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr); - - if (stmt->current_col >= 0) - { - if (pbic->data_left > 0) - { - ptr += strlen(ptr) - pbic->data_left; - len = pbic->data_left; - } - else - pbic->data_left = len; - } - - if (cbValueMax > 0) - { - copy_len = (len >= cbValueMax) ? cbValueMax - 1 : len; - -#ifdef HAVE_LOCALE_H - switch (field_type) - { - case PG_TYPE_FLOAT4: - case PG_TYPE_FLOAT8: - case PG_TYPE_NUMERIC: - { - struct lconv *lc; - char *new_string; - int i, j; - - new_string = malloc( cbValueMax ); - lc = localeconv(); - for (i = 0, j = 0; ptr[i]; i++) - if (ptr[i] == '.') - { - strncpy(&new_string[j], lc->decimal_point, strlen(lc->decimal_point)); - j += strlen(lc->decimal_point); - } - else - new_string[j++] = ptr[i]; - new_string[j] = '\0'; - strncpy_null(rgbValueBindRow, new_string, copy_len + 1); - free(new_string); - break; - } - default: - /* Copy the data */ - strncpy_null(rgbValueBindRow, ptr, copy_len + 1); - } -#else /* HAVE_LOCALE_H */ - /* Copy the data */ - memcpy(rgbValueBindRow, ptr, copy_len); - rgbValueBindRow[copy_len] = '\0'; -#endif /* HAVE_LOCALE_H */ - - /* Adjust data_left for next time */ - if (stmt->current_col >= 0) - pbic->data_left -= copy_len; - } - - /* - * Finally, check for truncation so that proper status can - * be returned - */ - if (cbValueMax > 0 && len >= cbValueMax) - result = COPY_RESULT_TRUNCATED; - else - { - if (pbic->ttlbuf != NULL) - { - free(pbic->ttlbuf); - pbic->ttlbuf = NULL; - } - } - - - mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValueBindRow = '%s'\n", len, cbValueMax, rgbValueBindRow); - break; - } -#ifdef UNICODE_SUPPORT - if (SQL_C_WCHAR == fCType && ! wchanged) - { - if (cbValueMax > 2 * len) - { - char *str = strdup(rgbValueBindRow); - UInt4 ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / 2); - if (cbValueMax < 2 * (SDWORD) ucount) - result = COPY_RESULT_TRUNCATED; - len = ucount * 2; - free(str); - } - else - { - len *= 2; - result = COPY_RESULT_TRUNCATED; - } - } -#endif /* UNICODE_SUPPORT */ - - } - else - { - /* - * for SQL_C_CHAR, it's probably ok to leave currency symbols in. - * But to convert to numeric types, it is necessary to get rid of - * those. - */ - if (field_type == PG_TYPE_MONEY) - { - if (convert_money(neut_str, midtemp[mtemp_cnt], sizeof(midtemp[0]))) - { - neut_str = midtemp[mtemp_cnt]; - mtemp_cnt++; - } - else - return COPY_UNSUPPORTED_TYPE; - } - - switch (fCType) - { - case SQL_C_DATE: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_DATE: /* 91 */ -#endif - len = 6; - { - DATE_STRUCT *ds; - - if (bind_size > 0) - ds = (DATE_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - else - ds = (DATE_STRUCT *) rgbValue + bind_row; - ds->year = st.y; - ds->month = st.m; - ds->day = st.d; - } - break; - - case SQL_C_TIME: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_TIME: /* 92 */ -#endif - len = 6; - { - TIME_STRUCT *ts; - - if (bind_size > 0) - ts = (TIME_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - else - ts = (TIME_STRUCT *) rgbValue + bind_row; - ts->hour = st.hh; - ts->minute = st.mm; - ts->second = st.ss; - } - break; - - case SQL_C_TIMESTAMP: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_TIMESTAMP: /* 93 */ -#endif - len = 16; - { - TIMESTAMP_STRUCT *ts; - - if (bind_size > 0) - ts = (TIMESTAMP_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - else - ts = (TIMESTAMP_STRUCT *) rgbValue + bind_row; - ts->year = st.y; - ts->month = st.m; - ts->day = st.d; - ts->hour = st.hh; - ts->minute = st.mm; - ts->second = st.ss; - ts->fraction = st.fr; - } - break; - - case SQL_C_BIT: - len = 1; - if (bind_size > 0) - *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str); - else - *((UCHAR *) rgbValue + bind_row) = atoi(neut_str); - - /* - * mylog("SQL_C_BIT: bind_row = %d val = %d, cb = %d, - * rgb=%d\n", bind_row, atoi(neut_str), cbValueMax, - * *((UCHAR *)rgbValue)); - */ - break; - - case SQL_C_STINYINT: - case SQL_C_TINYINT: - len = 1; - if (bind_size > 0) - *(SCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str); - else - *((SCHAR *) rgbValue + bind_row) = atoi(neut_str); - break; - - case SQL_C_UTINYINT: - len = 1; - if (bind_size > 0) - *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str); - else - *((UCHAR *) rgbValue + bind_row) = atoi(neut_str); - break; - - case SQL_C_FLOAT: -#ifdef HAVE_LOCALE_H - strcpy(saved_locale, setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); -#endif /* HAVE_LOCALE_H */ - len = 4; - if (bind_size > 0) - *(SFLOAT *) ((char *) rgbValue + (bind_row * bind_size)) = (float) atof(neut_str); - else - *((SFLOAT *) rgbValue + bind_row) = (float) atof(neut_str); -#ifdef HAVE_LOCALE_H - setlocale(LC_ALL, saved_locale); -#endif /* HAVE_LOCALE_H */ - break; - - case SQL_C_DOUBLE: -#ifdef HAVE_LOCALE_H - strcpy(saved_locale, setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); -#endif /* HAVE_LOCALE_H */ - len = 8; - if (bind_size > 0) - *(SDOUBLE *) ((char *) rgbValue + (bind_row * bind_size)) = atof(neut_str); - else - *((SDOUBLE *) rgbValue + bind_row) = atof(neut_str); -#ifdef HAVE_LOCALE_H - setlocale(LC_ALL, saved_locale); -#endif /* HAVE_LOCALE_H */ - break; - -#if (ODBCVER >= 0x0300) - case SQL_C_NUMERIC: -#ifdef HAVE_LOCALE_H - /* strcpy(saved_locale, setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); not needed currently */ -#endif /* HAVE_LOCALE_H */ - { - SQL_NUMERIC_STRUCT *ns; - int i, nlen, bit, hval, tv, dig, sta, olen; - char calv[SQL_MAX_NUMERIC_LEN * 3], *wv; - BOOL dot_exist; - - len = sizeof(SQL_NUMERIC_STRUCT); - if (bind_size > 0) - ns = (SQL_NUMERIC_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - else - ns = (SQL_NUMERIC_STRUCT *) rgbValue + bind_row; - for (wv = neut_str; *wv && isspace(*wv); wv++) - ; - ns->sign = 1; - if (*wv == '-') - { - ns->sign = 0; - wv++; - } - else if (*wv == '+') - wv++; - while (*wv == '0') wv++; - ns->precision = 0; - ns->scale = 0; - for (nlen = 0, dot_exist = FALSE;; wv++) - { - if (*wv == '.') - { - if (dot_exist) - break; - dot_exist = TRUE; - } - else if (!isdigit(*wv)) - break; - else - { - if (dot_exist) - ns->scale++; - else - ns->precision++; - calv[nlen++] = *wv; - } - } - memset(ns->val, 0, sizeof(ns->val)); - for (hval = 0, bit = 1L, sta = 0, olen = 0; sta < nlen;) - { - for (dig = 0, i = sta; i < nlen; i++) - { - tv = dig * 10 + calv[i] - '0'; - dig = tv % 2; - calv[i] = tv / 2 + '0'; - if (i == sta && tv < 2) - sta++; - } - if (dig > 0) - hval |= bit; - bit <<= 1; - if (bit >= (1L << 8)) - { - ns->val[olen++] = hval; - hval = 0; - bit = 1L; - if (olen >= SQL_MAX_NUMERIC_LEN - 1) - { - ns->scale = sta - ns->precision; - break; - } - } - } - if (hval && olen < SQL_MAX_NUMERIC_LEN - 1) - ns->val[olen++] = hval; - } -#ifdef HAVE_LOCALE_H - /* setlocale(LC_ALL, saved_locale); */ -#endif /* HAVE_LOCALE_H */ - break; -#endif /* ODBCVER */ - - case SQL_C_SSHORT: - case SQL_C_SHORT: - len = 2; - if (bind_size > 0) - *(SWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str); - else - *((SWORD *) rgbValue + bind_row) = atoi(neut_str); - break; - - case SQL_C_USHORT: - len = 2; - if (bind_size > 0) - *(UWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str); - else - *((UWORD *) rgbValue + bind_row) = atoi(neut_str); - break; - - case SQL_C_SLONG: - case SQL_C_LONG: - len = 4; - if (bind_size > 0) - *(SDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(neut_str); - else - *((SDWORD *) rgbValue + bind_row) = atol(neut_str); - break; - - case SQL_C_ULONG: - len = 4; - if (bind_size > 0) - *(UDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(neut_str); - else - *((UDWORD *) rgbValue + bind_row) = atol(neut_str); - break; - -#if (ODBCVER >= 0x0300) && defined(ODBCINT64) -#ifdef WIN32 - case SQL_C_SBIGINT: - len = 8; - if (bind_size > 0) - *(SQLBIGINT *) ((char *) rgbValue + (bind_row * bind_size)) = _atoi64(neut_str); - else - *((SQLBIGINT *) rgbValue + bind_row) = _atoi64(neut_str); - break; - - case SQL_C_UBIGINT: - len = 8; - if (bind_size > 0) - *(SQLUBIGINT *) ((char *) rgbValue + (bind_row * bind_size)) = _atoi64(neut_str); - else - *((SQLUBIGINT *) rgbValue + bind_row) = _atoi64(neut_str); - break; - -#endif /* WIN32 */ -#endif /* ODBCINT64 */ - case SQL_C_BINARY: - - /* truncate if necessary */ - /* convert octal escapes to bytes */ - - if (stmt->current_col < 0) - { - pbic = &sbic; - pbic->data_left = -1; - } - else - pbic = &opts->bindings[stmt->current_col]; - if (!pbic->ttlbuf) - pbic->ttlbuflen = 0; - if (len = strlen(neut_str), len >= (int) pbic->ttlbuflen) - { - pbic->ttlbuf = realloc(pbic->ttlbuf, len + 1); - pbic->ttlbuflen = len + 1; - } - len = convert_from_pgbinary(neut_str, pbic->ttlbuf, pbic->ttlbuflen); - ptr = pbic->ttlbuf; - - if (stmt->current_col >= 0) - { - /* - * Second (or more) call to SQLGetData so move the - * pointer - */ - if (pbic->data_left > 0) - { - ptr += len - pbic->data_left; - len = pbic->data_left; - } - - /* First call to SQLGetData so initialize data_left */ - else - pbic->data_left = len; - - } - - if (cbValueMax > 0) - { - copy_len = (len > cbValueMax) ? cbValueMax : len; - - /* Copy the data */ - memcpy(rgbValueBindRow, ptr, copy_len); - - /* Adjust data_left for next time */ - if (stmt->current_col >= 0) - pbic->data_left -= copy_len; - } - - /* - * Finally, check for truncation so that proper status can - * be returned - */ - if (len > cbValueMax) - result = COPY_RESULT_TRUNCATED; - - if (pbic->ttlbuf) - { - free(pbic->ttlbuf); - pbic->ttlbuf = NULL; - } - mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len); - break; - - default: - return COPY_UNSUPPORTED_TYPE; - } - } - - /* store the length of what was copied, if there's a place for it */ - if (pcbValue) - *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len; - - if (result == COPY_OK && stmt->current_col >= 0) - opts->bindings[stmt->current_col].data_left = 0; - return result; - -} - - -/*-------------------------------------------------------------------- - * Functions/Macros to get rid of query size limit. - * - * I always used the follwoing macros to convert from - * old_statement to new_statement. Please improve it - * if you have a better way. Hiroshi 2001/05/22 - *-------------------------------------------------------------------- - */ - -#define FLGP_PREPARE_DUMMY_CURSOR 1L -#define FLGP_CURSOR_CHECK_OK (1L << 1) -#define FLGP_SELECT_INTO (1L << 2) -#define FLGP_SELECT_FOR_UPDATE (1L << 3) -typedef struct _QueryParse { - const char *statement; - int statement_type; - UInt4 opos; - int from_pos; - int where_pos; - UInt4 stmt_len; - BOOL in_quote, in_dquote, in_escape; - char token_save[64]; - int token_len; - BOOL prev_token_end; - BOOL proc_no_param; - unsigned int declare_pos; - UInt4 flags; -#ifdef MULTIBYTE - encoded_str encstr; -#endif /* MULTIBYTE */ -} QueryParse; - -static int -QP_initialize(QueryParse *q, const StatementClass *stmt) -{ - q->statement = stmt->statement; - q->statement_type = stmt->statement_type; - q->opos = 0; - q->from_pos = -1; - q->where_pos = -1; - q->stmt_len = (q->statement) ? strlen(q->statement) : -1; - q->in_quote = q->in_dquote = q->in_escape = FALSE; - q->token_save[0] = '\0'; - q->token_len = 0; - q->prev_token_end = TRUE; - q->proc_no_param = TRUE; - q->declare_pos = 0; - q->flags = 0; -#ifdef MULTIBYTE - make_encoded_str(&q->encstr, SC_get_conn(stmt), q->statement); -#endif /* MULTIBYTE */ - - return q->stmt_len; -} - -#define FLGB_PRE_EXECUTING 1L -#define FLGB_INACCURATE_RESULT (1L << 1) -#define FLGB_CREATE_KEYSET (1L << 2) -#define FLGB_KEYSET_DRIVEN (1L << 3) -typedef struct _QueryBuild { - char *query_statement; - UInt4 str_size_limit; - UInt4 str_alsize; - UInt4 npos; - int current_row; - int param_number; - APDFields *apdopts; - UInt4 load_stmt_len; - UInt4 flags; - BOOL lf_conv; - int ccsc; - int errornumber; - const char *errormsg; - - ConnectionClass *conn; /* mainly needed for LO handling */ - StatementClass *stmt; /* needed to set error info in ENLARGE_.. */ -} QueryBuild; - -#define INIT_MIN_ALLOC 4096 -static int -QB_initialize(QueryBuild *qb, UInt4 size, StatementClass *stmt, ConnectionClass *conn) -{ - UInt4 newsize = 0; - - qb->flags = 0; - qb->load_stmt_len = 0; - qb->stmt = stmt; - qb->apdopts = NULL; - if (conn) - qb->conn = conn; - else if (stmt) - { - qb->apdopts = SC_get_APD(stmt); - qb->conn = SC_get_conn(stmt); - if (stmt->pre_executing) - qb->flags |= FLGB_PRE_EXECUTING; - } - else - { - qb->conn = NULL; - return -1; - } - qb->lf_conv = qb->conn->connInfo.lf_conversion; - qb->ccsc = qb->conn->ccsc; - - if (stmt) - qb->str_size_limit = stmt->stmt_size_limit; - else - qb->str_size_limit = -1; - if (qb->str_size_limit > 0) - { - if (size > qb->str_size_limit) - return -1; - newsize = qb->str_size_limit; - } - else - { - newsize = INIT_MIN_ALLOC; - while (newsize <= size) - newsize *= 2; - } - if ((qb->query_statement = malloc(newsize)) == NULL) - { - qb->str_alsize = 0; - return -1; - } - qb->query_statement[0] = '\0'; - qb->str_alsize = newsize; - qb->npos = 0; - qb->current_row = stmt->exec_current_row < 0 ? 0 : stmt->exec_current_row; - qb->param_number = -1; - qb->errornumber = 0; - qb->errormsg = NULL; - - return newsize; -} - -static int -QB_initialize_copy(QueryBuild *qb_to, const QueryBuild *qb_from, UInt4 size) -{ - memcpy(qb_to, qb_from, sizeof(QueryBuild)); - - if (qb_to->str_size_limit > 0) - { - if (size > qb_to->str_size_limit) - return -1; - } - if ((qb_to->query_statement = malloc(size)) == NULL) - { - qb_to->str_alsize = 0; - return -1; - } - qb_to->query_statement[0] = '\0'; - qb_to->str_alsize = size; - qb_to->npos = 0; - - return size; -} - -static void -QB_Destructor(QueryBuild *qb) -{ - if (qb->query_statement) - { - free(qb->query_statement); - qb->query_statement = NULL; - qb->str_alsize = 0; - } -} - -/* - * New macros (Aceto) - *-------------------- - */ - -#define F_OldChar(qp) \ -qp->statement[qp->opos] - -#define F_OldPtr(qp) \ -(qp->statement + qp->opos) - -#define F_OldNext(qp) \ -(++qp->opos) - -#define F_OldPrior(qp) \ -(--qp->opos) - -#define F_OldPos(qp) \ -qp->opos - -#define F_ExtractOldTo(qp, buf, ch, maxsize) \ -do { \ - unsigned int c = 0; \ - while (qp->statement[qp->opos] != '\0' && qp->statement[qp->opos] != ch) \ - { \ - buf[c++] = qp->statement[qp->opos++]; \ - if (c >= maxsize) \ - break; \ - } \ - if (qp->statement[qp->opos] == '\0') \ - return SQL_ERROR; \ - buf[c] = '\0'; \ -} while (0) - -#define F_NewChar(qb) \ -qb->query_statement[qb->npos] - -#define F_NewPtr(qb) \ -(qb->query_statement + qb->npos) - -#define F_NewNext(qb) \ -(++qb->npos) - -#define F_NewPos(qb) \ -(qb->npos) - - -static int -convert_escape(QueryParse *qp, QueryBuild *qb); -static int -inner_process_tokens(QueryParse *qp, QueryBuild *qb); -static int -ResolveOneParam(QueryBuild *qb); -static int -processParameters(QueryParse *qp, QueryBuild *qb, -UInt4 *output_count, Int4 param_pos[][2]); - -static int -enlarge_query_statement(QueryBuild *qb, unsigned int newsize) -{ - unsigned int newalsize = INIT_MIN_ALLOC; - static char *func = "enlarge_statement"; - - if (qb->str_size_limit > 0 && qb->str_size_limit < (int) newsize) - { - free(qb->query_statement); - qb->query_statement = NULL; - qb->str_alsize = 0; - if (qb->stmt) - { - qb->stmt->errormsg = "Query buffer overflow in copy_statement_with_parameters"; - qb->stmt->errornumber = STMT_EXEC_ERROR; - SC_log_error(func, "", qb->stmt); - } - else - { - qb->errormsg = "Query buffer overflow in copy_statement_with_parameters"; - qb->errornumber = STMT_EXEC_ERROR; - } - return -1; - } - while (newalsize <= newsize) - newalsize *= 2; - if (!(qb->query_statement = realloc(qb->query_statement, newalsize))) - { - qb->str_alsize = 0; - if (qb->stmt) - { - qb->stmt->errormsg = "Query buffer allocate error in copy_statement_with_parameters"; - qb->stmt->errornumber = STMT_EXEC_ERROR; - } - else - { - qb->errormsg = "Query buffer allocate error in copy_statement_with_parameters"; - qb->errornumber = STMT_EXEC_ERROR; - } - return 0; - } - qb->str_alsize = newalsize; - return newalsize; -} - -/*---------- - * Enlarge stmt_with_params if necessary. - *---------- - */ -#define ENLARGE_NEWSTATEMENT(qb, newpos) \ - if (newpos >= qb->str_alsize) \ - { \ - if (enlarge_query_statement(qb, newpos) <= 0) \ - return SQL_ERROR; \ - } - -/*---------- - * Terminate the stmt_with_params string with NULL. - *---------- - */ -#define CVT_TERMINATE(qb) \ -do { \ - qb->query_statement[qb->npos] = '\0'; \ -} while (0) - -/*---------- - * Append a data. - *---------- - */ -#define CVT_APPEND_DATA(qb, s, len) \ -do { \ - unsigned int newpos = qb->npos + len; \ - ENLARGE_NEWSTATEMENT(qb, newpos) \ - memcpy(&qb->query_statement[qb->npos], s, len); \ - qb->npos = newpos; \ - qb->query_statement[newpos] = '\0'; \ -} while (0) - -/*---------- - * Append a string. - *---------- - */ -#define CVT_APPEND_STR(qb, s) \ -do { \ - unsigned int len = strlen(s); \ - CVT_APPEND_DATA(qb, s, len); \ -} while (0) - -/*---------- - * Append a char. - *---------- - */ -#define CVT_APPEND_CHAR(qb, c) \ -do { \ - ENLARGE_NEWSTATEMENT(qb, qb->npos + 1); \ - qb->query_statement[qb->npos++] = c; \ -} while (0) - -/*---------- - * Append a binary data. - * Newly reqeuired size may be overestimated currently. - *---------- - */ -#define CVT_APPEND_BINARY(qb, buf, used) \ -do { \ - unsigned int newlimit = qb->npos + 5 * used; \ - ENLARGE_NEWSTATEMENT(qb, newlimit); \ - qb->npos += convert_to_pgbinary(buf, &qb->query_statement[qb->npos], used); \ -} while (0) - -/*---------- - * - *---------- - */ -#define CVT_SPECIAL_CHARS(qb, buf, used) \ -do { \ - int cnvlen = convert_special_chars(buf, NULL, used, qb->lf_conv, qb->ccsc); \ - unsigned int newlimit = qb->npos + cnvlen; \ -\ - ENLARGE_NEWSTATEMENT(qb, newlimit); \ - convert_special_chars(buf, &qb->query_statement[qb->npos], used, qb->lf_conv, qb->ccsc); \ - qb->npos += cnvlen; \ -} while (0) - -/*---------- - * Check if the statement is - * SELECT ... INTO table FROM ..... - * This isn't really a strict check but ... - *---------- - */ -static BOOL -into_table_from(const char *stmt) -{ - if (strnicmp(stmt, "into", 4)) - return FALSE; - stmt += 4; - if (!isspace((unsigned char) *stmt)) - return FALSE; - while (isspace((unsigned char) *(++stmt))); - switch (*stmt) - { - case '\0': - case ',': - case '\'': - return FALSE; - case '\"': /* double quoted table name ? */ - do - { - do - while (*(++stmt) != '\"' && *stmt); - while (*stmt && *(++stmt) == '\"'); - while (*stmt && !isspace((unsigned char) *stmt) && *stmt != '\"') - stmt++; - } - while (*stmt == '\"'); - break; - default: - while (!isspace((unsigned char) *(++stmt))); - break; - } - if (!*stmt) - return FALSE; - while (isspace((unsigned char) *(++stmt))); - if (strnicmp(stmt, "from", 4)) - return FALSE; - return isspace((unsigned char) stmt[4]); -} - -/*---------- - * Check if the statement is - * SELECT ... FOR UPDATE ..... - * This isn't really a strict check but ... - *---------- - */ -static BOOL -table_for_update(const char *stmt, int *endpos) -{ - const char *wstmt = stmt; - - while (isspace((unsigned char) *(++wstmt))); - if (!*wstmt) - return FALSE; - if (strnicmp(wstmt, "update", 6)) - return FALSE; - wstmt += 6; - *endpos = wstmt - stmt; - return !wstmt[0] || isspace((unsigned char) wstmt[0]); -} - -/*---------- - * Check if the statement is - * INSERT INTO ... () VALUES () - * This isn't really a strict check but ... - *---------- - */ -static BOOL -insert_without_target(const char *stmt, int *endpos) -{ - const char *wstmt = stmt; - - while (isspace((unsigned char) *(++wstmt))); - if (!*wstmt) - return FALSE; - if (strnicmp(wstmt, "VALUES", 6)) - return FALSE; - wstmt += 6; - if (!wstmt[0] || !isspace((unsigned char) wstmt[0])) - return FALSE; - while (isspace((unsigned char) *(++wstmt))); - if (*wstmt != '(' || *(++wstmt) != ')') - return FALSE; - wstmt++; - *endpos = wstmt - stmt; - return !wstmt[0] || isspace((unsigned char) wstmt[0]) - || ';' == wstmt[0]; -} - -#ifdef MULTIBYTE -#define my_strchr(conn, s1,c1) pg_mbschr(conn->ccsc, s1,c1) -#else -#define my_strchr(conn, s1,c1) strchr(s1,c1) -#endif -/* - * This function inserts parameters into an SQL statements. - * It will also modify a SELECT statement for use with declare/fetch cursors. - * This function does a dynamic memory allocation to get rid of query size limit! - */ -int -copy_statement_with_parameters(StatementClass *stmt) -{ - static char *func = "copy_statement_with_parameters"; - RETCODE retval; - QueryParse query_org, *qp; - QueryBuild query_crt, *qb; - - char *new_statement; - - BOOL begin_first = FALSE, prepare_dummy_cursor = FALSE; - ConnectionClass *conn = SC_get_conn(stmt); - ConnInfo *ci = &(conn->connInfo); - int current_row; - - if (!stmt->statement) - { - SC_log_error(func, "No statement string", stmt); - return SQL_ERROR; - } - - current_row = stmt->exec_current_row < 0 ? 0 : stmt->exec_current_row; - qp = &query_org; - QP_initialize(qp, stmt); - - if (ci->disallow_premature) - prepare_dummy_cursor = stmt->pre_executing; - if (prepare_dummy_cursor); - qp->flags |= FLGP_PREPARE_DUMMY_CURSOR; - - -#ifdef DRIVER_CURSOR_IMPLEMENT - if (stmt->statement_type != STMT_TYPE_SELECT) - { - stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY; - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - } - else if (stmt->options.cursor_type == SQL_CURSOR_FORWARD_ONLY) - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - else if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY) - { - if (stmt->parse_status == STMT_PARSE_NONE) - parse_statement(stmt); - if (stmt->parse_status == STMT_PARSE_FATAL) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - else if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - stmt->options.cursor_type = SQL_CURSOR_STATIC; - } - else - { - qp->from_pos = stmt->from_pos; - qp->where_pos = stmt->where_pos; - } - } -#else - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) - stmt->options.cursor_type = SQL_CURSOR_STATIC; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - /* If the application hasn't set a cursor name, then generate one */ - if (stmt->cursor_name[0] == '\0') - sprintf(stmt->cursor_name, "SQL_CUR%p", stmt); - if (stmt->stmt_with_params) - { - free(stmt->stmt_with_params); - stmt->stmt_with_params = NULL; - } - qb = &query_crt; - if (QB_initialize(qb, qp->stmt_len, stmt, NULL) < 0) - return SQL_ERROR; - new_statement = qb->query_statement; - - stmt->miscinfo = 0; - /* For selects, prepend a declare cursor to the statement */ - if (stmt->statement_type == STMT_TYPE_SELECT) - { - SC_set_pre_executable(stmt); - if (prepare_dummy_cursor || ci->drivers.use_declarefetch) - { - if (prepare_dummy_cursor) - { - if (!CC_is_in_trans(conn) && PG_VERSION_GE(conn, 7.1)) - { - strcpy(new_statement, "BEGIN;"); - begin_first = TRUE; - } - } - else if (ci->drivers.use_declarefetch) - SC_set_fetchcursor(stmt); - sprintf(new_statement, "%sdeclare %s cursor for ", - new_statement, stmt->cursor_name); - qb->npos = strlen(new_statement); - qp->flags |= FLGP_CURSOR_CHECK_OK; - qp->declare_pos = qb->npos; - } - else if (SQL_CONCUR_READ_ONLY != stmt->options.scroll_concurrency) - { - qb->flags |= FLGB_CREATE_KEYSET; - if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type) - qb->flags |= FLGB_KEYSET_DRIVEN; - } - } - - for (qp->opos = 0; qp->opos < qp->stmt_len; qp->opos++) - { - retval = inner_process_tokens(qp, qb); - if (SQL_ERROR == retval) - { - if (0 == stmt->errornumber) - { - stmt->errornumber = qb->errornumber; - stmt->errormsg = qb->errormsg; - } - SC_log_error(func, "", stmt); - QB_Destructor(qb); - return retval; - } - } - /* make sure new_statement is always null-terminated */ - CVT_TERMINATE(qb); - - new_statement = qb->query_statement; - stmt->statement_type = qp->statement_type; - stmt->inaccurate_result = (0 != (qb->flags & FLGB_INACCURATE_RESULT)); - if (0 != (qp->flags & FLGP_SELECT_INTO)) - { - SC_no_pre_executable(stmt); - SC_no_fetchcursor(stmt); - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - } - if (0 != (qp->flags & FLGP_SELECT_FOR_UPDATE)) - { - SC_no_fetchcursor(stmt); - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - } - - if (conn->DriverToDataSource != NULL) - { - int length = strlen(new_statement); - - conn->DriverToDataSource(conn->translation_option, - SQL_CHAR, - new_statement, length, - new_statement, length, NULL, - NULL, 0, NULL); - } - -#ifdef DRIVER_CURSOR_IMPLEMENT - if (!stmt->load_statement && qp->from_pos >= 0) - { - UInt4 npos = qb->load_stmt_len; - - if (0 == npos) - { - npos = qb->npos; - for (; npos > 0; npos--) - { - if (isspace(new_statement[npos - 1])) - continue; - if (';' != new_statement[npos - 1]) - break; - } - if (0 != (qb->flags & FLGB_KEYSET_DRIVEN)) - { - qb->npos = npos; - /* ---------- - * 1st query is for field information - * 2nd query is keyset gathering - */ - CVT_APPEND_STR(qb, " where ctid = '(,)';select ctid, oid from "); - CVT_APPEND_DATA(qb, qp->statement + qp->from_pos + 5, npos - qp->from_pos - 5); - } - } - stmt->load_statement = malloc(npos + 1); - memcpy(stmt->load_statement, qb->query_statement, npos); - stmt->load_statement[npos] = '\0'; - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - if (prepare_dummy_cursor && SC_is_pre_executable(stmt)) - { - char fetchstr[128]; - - sprintf(fetchstr, ";fetch backward in %s;close %s;", - stmt->cursor_name, stmt->cursor_name); - if (begin_first && CC_is_in_autocommit(conn)) - strcat(fetchstr, "COMMIT;"); - CVT_APPEND_STR(qb, fetchstr); - stmt->inaccurate_result = TRUE; - } - - stmt->stmt_with_params = qb->query_statement; - return SQL_SUCCESS; -} - -static int -inner_process_tokens(QueryParse *qp, QueryBuild *qb) -{ - static char *func = "inner_process_tokens"; - BOOL lf_conv = qb->lf_conv; - - RETCODE retval; - char oldchar; - - if (qp->from_pos == (Int4) qp->opos) - { - CVT_APPEND_STR(qb, ", CTID, OID "); - } - else if (qp->where_pos == (Int4) qp->opos) - { - qb->load_stmt_len = qb->npos; - if (0 != (qb->flags & FLGB_KEYSET_DRIVEN)) - { - CVT_APPEND_STR(qb, "where ctid = '(,)';select CTID, OID from "); - CVT_APPEND_DATA(qb, qp->statement + qp->from_pos + 5, qp->where_pos - qp->from_pos - 5); - } - } -#ifdef MULTIBYTE - oldchar = encoded_byte_check(&qp->encstr, qp->opos); - if (ENCODE_STATUS(qp->encstr) != 0) - { - CVT_APPEND_CHAR(qb, oldchar); - return SQL_SUCCESS; - } - - /* - * From here we are guaranteed to handle a 1-byte character. - */ -#else - oldchar = qp->statement[qp->opos]; -#endif - - if (qp->in_escape) /* escape check */ - { - qp->in_escape = FALSE; - CVT_APPEND_CHAR(qb, oldchar); - return SQL_SUCCESS; - } - else if (qp->in_quote || qp->in_dquote) /* quote/double quote check */ - { - if (oldchar == '\\') - qp->in_escape = TRUE; - else if (oldchar == '\'' && qp->in_quote) - qp->in_quote = FALSE; - else if (oldchar == '\"' && qp->in_dquote) - qp->in_dquote = FALSE; - CVT_APPEND_CHAR(qb, oldchar); - return SQL_SUCCESS; - } - - /* - * From here we are guranteed to be in neither an escape, a quote - * nor a double quote. - */ - /* Squeeze carriage-return/linefeed pairs to linefeed only */ - else if (lf_conv && oldchar == '\r' && qp->opos + 1 < qp->stmt_len && - qp->statement[qp->opos + 1] == '\n') - return SQL_SUCCESS; - - /* - * Handle literals (date, time, timestamp) and ODBC scalar - * functions - */ - else if (oldchar == '{') - { - if (SQL_ERROR == convert_escape(qp, qb)) - { - if (0 == qb->errornumber) - { - qb->errornumber = STMT_EXEC_ERROR; - qb->errormsg = "ODBC escape convert error"; - } - mylog("%s convert_escape error\n", func); - return SQL_ERROR; - } - if (isalnum(F_OldPtr(qp)[1])) - CVT_APPEND_CHAR(qb, ' '); - return SQL_SUCCESS; - } - /* End of an escape sequence */ - else if (oldchar == '}') - { - if (qp->statement_type == STMT_TYPE_PROCCALL) - { - if (qp->proc_no_param) - CVT_APPEND_STR(qb, "()"); - } - else if (!isspace(F_OldPtr(qp)[1])) - CVT_APPEND_CHAR(qb, ' '); - return SQL_SUCCESS; - } - - /* - * Can you have parameter markers inside of quotes? I dont think - * so. All the queries I've seen expect the driver to put quotes - * if needed. - */ - else if (oldchar != '?') - { - if (oldchar == '\'') - qp->in_quote = TRUE; - else if (oldchar == '\\') - qp->in_escape = TRUE; - else if (oldchar == '\"') - qp->in_dquote = TRUE; - else - { - if (isspace((unsigned char) oldchar)) - { - if (!qp->prev_token_end) - { - qp->prev_token_end = TRUE; - qp->token_save[qp->token_len] = '\0'; - if (qp->token_len == 4) - { - if (0 != (qp->flags & FLGP_CURSOR_CHECK_OK) && - into_table_from(&qp->statement[qp->opos - qp->token_len])) - { - qp->flags |= FLGP_SELECT_INTO; - qp->flags &= ~FLGP_CURSOR_CHECK_OK; - qb->flags &= ~FLGB_KEYSET_DRIVEN; - qp->statement_type = STMT_TYPE_CREATE; - memmove(qb->query_statement, qb->query_statement + qp->declare_pos, qb->npos - qp->declare_pos); - qb->npos -= qp->declare_pos; - } - } - else if (qp->token_len == 3) - { - int endpos; - - if (0 != (qp->flags & FLGP_CURSOR_CHECK_OK) && - strnicmp(qp->token_save, "for", 3) == 0 && - table_for_update(&qp->statement[qp->opos], &endpos)) - { - qp->flags |= FLGP_SELECT_FOR_UPDATE; - qp->flags &= ~FLGP_CURSOR_CHECK_OK; - if (qp->flags & FLGP_PREPARE_DUMMY_CURSOR) - { - qb->npos -= 4; - qp->opos += endpos; - } - else - { - memmove(qb->query_statement, qb->query_statement + qp->declare_pos, qb->npos - qp->declare_pos); - qb->npos -= qp->declare_pos; - } - } - } - else if (qp->token_len == 2) - { - int endpos; - - if (STMT_TYPE_INSERT == qp->statement_type && - strnicmp(qp->token_save, "()", 2) == 0 && - insert_without_target(&qp->statement[qp->opos], &endpos)) - { - qb->npos -= 2; - CVT_APPEND_STR(qb, "DEFAULT VALUES"); - qp->opos += endpos; - return SQL_SUCCESS; - } - } - } - } - else if (qp->prev_token_end) - { - qp->prev_token_end = FALSE; - qp->token_save[0] = oldchar; - qp->token_len = 1; - } - else if (qp->token_len + 1 < sizeof(qp->token_save)) - qp->token_save[qp->token_len++] = oldchar; - } - CVT_APPEND_CHAR(qb, oldchar); - return SQL_SUCCESS; - } - - /* - * Its a '?' parameter alright - */ - if (retval = ResolveOneParam(qb), retval < 0) - return retval; - - return SQL_SUCCESS; -} - -#if (ODBCVER >= 0x0300) -static BOOL -ResolveNumericParam(const SQL_NUMERIC_STRUCT *ns, char *chrform) -{ - static int prec[] = {1, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 29, 32, 34, 37, 39}; - Int4 i, j, k, ival, vlen, len, newlen; - unsigned char calv[40]; - const unsigned char *val = (const unsigned char *) ns->val; - BOOL next_figure; - - if (0 == ns->precision) - { - strcpy(chrform, "0"); - return TRUE; - } - else if (ns->precision < prec[sizeof(Int4)]) - { - for (i = 0, ival = 0; i < sizeof(Int4) && prec[i] <= ns->precision; i++) - { - ival += (val[i] << (8 * i)); /* ns->val is little endian */ - } - if (0 == ns->scale) - { - if (0 == ns->sign) - ival *= -1; - sprintf(chrform, "%d", ival); - } - else if (ns->scale > 0) - { - Int4 i, div, o1val, o2val; - - for (i = 0, div = 1; i < ns->scale; i++) - div *= 10; - o1val = ival / div; - o2val = ival % div; - if (0 == ns->sign) - o1val *= -1; - sprintf(chrform, "%d.%0.*d", o1val, ns->scale, o2val); - } - return TRUE; - } - - for (i = 0; i < SQL_MAX_NUMERIC_LEN && prec[i] <= ns->precision; i++) - ; - vlen = i; - len = 0; - memset(calv, 0, sizeof(calv)); - for (i = vlen - 1; i >= 0; i--) - { - for (j = len - 1; j >= 0; j--) - { - if (!calv[j]) - continue; - ival = (((Int4)calv[j]) << 8); - calv[j] = (ival % 10); - ival /= 10; - calv[j + 1] += (ival % 10); - ival /= 10; - calv[j + 2] += (ival % 10); - ival /= 10; - calv[j + 3] += ival; - for (k = j;; k++) - { - next_figure = FALSE; - if (calv[k] > 0) - { - if (k >= len) - len = k + 1; - while (calv[k] > 9) - { - calv[k + 1]++; - calv[k] -= 10; - next_figure = TRUE; - } - } - if (k >= j + 3 && !next_figure) - break; - } - } - ival = val[i]; - if (!ival) - continue; - calv[0] += (ival % 10); - ival /= 10; - calv[1] += (ival % 10); - ival /= 10; - calv[2] += ival; - for (j = 0;; j++) - { - next_figure = FALSE; - if (calv[j] > 0) - { - if (j >= len) - len = j + 1; - while (calv[j] > 9) - { - calv[j + 1]++; - calv[j] -= 10; - next_figure = TRUE; - } - } - if (j >= 2 && !next_figure) - break; - } - } - newlen = 0; - if (0 == ns->sign) - chrform[newlen++] = '-'; - for (i = len - 1; i >= ns->scale; i--) - chrform[newlen++] = calv[i] + '0'; - if (ns->scale > 0) - { - chrform[newlen++] = '.'; - for (; i >= 0; i--) - chrform[newlen++] = calv[i] + '0'; - } - chrform[newlen] = '\0'; - return TRUE; -} -#endif /* ODBCVER */ - -/* - * - */ -static int -ResolveOneParam(QueryBuild *qb) -{ - const char *func = "ResolveOneParam"; - - ConnectionClass *conn = qb->conn; - ConnInfo *ci = &(conn->connInfo); - APDFields *opts = qb->apdopts; - - int param_number; - char param_string[128], tmp[256], - cbuf[PG_NUMERIC_MAX_PRECISION * 2]; /* seems big enough to handle the data in this function */ - Int2 param_ctype, param_sqltype; - SIMPLE_TIME st; - time_t t; - struct tm *tim; - SDWORD used; - char *buffer, *buf, *allocbuf; - Oid lobj_oid; - int lobj_fd, retval; - UInt4 offset = opts->param_offset_ptr ? *opts->param_offset_ptr : 0; - UInt4 current_row = qb->current_row; - - /* - * Its a '?' parameter alright - */ - param_number = ++qb->param_number; - - if (param_number >= opts->allocated) - { - if (0 != (qb->flags & FLGB_PRE_EXECUTING)) - { - CVT_APPEND_STR(qb, "NULL"); - qb->flags |= FLGB_INACCURATE_RESULT; - return SQL_SUCCESS; - } - else - { - CVT_APPEND_CHAR(qb, '?'); - return SQL_SUCCESS; - } - } - - /* Assign correct buffers based on data at exec param or not */ - if (opts->parameters[param_number].data_at_exec) - { - used = opts->parameters[param_number].EXEC_used ? *opts->parameters[param_number].EXEC_used : SQL_NTS; - buffer = opts->parameters[param_number].EXEC_buffer; - } - else - { - UInt4 bind_size = opts->param_bind_type; - UInt4 ctypelen; - - buffer = opts->parameters[param_number].buffer + offset; - if (current_row > 0) - { - if (bind_size > 0) - buffer += (bind_size * current_row); - else if (ctypelen = ctype_length(opts->parameters[param_number].CType), ctypelen > 0) - buffer += current_row * ctypelen; - else - buffer += current_row * opts->parameters[param_number].buflen; - } - if (opts->parameters[param_number].used) - { - UInt4 p_offset = offset; - if (bind_size > 0) - p_offset = offset + bind_size * current_row; - else - p_offset = offset + sizeof(SDWORD) * current_row; - used = *(SDWORD *)((char *)opts->parameters[param_number].used + p_offset); - } - else - used = SQL_NTS; - } - - /* Handle NULL parameter data */ - if (used == SQL_NULL_DATA) - { - CVT_APPEND_STR(qb, "NULL"); - return SQL_SUCCESS; - } - - /* - * If no buffer, and it's not null, then what the hell is it? Just - * leave it alone then. - */ - if (!buffer) - { - if (0 != (qb->flags & FLGB_PRE_EXECUTING)) - { - CVT_APPEND_STR(qb, "NULL"); - qb->flags |= FLGB_INACCURATE_RESULT; - return SQL_SUCCESS; - } - else - { - CVT_APPEND_CHAR(qb, '?'); - return SQL_SUCCESS; - } - } - - param_ctype = opts->parameters[param_number].CType; - param_sqltype = opts->parameters[param_number].SQLType; - - mylog("%s: from(fcType)=%d, to(fSqlType)=%d\n", func, - param_ctype, param_sqltype); - - /* replace DEFAULT with something we can use */ - if (param_ctype == SQL_C_DEFAULT) - param_ctype = sqltype_to_default_ctype(param_sqltype); - - allocbuf = buf = NULL; - param_string[0] = '\0'; - cbuf[0] = '\0'; - memset(&st, 0, sizeof(st)); - t = time(NULL); - tim = localtime(&t); - st.m = tim->tm_mon + 1; - st.d = tim->tm_mday; - st.y = tim->tm_year + 1900; - - /* Convert input C type to a neutral format */ - switch (param_ctype) - { - case SQL_C_BINARY: - case SQL_C_CHAR: - buf = buffer; - break; - -#ifdef UNICODE_SUPPORT - case SQL_C_WCHAR: - buf = allocbuf = ucs2_to_utf8((SQLWCHAR *) buffer, used / 2, &used); - used *= 2; - break; -#endif /* UNICODE_SUPPORT */ - - case SQL_C_DOUBLE: - sprintf(param_string, "%.15g", - *((SDOUBLE *) buffer)); - break; - - case SQL_C_FLOAT: - sprintf(param_string, "%.6g", - *((SFLOAT *) buffer)); - break; - - case SQL_C_SLONG: - case SQL_C_LONG: - sprintf(param_string, "%ld", - *((SDWORD *) buffer)); - break; - -#if (ODBCVER >= 0x0300) && defined(ODBCINT64) -#ifdef WIN32 - case SQL_C_SBIGINT: - sprintf(param_string, "%I64d", - *((SQLBIGINT *) buffer)); - break; - - case SQL_C_UBIGINT: - sprintf(param_string, "%I64u", - *((SQLUBIGINT *) buffer)); - break; - -#endif /* WIN32 */ -#endif /* ODBCINT64 */ - case SQL_C_SSHORT: - case SQL_C_SHORT: - sprintf(param_string, "%d", - *((SWORD *) buffer)); - break; - - case SQL_C_STINYINT: - case SQL_C_TINYINT: - sprintf(param_string, "%d", - *((SCHAR *) buffer)); - break; - - case SQL_C_ULONG: - sprintf(param_string, "%lu", - *((UDWORD *) buffer)); - break; - - case SQL_C_USHORT: - sprintf(param_string, "%u", - *((UWORD *) buffer)); - break; - - case SQL_C_UTINYINT: - sprintf(param_string, "%u", - *((UCHAR *) buffer)); - break; - - case SQL_C_BIT: - { - int i = *((UCHAR *) buffer); - - sprintf(param_string, "%d", i ? 1 : 0); - break; - } - - case SQL_C_DATE: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_DATE: /* 91 */ -#endif - { - DATE_STRUCT *ds = (DATE_STRUCT *) buffer; - - st.m = ds->month; - st.d = ds->day; - st.y = ds->year; - - break; - } - - case SQL_C_TIME: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_TIME: /* 92 */ -#endif - { - TIME_STRUCT *ts = (TIME_STRUCT *) buffer; - - st.hh = ts->hour; - st.mm = ts->minute; - st.ss = ts->second; - - break; - } - - case SQL_C_TIMESTAMP: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_TIMESTAMP: /* 93 */ -#endif - { - TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer; - - st.m = tss->month; - st.d = tss->day; - st.y = tss->year; - st.hh = tss->hour; - st.mm = tss->minute; - st.ss = tss->second; - st.fr = tss->fraction; - - mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss); - - break; - - } -#if (ODBCVER >= 0x0300) - case SQL_C_NUMERIC: - if (ResolveNumericParam((SQL_NUMERIC_STRUCT *) buffer, param_string)) - break; -#endif - default: - /* error */ - qb->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters"; - qb->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - CVT_TERMINATE(qb); /* just in case */ - return SQL_ERROR; - } - - /* - * Now that the input data is in a neutral format, convert it to - * the desired output format (sqltype) - */ - - switch (param_sqltype) - { - case SQL_CHAR: - case SQL_VARCHAR: - case SQL_LONGVARCHAR: -#ifdef UNICODE_SUPPORT - case SQL_WCHAR: - case SQL_WVARCHAR: - case SQL_WLONGVARCHAR: -#endif /* UNICODE_SUPPORT */ - - CVT_APPEND_CHAR(qb, '\''); /* Open Quote */ - - /* it was a SQL_C_CHAR */ - if (buf) - CVT_SPECIAL_CHARS(qb, buf, used); - - /* it was a numeric type */ - else if (param_string[0] != '\0') - CVT_APPEND_STR(qb, param_string); - - /* it was date,time,timestamp -- use m,d,y,hh,mm,ss */ - else - { - sprintf(tmp, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", - st.y, st.m, st.d, st.hh, st.mm, st.ss); - - CVT_APPEND_STR(qb, tmp); - } - - CVT_APPEND_CHAR(qb, '\''); /* Close Quote */ - - break; - - case SQL_DATE: -#if (ODBCVER >= 0x0300) - case SQL_TYPE_DATE: /* 91 */ -#endif - if (buf) - { /* copy char data to time */ - my_strcpy(cbuf, sizeof(cbuf), buf, used); - parse_datetime(cbuf, &st); - } - - sprintf(tmp, "'%.4d-%.2d-%.2d'::date", st.y, st.m, st.d); - - CVT_APPEND_STR(qb, tmp); - break; - - case SQL_TIME: -#if (ODBCVER >= 0x0300) - case SQL_TYPE_TIME: /* 92 */ -#endif - if (buf) - { /* copy char data to time */ - my_strcpy(cbuf, sizeof(cbuf), buf, used); - parse_datetime(cbuf, &st); - } - - sprintf(tmp, "'%.2d:%.2d:%.2d'::time", st.hh, st.mm, st.ss); - - CVT_APPEND_STR(qb, tmp); - break; - - case SQL_TIMESTAMP: -#if (ODBCVER >= 0x0300) - case SQL_TYPE_TIMESTAMP: /* 93 */ -#endif - - if (buf) - { - my_strcpy(cbuf, sizeof(cbuf), buf, used); - parse_datetime(cbuf, &st); - } - - /* - * sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'", st.y, - * st.m, st.d, st.hh, st.mm, st.ss); - */ - tmp[0] = '\''; - /* Time zone stuff is unreliable */ - stime2timestamp(&st, tmp + 1, USE_ZONE, PG_VERSION_GE(conn, 7.2)); - strcat(tmp, "'::timestamp"); - - CVT_APPEND_STR(qb, tmp); - - break; - - case SQL_BINARY: - case SQL_VARBINARY:/* non-ascii characters should be - * converted to octal */ - CVT_APPEND_CHAR(qb, '\''); /* Open Quote */ - - mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used); - - CVT_APPEND_BINARY(qb, buf, used); - - CVT_APPEND_CHAR(qb, '\''); /* Close Quote */ - - break; - - case SQL_LONGVARBINARY: - - if (opts->parameters[param_number].data_at_exec) - lobj_oid = opts->parameters[param_number].lobj_oid; - else - { - /* begin transaction if needed */ - if (!CC_is_in_trans(conn)) - { - if (!CC_begin(conn)) - { - qb->errormsg = "Could not begin (in-line) a transaction"; - qb->errornumber = STMT_EXEC_ERROR; - return SQL_ERROR; - } - } - - /* store the oid */ - lobj_oid = lo_creat(conn, INV_READ | INV_WRITE); - if (lobj_oid == 0) - { - qb->errornumber = STMT_EXEC_ERROR; - qb->errormsg = "Couldnt create (in-line) large object."; - return SQL_ERROR; - } - - /* store the fd */ - lobj_fd = lo_open(conn, lobj_oid, INV_WRITE); - if (lobj_fd < 0) - { - qb->errornumber = STMT_EXEC_ERROR; - qb->errormsg = "Couldnt open (in-line) large object for writing."; - return SQL_ERROR; - } - - retval = lo_write(conn, lobj_fd, buffer, used); - - lo_close(conn, lobj_fd); - - /* commit transaction if needed */ - if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn)) - { - if (!CC_commit(conn)) - { - qb->errormsg = "Could not commit (in-line) a transaction"; - qb->errornumber = STMT_EXEC_ERROR; - return SQL_ERROR; - } - } - } - - /* - * the oid of the large object -- just put that in for the - * parameter marker -- the data has already been sent to - * the large object - */ - sprintf(param_string, "'%d'", lobj_oid); - CVT_APPEND_STR(qb, param_string); - - break; - - /* - * because of no conversion operator for bool and int4, - * SQL_BIT - */ - /* must be quoted (0 or 1 is ok to use inside the quotes) */ - - case SQL_REAL: - if (buf) - my_strcpy(param_string, sizeof(param_string), buf, used); - sprintf(tmp, "'%s'::float4", param_string); - CVT_APPEND_STR(qb, tmp); - break; - case SQL_FLOAT: - case SQL_DOUBLE: - if (buf) - my_strcpy(param_string, sizeof(param_string), buf, used); - sprintf(tmp, "'%s'::float8", param_string); - CVT_APPEND_STR(qb, tmp); - break; - case SQL_NUMERIC: - if (buf) - { - cbuf[0] = '\''; - my_strcpy(cbuf + 1, sizeof(cbuf) - 3, buf, used); /* 3 = 1('\'') + - * strlen("'") - * + 1('\0') */ - strcat(cbuf, "'"); - } - else - sprintf(cbuf, "'%s'", param_string); - CVT_APPEND_STR(qb, cbuf); - break; - default: /* a numeric type or SQL_BIT */ - if (param_sqltype == SQL_BIT) - CVT_APPEND_CHAR(qb, '\''); /* Open Quote */ - - if (buf) - { - switch (used) - { - case SQL_NULL_DATA: - break; - case SQL_NTS: - CVT_APPEND_STR(qb, buf); - break; - default: - CVT_APPEND_DATA(qb, buf, used); - } - } - else - CVT_APPEND_STR(qb, param_string); - - if (param_sqltype == SQL_BIT) - CVT_APPEND_CHAR(qb, '\''); /* Close Quote */ - - break; - } -#ifdef UNICODE_SUPPORT - if (allocbuf) - free(allocbuf); -#endif /* UNICODE_SUPPORT */ - return SQL_SUCCESS; -} - - -static const char * -mapFunction(const char *func, int param_count) -{ - int i; - - for (i = 0; mapFuncs[i][0]; i++) - { - if (mapFuncs[i][0][0] == '%') - { - if (mapFuncs[i][0][1] - '0' == param_count && - !stricmp(mapFuncs[i][0] + 2, func)) - return mapFuncs[i][1]; - } - else if (!stricmp(mapFuncs[i][0], func)) - return mapFuncs[i][1]; - } - - return NULL; -} - -/* - * processParameters() - * Process function parameters and work with embedded escapes sequences. - */ -static int -processParameters(QueryParse *qp, QueryBuild *qb, - UInt4 *output_count, Int4 param_pos[][2]) -{ - static const char *func = "processParameters"; - int retval, innerParenthesis, param_count; - BOOL stop; - - /* begin with outer '(' */ - innerParenthesis = 0; - param_count = 0; - stop = FALSE; - for (; F_OldPos(qp) < qp->stmt_len; F_OldNext(qp)) - { - retval = inner_process_tokens(qp, qb); - if (retval == SQL_ERROR) - return retval; -#ifdef MULTIBYTE - if (ENCODE_STATUS(qp->encstr) != 0) - continue; -#endif - if (qp->in_dquote || qp->in_quote || qp->in_escape) - continue; - - switch (F_OldChar(qp)) - { - case ',': - if (1 == innerParenthesis) - { - param_pos[param_count][1] = F_NewPos(qb) - 2; - param_count++; - param_pos[param_count][0] = F_NewPos(qb); - param_pos[param_count][1] = -1; - } - break; - case '(': - if (0 == innerParenthesis) - { - param_pos[param_count][0] = F_NewPos(qb); - param_pos[param_count][1] = -1; - } - innerParenthesis++; - break; - - case ')': - innerParenthesis--; - if (0 == innerParenthesis) - { - param_pos[param_count][1] = F_NewPos(qb) - 2; - param_count++; - param_pos[param_count][0] = - param_pos[param_count][1] = -1; - } - if (output_count) - *output_count = F_NewPos(qb); - break; - - case '}': - stop = (0 == innerParenthesis); - break; - - } - if (stop) /* returns with the last } position */ - break; - } - if (param_pos[param_count][0] >= 0) - { - mylog("%s closing ) not found %d\n", func, innerParenthesis); - qb->errornumber = STMT_EXEC_ERROR; - qb->errormsg = "processParameters closing ) not found"; - return SQL_ERROR; - } - else if (1 == param_count) /* the 1 parameter is really valid ? */ - { - BOOL param_exist = FALSE; - int i; - - for (i = param_pos[0][0]; i <= param_pos[0][1]; i++) - { - if (!isspace(qb->query_statement[i])) - { - param_exist = TRUE; - break; - } - } - if (!param_exist) - { - param_pos[0][0] = param_pos[0][1] = -1; - } - } - - return SQL_SUCCESS; -} - -/* - * convert_escape() - * This function doesn't return a pointer to static memory any longer ! - */ -static int -convert_escape(QueryParse *qp, QueryBuild *qb) -{ - static const char *func = "convert_escape"; - RETCODE retval = SQL_SUCCESS; - char buf[1024], key[65]; - unsigned char ucv; - UInt4 prtlen; - - if (F_OldChar(qp) == '{') /* skip the first { */ - F_OldNext(qp); - /* Separate off the key, skipping leading and trailing whitespace */ - while ((ucv = F_OldChar(qp)) != '\0' && isspace(ucv)) - F_OldNext(qp); - /* - * procedure calls - */ - if (qp->statement_type == STMT_TYPE_PROCCALL) - { - int lit_call_len = 4; - ConnectionClass *conn = qb->conn; - - /* '?=' to accept return values exists ? */ - if (F_OldChar(qp) == '?') - { - qb->param_number++; - while (isspace((unsigned char) qp->statement[++qp->opos])); - if (F_OldChar(qp) != '=') - { - F_OldPrior(qp); - return SQL_SUCCESS; - } - while (isspace((unsigned char) qp->statement[++qp->opos])); - } - if (strnicmp(F_OldPtr(qp), "call", lit_call_len) || - !isspace((unsigned char) F_OldPtr(qp)[lit_call_len])) - { - F_OldPrior(qp); - return SQL_SUCCESS; - } - qp->opos += lit_call_len; - CVT_APPEND_STR(qb, "SELECT "); - if (my_strchr(conn, F_OldPtr(qp), '(')) - qp->proc_no_param = FALSE; - return SQL_SUCCESS; - } - - sscanf(F_OldPtr(qp), "%32s", key); - while ((ucv = F_OldChar(qp)) != '\0' && (!isspace(ucv))) - F_OldNext(qp); - while ((ucv = F_OldChar(qp)) != '\0' && isspace(ucv)) - F_OldNext(qp); - - /* Avoid the concatenation of the function name with the previous word. Aceto */ - - if (F_NewPos(qb) > 0 && isalnum(F_NewPtr(qb)[-1])) - CVT_APPEND_CHAR(qb, ' '); - - if (strcmp(key, "d") == 0) - { - /* Literal; return the escape part adding type cast */ - F_ExtractOldTo(qp, buf, '}', sizeof(buf)); - prtlen = snprintf(buf, sizeof(buf), "%s::date ", buf); - CVT_APPEND_DATA(qb, buf, prtlen); - } - else if (strcmp(key, "t") == 0) - { - /* Literal; return the escape part adding type cast */ - F_ExtractOldTo(qp, buf, '}', sizeof(buf)); - prtlen = snprintf(buf, sizeof(buf), "%s::time", buf); - CVT_APPEND_DATA(qb, buf, prtlen); - } - else if (strcmp(key, "ts") == 0) - { - /* Literal; return the escape part adding type cast */ - F_ExtractOldTo(qp, buf, '}', sizeof(buf)); - if (PG_VERSION_LT(qb->conn, 7.1)) - prtlen = snprintf(buf, sizeof(buf), "%s::datetime", buf); - else - prtlen = snprintf(buf, sizeof(buf), "%s::timestamp", buf); - CVT_APPEND_DATA(qb, buf, prtlen); - } - else if (strcmp(key, "oj") == 0) /* {oj syntax support for 7.1 * servers */ - { - F_OldPrior(qp); - return SQL_SUCCESS; /* Continue at inner_process_tokens loop */ - } - else if (strcmp(key, "fn") == 0) - { - QueryBuild nqb; - const char *mapExpr; - int i, param_count; - UInt4 param_consumed; - Int4 param_pos[16][2]; - - /* Separate off the func name, skipping leading and trailing whitespace */ - i = 0; - while ((ucv = F_OldChar(qp)) != '\0' && ucv != '(' && - (!isspace(ucv))) - { - if (i < sizeof(key)-1) - key[i++] = ucv; - F_OldNext(qp); - } - key[i] = '\0'; - while ((ucv = F_OldChar(qp)) != '\0' && isspace(ucv)) - F_OldNext(qp); - - /* - * We expect left parenthesis here, else return fn body as-is - * since it is one of those "function constants". - */ - if (F_OldChar(qp) != '(') - { - CVT_APPEND_STR(qb, key); - return SQL_SUCCESS; - } - - /* - * Process parameter list and inner escape - * sequences - * Aceto 2002-01-29 - */ - - QB_initialize_copy(&nqb, qb, 1024); - if (retval = processParameters(qp, &nqb, ¶m_consumed, param_pos), retval == SQL_ERROR) - { - qb->errornumber = nqb.errornumber; - qb->errormsg = nqb.errormsg; - QB_Destructor(&nqb); - return retval; - } - - for (param_count = 0;; param_count++) - { - if (param_pos[param_count][0] < 0) - break; - } - if (param_count == 1 && - param_pos[0][1] < param_pos[0][0]) - param_count = 0; - - mapExpr = mapFunction(key, param_count); - if (mapExpr == NULL) - { - CVT_APPEND_STR(qb, key); - CVT_APPEND_DATA(qb, nqb.query_statement, nqb.npos); - } - else - { - const char *mapptr; - int from, to, pidx, paramlen; - - for (prtlen = 0, mapptr = mapExpr; *mapptr; mapptr++) - { - if (*mapptr != '$') - { - CVT_APPEND_CHAR(qb, *mapptr); - continue; - } - mapptr++; - if (*mapptr == '*') - { - from = 1; - to = param_consumed - 2; - } - else if (isdigit(*mapptr)) - { - pidx = *mapptr - '0' - 1; - if (pidx < 0 || - param_pos[pidx][0] < 0) - { - qb->errornumber = STMT_EXEC_ERROR; - qb->errormsg = "param not found"; - qlog("%s %dth param not found for the expression %s\n", pidx + 1, mapExpr); - retval = SQL_ERROR; - break; - } - from = param_pos[pidx][0]; - to = param_pos[pidx][1]; - } - else - { - qb->errornumber = STMT_EXEC_ERROR; - qb->errormsg = "internal expression error"; - qlog("%s internal expression error %s\n", func, mapExpr); - retval = SQL_ERROR; - break; - } - paramlen = to - from + 1; - if (paramlen > 0) - CVT_APPEND_DATA(qb, nqb.query_statement+ from, paramlen); - } - } - if (0 == qb->errornumber) - { - qb->errornumber = nqb.errornumber; - qb->errormsg = nqb.errormsg; - } - if (SQL_ERROR != retval) - { - qb->param_number = nqb.param_number; - qb->flags = nqb.flags; - } - QB_Destructor(&nqb); - } - else - { - /* Bogus key, leave untranslated */ - return SQL_ERROR; - } - - return retval; -} - -BOOL -convert_money(const char *s, char *sout, size_t soutmax) -{ - size_t i = 0, - out = 0; - - for (i = 0; s[i]; i++) - { - if (s[i] == '$' || s[i] == ',' || s[i] == ')') - ; /* skip these characters */ - else - { - if (out + 1 >= soutmax) - return FALSE; /* sout is too short */ - if (s[i] == '(') - sout[out++] = '-'; - else - sout[out++] = s[i]; - } - } - sout[out] = '\0'; - return TRUE; -} - - -/* - * This function parses a character string for date/time info and fills in SIMPLE_TIME - * It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value - */ -char -parse_datetime(const char *buf, SIMPLE_TIME *st) -{ - int y, - m, - d, - hh, - mm, - ss; - int nf; - - y = m = d = hh = mm = ss = 0; - st->fr = 0; - st->infinity = 0; - - /* escape sequence ? */ - if (buf[0] == '{') - { - while (*(++buf) && *buf != '\''); - if (!(*buf)) - return FALSE; - buf++; - } - if (buf[4] == '-') /* year first */ - nf = sscanf(buf, "%4d-%2d-%2d %2d:%2d:%2d", &y, &m, &d, &hh, &mm, &ss); - else - nf = sscanf(buf, "%2d-%2d-%4d %2d:%2d:%2d", &m, &d, &y, &hh, &mm, &ss); - - if (nf == 5 || nf == 6) - { - st->y = y; - st->m = m; - st->d = d; - st->hh = hh; - st->mm = mm; - st->ss = ss; - - return TRUE; - } - - if (buf[4] == '-') /* year first */ - nf = sscanf(buf, "%4d-%2d-%2d", &y, &m, &d); - else - nf = sscanf(buf, "%2d-%2d-%4d", &m, &d, &y); - - if (nf == 3) - { - st->y = y; - st->m = m; - st->d = d; - - return TRUE; - } - - nf = sscanf(buf, "%2d:%2d:%2d", &hh, &mm, &ss); - if (nf == 2 || nf == 3) - { - st->hh = hh; - st->mm = mm; - st->ss = ss; - - return TRUE; - } - - return FALSE; -} - - -/* Change linefeed to carriage-return/linefeed */ -int -convert_linefeeds(const char *si, char *dst, size_t max, BOOL convlf, BOOL *changed) -{ - size_t i = 0, - out = 0; - - if (max == 0) - max = 0xffffffff; - *changed = FALSE; - for (i = 0; si[i] && out < max - 1; i++) - { - if (convlf && si[i] == '\n') - { - /* Only add the carriage-return if needed */ - if (i > 0 && si[i - 1] == '\r') - { - if (dst) - dst[out++] = si[i]; - else - out++; - continue; - } - *changed = TRUE; - - if (dst) - { - dst[out++] = '\r'; - dst[out++] = '\n'; - } - else - out += 2; - } - else - { - if (dst) - dst[out++] = si[i]; - else - out++; - } - } - if (dst) - dst[out] = '\0'; - return out; -} - - -/* - * Change carriage-return/linefeed to just linefeed - * Plus, escape any special characters. - */ -int -convert_special_chars(const char *si, char *dst, int used, BOOL convlf, int ccsc) -{ - size_t i = 0, - out = 0, - max; - char *p = NULL; -#ifdef MULTIBYTE - encoded_str encstr; -#endif - - - if (used == SQL_NTS) - max = strlen(si); - else - max = used; - if (dst) - { - p = dst; - p[0] = '\0'; - } -#ifdef MULTIBYTE - encoded_str_constr(&encstr, ccsc, si); -#endif - - for (i = 0; i < max && si[i]; i++) - { -#ifdef MULTIBYTE - encoded_nextchar(&encstr); - if (ENCODE_STATUS(encstr) != 0) - { - if (p) - p[out] = si[i]; - out++; - continue; - } -#endif - if (convlf && si[i] == '\r' && si[i + 1] == '\n') - continue; - else if (si[i] == '\'' || si[i] == '\\') - { - if (p) - p[out++] = '\\'; - else - out++; - } - if (p) - p[out++] = si[i]; - else - out++; - } - if (p) - p[out] = '\0'; - return out; -} - - -/* !!! Need to implement this function !!! */ -int -convert_pgbinary_to_char(const char *value, char *rgbValue, int cbValueMax) -{ - mylog("convert_pgbinary_to_char: value = '%s'\n", value); - - strncpy_null(rgbValue, value, cbValueMax); - return 0; -} - - -static unsigned int -conv_from_octal(const unsigned char *s) -{ - int i, - y = 0; - - for (i = 1; i <= 3; i++) - y += (s[i] - '0') << (3 * (3 - i)); - - return y; - -} - - -static unsigned int -conv_from_hex(const unsigned char *s) -{ - int i, - y = 0, - val; - - for (i = 1; i <= 2; i++) - { - if (s[i] >= 'a' && s[i] <= 'f') - val = s[i] - 'a' + 10; - else if (s[i] >= 'A' && s[i] <= 'F') - val = s[i] - 'A' + 10; - else - val = s[i] - '0'; - - y += val << (4 * (2 - i)); - } - - return y; -} - - -/* convert octal escapes to bytes */ -int -convert_from_pgbinary(const unsigned char *value, unsigned char *rgbValue, int cbValueMax) -{ - size_t i, - ilen = strlen(value); - int o = 0; - - - for (i = 0; i < ilen;) - { - if (value[i] == '\\') - { - if (value[i + 1] == '\\') - { - rgbValue[o] = value[i]; - i += 2; - } - else - { - rgbValue[o] = conv_from_octal(&value[i]); - i += 4; - } - } - else - rgbValue[o] = value[i++]; - mylog("convert_from_pgbinary: i=%d, rgbValue[%d] = %d, %c\n", i, o, rgbValue[o], rgbValue[o]); - o++; - } - - rgbValue[o] = '\0'; /* extra protection */ - - return o; -} - - -static char * -conv_to_octal(unsigned char val) -{ - int i; - static char x[6]; - - x[0] = '\\'; - x[1] = '\\'; - x[5] = '\0'; - - for (i = 4; i > 1; i--) - { - x[i] = (val & 7) + '0'; - val >>= 3; - } - - return x; -} - - -/* convert non-ascii bytes to octal escape sequences */ -int -convert_to_pgbinary(const unsigned char *in, char *out, int len) -{ - int i, - o = 0; - - for (i = 0; i < len; i++) - { - mylog("convert_to_pgbinary: in[%d] = %d, %c\n", i, in[i], in[i]); - if (isalnum(in[i]) || in[i] == ' ') - out[o++] = in[i]; - else - { - strcpy(&out[o], conv_to_octal(in[i])); - o += 5; - } - } - - mylog("convert_to_pgbinary: returning %d, out='%.*s'\n", o, o, out); - - return o; -} - - -void -encode(const char *in, char *out) -{ - unsigned int i, - ilen = strlen(in), - o = 0; - - for (i = 0; i < ilen; i++) - { - if (in[i] == '+') - { - sprintf(&out[o], "%%2B"); - o += 3; - } - else if (isspace((unsigned char) in[i])) - out[o++] = '+'; - else if (!isalnum((unsigned char) in[i])) - { - sprintf(&out[o], "%%%02x", (unsigned char) in[i]); - o += 3; - } - else - out[o++] = in[i]; - } - out[o++] = '\0'; -} - - -void -decode(const char *in, char *out) -{ - unsigned int i, - ilen = strlen(in), - o = 0; - - for (i = 0; i < ilen; i++) - { - if (in[i] == '+') - out[o++] = ' '; - else if (in[i] == '%') - { - sprintf(&out[o++], "%c", conv_from_hex(&in[i])); - i += 2; - } - else - out[o++] = in[i]; - } - out[o++] = '\0'; -} - -static const char *hextbl = "0123456789ABCDEF"; -static int -pg_bin2hex(UCHAR *src, UCHAR *dst, int length) -{ - UCHAR chr, - *src_wk, - *dst_wk; - BOOL backwards; - int i; - - backwards = FALSE; - if (dst < src) - { - if (dst + length > src + 1) - return -1; - } - else if (dst < src + length) - backwards = TRUE; - if (backwards) - { - for (i = 0, src_wk = src + length - 1, dst_wk = dst + 2 * length - 1; i < length; i++, src_wk--) - { - chr = *src_wk; - *dst_wk-- = hextbl[chr % 16]; - *dst_wk-- = hextbl[chr >> 4]; - } - } - else - { - for (i = 0, src_wk = src, dst_wk = dst; i < length; i++, src_wk++) - { - chr = *src_wk; - *dst_wk++ = hextbl[chr >> 4]; - *dst_wk++ = hextbl[chr % 16]; - } - } - dst[2 * length] = '\0'; - return length; -} - -/*------- - * 1. get oid (from 'value') - * 2. open the large object - * 3. read from the large object (handle multiple GetData) - * 4. close when read less than requested? -OR- - * lseek/read each time - * handle case where application receives truncated and - * decides not to continue reading. - * - * CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only - * data type currently mapped to a PG_TYPE_LO. But, if any other types - * are desired to map to a large object (PG_TYPE_LO), then that would - * need to be handled here. For example, LONGVARCHAR could possibly be - * mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now. - *------- - */ -int -convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue, - SDWORD cbValueMax, SDWORD *pcbValue) -{ - Oid oid; - int retval, - result, - left = -1; - BindInfoClass *bindInfo = NULL; - ConnectionClass *conn = SC_get_conn(stmt); - ConnInfo *ci = &(conn->connInfo); - ARDFields *opts = SC_get_ARD(stmt); - int factor = (fCType == SQL_C_CHAR ? 2 : 1); - - /* If using SQLGetData, then current_col will be set */ - if (stmt->current_col >= 0) - { - bindInfo = &opts->bindings[stmt->current_col]; - left = bindInfo->data_left; - } - - /* - * if this is the first call for this column, open the large object - * for reading - */ - - if (!bindInfo || bindInfo->data_left == -1) - { - /* begin transaction if needed */ - if (!CC_is_in_trans(conn)) - { - if (!CC_begin(conn)) - { - stmt->errormsg = "Could not begin (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - return COPY_GENERAL_ERROR; - } - } - - oid = atoi(value); - stmt->lobj_fd = lo_open(conn, oid, INV_READ); - if (stmt->lobj_fd < 0) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Couldnt open large object for reading."; - return COPY_GENERAL_ERROR; - } - - /* Get the size */ - retval = lo_lseek(conn, stmt->lobj_fd, 0L, SEEK_END); - if (retval >= 0) - { - left = lo_tell(conn, stmt->lobj_fd); - if (bindInfo) - bindInfo->data_left = left; - - /* return to beginning */ - lo_lseek(conn, stmt->lobj_fd, 0L, SEEK_SET); - } - } - mylog("lo data left = %d\n", left); - - if (left == 0) - return COPY_NO_DATA_FOUND; - - if (stmt->lobj_fd < 0) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Large object FD undefined for multiple read."; - return COPY_GENERAL_ERROR; - } - - retval = lo_read(conn, stmt->lobj_fd, (char *) rgbValue, factor > 1 ? (cbValueMax - 1) / factor : cbValueMax); - if (retval < 0) - { - lo_close(conn, stmt->lobj_fd); - - /* commit transaction if needed */ - if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn)) - { - if (!CC_commit(conn)) - { - stmt->errormsg = "Could not commit (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - return COPY_GENERAL_ERROR; - } - } - - stmt->lobj_fd = -1; - - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Error reading from large object."; - return COPY_GENERAL_ERROR; - } - - if (factor > 1) - pg_bin2hex((char *) rgbValue, (char *) rgbValue, retval); - if (retval < left) - result = COPY_RESULT_TRUNCATED; - else - result = COPY_OK; - - if (pcbValue) - *pcbValue = left < 0 ? SQL_NO_TOTAL : left * factor; - - if (bindInfo && bindInfo->data_left > 0) - bindInfo->data_left -= retval; - - if (!bindInfo || bindInfo->data_left == 0) - { - lo_close(conn, stmt->lobj_fd); - - /* commit transaction if needed */ - if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn)) - { - if (!CC_commit(conn)) - { - stmt->errormsg = "Could not commit (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - return COPY_GENERAL_ERROR; - } - } - - stmt->lobj_fd = -1; /* prevent further reading */ - } - - return result; -} diff --git a/src/interfaces/odbc/convert.h b/src/interfaces/odbc/convert.h deleted file mode 100644 index 8f65472e1f..0000000000 --- a/src/interfaces/odbc/convert.h +++ /dev/null @@ -1,56 +0,0 @@ -/* File: convert.h - * - * Description: See "convert.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __CONVERT_H__ -#define __CONVERT_H__ - -#include "psqlodbc.h" - -/* copy_and_convert results */ -#define COPY_OK 0 -#define COPY_UNSUPPORTED_TYPE 1 -#define COPY_UNSUPPORTED_CONVERSION 2 -#define COPY_RESULT_TRUNCATED 3 -#define COPY_GENERAL_ERROR 4 -#define COPY_NO_DATA_FOUND 5 -/* convert_escape results */ -#define CONVERT_ESCAPE_OK 0 -#define CONVERT_ESCAPE_OVERFLOW 1 -#define CONVERT_ESCAPE_ERROR -1 - -typedef struct -{ - int infinity; - int m; - int d; - int y; - int hh; - int mm; - int ss; - int fr; -} SIMPLE_TIME; - -int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col); -int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, - PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue); - -int copy_statement_with_parameters(StatementClass *stmt); -BOOL convert_money(const char *s, char *sout, size_t soutmax); -char parse_datetime(const char *buf, SIMPLE_TIME *st); -int convert_linefeeds(const char *s, char *dst, size_t max, BOOL convlf, BOOL *changed); -int convert_special_chars(const char *si, char *dst, int used, BOOL convlf,int ccsc); - -int convert_pgbinary_to_char(const char *value, char *rgbValue, int cbValueMax); -int convert_from_pgbinary(const unsigned char *value, unsigned char *rgbValue, int cbValueMax); -int convert_to_pgbinary(const unsigned char *in, char *out, int len); -void encode(const char *in, char *out); -void decode(const char *in, char *out); -int convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue, - SDWORD cbValueMax, SDWORD *pcbValue); - -#endif diff --git a/src/interfaces/odbc/descriptor.h b/src/interfaces/odbc/descriptor.h deleted file mode 100644 index c3f016a7dc..0000000000 --- a/src/interfaces/odbc/descriptor.h +++ /dev/null @@ -1,104 +0,0 @@ -/* File: descriptor.h - * - * Description: This file contains defines and declarations that are related to - * the entire driver. - * - * Comments: See "notice.txt" for copyright and license information. - * - * $Id: descriptor.h,v 1.6 2002/06/06 04:50:47 inoue Exp $ - * - */ - -#ifndef __DESCRIPTOR_H__ -#define __DESCRIPTOR_H__ - -#include "psqlodbc.h" - -typedef struct -{ - COL_INFO *col_info; /* cached SQLColumns info for this table */ - char schema[MAX_SCHEMA_LEN + 1]; - char name[MAX_TABLE_LEN + 1]; - char alias[MAX_TABLE_LEN + 1]; - char updatable; -} TABLE_INFO; - -typedef struct -{ - TABLE_INFO *ti; /* resolve to explicit table names */ - int column_size; /* precision in 2.x */ - int decimal_digits; /* scale in 2.x */ - int display_size; - int length; - int type; - char nullable; - char func; - char expr; - char quote; - char dquote; - char numeric; - char updatable; - char dot[MAX_TABLE_LEN + 1]; - char name[MAX_COLUMN_LEN + 1]; - char alias[MAX_COLUMN_LEN + 1]; - char *schema; -} FIELD_INFO; -Int4 FI_precision(const FIELD_INFO *); -Int4 FI_scale(const FIELD_INFO *); - -struct ARDFields_ -{ - StatementClass *stmt; - int rowset_size; - int bind_size; /* size of each structure if using Row - * Binding */ - UInt2 *row_operation_ptr; - UInt4 *row_offset_ptr; - BindInfoClass *bookmark; - BindInfoClass *bindings; - int allocated; -}; - -struct APDFields_ -{ - StatementClass *stmt; - int paramset_size; - int param_bind_type; /* size of each structure if using Param - * Binding */ - UInt2 *param_operation_ptr; - UInt4 *param_offset_ptr; - ParameterInfoClass *parameters; - int allocated; -}; - -struct IRDFields_ -{ - StatementClass *stmt; - UInt4 *rowsFetched; - UInt2 *rowStatusArray; - UInt4 nfields; - FIELD_INFO **fi; -}; - -struct IPDFields_ -{ - StatementClass *stmt; - UInt4 *param_processed_ptr; - UInt2 *param_status_ptr; -}; - -void InitializeARDFields(ARDFields *self); -void InitializeAPDFields(APDFields *self); -/* void InitializeIRDFields(IRDFields *self); -void InitializeIPDFiedls(IPDFields *self); */ -void ARDFields_free(ARDFields *self); -void APDFields_free(APDFields *self); -void IRDFields_free(IRDFields *self); -void IPDFields_free(IPDFields *self); -void ARD_unbind_cols(ARDFields *self, BOOL freeall); -void APD_free_params(APDFields *self, char option); -#if (ODBCVER >= 0x0300) -void Desc_set_error(SQLHDESC hdesc, int errornumber, const char * errormsg); -#endif /* ODBCVER */ - -#endif diff --git a/src/interfaces/odbc/dlg_specific.c b/src/interfaces/odbc/dlg_specific.c deleted file mode 100644 index 4f96a6f7c5..0000000000 --- a/src/interfaces/odbc/dlg_specific.c +++ /dev/null @@ -1,971 +0,0 @@ -/*------- - * Module: dlg_specific.c - * - * Description: This module contains any specific code for handling - * dialog boxes such as driver/datasource options. Both the - * ConfigDSN() and the SQLDriverConnect() functions use - * functions in this module. If you were to add a new option - * to any dialog box, you would most likely only have to change - * things in here rather than in 2 separate places as before. - * - * Classes: none - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ -/* Multibyte support Eiji Tokuya 2001-03-15 */ - -#include "dlg_specific.h" - -#include "convert.h" - -#ifdef MULTIBYTE -#include "multibyte.h" -#endif -#include "pgapifunc.h" - -#ifndef BOOL -#define BOOL int -#endif -#ifndef FALSE -#define FALSE (BOOL)0 -#endif -#ifndef TRUE -#define TRUE (BOOL)1 -#endif - -extern GLOBAL_VALUES globals; - -void -makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len) -{ - char got_dsn = (ci->dsn[0] != '\0'); - char encoded_conn_settings[LARGE_REGISTRY_LEN]; - UWORD hlen; - /*BOOL abbrev = (len <= 400);*/ - BOOL abbrev = (len < 1024); - - /* fundamental info */ - sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s", - got_dsn ? "DSN" : "DRIVER", - got_dsn ? ci->dsn : ci->driver, - ci->database, - ci->server, - ci->port, - ci->username, - ci->password); - - encode(ci->conn_settings, encoded_conn_settings); - - /* extra info */ - hlen = strlen(connect_string); - if (!abbrev) - sprintf(&connect_string[hlen], - ";%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d", - INI_READONLY, - ci->onlyread, - INI_PROTOCOL, - ci->protocol, - INI_FAKEOIDINDEX, - ci->fake_oid_index, - INI_SHOWOIDCOLUMN, - ci->show_oid_column, - INI_ROWVERSIONING, - ci->row_versioning, - INI_SHOWSYSTEMTABLES, - ci->show_system_tables, - INI_CONNSETTINGS, - encoded_conn_settings, - INI_FETCH, - ci->drivers.fetch_max, - INI_SOCKET, - ci->drivers.socket_buffersize, - INI_UNKNOWNSIZES, - ci->drivers.unknown_sizes, - INI_MAXVARCHARSIZE, - ci->drivers.max_varchar_size, - INI_MAXLONGVARCHARSIZE, - ci->drivers.max_longvarchar_size, - INI_DEBUG, - ci->drivers.debug, - INI_COMMLOG, - ci->drivers.commlog, - INI_OPTIMIZER, - ci->drivers.disable_optimizer, - INI_KSQO, - ci->drivers.ksqo, - INI_USEDECLAREFETCH, - ci->drivers.use_declarefetch, - INI_TEXTASLONGVARCHAR, - ci->drivers.text_as_longvarchar, - INI_UNKNOWNSASLONGVARCHAR, - ci->drivers.unknowns_as_longvarchar, - INI_BOOLSASCHAR, - ci->drivers.bools_as_char, - INI_PARSE, - ci->drivers.parse, - INI_CANCELASFREESTMT, - ci->drivers.cancel_as_freestmt, - INI_EXTRASYSTABLEPREFIXES, - ci->drivers.extra_systable_prefixes, - INI_LFCONVERSION, - ci->lf_conversion, - INI_UPDATABLECURSORS, - ci->allow_keyset, - INI_DISALLOWPREMATURE, - ci->disallow_premature, - INI_TRUEISMINUS1, - ci->true_is_minus1, - INI_INT8AS, - ci->true_is_minus1); - /* Abbrebiation is needed ? */ - if (abbrev || strlen(connect_string) >= len) - { - unsigned long flag = 0; - if (ci->disallow_premature) - flag |= BIT_DISALLOWPREMATURE; - if (ci->allow_keyset) - flag |= BIT_UPDATABLECURSORS; - if (ci->lf_conversion) - flag |= BIT_LFCONVERSION; - if (ci->drivers.unique_index) - flag |= BIT_UNIQUEINDEX; - if (strncmp(ci->protocol, PG64, strlen(PG64)) == 0) - flag |= BIT_PROTOCOL_64; - else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0) - flag |= BIT_PROTOCOL_63; - switch (ci->drivers.unknown_sizes) - { - case UNKNOWNS_AS_DONTKNOW: - flag |= BIT_UNKNOWN_DONTKNOW; - break; - case UNKNOWNS_AS_MAX: - flag |= BIT_UNKNOWN_ASMAX; - break; - } - if (ci->drivers.disable_optimizer) - flag |= BIT_OPTIMIZER; - if (ci->drivers.ksqo) - flag |= BIT_KSQO; - if (ci->drivers.commlog) - flag |= BIT_COMMLOG; - if (ci->drivers.debug) - flag |= BIT_DEBUG; - if (ci->drivers.parse) - flag |= BIT_PARSE; - if (ci->drivers.cancel_as_freestmt) - flag |= BIT_CANCELASFREESTMT; - if (ci->drivers.use_declarefetch) - flag |= BIT_USEDECLAREFETCH; - if (ci->onlyread[0] == '1') - flag |= BIT_READONLY; - if (ci->drivers.text_as_longvarchar) - flag |= BIT_TEXTASLONGVARCHAR; - if (ci->drivers.unknowns_as_longvarchar) - flag |= BIT_UNKNOWNSASLONGVARCHAR; - if (ci->drivers.bools_as_char) - flag |= BIT_BOOLSASCHAR; - if (ci->row_versioning[0] == '1') - flag |= BIT_ROWVERSIONING; - if (ci->show_system_tables[0] == '1') - flag |= BIT_SHOWSYSTEMTABLES; - if (ci->show_oid_column[0] == '1') - flag |= BIT_SHOWOIDCOLUMN; - if (ci->fake_oid_index[0] == '1') - flag |= BIT_FAKEOIDINDEX; - if (ci->true_is_minus1) - flag |= BIT_TRUEISMINUS1; - - sprintf(&connect_string[hlen], - ";A6=%s;A7=%d;A8=%d;B0=%d;B1=%d;%s=%d;C2=%s;CX=%02x%lx", - encoded_conn_settings, - ci->drivers.fetch_max, - ci->drivers.socket_buffersize, - ci->drivers.max_varchar_size, - ci->drivers.max_longvarchar_size, - INI_INT8AS, - ci->int8_as, - ci->drivers.extra_systable_prefixes, - EFFECTIVE_BIT_COUNT, - flag); - } -} - -static void -unfoldCXAttribute(ConnInfo *ci, const char *value) -{ - int count; - unsigned long flag; - - if (strlen(value) < 2) - { - count = 3; - sscanf(value, "%lx", &flag); - } - else - { - char cnt[8]; - memcpy(cnt, value, 2); - cnt[2] = '\0'; - sscanf(cnt, "%x", &count); - sscanf(value + 2, "%lx", &flag); - } - ci->disallow_premature = (char)((flag & BIT_DISALLOWPREMATURE) != 0); - ci->allow_keyset = (char)((flag & BIT_UPDATABLECURSORS) != 0); - ci->lf_conversion = (char)((flag & BIT_LFCONVERSION) != 0); - if (count < 4) - return; - ci->drivers.unique_index = (char)((flag & BIT_UNIQUEINDEX) != 0); - if ((flag & BIT_PROTOCOL_64) != 0) - strcpy(ci->protocol, PG64); - else if ((flag & BIT_PROTOCOL_63) != 0) - strcpy(ci->protocol, PG63); - else - strcpy(ci->protocol, PG62); - if ((flag & BIT_UNKNOWN_DONTKNOW) != 0) - ci->drivers.unknown_sizes = UNKNOWNS_AS_DONTKNOW; - else if ((flag & BIT_UNKNOWN_ASMAX) != 0) - ci->drivers.unknown_sizes = UNKNOWNS_AS_MAX; - else - ci->drivers.unknown_sizes = UNKNOWNS_AS_LONGEST; - ci->drivers.disable_optimizer = (char)((flag & BIT_OPTIMIZER) != 0); - ci->drivers.ksqo = (char)((flag & BIT_KSQO) != 0); - ci->drivers.commlog = (char)((flag & BIT_COMMLOG) != 0); - ci->drivers.debug = (char)((flag & BIT_DEBUG) != 0); - ci->drivers.parse = (char)((flag & BIT_PARSE) != 0); - ci->drivers.cancel_as_freestmt = (char)((flag & BIT_CANCELASFREESTMT) != 0); - ci->drivers.use_declarefetch = (char)((flag & BIT_USEDECLAREFETCH) != 0); - sprintf(ci->onlyread, "%d", (char)((flag & BIT_READONLY) != 0)); - ci->drivers.text_as_longvarchar = (char)((flag & BIT_TEXTASLONGVARCHAR) !=0); - ci->drivers.unknowns_as_longvarchar = (char)((flag & BIT_UNKNOWNSASLONGVARCHAR) !=0); - ci->drivers.bools_as_char = (char)((flag & BIT_BOOLSASCHAR) != 0); - sprintf(ci->row_versioning, "%d", (char)((flag & BIT_ROWVERSIONING) != 0)); - sprintf(ci->show_system_tables, "%d", (char)((flag & BIT_SHOWSYSTEMTABLES) != 0)); - sprintf(ci->show_oid_column, "%d", (char)((flag & BIT_SHOWOIDCOLUMN) != 0)); - sprintf(ci->fake_oid_index, "%d", (char)((flag & BIT_FAKEOIDINDEX) != 0)); - ci->true_is_minus1 = (char)((flag & BIT_TRUEISMINUS1) != 0); -} -void -copyAttributes(ConnInfo *ci, const char *attribute, const char *value) -{ - if (stricmp(attribute, "DSN") == 0) - strcpy(ci->dsn, value); - - else if (stricmp(attribute, "driver") == 0) - strcpy(ci->driver, value); - - else if (stricmp(attribute, INI_DATABASE) == 0) - strcpy(ci->database, value); - - else if (stricmp(attribute, INI_SERVER) == 0 || stricmp(attribute, "server") == 0) - strcpy(ci->server, value); - - else if (stricmp(attribute, INI_USER) == 0 || stricmp(attribute, "uid") == 0) - strcpy(ci->username, value); - - else if (stricmp(attribute, INI_PASSWORD) == 0 || stricmp(attribute, "pwd") == 0) - strcpy(ci->password, value); - - else if (stricmp(attribute, INI_PORT) == 0) - strcpy(ci->port, value); - - else if (stricmp(attribute, INI_READONLY) == 0 || stricmp(attribute, "A0") == 0) - strcpy(ci->onlyread, value); - - else if (stricmp(attribute, INI_PROTOCOL) == 0 || stricmp(attribute, "A1") == 0) - strcpy(ci->protocol, value); - - else if (stricmp(attribute, INI_SHOWOIDCOLUMN) == 0 || stricmp(attribute, "A3") == 0) - strcpy(ci->show_oid_column, value); - - else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0 || stricmp(attribute, "A2") == 0) - strcpy(ci->fake_oid_index, value); - - else if (stricmp(attribute, INI_ROWVERSIONING) == 0 || stricmp(attribute, "A4") == 0) - strcpy(ci->row_versioning, value); - - else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0 || stricmp(attribute, "A5") == 0) - strcpy(ci->show_system_tables, value); - - else if (stricmp(attribute, INI_CONNSETTINGS) == 0 || stricmp(attribute, "A6") == 0) - { - decode(value, ci->conn_settings); - /* strcpy(ci->conn_settings, value); */ - } - else if (stricmp(attribute, INI_DISALLOWPREMATURE) == 0 || stricmp(attribute, "C3") == 0) - ci->disallow_premature = atoi(value); - else if (stricmp(attribute, INI_UPDATABLECURSORS) == 0 || stricmp(attribute, "C4") == 0) - ci->allow_keyset = atoi(value); - else if (stricmp(attribute, INI_LFCONVERSION) == 0) - ci->lf_conversion = atoi(value); - else if (stricmp(attribute, INI_TRUEISMINUS1) == 0) - ci->true_is_minus1 = atoi(value); - else if (stricmp(attribute, INI_INT8AS) == 0) - ci->int8_as = atoi(value); - else if (stricmp(attribute, "CX") == 0) - unfoldCXAttribute(ci, value); - - mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature); -} - -void -copyCommonAttributes(ConnInfo *ci, const char *attribute, const char *value) -{ - if (stricmp(attribute, INI_FETCH) == 0 || stricmp(attribute, "A7") == 0) - ci->drivers.fetch_max = atoi(value); - else if (stricmp(attribute, INI_SOCKET) == 0 || stricmp(attribute, "A8") == 0) - ci->drivers.socket_buffersize = atoi(value); - else if (stricmp(attribute, INI_DEBUG) == 0 || stricmp(attribute, "B2") == 0) - ci->drivers.debug = atoi(value); - else if (stricmp(attribute, INI_COMMLOG) == 0 || stricmp(attribute, "B3") == 0) - ci->drivers.commlog = atoi(value); - else if (stricmp(attribute, INI_OPTIMIZER) == 0 || stricmp(attribute, "B4") == 0) - ci->drivers.disable_optimizer = atoi(value); - else if (stricmp(attribute, INI_KSQO) == 0 || stricmp(attribute, "B5") == 0) - ci->drivers.ksqo = atoi(value); - - /* - * else if (stricmp(attribute, INI_UNIQUEINDEX) == 0 || - * stricmp(attribute, "UIX") == 0) ci->drivers.unique_index = - * atoi(value); - */ - else if (stricmp(attribute, INI_UNKNOWNSIZES) == 0 || stricmp(attribute, "A9") == 0) - ci->drivers.unknown_sizes = atoi(value); - else if (stricmp(attribute, INI_LIE) == 0) - ci->drivers.lie = atoi(value); - else if (stricmp(attribute, INI_PARSE) == 0 || stricmp(attribute, "C0") == 0) - ci->drivers.parse = atoi(value); - else if (stricmp(attribute, INI_CANCELASFREESTMT) == 0 || stricmp(attribute, "C1") == 0) - ci->drivers.cancel_as_freestmt = atoi(value); - else if (stricmp(attribute, INI_USEDECLAREFETCH) == 0 || stricmp(attribute, "B6") == 0) - ci->drivers.use_declarefetch = atoi(value); - else if (stricmp(attribute, INI_MAXVARCHARSIZE) == 0 || stricmp(attribute, "B0") == 0) - ci->drivers.max_varchar_size = atoi(value); - else if (stricmp(attribute, INI_MAXLONGVARCHARSIZE) == 0 || stricmp(attribute, "B1") == 0) - ci->drivers.max_longvarchar_size = atoi(value); - else if (stricmp(attribute, INI_TEXTASLONGVARCHAR) == 0 || stricmp(attribute, "B7") == 0) - ci->drivers.text_as_longvarchar = atoi(value); - else if (stricmp(attribute, INI_UNKNOWNSASLONGVARCHAR) == 0 || stricmp(attribute, "B8") == 0) - ci->drivers.unknowns_as_longvarchar = atoi(value); - else if (stricmp(attribute, INI_BOOLSASCHAR) == 0 || stricmp(attribute, "B9") == 0) - ci->drivers.bools_as_char = atoi(value); - else if (stricmp(attribute, INI_EXTRASYSTABLEPREFIXES) == 0 || stricmp(attribute, "C2") == 0) - strcpy(ci->drivers.extra_systable_prefixes, value); - mylog("CopyCommonAttributes: A7=%d;A8=%d;A9=%d;B0=%d;B1=%d;B2=%d;B3=%d;B4=%d;B5=%d;B6=%d;B7=%d;B8=%d;B9=%d;C0=%d;C1=%d;C2=%s", - ci->drivers.fetch_max, - ci->drivers.socket_buffersize, - ci->drivers.unknown_sizes, - ci->drivers.max_varchar_size, - ci->drivers.max_longvarchar_size, - ci->drivers.debug, - ci->drivers.commlog, - ci->drivers.disable_optimizer, - ci->drivers.ksqo, - ci->drivers.use_declarefetch, - ci->drivers.text_as_longvarchar, - ci->drivers.unknowns_as_longvarchar, - ci->drivers.bools_as_char, - ci->drivers.parse, - ci->drivers.cancel_as_freestmt, - ci->drivers.extra_systable_prefixes); -} - - -void -getDSNdefaults(ConnInfo *ci) -{ - if (ci->port[0] == '\0') - strcpy(ci->port, DEFAULT_PORT); - - if (ci->onlyread[0] == '\0') - sprintf(ci->onlyread, "%d", globals.onlyread); - - if (ci->protocol[0] == '\0') - strcpy(ci->protocol, globals.protocol); - - if (ci->fake_oid_index[0] == '\0') - sprintf(ci->fake_oid_index, "%d", DEFAULT_FAKEOIDINDEX); - - if (ci->show_oid_column[0] == '\0') - sprintf(ci->show_oid_column, "%d", DEFAULT_SHOWOIDCOLUMN); - - if (ci->show_system_tables[0] == '\0') - sprintf(ci->show_system_tables, "%d", DEFAULT_SHOWSYSTEMTABLES); - - if (ci->row_versioning[0] == '\0') - sprintf(ci->row_versioning, "%d", DEFAULT_ROWVERSIONING); - - if (ci->disallow_premature < 0) - ci->disallow_premature = DEFAULT_DISALLOWPREMATURE; - if (ci->allow_keyset < 0) - ci->allow_keyset = DEFAULT_UPDATABLECURSORS; - if (ci->lf_conversion < 0) - ci->lf_conversion = DEFAULT_LFCONVERSION; - if (ci->true_is_minus1 < 0) - ci->true_is_minus1 = DEFAULT_TRUEISMINUS1; - if (ci->int8_as < -100) - ci->int8_as = DEFAULT_INT8AS; -} - - -void -getDSNinfo(ConnInfo *ci, char overwrite) -{ - char *DSN = ci->dsn; - char encoded_conn_settings[LARGE_REGISTRY_LEN], - temp[SMALL_REGISTRY_LEN]; - -/* - * If a driver keyword was present, then dont use a DSN and return. - * If DSN is null and no driver, then use the default datasource. - */ - if (DSN[0] == '\0') - { - if (ci->driver[0] != '\0') - return; - else - strcpy(DSN, INI_DSN); - } - - /* brute-force chop off trailing blanks... */ - while (*(DSN + strlen(DSN) - 1) == ' ') - *(DSN + strlen(DSN) - 1) = '\0'; - - /* Proceed with getting info for the given DSN. */ - - if (ci->desc[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_KDESC, "", ci->desc, sizeof(ci->desc), ODBC_INI); - - if (ci->server[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_SERVER, "", ci->server, sizeof(ci->server), ODBC_INI); - - if (ci->database[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_DATABASE, "", ci->database, sizeof(ci->database), ODBC_INI); - - if (ci->username[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_USER, "", ci->username, sizeof(ci->username), ODBC_INI); - - if (ci->password[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_PASSWORD, "", ci->password, sizeof(ci->password), ODBC_INI); - - if (ci->port[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_PORT, "", ci->port, sizeof(ci->port), ODBC_INI); - - if (ci->onlyread[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_READONLY, "", ci->onlyread, sizeof(ci->onlyread), ODBC_INI); - - if (ci->show_oid_column[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_SHOWOIDCOLUMN, "", ci->show_oid_column, sizeof(ci->show_oid_column), ODBC_INI); - - if (ci->fake_oid_index[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI); - - if (ci->row_versioning[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI); - - if (ci->show_system_tables[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI); - - if (ci->protocol[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_PROTOCOL, "", ci->protocol, sizeof(ci->protocol), ODBC_INI); - - if (ci->conn_settings[0] == '\0' || overwrite) - { - SQLGetPrivateProfileString(DSN, INI_CONNSETTINGS, "", encoded_conn_settings, sizeof(encoded_conn_settings), ODBC_INI); - decode(encoded_conn_settings, ci->conn_settings); - } - - if (ci->translation_dll[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_TRANSLATIONDLL, "", ci->translation_dll, sizeof(ci->translation_dll), ODBC_INI); - - if (ci->translation_option[0] == '\0' || overwrite) - SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI); - - if (ci->disallow_premature < 0 || overwrite) - { - SQLGetPrivateProfileString(DSN, INI_DISALLOWPREMATURE, "", temp, sizeof(temp), ODBC_INI); - if (temp[0]) - ci->disallow_premature = atoi(temp); - } - - if (ci->allow_keyset < 0 || overwrite) - { - SQLGetPrivateProfileString(DSN, INI_UPDATABLECURSORS, "", temp, sizeof(temp), ODBC_INI); - if (temp[0]) - ci->allow_keyset = atoi(temp); - } - - if (ci->lf_conversion < 0 || overwrite) - { - SQLGetPrivateProfileString(DSN, INI_LFCONVERSION, "", temp, sizeof(temp), ODBC_INI); - if (temp[0]) - ci->lf_conversion = atoi(temp); - } - - if (ci->true_is_minus1 < 0 || overwrite) - { - SQLGetPrivateProfileString(DSN, INI_TRUEISMINUS1, "", temp, sizeof(temp), ODBC_INI); - if (temp[0]) - ci->true_is_minus1 = atoi(temp); - } - - if (ci->int8_as < -100 || overwrite) - { - SQLGetPrivateProfileString(DSN, INI_INT8AS, "", temp, sizeof(temp), ODBC_INI); - if (temp[0]) - ci->int8_as = atoi(temp); - } - - /* Allow override of odbcinst.ini parameters here */ - getCommonDefaults(DSN, ODBC_INI, ci); - - qlog("DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n", - DSN, - ci->server, - ci->port, - ci->database, - ci->username, - ci->password); - qlog(" onlyread='%s',protocol='%s',showoid='%s',fakeoidindex='%s',showsystable='%s'\n", - ci->onlyread, - ci->protocol, - ci->show_oid_column, - ci->fake_oid_index, - ci->show_system_tables); - -#ifdef MULTIBYTE - check_client_encoding(ci->conn_settings); - qlog(" conn_settings='%s',conn_encoding='%s'\n", - ci->conn_settings, - check_client_encoding(ci->conn_settings)); -#else - qlog(" conn_settings='%s'\n", - ci->conn_settings); -#endif - - qlog(" translation_dll='%s',translation_option='%s'\n", - ci->translation_dll, - ci->translation_option); -} - -/* - * This function writes any global parameters (that can be manipulated) - * to the ODBCINST.INI portion of the registry - */ -void -writeDriverCommoninfo(const ConnInfo *ci) -{ - const char *sectionName; - const char *fileName; - const GLOBAL_VALUES *comval; - char tmp[128]; - - if (ci) - if (ci->dsn && ci->dsn[0]) - { - mylog("DSN=%s updating\n", ci->dsn); - comval = &(ci->drivers); - sectionName = ci->dsn; - fileName = ODBC_INI; - } - else - { - mylog("ci but dsn==NULL\n"); - return; - } - else - { - mylog("drivers updating\n"); - comval = &globals; - sectionName = DBMS_NAME; - fileName = ODBCINST_INI; - } - sprintf(tmp, "%d", comval->fetch_max); - SQLWritePrivateProfileString(sectionName, - INI_FETCH, tmp, fileName); - - sprintf(tmp, "%d", comval->commlog); - SQLWritePrivateProfileString(sectionName, - INI_COMMLOG, tmp, fileName); - - sprintf(tmp, "%d", comval->debug); - SQLWritePrivateProfileString(sectionName, - INI_DEBUG, tmp, fileName); - - sprintf(tmp, "%d", comval->disable_optimizer); - SQLWritePrivateProfileString(sectionName, - INI_OPTIMIZER, tmp, fileName); - - sprintf(tmp, "%d", comval->ksqo); - SQLWritePrivateProfileString(sectionName, - INI_KSQO, tmp, fileName); - - sprintf(tmp, "%d", comval->unique_index); - SQLWritePrivateProfileString(sectionName, INI_UNIQUEINDEX, tmp, fileName); - /* - * Never update the onlyread from this module. - */ - if (!ci) - { - sprintf(tmp, "%d", comval->onlyread); - SQLWritePrivateProfileString(sectionName, INI_READONLY, tmp, - fileName); - } - - sprintf(tmp, "%d", comval->use_declarefetch); - SQLWritePrivateProfileString(sectionName, - INI_USEDECLAREFETCH, tmp, fileName); - - sprintf(tmp, "%d", comval->unknown_sizes); - SQLWritePrivateProfileString(sectionName, - INI_UNKNOWNSIZES, tmp, fileName); - - sprintf(tmp, "%d", comval->text_as_longvarchar); - SQLWritePrivateProfileString(sectionName, - INI_TEXTASLONGVARCHAR, tmp, fileName); - - sprintf(tmp, "%d", comval->unknowns_as_longvarchar); - SQLWritePrivateProfileString(sectionName, - INI_UNKNOWNSASLONGVARCHAR, tmp, fileName); - - sprintf(tmp, "%d", comval->bools_as_char); - SQLWritePrivateProfileString(sectionName, - INI_BOOLSASCHAR, tmp, fileName); - - sprintf(tmp, "%d", comval->parse); - SQLWritePrivateProfileString(sectionName, - INI_PARSE, tmp, fileName); - - sprintf(tmp, "%d", comval->cancel_as_freestmt); - SQLWritePrivateProfileString(sectionName, - INI_CANCELASFREESTMT, tmp, fileName); - - sprintf(tmp, "%d", comval->max_varchar_size); - SQLWritePrivateProfileString(sectionName, - INI_MAXVARCHARSIZE, tmp, fileName); - - sprintf(tmp, "%d", comval->max_longvarchar_size); - SQLWritePrivateProfileString(sectionName, - INI_MAXLONGVARCHARSIZE, tmp, fileName); - - SQLWritePrivateProfileString(sectionName, - INI_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, fileName); - - /* - * Never update the conn_setting from this module - * SQLWritePrivateProfileString(sectionName, INI_CONNSETTINGS, - * comval->conn_settings, fileName); - */ -} - -/* This is for datasource based options only */ -void -writeDSNinfo(const ConnInfo *ci) -{ - const char *DSN = ci->dsn; - char encoded_conn_settings[LARGE_REGISTRY_LEN], - temp[SMALL_REGISTRY_LEN]; - - encode(ci->conn_settings, encoded_conn_settings); - - SQLWritePrivateProfileString(DSN, - INI_KDESC, - ci->desc, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_DATABASE, - ci->database, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_SERVER, - ci->server, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_PORT, - ci->port, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_USER, - ci->username, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_PASSWORD, - ci->password, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_READONLY, - ci->onlyread, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_SHOWOIDCOLUMN, - ci->show_oid_column, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_FAKEOIDINDEX, - ci->fake_oid_index, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_ROWVERSIONING, - ci->row_versioning, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_SHOWSYSTEMTABLES, - ci->show_system_tables, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_PROTOCOL, - ci->protocol, - ODBC_INI); - - SQLWritePrivateProfileString(DSN, - INI_CONNSETTINGS, - encoded_conn_settings, - ODBC_INI); - - sprintf(temp, "%d", ci->disallow_premature); - SQLWritePrivateProfileString(DSN, - INI_DISALLOWPREMATURE, - temp, - ODBC_INI); - sprintf(temp, "%d", ci->allow_keyset); - SQLWritePrivateProfileString(DSN, - INI_UPDATABLECURSORS, - temp, - ODBC_INI); - sprintf(temp, "%d", ci->lf_conversion); - SQLWritePrivateProfileString(DSN, - INI_LFCONVERSION, - temp, - ODBC_INI); - sprintf(temp, "%d", ci->true_is_minus1); - SQLWritePrivateProfileString(DSN, - INI_TRUEISMINUS1, - temp, - ODBC_INI); - sprintf(temp, "%d", ci->int8_as); - SQLWritePrivateProfileString(DSN, - INI_INT8AS, - temp, - ODBC_INI); -} - - -/* - * This function reads the ODBCINST.INI portion of - * the registry and gets any driver defaults. - */ -void -getCommonDefaults(const char *section, const char *filename, ConnInfo *ci) -{ - char temp[256]; - GLOBAL_VALUES *comval; - - if (ci) - comval = &(ci->drivers); - else - comval = &globals; - /* Fetch Count is stored in driver section */ - SQLGetPrivateProfileString(section, INI_FETCH, "", - temp, sizeof(temp), filename); - if (temp[0]) - { - comval->fetch_max = atoi(temp); - /* sanity check if using cursors */ - if (comval->fetch_max <= 0) - comval->fetch_max = FETCH_MAX; - } - else if (!ci) - comval->fetch_max = FETCH_MAX; - - /* Socket Buffersize is stored in driver section */ - SQLGetPrivateProfileString(section, INI_SOCKET, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->socket_buffersize = atoi(temp); - else if (!ci) - comval->socket_buffersize = SOCK_BUFFER_SIZE; - - /* Debug is stored in the driver section */ - SQLGetPrivateProfileString(section, INI_DEBUG, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->debug = atoi(temp); - else if (!ci) - comval->debug = DEFAULT_DEBUG; - - /* CommLog is stored in the driver section */ - SQLGetPrivateProfileString(section, INI_COMMLOG, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->commlog = atoi(temp); - else if (!ci) - comval->commlog = DEFAULT_COMMLOG; - - if (!ci) - logs_on_off(0, 0, 0); - /* Optimizer is stored in the driver section only */ - SQLGetPrivateProfileString(section, INI_OPTIMIZER, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->disable_optimizer = atoi(temp); - else if (!ci) - comval->disable_optimizer = DEFAULT_OPTIMIZER; - - /* KSQO is stored in the driver section only */ - SQLGetPrivateProfileString(section, INI_KSQO, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->ksqo = atoi(temp); - else if (!ci) - comval->ksqo = DEFAULT_KSQO; - - /* Recognize Unique Index is stored in the driver section only */ - SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->unique_index = atoi(temp); - else if (!ci) - comval->unique_index = DEFAULT_UNIQUEINDEX; - - - /* Unknown Sizes is stored in the driver section only */ - SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->unknown_sizes = atoi(temp); - else if (!ci) - comval->unknown_sizes = DEFAULT_UNKNOWNSIZES; - - - /* Lie about supported functions? */ - SQLGetPrivateProfileString(section, INI_LIE, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->lie = atoi(temp); - else if (!ci) - comval->lie = DEFAULT_LIE; - - /* Parse statements */ - SQLGetPrivateProfileString(section, INI_PARSE, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->parse = atoi(temp); - else if (!ci) - comval->parse = DEFAULT_PARSE; - - /* SQLCancel calls SQLFreeStmt in Driver Manager */ - SQLGetPrivateProfileString(section, INI_CANCELASFREESTMT, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->cancel_as_freestmt = atoi(temp); - else if (!ci) - comval->cancel_as_freestmt = DEFAULT_CANCELASFREESTMT; - - /* UseDeclareFetch is stored in the driver section only */ - SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->use_declarefetch = atoi(temp); - else if (!ci) - comval->use_declarefetch = DEFAULT_USEDECLAREFETCH; - - /* Max Varchar Size */ - SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->max_varchar_size = atoi(temp); - else if (!ci) - comval->max_varchar_size = MAX_VARCHAR_SIZE; - - /* Max TextField Size */ - SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->max_longvarchar_size = atoi(temp); - else if (!ci) - comval->max_longvarchar_size = TEXT_FIELD_SIZE; - - /* Text As LongVarchar */ - SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->text_as_longvarchar = atoi(temp); - else if (!ci) - comval->text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR; - - /* Unknowns As LongVarchar */ - SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->unknowns_as_longvarchar = atoi(temp); - else if (!ci) - comval->unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR; - - /* Bools As Char */ - SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->bools_as_char = atoi(temp); - else if (!ci) - comval->bools_as_char = DEFAULT_BOOLSASCHAR; - - /* Extra Systable prefixes */ - - /* - * Use @@@ to distinguish between blank extra prefixes and no key - * entry - */ - SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, "@@@", - temp, sizeof(temp), filename); - if (strcmp(temp, "@@@")) - strcpy(comval->extra_systable_prefixes, temp); - else if (!ci) - strcpy(comval->extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES); - - mylog("globals.extra_systable_prefixes = '%s'\n", comval->extra_systable_prefixes); - - - /* Dont allow override of an override! */ - if (!ci) - { - /* - * ConnSettings is stored in the driver section and per datasource - * for override - */ - SQLGetPrivateProfileString(section, INI_CONNSETTINGS, "", - comval->conn_settings, sizeof(comval->conn_settings), filename); - - /* Default state for future DSN's Readonly attribute */ - SQLGetPrivateProfileString(section, INI_READONLY, "", - temp, sizeof(temp), filename); - if (temp[0]) - comval->onlyread = atoi(temp); - else - comval->onlyread = DEFAULT_READONLY; - - /* - * Default state for future DSN's protocol attribute This isn't a - * real driver option YET. This is more intended for - * customization from the install. - */ - SQLGetPrivateProfileString(section, INI_PROTOCOL, "@@@", - temp, sizeof(temp), filename); - if (strcmp(temp, "@@@")) - strcpy(comval->protocol, temp); - else - strcpy(comval->protocol, DEFAULT_PROTOCOL); - } -} diff --git a/src/interfaces/odbc/dlg_specific.h b/src/interfaces/odbc/dlg_specific.h deleted file mode 100644 index 99005d3a33..0000000000 --- a/src/interfaces/odbc/dlg_specific.h +++ /dev/null @@ -1,200 +0,0 @@ -/* File: dlg_specific.h - * - * Description: See "dlg_specific.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __DLG_SPECIFIC_H__ -#define __DLG_SPECIFIC_H__ - -#include "psqlodbc.h" -#include "connection.h" - -#ifdef WIN32 -#include -#include "resource.h" -#endif - -/* Unknown data type sizes */ -#define UNKNOWNS_AS_MAX 0 -#define UNKNOWNS_AS_DONTKNOW 1 -#define UNKNOWNS_AS_LONGEST 2 - -/* ODBC initialization files */ -#ifndef WIN32 -#define ODBC_INI ".odbc.ini" -#define ODBCINST_INI "odbcinst.ini" -#else -#define ODBC_INI "ODBC.INI" -#define ODBCINST_INI "ODBCINST.INI" -#endif - - -#define INI_DSN DBMS_NAME /* Name of default - * Datasource in ini - * file (not used?) */ -#define INI_KDESC "Description" /* Data source - * description */ -#define INI_SERVER "Servername" /* Name of Server - * running the Postgres - * service */ -#define INI_PORT "Port" /* Port on which the - * Postmaster is listening */ -#define INI_DATABASE "Database" /* Database Name */ -#define INI_USER "Username" /* Default User Name */ -#define INI_PASSWORD "Password" /* Default Password */ -#define INI_DEBUG "Debug" /* Debug flag */ -#define INI_FETCH "Fetch" /* Fetch Max Count */ -#define INI_SOCKET "Socket" /* Socket buffer size */ -#define INI_READONLY "ReadOnly" /* Database is read only */ -#define INI_COMMLOG "CommLog" /* Communication to - * backend logging */ -#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */ -#define INI_OPTIMIZER "Optimizer" /* Use backend genetic - * optimizer */ -#define INI_KSQO "Ksqo" /* Keyset query - * optimization */ -#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to - * backend on successful - * connection */ -#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique - * indexes */ -#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown - * result set sizes */ - -#define INI_CANCELASFREESTMT "CancelAsFreeStmt" - -#define INI_USEDECLAREFETCH "UseDeclareFetch" /* Use Declare/Fetch - * cursors */ - -/* More ini stuff */ -#define INI_TEXTASLONGVARCHAR "TextAsLongVarchar" -#define INI_UNKNOWNSASLONGVARCHAR "UnknownsAsLongVarchar" -#define INI_BOOLSASCHAR "BoolsAsChar" -#define INI_MAXVARCHARSIZE "MaxVarcharSize" -#define INI_MAXLONGVARCHARSIZE "MaxLongVarcharSize" - -#define INI_FAKEOIDINDEX "FakeOidIndex" -#define INI_SHOWOIDCOLUMN "ShowOidColumn" -#define INI_ROWVERSIONING "RowVersioning" -#define INI_SHOWSYSTEMTABLES "ShowSystemTables" -#define INI_LIE "Lie" -#define INI_PARSE "Parse" -#define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes" - -#define INI_TRANSLATIONNAME "TranslationName" -#define INI_TRANSLATIONDLL "TranslationDLL" -#define INI_TRANSLATIONOPTION "TranslationOption" -#define INI_DISALLOWPREMATURE "DisallowPremature" -#define INI_UPDATABLECURSORS "UpdatableCursors" -#define INI_LFCONVERSION "LFConversion" -#define INI_TRUEISMINUS1 "TrueIsMinus1" -#define INI_INT8AS "BI" -/* Bit representaion for abbreviated connection strings */ -#define BIT_LFCONVERSION (1L) -#define BIT_UPDATABLECURSORS (1L<<1) -#define BIT_DISALLOWPREMATURE (1L<<2) -#define BIT_UNIQUEINDEX (1L<<3) -#define BIT_PROTOCOL_63 (1L<<4) -#define BIT_PROTOCOL_64 (1L<<5) -#define BIT_UNKNOWN_DONTKNOW (1L<<6) -#define BIT_UNKNOWN_ASMAX (1L<<7) -#define BIT_OPTIMIZER (1L<<8) -#define BIT_KSQO (1L<<9) -#define BIT_COMMLOG (1L<<10) -#define BIT_DEBUG (1L<<11) -#define BIT_PARSE (1L<<12) -#define BIT_CANCELASFREESTMT (1L<<13) -#define BIT_USEDECLAREFETCH (1L<<14) -#define BIT_READONLY (1L<<15) -#define BIT_TEXTASLONGVARCHAR (1L<<16) -#define BIT_UNKNOWNSASLONGVARCHAR (1L<<17) -#define BIT_BOOLSASCHAR (1L<<18) -#define BIT_ROWVERSIONING (1L<<19) -#define BIT_SHOWSYSTEMTABLES (1L<<20) -#define BIT_SHOWOIDCOLUMN (1L<<21) -#define BIT_FAKEOIDINDEX (1L<<22) -#define BIT_TRUEISMINUS1 (1L<<23) - -#define EFFECTIVE_BIT_COUNT 24 - - -/* Connection Defaults */ -#define DEFAULT_PORT "5432" -#define DEFAULT_READONLY 0 -#define DEFAULT_PROTOCOL "6.4" /* the latest protocol is - * the default */ -#define DEFAULT_USEDECLAREFETCH 0 -#define DEFAULT_TEXTASLONGVARCHAR 1 -#define DEFAULT_UNKNOWNSASLONGVARCHAR 0 -#define DEFAULT_BOOLSASCHAR 1 -#define DEFAULT_OPTIMIZER 1 /* disable */ -#define DEFAULT_KSQO 1 /* on */ -#define DEFAULT_UNIQUEINDEX 1 /* dont recognize */ -#define DEFAULT_COMMLOG 0 /* dont log */ -#define DEFAULT_DEBUG 0 -#define DEFAULT_UNKNOWNSIZES UNKNOWNS_AS_MAX - - -#define DEFAULT_FAKEOIDINDEX 0 -#define DEFAULT_SHOWOIDCOLUMN 0 -#define DEFAULT_ROWVERSIONING 0 -#define DEFAULT_SHOWSYSTEMTABLES 0 /* dont show system tables */ -#define DEFAULT_LIE 0 -#define DEFAULT_PARSE 0 - -#define DEFAULT_CANCELASFREESTMT 0 - -#define DEFAULT_EXTRASYSTABLEPREFIXES "dd_;" - -#define DEFAULT_DISALLOWPREMATURE 0 -#define DEFAULT_TRUEISMINUS1 0 -#ifdef DRIVER_CURSOR_IMPLEMENT -#define DEFAULT_UPDATABLECURSORS 1 -#else -#define DEFAULT_UPDATABLECURSORS 0 -#endif /* DRIVER_CURSOR_IMPLEMENT */ -#ifdef WIN32 -#define DEFAULT_LFCONVERSION 1 -#else -#define DEFAULT_LFCONVERSION 0 -#endif /* WIN32 */ -#define DEFAULT_INT8AS 0 - -/* prototypes */ -void getCommonDefaults(const char *section, const char *filename, ConnInfo *ci); - -#ifdef WIN32 -void SetDlgStuff(HWND hdlg, const ConnInfo *ci); -void GetDlgStuff(HWND hdlg, ConnInfo *ci); - -int CALLBACK driver_optionsProc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam); -int CALLBACK global_optionsProc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam); -int CALLBACK ds_options1Proc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam); -int CALLBACK ds_options2Proc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam); -#endif /* WIN32 */ - -void updateGlobals(void); -void writeDriverCommoninfo(const ConnInfo *ci); -void writeDSNinfo(const ConnInfo *ci); -void getDSNdefaults(ConnInfo *ci); -void getDSNinfo(ConnInfo *ci, char overwrite); -void makeConnectString(char *connect_string, const ConnInfo *ci, UWORD); -void copyAttributes(ConnInfo *ci, const char *attribute, const char *value); -void copyCommonAttributes(ConnInfo *ci, const char *attribute, const char *value); - -#endif diff --git a/src/interfaces/odbc/dlg_wingui.c b/src/interfaces/odbc/dlg_wingui.c deleted file mode 100644 index 88c2e9f4c4..0000000000 --- a/src/interfaces/odbc/dlg_wingui.c +++ /dev/null @@ -1,523 +0,0 @@ -#ifdef WIN32 -/*------- - * Module: dlg_wingui.c - * - * Description: This module contains any specific code for handling - * dialog boxes such as driver/datasource options. Both the - * ConfigDSN() and the SQLDriverConnect() functions use - * functions in this module. If you were to add a new option - * to any dialog box, you would most likely only have to change - * things in here rather than in 2 separate places as before. - * - * Classes: none - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ -/* Multibyte support Eiji Tokuya 2001-03-15 */ - -#include "dlg_specific.h" - -#include "convert.h" - -#ifdef MULTIBYTE -#include "multibyte.h" -#endif -#include "pgapifunc.h" - -#ifndef BOOL -#define BOOL int -#endif -#ifndef FALSE -#define FALSE (BOOL)0 -#endif -#ifndef TRUE -#define TRUE (BOOL)1 -#endif - -extern GLOBAL_VALUES globals; - -extern HINSTANCE NEAR s_hModule; -static int driver_optionsDraw(HWND, const ConnInfo *, int src, BOOL enable); -static int driver_options_update(HWND hdlg, ConnInfo *ci, BOOL); - -void -SetDlgStuff(HWND hdlg, const ConnInfo *ci) -{ - /* - * If driver attribute NOT present, then set the datasource name and - * description - */ - if (ci->driver[0] == '\0') - { - SetDlgItemText(hdlg, IDC_DSNAME, ci->dsn); - SetDlgItemText(hdlg, IDC_DESC, ci->desc); - } - - SetDlgItemText(hdlg, IDC_DATABASE, ci->database); - SetDlgItemText(hdlg, IDC_SERVER, ci->server); - SetDlgItemText(hdlg, IDC_USER, ci->username); - SetDlgItemText(hdlg, IDC_PASSWORD, ci->password); - SetDlgItemText(hdlg, IDC_PORT, ci->port); -} - - -void -GetDlgStuff(HWND hdlg, ConnInfo *ci) -{ - GetDlgItemText(hdlg, IDC_DESC, ci->desc, sizeof(ci->desc)); - - GetDlgItemText(hdlg, IDC_DATABASE, ci->database, sizeof(ci->database)); - GetDlgItemText(hdlg, IDC_SERVER, ci->server, sizeof(ci->server)); - GetDlgItemText(hdlg, IDC_USER, ci->username, sizeof(ci->username)); - GetDlgItemText(hdlg, IDC_PASSWORD, ci->password, sizeof(ci->password)); - GetDlgItemText(hdlg, IDC_PORT, ci->port, sizeof(ci->port)); -} - - -static int -driver_optionsDraw(HWND hdlg, const ConnInfo *ci, int src, BOOL enable) -{ - const GLOBAL_VALUES *comval; - static BOOL defset = FALSE; - static GLOBAL_VALUES defval; - - switch (src) - { - case 0: /* driver common */ - comval = &globals; - break; - case 1: /* dsn specific */ - comval = &(ci->drivers); - break; - case 2: /* default */ - if (!defset) - { - defval.commlog = DEFAULT_COMMLOG; - defval.disable_optimizer = DEFAULT_OPTIMIZER; - defval.ksqo = DEFAULT_KSQO; - defval.unique_index = DEFAULT_UNIQUEINDEX; - defval.onlyread = DEFAULT_READONLY; - defval.use_declarefetch = DEFAULT_USEDECLAREFETCH; - - defval.parse = DEFAULT_PARSE; - defval.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT; - defval.debug = DEFAULT_DEBUG; - - /* Unknown Sizes */ - defval.unknown_sizes = DEFAULT_UNKNOWNSIZES; - defval.text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR; - defval.unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR; - defval.bools_as_char = DEFAULT_BOOLSASCHAR; - } - defset = TRUE; - comval = &defval; - break; - } - - ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL2), enable ? SW_SHOW : SW_HIDE); - CheckDlgButton(hdlg, DRV_COMMLOG, comval->commlog); -#ifndef Q_LOG - EnableWindow(GetDlgItem(hdlg, DRV_COMMLOG), FALSE); -#endif /* Q_LOG */ - CheckDlgButton(hdlg, DRV_OPTIMIZER, comval->disable_optimizer); - CheckDlgButton(hdlg, DRV_KSQO, comval->ksqo); - CheckDlgButton(hdlg, DRV_UNIQUEINDEX, comval->unique_index); - /* EnableWindow(GetDlgItem(hdlg, DRV_UNIQUEINDEX), enable); */ - CheckDlgButton(hdlg, DRV_READONLY, comval->onlyread); - EnableWindow(GetDlgItem(hdlg, DRV_READONLY), enable); - CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, comval->use_declarefetch); - - /* Unknown Sizes clear */ - CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 0); - CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 0); - CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 0); - /* Unknown (Default) Data Type sizes */ - switch (comval->unknown_sizes) - { - case UNKNOWNS_AS_DONTKNOW: - CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1); - break; - case UNKNOWNS_AS_LONGEST: - CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 1); - break; - case UNKNOWNS_AS_MAX: - default: - CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 1); - break; - } - - CheckDlgButton(hdlg, DRV_TEXT_LONGVARCHAR, comval->text_as_longvarchar); - CheckDlgButton(hdlg, DRV_UNKNOWNS_LONGVARCHAR, comval->unknowns_as_longvarchar); - CheckDlgButton(hdlg, DRV_BOOLS_CHAR, comval->bools_as_char); - CheckDlgButton(hdlg, DRV_PARSE, comval->parse); - CheckDlgButton(hdlg, DRV_CANCELASFREESTMT, comval->cancel_as_freestmt); - CheckDlgButton(hdlg, DRV_DEBUG, comval->debug); -#ifndef MY_LOG - EnableWindow(GetDlgItem(hdlg, DRV_DEBUG), FALSE); -#endif /* MY_LOG */ - SetDlgItemInt(hdlg, DRV_CACHE_SIZE, comval->fetch_max, FALSE); - SetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, comval->max_varchar_size, FALSE); - SetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, comval->max_longvarchar_size, TRUE); - SetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes); - - /* Driver Connection Settings */ - SetDlgItemText(hdlg, DRV_CONNSETTINGS, comval->conn_settings); - EnableWindow(GetDlgItem(hdlg, DRV_CONNSETTINGS), enable); - ShowWindow(GetDlgItem(hdlg, IDPREVPAGE), enable ? SW_HIDE : SW_SHOW); - ShowWindow(GetDlgItem(hdlg, IDNEXTPAGE), enable ? SW_HIDE : SW_SHOW); - return 0; -} -static int -driver_options_update(HWND hdlg, ConnInfo *ci, BOOL updateProfile) -{ - GLOBAL_VALUES *comval; - - if (ci) - comval = &(ci->drivers); - else - comval = &globals; - comval->commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG); - comval->disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER); - comval->ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO); - comval->unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX); - if (!ci) - { - comval->onlyread = IsDlgButtonChecked(hdlg, DRV_READONLY); - } - comval->use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH); - - /* Unknown (Default) Data Type sizes */ - if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_MAX)) - comval->unknown_sizes = UNKNOWNS_AS_MAX; - else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_DONTKNOW)) - comval->unknown_sizes = UNKNOWNS_AS_DONTKNOW; - else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_LONGEST)) - comval->unknown_sizes = UNKNOWNS_AS_LONGEST; - else - comval->unknown_sizes = UNKNOWNS_AS_MAX; - - comval->text_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_TEXT_LONGVARCHAR); - comval->unknowns_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_UNKNOWNS_LONGVARCHAR); - comval->bools_as_char = IsDlgButtonChecked(hdlg, DRV_BOOLS_CHAR); - - comval->parse = IsDlgButtonChecked(hdlg, DRV_PARSE); - - comval->cancel_as_freestmt = IsDlgButtonChecked(hdlg, DRV_CANCELASFREESTMT); - comval->debug = IsDlgButtonChecked(hdlg, DRV_DEBUG); - - comval->fetch_max = GetDlgItemInt(hdlg, DRV_CACHE_SIZE, NULL, FALSE); - comval->max_varchar_size = GetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, NULL, FALSE); - comval->max_longvarchar_size = GetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, NULL, TRUE); /* allows for - * SQL_NO_TOTAL */ - - GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, sizeof(comval->extra_systable_prefixes)); - - /* Driver Connection Settings */ - if (!ci) - GetDlgItemText(hdlg, DRV_CONNSETTINGS, comval->conn_settings, sizeof(comval->conn_settings)); - - if (updateProfile) - writeDriverCommoninfo(ci); - - /* fall through */ - return 0; -} - -int CALLBACK -driver_optionsProc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam) -{ - ConnInfo *ci; - - switch (wMsg) - { - case WM_INITDIALOG: - SetWindowLong(hdlg, DWL_USER, lParam); /* save for OK etc */ - ci = (ConnInfo *) lParam; - SetWindowText(hdlg, "Advanced Options (Default)"); - SetWindowText(GetDlgItem(hdlg, IDOK), "Save"); - ShowWindow(GetDlgItem(hdlg, IDAPPLY), SW_HIDE); - driver_optionsDraw(hdlg, ci, 0, TRUE); - break; - - case WM_COMMAND: - switch (GET_WM_COMMAND_ID(wParam, lParam)) - { - case IDOK: - ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); - driver_options_update(hdlg, NULL, - ci && ci->dsn && ci->dsn[0]); - - case IDCANCEL: - EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); - return TRUE; - - case IDDEFAULTS: - driver_optionsDraw(hdlg, NULL, 2, TRUE); - break; - } - } - - return FALSE; -} - -int CALLBACK -global_optionsProc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam) -{ - - switch (wMsg) - { - case WM_INITDIALOG: - CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog); -#ifndef Q_LOG - EnableWindow(GetDlgItem(hdlg, DRV_COMMLOG), FALSE); -#endif /* Q_LOG */ - CheckDlgButton(hdlg, DRV_DEBUG, globals.debug); -#ifndef MY_LOG - EnableWindow(GetDlgItem(hdlg, DRV_DEBUG), FALSE); -#endif /* MY_LOG */ - break; - - case WM_COMMAND: - switch (GET_WM_COMMAND_ID(wParam, lParam)) - { - case IDOK: - globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG); - globals.debug = IsDlgButtonChecked(hdlg, DRV_DEBUG); - driver_options_update(hdlg, NULL, TRUE); - - case IDCANCEL: - EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); - return TRUE; - } - } - - return FALSE; -} - -int CALLBACK -ds_options1Proc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam) -{ - ConnInfo *ci; - - switch (wMsg) - { - case WM_INITDIALOG: - SetWindowLong(hdlg, DWL_USER, lParam); /* save for OK etc */ - ci = (ConnInfo *) lParam; - if (ci && ci->dsn && ci->dsn[0]) - SetWindowText(hdlg, "Advanced Options (DSN 1/2)"); - else - { - SetWindowText(hdlg, "Advanced Options (Connection 1/2)"); - ShowWindow(GetDlgItem(hdlg, IDAPPLY), SW_HIDE); - } - driver_optionsDraw(hdlg, ci, 1, FALSE); - break; - - case WM_COMMAND: - ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); - switch (GET_WM_COMMAND_ID(wParam, lParam)) - { - case IDOK: - driver_options_update(hdlg, ci, FALSE); - - case IDCANCEL: - EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); - return TRUE; - - case IDAPPLY: - driver_options_update(hdlg, ci, FALSE); - SendMessage(GetWindow(hdlg, GW_OWNER), WM_COMMAND, wParam, lParam); - break; - - case IDDEFAULTS: - driver_optionsDraw(hdlg, ci, 0, FALSE); - break; - - case IDNEXTPAGE: - driver_options_update(hdlg, ci, FALSE); - - EndDialog(hdlg, FALSE); - DialogBoxParam(s_hModule, - MAKEINTRESOURCE(DLG_OPTIONS_DS), - hdlg, ds_options2Proc, (LPARAM) -ci); - break; - } - } - - return FALSE; -} - - -int CALLBACK -ds_options2Proc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam) -{ - ConnInfo *ci; - char buf[128]; - DWORD cmd; - - switch (wMsg) - { - case WM_INITDIALOG: - ci = (ConnInfo *) lParam; - SetWindowLong(hdlg, DWL_USER, lParam); /* save for OK */ - - /* Change window caption */ - if (ci->driver[0]) - { - SetWindowText(hdlg, "Advanced Options (Connection 2/2)"); - ShowWindow(GetDlgItem(hdlg, IDAPPLY), SW_HIDE); } - else - { - sprintf(buf, "Advanced Options (%s) 2/2", ci->dsn); - SetWindowText(hdlg, buf); - } - - /* Readonly */ - CheckDlgButton(hdlg, DS_READONLY, atoi(ci->onlyread)); - - /* Protocol */ - if (strncmp(ci->protocol, PG62, strlen(PG62)) == 0) - CheckDlgButton(hdlg, DS_PG62, 1); - else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0) - CheckDlgButton(hdlg, DS_PG63, 1); - else - /* latest */ - CheckDlgButton(hdlg, DS_PG64, 1); - - /* Int8 As */ - switch (ci->int8_as) - { - case SQL_BIGINT: - CheckDlgButton(hdlg, DS_INT8_AS_BIGINT, 1); - break; - case SQL_NUMERIC: - CheckDlgButton(hdlg, DS_INT8_AS_NUMERIC, 1); - break; - case SQL_VARCHAR: - CheckDlgButton(hdlg, DS_INT8_AS_VARCHAR, 1); - break; - case SQL_DOUBLE: - CheckDlgButton(hdlg, DS_INT8_AS_DOUBLE, 1); - break; - case SQL_INTEGER: - CheckDlgButton(hdlg, DS_INT8_AS_INT4, 1); - break; - default: - CheckDlgButton(hdlg, DS_INT8_AS_DEFAULT, 1); - } - - CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column)); - CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index)); - CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning)); - CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables)); - CheckDlgButton(hdlg, DS_DISALLOWPREMATURE, ci->disallow_premature); - CheckDlgButton(hdlg, DS_LFCONVERSION, ci->lf_conversion); - CheckDlgButton(hdlg, DS_TRUEISMINUS1, ci->true_is_minus1); - CheckDlgButton(hdlg, DS_UPDATABLECURSORS, ci->allow_keyset); -#ifndef DRIVER_CURSOR_IMPLEMENT - EnableWindow(GetDlgItem(hdlg, DS_UPDATABLECURSORS), FALSE); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column)); - - /* Datasource Connection Settings */ - SetDlgItemText(hdlg, DS_CONNSETTINGS, ci->conn_settings); - break; - - case WM_COMMAND: - switch (cmd = GET_WM_COMMAND_ID(wParam, lParam)) - { - case DS_SHOWOIDCOLUMN: - mylog("WM_COMMAND: DS_SHOWOIDCOLUMN\n"); - EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN)); - return TRUE; - - case IDOK: - case IDAPPLY: - case IDPREVPAGE: - ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); - mylog("IDOK: got ci = %u\n", ci); - - /* Readonly */ - sprintf(ci->onlyread, "%d", IsDlgButtonChecked(hdlg, DS_READONLY)); - - /* Protocol */ - if (IsDlgButtonChecked(hdlg, DS_PG62)) - strcpy(ci->protocol, PG62); - else if (IsDlgButtonChecked(hdlg, DS_PG63)) - strcpy(ci->protocol, PG63); - else - /* latest */ - strcpy(ci->protocol, PG64); - - /* Int8 As */ - if (IsDlgButtonChecked(hdlg, DS_INT8_AS_DEFAULT)) - ci->int8_as = 0; - else if (IsDlgButtonChecked(hdlg, DS_INT8_AS_BIGINT)) - ci->int8_as = SQL_BIGINT; - else if (IsDlgButtonChecked(hdlg, DS_INT8_AS_NUMERIC)) - ci->int8_as = SQL_NUMERIC; - else if (IsDlgButtonChecked(hdlg, DS_INT8_AS_DOUBLE)) - ci->int8_as = SQL_DOUBLE; - else if (IsDlgButtonChecked(hdlg, DS_INT8_AS_INT4)) - ci->int8_as = SQL_INTEGER; - else - ci->int8_as = SQL_VARCHAR; - - sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES)); - - sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING)); - ci->disallow_premature = IsDlgButtonChecked(hdlg, DS_DISALLOWPREMATURE); - ci->lf_conversion = IsDlgButtonChecked(hdlg, DS_LFCONVERSION); - ci->true_is_minus1 = IsDlgButtonChecked(hdlg, DS_TRUEISMINUS1); -#ifdef DRIVER_CURSOR_IMPLEMENT - ci->allow_keyset = IsDlgButtonChecked(hdlg, DS_UPDATABLECURSORS); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - /* OID Options */ - sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX)); - sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN)); - - /* Datasource Connection Settings */ - GetDlgItemText(hdlg, DS_CONNSETTINGS, ci->conn_settings, sizeof(ci->conn_settings)); - if (IDAPPLY == cmd) - { - SendMessage(GetWindow(hdlg, GW_OWNER), WM_COMMAND, wParam, lParam); - break; - } - - EndDialog(hdlg, cmd == IDOK); - if (IDOK == cmd) - return TRUE; - DialogBoxParam(s_hModule, - MAKEINTRESOURCE(DLG_OPTIONS_DRV), - hdlg, ds_options1Proc, (LPARAM) ci); - break; - - case IDCANCEL: - EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); - return TRUE; - } - } - - return FALSE; -} - -#endif /* WIN32 */ diff --git a/src/interfaces/odbc/drvconn.c b/src/interfaces/odbc/drvconn.c deleted file mode 100644 index 6c08376ac4..0000000000 --- a/src/interfaces/odbc/drvconn.c +++ /dev/null @@ -1,435 +0,0 @@ -/*------- - Module: drvconn.c - * - * Description: This module contains only routines related to - * implementing SQLDriverConnect. - * - * Classes: n/a - * - * API functions: SQLDriverConnect - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "psqlodbc.h" - -#include -#include - -#include "connection.h" - -#ifndef WIN32 -#include -#include -#define NEAR -#else -#include -#endif - -#include - -#ifdef WIN32 -#include -#include "resource.h" -#endif -#include "pgapifunc.h" - -#ifndef TRUE -#define TRUE (BOOL)1 -#endif -#ifndef FALSE -#define FALSE (BOOL)0 -#endif - -#include "dlg_specific.h" - -/* prototypes */ -void dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci); -static void dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci); - -#ifdef WIN32 -BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam); -RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci); - -extern HINSTANCE NEAR s_hModule; /* Saved module handle. */ -#endif - - -RETCODE SQL_API -PGAPI_DriverConnect( - HDBC hdbc, - HWND hwnd, - UCHAR FAR * szConnStrIn, - SWORD cbConnStrIn, - UCHAR FAR * szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR * pcbConnStrOut, - UWORD fDriverCompletion) -{ - static char *func = "PGAPI_DriverConnect"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci; - -#ifdef WIN32 - RETCODE dialog_result; -#endif - RETCODE result; - char connStrIn[MAX_CONNECT_STRING]; - char connStrOut[MAX_CONNECT_STRING]; - int retval; - char salt[5]; - char password_required = AUTH_REQ_OK; - int len = 0; - SWORD lenStrout; - - - mylog("%s: entering...\n", func); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - make_string(szConnStrIn, cbConnStrIn, connStrIn); - - mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn); - qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion); - - ci = &(conn->connInfo); - - /* Parse the connect string and fill in conninfo for this hdbc. */ - dconn_get_connect_attributes(connStrIn, ci); - - /* - * If the ConnInfo in the hdbc is missing anything, this function will - * fill them in from the registry (assuming of course there is a DSN - * given -- if not, it does nothing!) - */ - getDSNinfo(ci, CONN_DONT_OVERWRITE); - dconn_get_common_attributes(connStrIn, ci); - logs_on_off(1, ci->drivers.debug, ci->drivers.commlog); - - /* Fill in any default parameters if they are not there. */ - getDSNdefaults(ci); - /* initialize pg_version */ - CC_initialize_pg_version(conn); - salt[0] = '\0'; - -#ifdef WIN32 -dialog: -#endif - ci->focus_password = password_required; - - switch (fDriverCompletion) - { -#ifdef WIN32 - case SQL_DRIVER_PROMPT: - dialog_result = dconn_DoDialog(hwnd, ci); - if (dialog_result != SQL_SUCCESS) - return dialog_result; - break; - - case SQL_DRIVER_COMPLETE_REQUIRED: - - /* Fall through */ - - case SQL_DRIVER_COMPLETE: - - /* Password is not a required parameter. */ - if (ci->username[0] == '\0' || - ci->server[0] == '\0' || - ci->database[0] == '\0' || - ci->port[0] == '\0' || - password_required) - { - dialog_result = dconn_DoDialog(hwnd, ci); - if (dialog_result != SQL_SUCCESS) - return dialog_result; - } - break; -#else - case SQL_DRIVER_PROMPT: - case SQL_DRIVER_COMPLETE: - case SQL_DRIVER_COMPLETE_REQUIRED: -#endif - case SQL_DRIVER_NOPROMPT: - break; - } - - /* - * Password is not a required parameter unless authentication asks for - * it. For now, I think it's better to just let the application ask - * over and over until a password is entered (the user can always hit - * Cancel to get out) - */ - if (ci->username[0] == '\0' || - ci->server[0] == '\0' || - ci->database[0] == '\0' || - ci->port[0] == '\0') - { - /* (password_required && ci->password[0] == '\0')) */ - - return SQL_NO_DATA_FOUND; - } - - /* do the actual connect */ - retval = CC_connect(conn, password_required, salt); - if (retval < 0) - { /* need a password */ - if (fDriverCompletion == SQL_DRIVER_NOPROMPT) - { - CC_log_error(func, "Need password but Driver_NoPrompt", conn); - return SQL_ERROR; /* need a password but not allowed to - * prompt so error */ - } - else - { -#ifdef WIN32 - password_required = -retval; - goto dialog; -#else - return SQL_ERROR; /* until a better solution is found. */ -#endif - } - } - else if (retval == 0) - { - /* error msg filled in above */ - CC_log_error(func, "Error from CC_Connect", conn); - return SQL_ERROR; - } - - /* - * Create the Output Connection String - */ - result = SQL_SUCCESS; - - lenStrout = cbConnStrOutMax; - if (conn->ms_jet && lenStrout > 255) - lenStrout = 255; - makeConnectString(connStrOut, ci, lenStrout); - len = strlen(connStrOut); - - if (szConnStrOut) - { - /* - * Return the completed string to the caller. The correct method - * is to only construct the connect string if a dialog was put up, - * otherwise, it should just copy the connection input string to - * the output. However, it seems ok to just always construct an - * output string. There are possible bad side effects on working - * applications (Access) by implementing the correct behavior, - * anyway. - */ - strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax); - - if (len >= cbConnStrOutMax) - { - int clen; - - for (clen = strlen(szConnStrOut) - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--) - szConnStrOut[clen] = '\0'; - result = SQL_SUCCESS_WITH_INFO; - conn->errornumber = CONN_TRUNCATED; - conn->errormsg = "The buffer was too small for the ConnStrOut."; - } - } - - if (pcbConnStrOut) - *pcbConnStrOut = len; - - mylog("szConnStrOut = '%s' len=%d,%d\n", szConnStrOut, len, cbConnStrOutMax); - qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut); - - - mylog("PGAPI_DriverConnect: returning %d\n", result); - return result; -} - - -#ifdef WIN32 -RETCODE -dconn_DoDialog(HWND hwnd, ConnInfo *ci) -{ - int dialog_result; - - mylog("dconn_DoDialog: ci = %u\n", ci); - - if (hwnd) - { - dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG), - hwnd, dconn_FDriverConnectProc, (LPARAM) ci); - if (!dialog_result || (dialog_result == -1)) - return SQL_NO_DATA_FOUND; - else - return SQL_SUCCESS; - } - - return SQL_ERROR; -} - - -BOOL FAR PASCAL -dconn_FDriverConnectProc( - HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam) -{ - ConnInfo *ci; - - switch (wMsg) - { - case WM_INITDIALOG: - ci = (ConnInfo *) lParam; - - /* Change the caption for the setup dialog */ - SetWindowText(hdlg, "PostgreSQL Connection"); - - SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection"); - - /* Hide the DSN and description fields */ - ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE); - ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE); - ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE); - ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE); - ShowWindow(GetDlgItem(hdlg, IDC_DRIVER), SW_HIDE); - - SetWindowLong(hdlg, DWL_USER, lParam); /* Save the ConnInfo for - * the "OK" */ - SetDlgStuff(hdlg, ci); - - if (ci->database[0] == '\0') - ; /* default focus */ - else if (ci->server[0] == '\0') - SetFocus(GetDlgItem(hdlg, IDC_SERVER)); - else if (ci->port[0] == '\0') - SetFocus(GetDlgItem(hdlg, IDC_PORT)); - else if (ci->username[0] == '\0') - SetFocus(GetDlgItem(hdlg, IDC_USER)); - else if (ci->focus_password) - SetFocus(GetDlgItem(hdlg, IDC_PASSWORD)); - break; - - case WM_COMMAND: - switch (GET_WM_COMMAND_ID(wParam, lParam)) - { - case IDOK: - ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); - - GetDlgStuff(hdlg, ci); - - case IDCANCEL: - EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); - return TRUE; - - case IDC_DATASOURCE: - ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); - DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV), - hdlg, ds_options1Proc, (LPARAM) ci); - break; - - case IDC_DRIVER: - ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); - DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV), - hdlg, driver_optionsProc, (LPARAM) ci); - break; - } - } - - return FALSE; -} -#endif /* WIN32 */ - - -void -dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci) -{ - char *our_connect_string; - char *pair, - *attribute, - *value, - *equals; - char *strtok_arg; - - CC_conninfo_init(ci); - - our_connect_string = strdup(connect_string); - strtok_arg = our_connect_string; - - mylog("our_connect_string = '%s'\n", our_connect_string); - - while (1) - { - pair = strtok(strtok_arg, ";"); - if (strtok_arg) - strtok_arg = 0; - if (!pair) - break; - - equals = strchr(pair, '='); - if (!equals) - continue; - - *equals = '\0'; - attribute = pair; /* ex. DSN */ - value = equals + 1; /* ex. 'CEO co1' */ - - mylog("attribute = '%s', value = '%s'\n", attribute, value); - - if (!attribute || !value) - continue; - - /* Copy the appropriate value to the conninfo */ - copyAttributes(ci, attribute, value); - - } - - free(our_connect_string); -} - -static void -dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci) -{ - char *our_connect_string; - char *pair, - *attribute, - *value, - *equals; - char *strtok_arg; - - our_connect_string = strdup(connect_string); - strtok_arg = our_connect_string; - - mylog("our_connect_string = '%s'\n", our_connect_string); - - while (1) - { - pair = strtok(strtok_arg, ";"); - if (strtok_arg) - strtok_arg = 0; - if (!pair) - break; - - equals = strchr(pair, '='); - if (!equals) - continue; - - *equals = '\0'; - attribute = pair; /* ex. DSN */ - value = equals + 1; /* ex. 'CEO co1' */ - - mylog("attribute = '%s', value = '%s'\n", attribute, value); - - if (!attribute || !value) - continue; - - /* Copy the appropriate value to the conninfo */ - copyCommonAttributes(ci, attribute, value); - - } - - free(our_connect_string); -} diff --git a/src/interfaces/odbc/environ.c b/src/interfaces/odbc/environ.c deleted file mode 100644 index 9ac8f8eb6c..0000000000 --- a/src/interfaces/odbc/environ.c +++ /dev/null @@ -1,661 +0,0 @@ -/*------- - * Module: environ.c - * - * Description: This module contains routines related to - * the environment, such as storing connection handles, - * and returning errors. - * - * Classes: EnvironmentClass (Functions prefix: "EN_") - * - * API functions: SQLAllocEnv, SQLFreeEnv, SQLError - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "environ.h" - -#include "connection.h" -#include "dlg_specific.h" -#include "statement.h" -#include -#include -#include "pgapifunc.h" - -extern GLOBAL_VALUES globals; - -/* The one instance of the handles */ -ConnectionClass *conns[MAX_CONNECTIONS]; - - -RETCODE SQL_API -PGAPI_AllocEnv(HENV FAR * phenv) -{ - static char *func = "PGAPI_AllocEnv"; - - mylog("**** in PGAPI_AllocEnv ** \n"); - - /* - * Hack for systems on which none of the constructor-making techniques - * in psqlodbc.c work: if globals appears not to have been - * initialized, then cause it to be initialized. Since this should be - * the first function called in this shared library, doing it here - * should work. - */ - if (globals.socket_buffersize <= 0) - getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL); - - *phenv = (HENV) EN_Constructor(); - if (!*phenv) - { - *phenv = SQL_NULL_HENV; - EN_log_error(func, "Error allocating environment", NULL); - return SQL_ERROR; - } - - mylog("** exit PGAPI_AllocEnv: phenv = %u **\n", *phenv); - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_FreeEnv(HENV henv) -{ - static char *func = "PGAPI_FreeEnv"; - EnvironmentClass *env = (EnvironmentClass *) henv; - - mylog("**** in PGAPI_FreeEnv: env = %u ** \n", env); - - if (env && EN_Destructor(env)) - { - mylog(" ok\n"); - return SQL_SUCCESS; - } - - mylog(" error\n"); - EN_log_error(func, "Error freeing environment", env); - return SQL_ERROR; -} - - -static void -pg_sqlstate_set(const EnvironmentClass *env, UCHAR *szSqlState, const UCHAR *ver3str, const UCHAR *ver2str) -{ - strcpy(szSqlState, EN_is_odbc3(env) ? ver3str : ver2str); -} - -#define DRVMNGRDIV 511 -/* Returns the next SQL error information. */ -RETCODE SQL_API -PGAPI_StmtError( HSTMT hstmt, - SWORD RecNumber, - UCHAR FAR * szSqlState, - SDWORD FAR * pfNativeError, - UCHAR FAR * szErrorMsg, - SWORD cbErrorMsgMax, - SWORD FAR * pcbErrorMsg, - UWORD flag) -{ - /* CC: return an error of a hstmt */ - StatementClass *stmt = (StatementClass *) hstmt; - EnvironmentClass *env = (EnvironmentClass *) SC_get_conn(stmt)->henv; - char *msg; - int status; - BOOL partial_ok = ((flag & PODBC_ALLOW_PARTIAL_EXTRACT) != 0), - clear_str = ((flag & PODBC_ERROR_CLEAR) != 0); - SWORD msglen, stapos, wrtlen, pcblen; - - mylog("**** PGAPI_StmtError: hstmt=%u <%d>\n", hstmt, cbErrorMsgMax); - - if (cbErrorMsgMax < 0) - return SQL_ERROR; - - if (!SC_get_error(stmt, &status, &msg) || NULL == msg || !msg[0]) - { - mylog("SC_Get_error returned nothing.\n"); - if (NULL != szSqlState) - strcpy(szSqlState, "00000"); - if (NULL != pcbErrorMsg) - *pcbErrorMsg = 0; - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - szErrorMsg[0] = '\0'; - - return SQL_NO_DATA_FOUND; - } - mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg); - msglen = (SWORD) strlen(msg); - /* - * Even though an application specifies a larger error message - * buffer, the driver manager changes it silently. - * Therefore we divide the error message into ... - */ - if (stmt->error_recsize < 0) - { - if (cbErrorMsgMax > 0) - stmt->error_recsize = cbErrorMsgMax - 1; /* apply the first request */ - else - stmt->error_recsize = DRVMNGRDIV; - } - if (RecNumber < 0) - { - if (0 == stmt->errorpos) - RecNumber = 1; - else - RecNumber = 2 + (stmt->errorpos - 1) / stmt->error_recsize; - } - stapos = (RecNumber - 1) * stmt->error_recsize; - if (stapos > msglen) - return SQL_NO_DATA_FOUND; - pcblen = wrtlen = msglen - stapos; - if (pcblen > stmt->error_recsize) - pcblen = stmt->error_recsize; - if (0 == cbErrorMsgMax) - wrtlen = 0; - else if (wrtlen >= cbErrorMsgMax) - { - if (partial_ok) - wrtlen = cbErrorMsgMax - 1; - else if (cbErrorMsgMax <= stmt->error_recsize) - wrtlen = 0; - else - wrtlen = stmt->error_recsize; - } - if (wrtlen > pcblen) - wrtlen = pcblen; - if (NULL != pcbErrorMsg) - *pcbErrorMsg = pcblen; - - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - { - memcpy(szErrorMsg, msg + stapos, wrtlen); - szErrorMsg[wrtlen] = '\0'; - } - - if (NULL != pfNativeError) - *pfNativeError = status; - - if (NULL != szSqlState) - - switch (status) - { - /* now determine the SQLSTATE to be returned */ - case STMT_ROW_VERSION_CHANGED: - pg_sqlstate_set(env, szSqlState, "01001", "01001"); - /* data truncated */ - break; - case STMT_TRUNCATED: - pg_sqlstate_set(env, szSqlState, "01004", "01004"); - /* data truncated */ - break; - case STMT_INFO_ONLY: - pg_sqlstate_set(env, szSqlState, "00000", "0000"); - /* just information that is returned, no error */ - break; - case STMT_BAD_ERROR: - pg_sqlstate_set(env, szSqlState, "08S01", "08S01"); - /* communication link failure */ - break; - case STMT_CREATE_TABLE_ERROR: - pg_sqlstate_set(env, szSqlState, "42S01", "S0001"); - /* table already exists */ - break; - case STMT_STATUS_ERROR: - case STMT_SEQUENCE_ERROR: - pg_sqlstate_set(env, szSqlState, "HY010", "S1010"); - /* Function sequence error */ - break; - case STMT_NO_MEMORY_ERROR: - pg_sqlstate_set(env, szSqlState, "HY001", "S1001"); - /* memory allocation failure */ - break; - case STMT_COLNUM_ERROR: - pg_sqlstate_set(env, szSqlState, "07009", "S1002"); - /* invalid column number */ - break; - case STMT_NO_STMTSTRING: - pg_sqlstate_set(env, szSqlState, "HY001", "S1001"); - /* having no stmtstring is also a malloc problem */ - break; - case STMT_ERROR_TAKEN_FROM_BACKEND: - pg_sqlstate_set(env, szSqlState, "HY000", "S1000"); - /* general error */ - break; - case STMT_INTERNAL_ERROR: - pg_sqlstate_set(env, szSqlState, "HY000", "S1000"); - /* general error */ - break; - case STMT_FETCH_OUT_OF_RANGE: - pg_sqlstate_set(env, szSqlState, "HY106", "S1106"); - break; - - case STMT_ROW_OUT_OF_RANGE: - pg_sqlstate_set(env, szSqlState, "HY107", "S1107"); - break; - - case STMT_OPERATION_CANCELLED: - pg_sqlstate_set(env, szSqlState, "HY008", "S1008"); - break; - - case STMT_NOT_IMPLEMENTED_ERROR: - pg_sqlstate_set(env, szSqlState, "HYC00", "S1C00"); /* == 'driver not - * capable' */ - break; - case STMT_OPTION_OUT_OF_RANGE_ERROR: - pg_sqlstate_set(env, szSqlState, "HY092", "S1092"); - break; - case STMT_BAD_PARAMETER_NUMBER_ERROR: - pg_sqlstate_set(env, szSqlState, "07009", "S1093"); - break; - case STMT_INVALID_COLUMN_NUMBER_ERROR: - pg_sqlstate_set(env, szSqlState, "07009", "S1002"); - break; - case STMT_RESTRICTED_DATA_TYPE_ERROR: - pg_sqlstate_set(env, szSqlState, "07006", "07006"); - break; - case STMT_INVALID_CURSOR_STATE_ERROR: - pg_sqlstate_set(env, szSqlState, "07005", "24000"); - break; - case STMT_ERROR_IN_ROW: - pg_sqlstate_set(env, szSqlState, "01S01", "01S01"); - break; - case STMT_OPTION_VALUE_CHANGED: - pg_sqlstate_set(env, szSqlState, "01S02", "01S02"); - break; - case STMT_POS_BEFORE_RECORDSET: - pg_sqlstate_set(env, szSqlState, "01S06", "01S06"); - break; - case STMT_INVALID_CURSOR_NAME: - pg_sqlstate_set(env, szSqlState, "34000", "34000"); - break; - case STMT_NO_CURSOR_NAME: - pg_sqlstate_set(env, szSqlState, "S1015", "S1015"); - break; - case STMT_INVALID_ARGUMENT_NO: - pg_sqlstate_set(env, szSqlState, "HY024", "S1009"); - /* invalid argument value */ - break; - case STMT_INVALID_CURSOR_POSITION: - pg_sqlstate_set(env, szSqlState, "HY109", "S1109"); - break; - case STMT_RETURN_NULL_WITHOUT_INDICATOR: - pg_sqlstate_set(env, szSqlState, "22002", "22002"); - break; - case STMT_VALUE_OUT_OF_RANGE: - pg_sqlstate_set(env, szSqlState, "HY019", "22003"); - break; - case STMT_OPERATION_INVALID: - pg_sqlstate_set(env, szSqlState, "HY011", "S1011"); - break; - case STMT_INVALID_DESCRIPTOR_IDENTIFIER: - pg_sqlstate_set(env, szSqlState, "HY091", "HY091"); - break; - case STMT_INVALID_OPTION_IDENTIFIER: - pg_sqlstate_set(env, szSqlState, "HY092", "HY092"); - break; - case STMT_OPTION_NOT_FOR_THE_DRIVER: - pg_sqlstate_set(env, szSqlState, "HYC00", "HYC00"); - break; - case STMT_EXEC_ERROR: - default: - pg_sqlstate_set(env, szSqlState, "HY000", "S1000"); - /* also a general error */ - break; - } - mylog(" szSqlState = '%s',len=%d, szError='%s'\n", szSqlState, pcblen, szErrorMsg); - if (clear_str) - { - stmt->errorpos = stapos + wrtlen; - if (stmt->errorpos >= msglen) - SC_clear_error(stmt); - } - if (wrtlen == 0) - return SQL_SUCCESS_WITH_INFO; - else - return SQL_SUCCESS; -} - -RETCODE SQL_API -PGAPI_ConnectError( HDBC hdbc, - SWORD RecNumber, - UCHAR FAR * szSqlState, - SDWORD FAR * pfNativeError, - UCHAR FAR * szErrorMsg, - SWORD cbErrorMsgMax, - SWORD FAR * pcbErrorMsg, - UWORD flag) -{ - ConnectionClass *conn = (ConnectionClass *) hdbc; - EnvironmentClass *env = (EnvironmentClass *) conn->henv; - char *msg; - int status; - BOOL once_again = FALSE; - SWORD msglen; - - mylog("**** PGAPI_ConnectError: hdbc=%u <%d>\n", hdbc, cbErrorMsgMax); - if (RecNumber != 1 && RecNumber != -1) - return SQL_NO_DATA_FOUND; - if (cbErrorMsgMax < 0) - return SQL_ERROR; - if (!CC_get_error(conn, &status, &msg) || NULL == msg) - { - mylog("CC_Get_error returned nothing.\n"); - if (NULL != szSqlState) - strcpy(szSqlState, "00000"); - if (NULL != pcbErrorMsg) - *pcbErrorMsg = 0; - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - szErrorMsg[0] = '\0'; - - return SQL_NO_DATA_FOUND; - } - mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg); - - msglen = strlen(msg); - if (NULL != pcbErrorMsg) - { - *pcbErrorMsg = msglen; - if (cbErrorMsgMax == 0) - once_again = TRUE; - else if (msglen >= cbErrorMsgMax) - *pcbErrorMsg = cbErrorMsgMax - 1; - } - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - strncpy_null(szErrorMsg, msg, cbErrorMsgMax); - if (NULL != pfNativeError) - *pfNativeError = status; - - if (NULL != szSqlState) - switch (status) - { - case STMT_OPTION_VALUE_CHANGED: - case CONN_OPTION_VALUE_CHANGED: - pg_sqlstate_set(env, szSqlState, "01S02", "01S02"); - break; - case STMT_TRUNCATED: - case CONN_TRUNCATED: - pg_sqlstate_set(env, szSqlState, "01004", "01004"); - /* data truncated */ - break; - case CONN_INIREAD_ERROR: - pg_sqlstate_set(env, szSqlState, "IM002", "IM002"); - /* data source not found */ - break; - case CONNECTION_SERVER_NOT_REACHED: - case CONN_OPENDB_ERROR: - pg_sqlstate_set(env, szSqlState, "08001", "08001"); - /* unable to connect to data source */ - break; - case CONN_INVALID_AUTHENTICATION: - case CONN_AUTH_TYPE_UNSUPPORTED: - pg_sqlstate_set(env, szSqlState, "28000", "28000"); - break; - case CONN_STMT_ALLOC_ERROR: - pg_sqlstate_set(env, szSqlState, "HY001", "S1001"); - /* memory allocation failure */ - break; - case CONN_IN_USE: - pg_sqlstate_set(env, szSqlState, "HY000", "S1000"); - /* general error */ - break; - case CONN_UNSUPPORTED_OPTION: - pg_sqlstate_set(env, szSqlState, "IM001", "IM001"); - /* driver does not support this function */ - case CONN_INVALID_ARGUMENT_NO: - pg_sqlstate_set(env, szSqlState, "HY009", "S1009"); - /* invalid argument value */ - break; - case CONN_TRANSACT_IN_PROGRES: - pg_sqlstate_set(env, szSqlState, "HY010", "S1010"); - - /* - * when the user tries to switch commit mode in a - * transaction - */ - /* -> function sequence error */ - break; - case CONN_NO_MEMORY_ERROR: - pg_sqlstate_set(env, szSqlState, "HY001", "S1001"); - break; - case CONN_NOT_IMPLEMENTED_ERROR: - case STMT_NOT_IMPLEMENTED_ERROR: - pg_sqlstate_set(env, szSqlState, "HYC00", "S1C00"); - break; - case STMT_RETURN_NULL_WITHOUT_INDICATOR: - pg_sqlstate_set(env, szSqlState, "22002", "22002"); - break; - case CONN_VALUE_OUT_OF_RANGE: - case STMT_VALUE_OUT_OF_RANGE: - pg_sqlstate_set(env, szSqlState, "HY019", "22003"); - break; - default: - pg_sqlstate_set(env, szSqlState, "HY000", "S1000"); - /* general error */ - break; - } - - mylog(" szSqlState = '%s',len=%d, szError='%s'\n", szSqlState, msglen, szErrorMsg); - if (once_again) - { - conn->errornumber = status; - return SQL_SUCCESS_WITH_INFO; - } - else - return SQL_SUCCESS; -} - -RETCODE SQL_API -PGAPI_EnvError( HENV henv, - SWORD RecNumber, - UCHAR FAR * szSqlState, - SDWORD FAR * pfNativeError, - UCHAR FAR * szErrorMsg, - SWORD cbErrorMsgMax, - SWORD FAR * pcbErrorMsg, - UWORD flag) -{ - EnvironmentClass *env = (EnvironmentClass *) henv; - char *msg; - int status; - - mylog("**** PGAPI_EnvError: henv=%u <%d>\n", henv, cbErrorMsgMax); - if (RecNumber != 1 && RecNumber != -1) - return SQL_NO_DATA_FOUND; - if (cbErrorMsgMax < 0) - return SQL_ERROR; - if (!EN_get_error(env, &status, &msg) || NULL == msg) - { - mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg); - - if (NULL != szSqlState) - pg_sqlstate_set(env, szSqlState, "00000", "00000"); - if (NULL != pcbErrorMsg) - *pcbErrorMsg = 0; - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - szErrorMsg[0] = '\0'; - - return SQL_NO_DATA_FOUND; - } - mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg); - - if (NULL != pcbErrorMsg) - *pcbErrorMsg = (SWORD) strlen(msg); - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - strncpy_null(szErrorMsg, msg, cbErrorMsgMax); - if (NULL != pfNativeError) - *pfNativeError = status; - - if (szSqlState) - { - switch (status) - { - case ENV_ALLOC_ERROR: - /* memory allocation failure */ - pg_sqlstate_set(env, szSqlState, "HY001", "S1001"); - break; - default: - pg_sqlstate_set(env, szSqlState, "HY000", "S1000"); - /* general error */ - break; - } - } - - return SQL_SUCCESS; -} - - -/* Returns the next SQL error information. */ -RETCODE SQL_API -PGAPI_Error( - HENV henv, - HDBC hdbc, - HSTMT hstmt, - UCHAR FAR * szSqlState, - SDWORD FAR * pfNativeError, - UCHAR FAR * szErrorMsg, - SWORD cbErrorMsgMax, - SWORD FAR * pcbErrorMsg) -{ - RETCODE ret; - UWORD flag = PODBC_ALLOW_PARTIAL_EXTRACT | PODBC_ERROR_CLEAR; - - mylog("**** PGAPI_Error: henv=%u, hdbc=%u hstmt=%d\n", henv, hdbc, hstmt); - - if (cbErrorMsgMax < 0) - return SQL_ERROR; - if (SQL_NULL_HSTMT != hstmt) - ret = PGAPI_StmtError(hstmt, -1, szSqlState, pfNativeError, - szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag); - else if (SQL_NULL_HDBC != hdbc) - ret = PGAPI_ConnectError(hdbc, -1, szSqlState, pfNativeError, - szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag); - else if (SQL_NULL_HENV != hdbc) - ret = PGAPI_EnvError(henv, -1, szSqlState, pfNativeError, - szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag); - else - { - if (NULL != szSqlState) - strcpy(szSqlState, "00000"); - if (NULL != pcbErrorMsg) - *pcbErrorMsg = 0; - if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) - szErrorMsg[0] = '\0'; - - ret = SQL_NO_DATA_FOUND; - } - mylog("**** PGAPI_Error exit code=%d\n", ret); - return ret; -} - -/* - * EnvironmentClass implementation - */ -EnvironmentClass * -EN_Constructor(void) -{ - EnvironmentClass *rv; - - rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass)); - if (rv) - { - rv->errormsg = 0; - rv->errornumber = 0; - rv->flag = 0; - } - - return rv; -} - - -char -EN_Destructor(EnvironmentClass *self) -{ - int lf; - char rv = 1; - - mylog("in EN_Destructor, self=%u\n", self); - - /* - * the error messages are static strings distributed throughout the - * source--they should not be freed - */ - - /* Free any connections belonging to this environment */ - for (lf = 0; lf < MAX_CONNECTIONS; lf++) - { - if (conns[lf] && conns[lf]->henv == self) - rv = rv && CC_Destructor(conns[lf]); - } - free(self); - - mylog("exit EN_Destructor: rv = %d\n", rv); -#ifdef _MEMORY_DEBUG_ - debug_memory_check(); -#endif /* _MEMORY_DEBUG_ */ - return rv; -} - - -char -EN_get_error(EnvironmentClass *self, int *number, char **message) -{ - if (self && self->errormsg && self->errornumber) - { - *message = self->errormsg; - *number = self->errornumber; - self->errormsg = 0; - self->errornumber = 0; - return 1; - } - else - return 0; -} - - -char -EN_add_connection(EnvironmentClass *self, ConnectionClass *conn) -{ - int i; - - mylog("EN_add_connection: self = %u, conn = %u\n", self, conn); - - for (i = 0; i < MAX_CONNECTIONS; i++) - { - if (!conns[i]) - { - conn->henv = self; - conns[i] = conn; - - mylog(" added at i =%d, conn->henv = %u, conns[i]->henv = %u\n", i, conn->henv, conns[i]->henv); - - return TRUE; - } - } - - return FALSE; -} - - -char -EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn) -{ - int i; - - for (i = 0; i < MAX_CONNECTIONS; i++) - if (conns[i] == conn && conns[i]->status != CONN_EXECUTING) - { - conns[i] = NULL; - return TRUE; - } - - return FALSE; -} - - -void -EN_log_error(char *func, char *desc, EnvironmentClass *self) -{ - if (self) - qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg); - else - qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc); -} diff --git a/src/interfaces/odbc/environ.h b/src/interfaces/odbc/environ.h deleted file mode 100644 index 24b456d489..0000000000 --- a/src/interfaces/odbc/environ.h +++ /dev/null @@ -1,38 +0,0 @@ -/* File: environ.h - * - * Description: See "environ.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __ENVIRON_H__ -#define __ENVIRON_H__ - -#include "psqlodbc.h" - -#define ENV_ALLOC_ERROR 1 - -/********** Environment Handle *************/ -struct EnvironmentClass_ -{ - char *errormsg; - int errornumber; - Int4 flag; -}; - -/* Environment prototypes */ -EnvironmentClass *EN_Constructor(void); -char EN_Destructor(EnvironmentClass *self); -char EN_get_error(EnvironmentClass *self, int *number, char **message); -char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn); -char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn); -void EN_log_error(char *func, char *desc, EnvironmentClass *self); - -#define EN_OV_ODBC2 1L -#define EN_is_odbc2(env) ((env->flag & EN_OV_ODBC2) != 0) -#define EN_is_odbc3(env) ((env->flag & EN_OV_ODBC2) == 0) -#define EN_set_odbc2(env) (env->flag |= EN_OV_ODBC2) -#define EN_set_odbc3(env) (env->flag &= EN_OV_ODBC2) - -#endif diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c deleted file mode 100644 index 598c2a2f61..0000000000 --- a/src/interfaces/odbc/execute.c +++ /dev/null @@ -1,1090 +0,0 @@ -/*------- - * Module: execute.c - * - * Description: This module contains routines related to - * preparing and executing an SQL statement. - * - * Classes: n/a - * - * API functions: SQLPrepare, SQLExecute, SQLExecDirect, SQLTransact, - * SQLCancel, SQLNativeSql, SQLParamData, SQLPutData - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "psqlodbc.h" - -#include -#include - -#include "connection.h" -#include "statement.h" -#include "qresult.h" -#include "convert.h" -#include "bind.h" -#include "pgtypes.h" -#include "lobj.h" -#include "pgapifunc.h" - -/*extern GLOBAL_VALUES globals;*/ - - -/* Perform a Prepare on the SQL statement */ -RETCODE SQL_API -PGAPI_Prepare(HSTMT hstmt, - UCHAR FAR * szSqlStr, - SDWORD cbSqlStr) -{ - static char *func = "PGAPI_Prepare"; - StatementClass *self = (StatementClass *) hstmt; - - mylog("%s: entering...\n", func); - - if (!self) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - /* - * According to the ODBC specs it is valid to call SQLPrepare mulitple - * times. In that case, the bound SQL statement is replaced by the new - * one - */ - - switch (self->status) - { - case STMT_PREMATURE: - mylog("**** PGAPI_Prepare: STMT_PREMATURE, recycle\n"); - SC_recycle_statement(self); /* recycle the statement, but do - * not remove parameter bindings */ - break; - - case STMT_FINISHED: - mylog("**** PGAPI_Prepare: STMT_FINISHED, recycle\n"); - SC_recycle_statement(self); /* recycle the statement, but do - * not remove parameter bindings */ - break; - - case STMT_ALLOCATED: - mylog("**** PGAPI_Prepare: STMT_ALLOCATED, copy\n"); - self->status = STMT_READY; - break; - - case STMT_READY: - mylog("**** PGAPI_Prepare: STMT_READY, change SQL\n"); - break; - - case STMT_EXECUTING: - mylog("**** PGAPI_Prepare: STMT_EXECUTING, error!\n"); - - self->errornumber = STMT_SEQUENCE_ERROR; - self->errormsg = "PGAPI_Prepare(): The handle does not point to a statement that is ready to be executed"; - SC_log_error(func, "", self); - - return SQL_ERROR; - - default: - self->errornumber = STMT_INTERNAL_ERROR; - self->errormsg = "An Internal Error has occured -- Unknown statement status."; - SC_log_error(func, "", self); - return SQL_ERROR; - } - - if (self->statement) - free(self->statement); - if (self->stmt_with_params) - free(self->stmt_with_params); - self->stmt_with_params = NULL; - if (self->load_statement) - free(self->load_statement); - self->load_statement = NULL; - - self->statement = make_string(szSqlStr, cbSqlStr, NULL); - if (!self->statement) - { - self->errornumber = STMT_NO_MEMORY_ERROR; - self->errormsg = "No memory available to store statement"; - SC_log_error(func, "", self); - return SQL_ERROR; - } - - self->prepare = TRUE; - self->statement_type = statement_type(self->statement); - - /* Check if connection is onlyread (only selects are allowed) */ - if (CC_is_onlyread(self->hdbc) && STMT_UPDATE(self)) - { - self->errornumber = STMT_EXEC_ERROR; - self->errormsg = "Connection is readonly, only select statements are allowed."; - SC_log_error(func, "", self); - return SQL_ERROR; - } - - return SQL_SUCCESS; -} - - -/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */ -RETCODE SQL_API -PGAPI_ExecDirect( - HSTMT hstmt, - UCHAR FAR * szSqlStr, - SDWORD cbSqlStr) -{ - StatementClass *stmt = (StatementClass *) hstmt; - RETCODE result; - static char *func = "PGAPI_ExecDirect"; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - if (stmt->statement) - free(stmt->statement); - if (stmt->stmt_with_params) - free(stmt->stmt_with_params); - stmt->stmt_with_params = NULL; - if (stmt->load_statement) - free(stmt->load_statement); - stmt->load_statement = NULL; - - /* - * keep a copy of the un-parametrized statement, in case they try to - * execute this statement again - */ - stmt->statement = make_string(szSqlStr, cbSqlStr, NULL); - if (!stmt->statement) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "No memory available to store statement"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - mylog("**** %s: hstmt=%u, statement='%s'\n", func, hstmt, stmt->statement); - - stmt->prepare = FALSE; - - /* - * If an SQLPrepare was performed prior to this, but was left in the - * premature state because an error occurred prior to SQLExecute then - * set the statement to finished so it can be recycled. - */ - if (stmt->status == STMT_PREMATURE) - stmt->status = STMT_FINISHED; - - stmt->statement_type = statement_type(stmt->statement); - - /* Check if connection is onlyread (only selects are allowed) */ - if (CC_is_onlyread(stmt->hdbc) && STMT_UPDATE(stmt)) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Connection is readonly, only select statements are allowed."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - mylog("%s: calling PGAPI_Execute...\n", func); - - result = PGAPI_Execute(hstmt); - - mylog("%s: returned %hd from PGAPI_Execute\n", func, result); - return result; -} - - -/* Execute a prepared SQL statement */ -RETCODE SQL_API -PGAPI_Execute( - HSTMT hstmt) -{ - static char *func = "PGAPI_Execute"; - StatementClass *stmt = (StatementClass *) hstmt; - APDFields *opts; - IPDFields *ipdopts; - ConnectionClass *conn; - int i, - retval, start_row, end_row; - int cursor_type, scroll_concurrency; - QResultClass *res; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func); - return SQL_INVALID_HANDLE; - } - - opts = SC_get_APD(stmt); - cursor_type = stmt->options.cursor_type; - scroll_concurrency = stmt->options.scroll_concurrency; - /* - * If the statement is premature, it means we already executed it from - * an SQLPrepare/SQLDescribeCol type of scenario. So just return - * success. - */ - if (stmt->prepare && stmt->status == STMT_PREMATURE) - { - if (stmt->inaccurate_result) - { - stmt->exec_current_row = -1; - SC_recycle_statement(stmt); - } - else - { - stmt->status = STMT_FINISHED; - if (stmt->errormsg == NULL) - { - mylog("%s: premature statement but return SQL_SUCCESS\n", func); - return SQL_SUCCESS; - } - else - { - SC_log_error(func, "", stmt); - mylog("%s: premature statement so return SQL_ERROR\n", func); - return SQL_ERROR; - } - } - } - - mylog("%s: clear errors...\n", func); - - SC_clear_error(stmt); - - conn = SC_get_conn(stmt); - if (conn->status == CONN_EXECUTING) - { - stmt->errormsg = "Connection is already in use."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - mylog("%s: problem with connection\n", func); - return SQL_ERROR; - } - - if (!stmt->statement) - { - stmt->errornumber = STMT_NO_STMTSTRING; - stmt->errormsg = "This handle does not have a SQL statement stored in it"; - SC_log_error(func, "", stmt); - mylog("%s: problem with handle\n", func); - return SQL_ERROR; - } - - /* - * If SQLExecute is being called again, recycle the statement. Note - * this should have been done by the application in a call to - * SQLFreeStmt(SQL_CLOSE) or SQLCancel. - */ - if (stmt->status == STMT_FINISHED) - { - mylog("%s: recycling statement (should have been done by app)...\n", func); -/******** Is this really NEEDED ? ******/ - SC_recycle_statement(stmt); - } - - /* Check if the statement is in the correct state */ - if ((stmt->prepare && stmt->status != STMT_READY) || - (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) - { - stmt->errornumber = STMT_STATUS_ERROR; - stmt->errormsg = "The handle does not point to a statement that is ready to be executed"; - SC_log_error(func, "", stmt); - mylog("%s: problem with statement\n", func); - return SQL_ERROR; - } - - if (start_row = stmt->exec_start_row, start_row < 0) - start_row = 0; - if (end_row = stmt->exec_end_row, end_row < 0) - end_row = opts->paramset_size - 1; - if (stmt->exec_current_row < 0) - stmt->exec_current_row = start_row; - ipdopts = SC_get_IPD(stmt); - if (stmt->exec_current_row == start_row) - { - if (ipdopts->param_processed_ptr) - *ipdopts->param_processed_ptr = 0; - SC_recycle_statement(stmt); - } - -next_param_row: -#if (ODBCVER >= 0x0300) - if (opts->param_operation_ptr) - { - while (opts->param_operation_ptr[stmt->exec_current_row] == SQL_PARAM_IGNORE) - { - if (ipdopts->param_status_ptr) - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_UNUSED; - if (stmt->exec_current_row >= end_row) - { - stmt->exec_current_row = -1; - return SQL_SUCCESS; - } - ++stmt->exec_current_row; - } - } -#endif /* ODBCVER */ - /* - * Check if statement has any data-at-execute parameters when it is - * not in SC_pre_execute. - */ - if (!stmt->pre_executing) - { - /* - * The bound parameters could have possibly changed since the last - * execute of this statement? Therefore check for params and - * re-copy. - */ - UInt4 offset = opts->param_offset_ptr ? *opts->param_offset_ptr : 0; - Int4 bind_size = opts->param_bind_type; - Int4 current_row = stmt->exec_current_row < 0 ? 0 : stmt->exec_current_row; - - stmt->data_at_exec = -1; - for (i = 0; i < opts->allocated; i++) - { - Int4 *pcVal = opts->parameters[i].used; - - opts->parameters[i].data_at_exec = FALSE; - if (pcVal) - { - if (bind_size > 0) - pcVal = (Int4 *)((char *)pcVal + offset + bind_size * current_row); - else - pcVal = (Int4 *)((char *)pcVal + offset + sizeof(SDWORD) * current_row); - if (*pcVal == SQL_DATA_AT_EXEC || *pcVal <= SQL_LEN_DATA_AT_EXEC_OFFSET) - opts->parameters[i].data_at_exec = TRUE; - } - /* Check for data at execution parameters */ - if (opts->parameters[i].data_at_exec) - { - if (stmt->data_at_exec < 0) - stmt->data_at_exec = 1; - else - stmt->data_at_exec++; - } - } - - /* - * If there are some data at execution parameters, return need - * data - */ - - /* - * SQLParamData and SQLPutData will be used to send params and - * execute the statement. - */ - if (stmt->data_at_exec > 0) - return SQL_NEED_DATA; - - } - - - mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement); - - /* Create the statement with parameters substituted. */ - retval = copy_statement_with_parameters(stmt); - if (retval != SQL_SUCCESS) - /* error msg passed from above */ - return retval; - - mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params); - - if (!stmt->inaccurate_result || !conn->connInfo.disallow_premature) - { - retval = SC_execute(stmt); - if (retval != SQL_ERROR) - { - if (ipdopts->param_processed_ptr) - (*ipdopts->param_processed_ptr)++; - /* special handling of result for keyset driven cursors */ - if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type && - SQL_CONCUR_READ_ONLY != stmt->options.scroll_concurrency) - { - QResultClass *kres; - - res = SC_get_Result(stmt); - if (kres = res->next, kres) - { - kres->fields = res->fields; - res->fields = NULL; - kres->num_fields = res->num_fields; - res->next = NULL; - QR_Destructor(res); - SC_set_Result(stmt, kres); - } - } - } -#if (ODBCVER >= 0x0300) - if (ipdopts->param_status_ptr) - { - switch (retval) - { - case SQL_SUCCESS: - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS; - break; - case SQL_SUCCESS_WITH_INFO: - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS_WITH_INFO; - break; - default: - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_ERROR; - break; - } - } -#endif /* ODBCVER */ - if (retval == SQL_ERROR || - stmt->inaccurate_result || - stmt->exec_current_row >= end_row) - { - stmt->exec_current_row = -1; - return retval; - } - stmt->exec_current_row++; - goto next_param_row; - } - /* - * Get the field info for the prepared query using dummy backward - * fetch. - */ - if (SC_is_pre_executable(stmt)) - { - BOOL in_trans = CC_is_in_trans(conn); - BOOL issued_begin = FALSE, - begin_included = FALSE; - QResultClass *curres; - - if (strnicmp(stmt->stmt_with_params, "BEGIN;", 6) == 0) - begin_included = TRUE; - else if (!in_trans) - { - if (issued_begin = CC_begin(conn), !issued_begin) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Handle prepare error"; - return SQL_ERROR; - } - } - /* we are now in a transaction */ - res = CC_send_query(conn, stmt->stmt_with_params, NULL, CLEAR_RESULT_ON_ABORT); - if (!res) - { - CC_abort(conn); - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Handle prepare error"; - return SQL_ERROR; - } - SC_set_Result(stmt, res); - for (curres = res; !curres->num_fields; curres = curres->next) - ; - SC_set_Curres(stmt, curres); - if (CC_is_in_autocommit(conn)) - { - if (issued_begin) - CC_commit(conn); - } - stmt->status = STMT_FINISHED; - return SQL_SUCCESS; - } - if (res = SC_get_Curres(stmt), res) - stmt->diag_row_count = res->recent_processed_row_count; - if (stmt->options.cursor_type != cursor_type || - stmt->options.scroll_concurrency != scroll_concurrency) - { - stmt->errornumber = STMT_OPTION_VALUE_CHANGED; - stmt->errormsg = "cursor updatability changed"; - return SQL_SUCCESS_WITH_INFO; - } - else - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_Transact( - HENV henv, - HDBC hdbc, - UWORD fType) -{ - static char *func = "PGAPI_Transact"; - extern ConnectionClass *conns[]; - ConnectionClass *conn; - QResultClass *res; - char ok, - *stmt_string; - int lf; - - mylog("entering %s: hdbc=%u, henv=%u\n", func, hdbc, henv); - - if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - /* - * If hdbc is null and henv is valid, it means transact all - * connections on that henv. - */ - if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) - { - for (lf = 0; lf < MAX_CONNECTIONS; lf++) - { - conn = conns[lf]; - - if (conn && conn->henv == henv) - if (PGAPI_Transact(henv, (HDBC) conn, fType) != SQL_SUCCESS) - return SQL_ERROR; - } - return SQL_SUCCESS; - } - - conn = (ConnectionClass *) hdbc; - - if (fType == SQL_COMMIT) - stmt_string = "COMMIT"; - else if (fType == SQL_ROLLBACK) - stmt_string = "ROLLBACK"; - else - { - conn->errornumber = CONN_INVALID_ARGUMENT_NO; - conn->errormsg = "PGAPI_Transact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - - /* If manual commit and in transaction, then proceed. */ - if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) - { - mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string); - - res = CC_send_query(conn, stmt_string, NULL, CLEAR_RESULT_ON_ABORT); - if (!res) - { - /* error msg will be in the connection */ - CC_on_abort(conn, NO_TRANS); - CC_log_error(func, "", conn); - return SQL_ERROR; - } - - ok = QR_command_maybe_successful(res); - QR_Destructor(res); - - if (!ok) - { - CC_on_abort(conn, NO_TRANS); - CC_log_error(func, "", conn); - return SQL_ERROR; - } - } - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_Cancel( - HSTMT hstmt) /* Statement to cancel. */ -{ - static char *func = "PGAPI_Cancel"; - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn; - RETCODE result; - ConnInfo *ci; - -#ifdef WIN32 - HMODULE hmodule; - FARPROC addr; -#endif - - mylog("%s: entering...\n", func); - - /* Check if this can handle canceling in the middle of a SQLPutData? */ - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - /* - * Not in the middle of SQLParamData/SQLPutData so cancel like a - * close. - */ - if (stmt->data_at_exec < 0) - { - /* - * Tell the Backend that we're cancelling this request - */ - if (stmt->status == STMT_EXECUTING) - CC_send_cancel_request(conn); - /* - * MAJOR HACK for Windows to reset the driver manager's cursor - * state: Because of what seems like a bug in the Odbc driver - * manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as - * many applications depend on this behavior. So, this brute - * force method calls the driver manager's function on behalf of - * the application. - */ - -#ifdef WIN32 - if (ci->drivers.cancel_as_freestmt) - { - hmodule = GetModuleHandle("ODBC32"); - addr = GetProcAddress(hmodule, "SQLFreeStmt"); - result = addr((char *) (stmt->phstmt) - 96, SQL_CLOSE); - } - else - result = PGAPI_FreeStmt(hstmt, SQL_CLOSE); -#else - result = PGAPI_FreeStmt(hstmt, SQL_CLOSE); -#endif - - mylog("PGAPI_Cancel: PGAPI_FreeStmt returned %d\n", result); - - SC_clear_error(hstmt); - return SQL_SUCCESS; - } - - /* In the middle of SQLParamData/SQLPutData, so cancel that. */ - - /* - * Note, any previous data-at-exec buffers will be freed in the - * recycle - */ - /* if they call SQLExecDirect or SQLExecute again. */ - - stmt->data_at_exec = -1; - stmt->current_exec_param = -1; - stmt->put_data = FALSE; - - return SQL_SUCCESS; -} - - -/* - * Returns the SQL string as modified by the driver. - * Currently, just copy the input string without modification - * observing buffer limits and truncation. - */ -RETCODE SQL_API -PGAPI_NativeSql( - HDBC hdbc, - UCHAR FAR * szSqlStrIn, - SDWORD cbSqlStrIn, - UCHAR FAR * szSqlStr, - SDWORD cbSqlStrMax, - SDWORD FAR * pcbSqlStr) -{ - static char *func = "PGAPI_NativeSql"; - int len = 0; - char *ptr; - ConnectionClass *conn = (ConnectionClass *) hdbc; - RETCODE result; - - mylog("%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn); - - ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL); - if (!ptr) - { - conn->errornumber = CONN_NO_MEMORY_ERROR; - conn->errormsg = "No memory available to store native sql string"; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - - result = SQL_SUCCESS; - len = strlen(ptr); - - if (szSqlStr) - { - strncpy_null(szSqlStr, ptr, cbSqlStrMax); - - if (len >= cbSqlStrMax) - { - result = SQL_SUCCESS_WITH_INFO; - conn->errornumber = STMT_TRUNCATED; - conn->errormsg = "The buffer was too small for the NativeSQL."; - } - } - - if (pcbSqlStr) - *pcbSqlStr = len; - - if (cbSqlStrIn) - free(ptr); - - return result; -} - - -/* - * Supplies parameter data at execution time. - * Used in conjuction with SQLPutData. - */ -RETCODE SQL_API -PGAPI_ParamData( - HSTMT hstmt, - PTR FAR * prgbValue) -{ - static char *func = "PGAPI_ParamData"; - StatementClass *stmt = (StatementClass *) hstmt; - APDFields *opts; - IPDFields *ipdopts; - int i, - retval; - ConnInfo *ci; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - ci = &(SC_get_conn(stmt)->connInfo); - opts = SC_get_APD(stmt); - - mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, opts->allocated); - - if (stmt->data_at_exec < 0) - { - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "No execution-time parameters for this statement"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (stmt->data_at_exec > opts->allocated) - { - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "Too many execution-time parameters were present"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - /* close the large object */ - if (stmt->lobj_fd >= 0) - { - lo_close(stmt->hdbc, stmt->lobj_fd); - - /* commit transaction if needed */ - if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) - { - if (!CC_commit(stmt->hdbc)) - { - stmt->errormsg = "Could not commit (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - stmt->lobj_fd = -1; - } - - /* Done, now copy the params and then execute the statement */ - ipdopts = SC_get_IPD(stmt); - if (stmt->data_at_exec == 0) - { - int end_row; - - retval = copy_statement_with_parameters(stmt); - if (retval != SQL_SUCCESS) - return retval; - - stmt->current_exec_param = -1; - - retval = SC_execute(stmt); - if (retval != SQL_ERROR) - { - if (ipdopts->param_processed_ptr) - (*ipdopts->param_processed_ptr)++; - } -#if (ODBCVER >= 0x0300) - if (ipdopts->param_status_ptr) - { - switch (retval) - { - case SQL_SUCCESS: - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS; - break; - case SQL_SUCCESS_WITH_INFO: - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS_WITH_INFO; - break; - default: - ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_ERROR; - break; - } - } -#endif /* ODBCVER */ - end_row = stmt->exec_end_row; - if (end_row < 0) - end_row = opts->paramset_size - 1; - if (retval == SQL_ERROR || - stmt->exec_current_row >= end_row) - { - stmt->exec_current_row = -1; - return retval; - } - stmt->exec_current_row++; - return PGAPI_Execute(stmt); - } - - /* - * Set beginning param; if first time SQLParamData is called , start - * at 0. Otherwise, start at the last parameter + 1. - */ - i = stmt->current_exec_param >= 0 ? stmt->current_exec_param + 1 : 0; - - /* At least 1 data at execution parameter, so Fill in the token value */ - for (; i < opts->allocated; i++) - { - if (opts->parameters[i].data_at_exec) - { - stmt->data_at_exec--; - stmt->current_exec_param = i; - stmt->put_data = FALSE; - *prgbValue = opts->parameters[i].buffer; /* token */ - break; - } - } - - return SQL_NEED_DATA; -} - - -/* - * Supplies parameter data at execution time. - * Used in conjunction with SQLParamData. - */ -RETCODE SQL_API -PGAPI_PutData( - HSTMT hstmt, - PTR rgbValue, - SDWORD cbValue) -{ - static char *func = "PGAPI_PutData"; - StatementClass *stmt = (StatementClass *) hstmt; - APDFields *opts; - int old_pos, - retval; - ParameterInfoClass *current_param; - char *buffer; - - mylog("%s: entering...\n", func); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - opts = SC_get_APD(stmt); - if (stmt->current_exec_param < 0) - { - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "Previous call was not SQLPutData or SQLParamData"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - current_param = &(opts->parameters[stmt->current_exec_param]); - - if (!stmt->put_data) - { /* first call */ - mylog("PGAPI_PutData: (1) cbValue = %d\n", cbValue); - - stmt->put_data = TRUE; - - current_param->EXEC_used = (SDWORD *) malloc(sizeof(SDWORD)); - if (!current_param->EXEC_used) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in PGAPI_PutData (1)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - *current_param->EXEC_used = cbValue; - - if (cbValue == SQL_NULL_DATA) - return SQL_SUCCESS; - - /* Handle Long Var Binary with Large Objects */ - if (current_param->SQLType == SQL_LONGVARBINARY) - { - /* begin transaction if needed */ - if (!CC_is_in_trans(stmt->hdbc)) - { - if (!CC_begin(stmt->hdbc)) - { - stmt->errormsg = "Could not begin (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - - /* store the oid */ - current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); - if (current_param->lobj_oid == 0) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Couldnt create large object."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - /* - * major hack -- to allow convert to see somethings there have - * to modify convert to handle this better - */ - current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid; - - /* store the fd */ - stmt->lobj_fd = lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE); - if (stmt->lobj_fd < 0) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Couldnt open large object for writing."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue); - mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval); - } - else - { - Int2 ctype = current_param->CType; - if (ctype == SQL_C_DEFAULT) - ctype = sqltype_to_default_ctype(current_param->SQLType); - -#ifdef UNICODE_SUPPORT - if (SQL_NTS == cbValue && SQL_C_WCHAR == ctype) - cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue); -#endif /* UNICODE_SUPPORT */ - /* for handling fields */ - if (cbValue == SQL_NTS) - { - current_param->EXEC_buffer = strdup(rgbValue); - if (!current_param->EXEC_buffer) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in PGAPI_PutData (2)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - else - { -#ifdef UNICODE_SUPPORT - if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY || ctype == SQL_C_WCHAR) -#else - if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY) -#endif /* UNICODE_SUPPORT */ - { - current_param->EXEC_buffer = malloc(cbValue + 1); - if (!current_param->EXEC_buffer) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in PGAPI_PutData (2)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - memcpy(current_param->EXEC_buffer, rgbValue, cbValue); - current_param->EXEC_buffer[cbValue] = '\0'; - } - else - { - Int4 used = ctype_length(ctype); - - current_param->EXEC_buffer = malloc(used); - if (!current_param->EXEC_buffer) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in PGAPI_PutData (2)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - memcpy(current_param->EXEC_buffer, rgbValue, used); - } - } - } - } - else - { - /* calling SQLPutData more than once */ - mylog("PGAPI_PutData: (>1) cbValue = %d\n", cbValue); - - if (current_param->SQLType == SQL_LONGVARBINARY) - { - /* the large object fd is in EXEC_buffer */ - retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue); - mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval); - - *current_param->EXEC_used += cbValue; - } - else - { - Int2 ctype = current_param->CType; - - if (ctype == SQL_C_DEFAULT) - ctype = sqltype_to_default_ctype(current_param->SQLType); - buffer = current_param->EXEC_buffer; - if (old_pos = *current_param->EXEC_used, SQL_NTS == old_pos) - { -#ifdef UNICODE_SUPPORT - if (SQL_C_WCHAR == ctype) - old_pos = 2 * ucs2strlen((SQLWCHAR *) buffer); - else -#endif /* UNICODE_SUPPORT */ - old_pos = strlen(buffer); - } - if (SQL_NTS == cbValue) - { -#ifdef UNICODE_SUPPORT - if (SQL_C_WCHAR == ctype) - cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue); - else -#endif /* UNICODE_SUPPORT */ - cbValue = strlen(rgbValue); - } - if (cbValue > 0) - { - *current_param->EXEC_used += cbValue; - - mylog(" cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used); - - /* dont lose the old pointer in case out of memory */ - buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1); - if (!buffer) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in PGAPI_PutData (3)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - memcpy(&buffer[old_pos], rgbValue, cbValue); - buffer[*current_param->EXEC_used] = '\0'; - - /* reassign buffer incase realloc moved it */ - current_param->EXEC_buffer = buffer; - } - else - { - SC_log_error(func, "bad cbValue", stmt); - return SQL_ERROR; - } - } - } - - return SQL_SUCCESS; -} diff --git a/src/interfaces/odbc/gpps.c b/src/interfaces/odbc/gpps.c deleted file mode 100644 index ee73a23eb4..0000000000 --- a/src/interfaces/odbc/gpps.c +++ /dev/null @@ -1,454 +0,0 @@ -/*------- - * GetPrivateProfileString() - * - * approximate implementation of - * Windows NT System Services version of GetPrivateProfileString() - * probably doesn't handle the NULL key for section name or value key - * correctly also, doesn't provide Microsoft backwards compatability - * wrt TAB characters in the value string - * - * Microsoft terminates value - * at the first TAB, but I couldn't discover what the behavior should - * be regarding TABS in quoted strings so, I treat tabs like any other - * characters - * - * NO comments following value string separated by a TAB - * are allowed (that is an anachronism anyway) - * Added code to search for ODBC_INI file in users home directory on - * Unix - *------- - */ - -#if !defined(WIN32) && !defined(WITH_UNIXODBC) && !defined(WITH_IODBC) - -#include "gpps.h" - -#include -#include -#include - -#if HAVE_PWD_H -#include -#endif - -#include -#include -#include "misc.h" -#include "dlg_specific.h" - -#ifndef TRUE -#define TRUE ((BOOL)1) -#endif -#ifndef FALSE -#define FALSE ((BOOL)0) -#endif - -#ifndef ODBCINSTDIR -#error "ODBCINSTDIR must be defined to compile this file" -#endif - - -/* - * theIniFileName is searched for in: - * $HOME/theIniFileName - * theIniFileName - * ODBCINSTDIR/ODBCINST_INI - */ -DWORD -GetPrivateProfileString(const char *theSection, /* section name */ - const char *theKey, /* search key name */ - const char *theDefault, /* default value if not - * found */ - char *theReturnBuffer, /* return value stored - * here */ - size_t theReturnBufferLength, /* byte length of return - * buffer */ - const char *theIniFileName) /* pathname of ini file - * to search */ -{ - char buf[MAXPGPATH]; - char *ptr = 0; - FILE *aFile = 0; - size_t aLength; - char aLine[2048]; - char *aValue; - char *aStart; - char *aString; - size_t aLineLength; - size_t aReturnLength = 0; - BOOL aSectionFound = FALSE; - BOOL aKeyFound = FALSE; - - ptr = (char *) getpwuid(getuid()); /* get user info */ - - if (ptr == NULL || (((struct passwd *) ptr)->pw_dir) == NULL || *(((struct passwd *) ptr)->pw_dir) == '\0') - ptr = "/home"; - else - ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */ - - /* - * If it can't be opened because the paths are too long, then skip it, - * don't just truncate the path string... The truncated path might - * accidently be an existing file. The default value will be returned - * instead. - */ - if (MAXPGPATH - 1 >= strlen(ptr) + 1 + strlen(theIniFileName)) - { - sprintf(buf, "%s/%s", ptr, theIniFileName); - aFile = (FILE *) fopen(buf, PG_BINARY_R); - } - - /* - * This code makes it so that a file in the users home dir overrides a - * the "default" file as passed in - */ - if (!aFile) - { - aFile = (FILE *) fopen(theIniFileName, PG_BINARY_R); - if (!aFile) - aFile = (FILE *) fopen(ODBCINSTDIR "/" ODBCINST_INI, PG_BINARY_R); - } - - aLength = (theDefault == NULL) ? 0 : strlen(theDefault); - - if (theReturnBufferLength == 0 || theReturnBuffer == NULL) - { - if (aFile) - fclose(aFile); - return 0; - } - - if (aFile == NULL) - { - /* no ini file specified, return the default */ - ++aLength; /* room for NULL char */ - aLength = theReturnBufferLength < aLength ? - theReturnBufferLength : aLength; - strncpy(theReturnBuffer, theDefault, aLength); - theReturnBuffer[aLength - 1] = '\0'; - return aLength - 1; - } - - while (fgets(aLine, sizeof(aLine), aFile) != NULL) - { - aLineLength = strlen(aLine); - /* strip final '\n' */ - if (aLineLength > 0 && aLine[aLineLength - 1] == '\n') - aLine[aLineLength - 1] = '\0'; - switch (*aLine) - { - case ' ': /* blank line */ - case ';': /* comment line */ - continue; - break; - - case '[': /* section marker */ - if ((aString = strchr(aLine, ']'))) - { - aStart = aLine + 1; - aString--; - while (isspace((unsigned char) *aStart)) - aStart++; - while (isspace((unsigned char) *aString)) - aString--; - *(aString + 1) = '\0'; - - /* accept as matched if NULL key or exact match */ - if (!theSection || !strcmp(aStart, theSection)) - aSectionFound = TRUE; - else - aSectionFound = FALSE; - } - break; - - default: - - /* try to match value keys if in proper section */ - if (aSectionFound) - { - /* try to match requested key */ - if ((aString = aValue = strchr(aLine, '='))) - { - *aValue = '\0'; - ++aValue; - - /* strip leading blanks in value field */ - while (*aValue == ' ' && aValue < aLine + sizeof(aLine)) - *aValue++ = '\0'; - if (aValue >= aLine + sizeof(aLine)) - aValue = ""; - } - else - aValue = ""; - - aStart = aLine; - while (isspace((unsigned char) *aStart)) - aStart++; - - /* strip trailing blanks from key */ - if (aString) - { - while (--aString >= aStart && *aString == ' ') - *aString = '\0'; - } - - /* see if key is matched */ - if (theKey == NULL || !strcmp(theKey, aStart)) - { - /* matched -- first, terminate value part */ - aKeyFound = TRUE; - aLength = strlen(aValue); - - /* remove trailing blanks from aValue if any */ - aString = aValue + aLength - 1; - - while (--aString > aValue && *aString == ' ') - { - *aString = '\0'; - --aLength; - } - - /* unquote value if quoted */ - if (aLength >= 2 && aValue[0] == '"' && - aValue[aLength - 1] == '"') - { - /* string quoted with double quotes */ - - aValue[aLength - 1] = '\0'; - ++aValue; - aLength -= 2; - } - else - { - /* single quotes allowed also... */ - if (aLength >= 2 && aValue[0] == '\'' && - aValue[aLength - 1] == '\'') - { - aValue[aLength - 1] = '\0'; - ++aValue; - aLength -= 2; - } - } - - /* compute maximum length copyable */ - aLineLength = (aLength < - theReturnBufferLength - aReturnLength) ? aLength : - theReturnBufferLength - aReturnLength; - - /* do the copy to return buffer */ - if (aLineLength) - { - strncpy(&theReturnBuffer[aReturnLength], - aValue, aLineLength); - aReturnLength += aLineLength; - if (aReturnLength < theReturnBufferLength) - { - theReturnBuffer[aReturnLength] = '\0'; - ++aReturnLength; - } - } - if (aFile) - { - fclose(aFile); - aFile = NULL; - } - return aReturnLength > 0 ? aReturnLength - 1 : 0; - } - } - break; - } - } - - if (aFile) - fclose(aFile); - - if (!aKeyFound) - { - /* key wasn't found return default */ - ++aLength; /* room for NULL char */ - aLength = theReturnBufferLength < aLength ? - theReturnBufferLength : aLength; - strncpy(theReturnBuffer, theDefault, aLength); - theReturnBuffer[aLength - 1] = '\0'; - aReturnLength = aLength - 1; - } - return aReturnLength > 0 ? aReturnLength - 1 : 0; -} - - -DWORD -WritePrivateProfileString(const char *theSection, /* section name */ - const char *theKey, /* write key name */ - const char *theBuffer, /* input buffer */ - const char *theIniFileName) /* pathname of ini file - * to write */ -{ - return 0; -} - - -#if NOT_USED -/* - * Ok. What the hell's the default behaviour for a null input buffer, and null - * section name. For now if either are null I ignore the request, until - * I find out different. - */ -DWORD -WritePrivateProfileString(char *theSection, /* section name */ - char *theKey, /* write key name */ - char *theBuffer, /* input buffer */ - char *theIniFileName) /* pathname of ini file to - * write */ -{ - char buf[MAXPGPATH]; - char *ptr = 0; - FILE *aFile = 0; - size_t aLength; - char aLine[2048]; - char *aValue; - char *aString; - size_t aLineLength; - size_t aReturnLength = 0; - - BOOL aSectionFound = FALSE; - BOOL keyFound = FALSE; - int j = 0; - - /* If this isn't correct processing we'll change it later */ - if (theSection == NULL || theKey == NULL || theBuffer == NULL || - theIniFileName == NULL) - return 0; - - aLength = strlen(theBuffer); - if (aLength == 0) - return 0; - - j = strlen(theIniFileName) + 1; - ptr = (char *) getpwuid(getuid()); /* get user info */ - - if (ptr == NULL) - { - if (MAXPGPATH - 1 < j) - theIniFileName[MAXPGPATH - 1] = '\0'; - - sprintf(buf, "%s", theIniFileName); - } - ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */ - if (ptr == NULL || *ptr == '\0') - ptr = "/home"; - - /* - * This doesn't make it so we find an ini file but allows normal - * processing to continue further on down. The likelihood is that the - * file won't be found and thus the default value will be returned. - */ - if (MAXPGPATH - 1 < strlen(ptr) + j) - { - if (MAXPGPATH - 1 < strlen(ptr)) - ptr[MAXPGPATH - 1] = '\0'; - else - theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0'; - } - - sprintf(buf, "%s/%s", ptr, theIniFileName); - - /* - * This code makes it so that a file in the users home dir overrides a - * the "default" file as passed in - */ - aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL); - if (!aFile) - { - sprintf(buf, "%s", theIniFileName); - aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL); - if (!aFile) - return 0; - } - - aLength = strlen(theBuffer); - - /* - * We have to search for theKey, because if it already exists we have - * to overwrite it. If it doesn't exist we just write a new line to - * the file. - */ - while (fgets(aLine, sizeof(aLine), aFile) != NULL) - { - aLineLength = strlen(aLine); - /* strip final '\n' */ - if (aLineLength > 0 && aLine[aLineLength - 1] == '\n') - aLine[aLineLength - 1] = '\0'; - switch (*aLine) - { - case ' ': /* blank line */ - case ';': /* comment line */ - continue; - break; - - case '[': /* section marker */ - if ((aString = strchr(aLine, ']'))) - { - *aString = '\0'; - - /* accept as matched if key exact match */ - - if (!strcmp(aLine + 1, theSection)) - aSectionFound = TRUE; - } - break; - - default: - /* try to match value keys if in proper section */ - if (aSectionFound) - { - /* try to match requested key */ - - if ((aString = aValue = strchr(aLine, '='))) - { - *aValue = '\0'; - ++aValue; - - /* strip leading blanks in value field */ - while (*aValue == ' ' && aValue < aLine + sizeof(aLine)) - *aValue++ = '\0'; - if (aValue >= aLine + sizeof(aLine)) - aValue = ""; - } - else - aValue = ""; - - /* strip trailing blanks from key */ - if (aString) - { - while (--aString >= aLine && *aString == ' ') - *aString = '\0'; - } - - /* see if key is matched */ - if (!strcmp(theKey, aLine)) - { - keyFound = TRUE; - /* matched -- first, terminate value part */ - - /* overwrite current value */ - fseek(aFile, -aLineLength, SEEK_CUR); - /* overwrite key and value */ - sprintf(aLine, "%s = %s\n", theKey, theBuffer); - fputs(aLine, aFile); - } - } - } - break; - } -} - -if (!keyFound) -{ /* theKey wasn't in file so */ - if (aFile) - fclose(aFile); - - return aReturnLength > 0 ? aReturnLength - 1 : 0; -} -#endif /* NOT_USED */ - -#endif /* not WIN32 */ diff --git a/src/interfaces/odbc/gpps.h b/src/interfaces/odbc/gpps.h deleted file mode 100644 index ab133a82d4..0000000000 --- a/src/interfaces/odbc/gpps.h +++ /dev/null @@ -1,48 +0,0 @@ -/* GetPrivateProfileString - * for UNIX use - */ -#ifndef GPPS_H -#define GPPS_H - -#include "psqlodbc.h" - -#ifndef WIN32 -#include -#endif - -#define SQLGetPrivateProfileString(a,b,c,d,e,f) GetPrivateProfileString(a,b,c,d,e,f) -#define SQLWritePrivateProfileString(a,b,c,d) WritePrivateProfileString(a,b,c,d) - -#ifdef __cplusplus -extern "C" -{ -#endif - -DWORD -GetPrivateProfileString(const char *theSection, /* section name */ - const char *theKey, /* search key name */ - const char *theDefault, /* default value if not - * found */ - char *theReturnBuffer, /* return valuse stored - * here */ - size_t theBufferLength, /* byte length of return - * buffer */ - const char *theIniFileName); /* pathname of ini file - * to search */ - -DWORD -WritePrivateProfileString(const char *theSection, /* section name */ - const char *theKey, /* write key name */ - const char *theBuffer, /* input buffer */ - const char *theIniFileName); /* pathname of ini file - * to write */ - -#ifdef __cplusplus -} -#endif - -#ifndef WIN32 -#undef DWORD -#endif - -#endif diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c deleted file mode 100644 index 3a3cda32ce..0000000000 --- a/src/interfaces/odbc/info.c +++ /dev/null @@ -1,4509 +0,0 @@ -/*-------- - * Module: info.c - * - * Description: This module contains routines related to - * ODBC informational functions. - * - * Classes: n/a - * - * API functions: SQLGetInfo, SQLGetTypeInfo, SQLGetFunctions, - * SQLTables, SQLColumns, SQLStatistics, SQLSpecialColumns, - * SQLPrimaryKeys, SQLForeignKeys, - * SQLProcedureColumns(NI), SQLProcedures, - * SQLTablePrivileges, SQLColumnPrivileges(NI) - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ - -#include "psqlodbc.h" - -#include -#include - -#ifndef WIN32 -#include -#endif - -#include "tuple.h" -#include "pgtypes.h" - -#include "environ.h" -#include "connection.h" -#include "statement.h" -#include "qresult.h" -#include "bind.h" -#include "misc.h" -#include "pgtypes.h" -#include "pgapifunc.h" -#ifdef MULTIBYTE -#include "multibyte.h" -#endif - - -/* Trigger related stuff for SQLForeign Keys */ -#define TRIGGER_SHIFT 3 -#define TRIGGER_MASK 0x03 -#define TRIGGER_DELETE 0x01 -#define TRIGGER_UPDATE 0x02 - - -/* extern GLOBAL_VALUES globals; */ - - - -RETCODE SQL_API -PGAPI_GetInfo( - HDBC hdbc, - UWORD fInfoType, - PTR rgbInfoValue, - SWORD cbInfoValueMax, - SWORD FAR * pcbInfoValue) -{ - static char *func = "PGAPI_GetInfo"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci; - char *p = NULL, - tmp[MAX_INFO_STRING]; - int len = 0, - value = 0; - RETCODE result; - - mylog("%s: entering...fInfoType=%d\n", func, fInfoType); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - ci = &(conn->connInfo); - - switch (fInfoType) - { - case SQL_ACCESSIBLE_PROCEDURES: /* ODBC 1.0 */ - p = "N"; - break; - - case SQL_ACCESSIBLE_TABLES: /* ODBC 1.0 */ - p = "N"; - break; - - case SQL_ACTIVE_CONNECTIONS: /* ODBC 1.0 */ - len = 2; - value = MAX_CONNECTIONS; - break; - - case SQL_ACTIVE_STATEMENTS: /* ODBC 1.0 */ - len = 2; - value = 0; - break; - - case SQL_ALTER_TABLE: /* ODBC 2.0 */ - len = 4; - value = SQL_AT_ADD_COLUMN; - break; - - case SQL_BOOKMARK_PERSISTENCE: /* ODBC 2.0 */ - /* very simple bookmark support */ - len = 4; - value = ci->drivers.use_declarefetch ? 0 : (SQL_BP_SCROLL | SQL_BP_DELETE | SQL_BP_UPDATE | SQL_BP_TRANSACTION); - break; - - case SQL_COLUMN_ALIAS: /* ODBC 2.0 */ - p = "N"; - break; - - case SQL_CONCAT_NULL_BEHAVIOR: /* ODBC 1.0 */ - len = 2; - value = SQL_CB_NON_NULL; - break; - - case SQL_CONVERT_BIGINT: - case SQL_CONVERT_BINARY: - case SQL_CONVERT_BIT: - case SQL_CONVERT_CHAR: - case SQL_CONVERT_DATE: - case SQL_CONVERT_DECIMAL: - case SQL_CONVERT_DOUBLE: - case SQL_CONVERT_FLOAT: - case SQL_CONVERT_INTEGER: - case SQL_CONVERT_LONGVARBINARY: - case SQL_CONVERT_LONGVARCHAR: - case SQL_CONVERT_NUMERIC: - case SQL_CONVERT_REAL: - case SQL_CONVERT_SMALLINT: - case SQL_CONVERT_TIME: - case SQL_CONVERT_TIMESTAMP: - case SQL_CONVERT_TINYINT: - case SQL_CONVERT_VARBINARY: - case SQL_CONVERT_VARCHAR: /* ODBC 1.0 */ - len = 4; - value = fInfoType; - break; - - case SQL_CONVERT_FUNCTIONS: /* ODBC 1.0 */ - len = 4; - value = 0; - break; - - case SQL_CORRELATION_NAME: /* ODBC 1.0 */ - - /* - * Saying no correlation name makes Query not work right. - * value = SQL_CN_NONE; - */ - len = 2; - value = SQL_CN_ANY; - break; - - case SQL_CURSOR_COMMIT_BEHAVIOR: /* ODBC 1.0 */ - len = 2; - value = SQL_CB_CLOSE; - if (ci->updatable_cursors) - if (!ci->drivers.use_declarefetch) - value = SQL_CB_PRESERVE; - break; - - case SQL_CURSOR_ROLLBACK_BEHAVIOR: /* ODBC 1.0 */ - len = 2; - value = SQL_CB_CLOSE; - if (ci->updatable_cursors) - if (!ci->drivers.use_declarefetch) - value = SQL_CB_PRESERVE; - break; - - case SQL_DATA_SOURCE_NAME: /* ODBC 1.0 */ - p = CC_get_DSN(conn); - break; - - case SQL_DATA_SOURCE_READ_ONLY: /* ODBC 1.0 */ - p = CC_is_onlyread(conn) ? "Y" : "N"; - break; - - case SQL_DATABASE_NAME: /* Support for old ODBC 1.0 Apps */ - - /* - * Returning the database name causes problems in MS Query. It - * generates query like: "SELECT DISTINCT a FROM byronnbad3 - * bad3" - * - * p = CC_get_database(conn); - */ - p = ""; - break; - - case SQL_DBMS_NAME: /* ODBC 1.0 */ - p = DBMS_NAME; - break; - - case SQL_DBMS_VER: /* ODBC 1.0 */ - - /* - * The ODBC spec wants ##.##.#### ...whatever... so prepend - * the driver - */ - /* version number to the dbms version string */ - sprintf(tmp, "%s %s", POSTGRESDRIVERVERSION, conn->pg_version); - p = tmp; - break; - - case SQL_DEFAULT_TXN_ISOLATION: /* ODBC 1.0 */ - len = 4; - if (PG_VERSION_LT(conn, 6.5)) - value = SQL_TXN_SERIALIZABLE; - else - value = SQL_TXN_READ_COMMITTED; - break; - - case SQL_DRIVER_NAME: /* ODBC 1.0 */ - p = DRIVER_FILE_NAME; - break; - - case SQL_DRIVER_ODBC_VER: - p = DRIVER_ODBC_VER; - break; - - case SQL_DRIVER_VER: /* ODBC 1.0 */ - p = POSTGRESDRIVERVERSION; - break; - - case SQL_EXPRESSIONS_IN_ORDERBY: /* ODBC 1.0 */ - p = "N"; - break; - - case SQL_FETCH_DIRECTION: /* ODBC 1.0 */ - len = 4; - value = ci->drivers.use_declarefetch ? (SQL_FD_FETCH_NEXT) : - (SQL_FD_FETCH_NEXT | - SQL_FD_FETCH_FIRST | - SQL_FD_FETCH_LAST | - SQL_FD_FETCH_PRIOR | - SQL_FD_FETCH_ABSOLUTE | - SQL_FD_FETCH_RELATIVE | - SQL_FD_FETCH_BOOKMARK); - break; - - case SQL_FILE_USAGE: /* ODBC 2.0 */ - len = 2; - value = SQL_FILE_NOT_SUPPORTED; - break; - - case SQL_GETDATA_EXTENSIONS: /* ODBC 2.0 */ - len = 4; - value = (SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND | SQL_GD_BLOCK); - break; - - case SQL_GROUP_BY: /* ODBC 2.0 */ - len = 2; - value = SQL_GB_GROUP_BY_EQUALS_SELECT; - break; - - case SQL_IDENTIFIER_CASE: /* ODBC 1.0 */ - - /* - * are identifiers case-sensitive (yes, but only when quoted. - * If not quoted, they default to lowercase) - */ - len = 2; - value = SQL_IC_LOWER; - break; - - case SQL_IDENTIFIER_QUOTE_CHAR: /* ODBC 1.0 */ - /* the character used to quote "identifiers" */ - p = PG_VERSION_LE(conn, 6.2) ? " " : "\""; - break; - - case SQL_KEYWORDS: /* ODBC 2.0 */ - p = ""; - break; - - case SQL_LIKE_ESCAPE_CLAUSE: /* ODBC 2.0 */ - - /* - * is there a character that escapes '%' and '_' in a LIKE - * clause? not as far as I can tell - */ - p = "N"; - break; - - case SQL_LOCK_TYPES: /* ODBC 2.0 */ - len = 4; - value = ci->drivers.lie ? (SQL_LCK_NO_CHANGE | SQL_LCK_EXCLUSIVE | SQL_LCK_UNLOCK) : SQL_LCK_NO_CHANGE; - break; - - case SQL_MAX_BINARY_LITERAL_LEN: /* ODBC 2.0 */ - len = 4; - value = 0; - break; - - case SQL_MAX_CHAR_LITERAL_LEN: /* ODBC 2.0 */ - len = 4; - value = 0; - break; - - case SQL_MAX_COLUMN_NAME_LEN: /* ODBC 1.0 */ - len = 2; - value = MAX_COLUMN_LEN; - break; - - case SQL_MAX_COLUMNS_IN_GROUP_BY: /* ODBC 2.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_COLUMNS_IN_INDEX: /* ODBC 2.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_COLUMNS_IN_ORDER_BY: /* ODBC 2.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_COLUMNS_IN_SELECT: /* ODBC 2.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_COLUMNS_IN_TABLE: /* ODBC 2.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_CURSOR_NAME_LEN: /* ODBC 1.0 */ - len = 2; - value = MAX_CURSOR_LEN; - break; - - case SQL_MAX_INDEX_SIZE: /* ODBC 2.0 */ - len = 4; - value = 0; - break; - - case SQL_MAX_OWNER_NAME_LEN: /* ODBC 1.0 */ - len = 2; - value = 0; - if (conn->schema_support) - value = MAX_SCHEMA_LEN; - break; - - case SQL_MAX_PROCEDURE_NAME_LEN: /* ODBC 1.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_QUALIFIER_NAME_LEN: /* ODBC 1.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_ROW_SIZE: /* ODBC 2.0 */ - len = 4; - if (PG_VERSION_GE(conn, 7.1)) - { - /* Large Rowa in 7.1+ */ - value = MAX_ROW_SIZE; - } - else - { - /* Without the Toaster we're limited to the blocksize */ - value = BLCKSZ; - } - break; - - case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */ - - /* - * does the preceding value include LONGVARCHAR and - * LONGVARBINARY fields? Well, it does include longvarchar, - * but not longvarbinary. - */ - p = "Y"; - break; - - case SQL_MAX_STATEMENT_LEN: /* ODBC 2.0 */ - /* maybe this should be 0? */ - len = 4; - value = CC_get_max_query_len(conn); - break; - - case SQL_MAX_TABLE_NAME_LEN: /* ODBC 1.0 */ - len = 2; - value = MAX_TABLE_LEN; - break; - - case SQL_MAX_TABLES_IN_SELECT: /* ODBC 2.0 */ - len = 2; - value = 0; - break; - - case SQL_MAX_USER_NAME_LEN: - len = 2; - value = 0; - break; - - case SQL_MULT_RESULT_SETS: /* ODBC 1.0 */ - /* Don't support multiple result sets but say yes anyway? */ - p = "Y"; - break; - - case SQL_MULTIPLE_ACTIVE_TXN: /* ODBC 1.0 */ - p = "Y"; - break; - - case SQL_NEED_LONG_DATA_LEN: /* ODBC 2.0 */ - - /* - * Don't need the length, SQLPutData can handle any size and - * multiple calls - */ - p = "N"; - break; - - case SQL_NON_NULLABLE_COLUMNS: /* ODBC 1.0 */ - len = 2; - value = SQL_NNC_NON_NULL; - break; - - case SQL_NULL_COLLATION: /* ODBC 2.0 */ - /* where are nulls sorted? */ - len = 2; - value = SQL_NC_END; - break; - - case SQL_NUMERIC_FUNCTIONS: /* ODBC 1.0 */ - len = 4; - value = 0; - break; - - case SQL_ODBC_API_CONFORMANCE: /* ODBC 1.0 */ - len = 2; - value = SQL_OAC_LEVEL1; - break; - - case SQL_ODBC_SAG_CLI_CONFORMANCE: /* ODBC 1.0 */ - len = 2; - value = SQL_OSCC_NOT_COMPLIANT; - break; - - case SQL_ODBC_SQL_CONFORMANCE: /* ODBC 1.0 */ - len = 2; - value = SQL_OSC_CORE; - break; - - case SQL_ODBC_SQL_OPT_IEF: /* ODBC 1.0 */ - p = "N"; - break; - - case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */ - len = 4; - if (PG_VERSION_GE(conn, 7.1)) - { - /* OJs in 7.1+ */ - value = (SQL_OJ_LEFT | - SQL_OJ_RIGHT | - SQL_OJ_FULL | - SQL_OJ_NESTED | - SQL_OJ_NOT_ORDERED | - SQL_OJ_INNER | - SQL_OJ_ALL_COMPARISON_OPS); - } - else - /* OJs not in <7.1 */ - value = 0; - break; - - case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */ - p = (PG_VERSION_LE(conn, 6.3)) ? "Y" : "N"; - break; - - case SQL_OUTER_JOINS: /* ODBC 1.0 */ - if (PG_VERSION_GE(conn, 7.1)) - /* OJs in 7.1+ */ - p = "Y"; - else - /* OJs not in <7.1 */ - p = "N"; - break; - - case SQL_OWNER_TERM: /* ODBC 1.0 */ - if (conn->schema_support) - p = "schema"; - else - p = "owner"; - break; - - case SQL_OWNER_USAGE: /* ODBC 2.0 */ - len = 4; - value = 0; - if (conn->schema_support) - value = SQL_OU_DML_STATEMENTS - | SQL_OU_TABLE_DEFINITION - | SQL_OU_INDEX_DEFINITION - | SQL_OU_PRIVILEGE_DEFINITION - ; - break; - - case SQL_POS_OPERATIONS: /* ODBC 2.0 */ - len = 4; - value = (SQL_POS_POSITION | SQL_POS_REFRESH); -#ifdef DRIVER_CURSOR_IMPLEMENT - if (ci->updatable_cursors) - value |= (SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - break; - - case SQL_POSITIONED_STATEMENTS: /* ODBC 2.0 */ - len = 4; - value = ci->drivers.lie ? (SQL_PS_POSITIONED_DELETE | - SQL_PS_POSITIONED_UPDATE | - SQL_PS_SELECT_FOR_UPDATE) : 0; - break; - - case SQL_PROCEDURE_TERM: /* ODBC 1.0 */ - p = "procedure"; - break; - - case SQL_PROCEDURES: /* ODBC 1.0 */ - p = "Y"; - break; - - case SQL_QUALIFIER_LOCATION: /* ODBC 2.0 */ - len = 2; - value = SQL_QL_START; - break; - - case SQL_QUALIFIER_NAME_SEPARATOR: /* ODBC 1.0 */ - p = ""; - break; - - case SQL_QUALIFIER_TERM: /* ODBC 1.0 */ - p = ""; - break; - - case SQL_QUALIFIER_USAGE: /* ODBC 2.0 */ - len = 4; - value = 0; - break; - - case SQL_QUOTED_IDENTIFIER_CASE: /* ODBC 2.0 */ - /* are "quoted" identifiers case-sensitive? YES! */ - len = 2; - value = SQL_IC_SENSITIVE; - break; - - case SQL_ROW_UPDATES: /* ODBC 1.0 */ - - /* - * Driver doesn't support keyset-driven or mixed cursors, so - * not much point in saying row updates are supported - */ - p = (ci->updatable_cursors) ? "Y" : "N"; - break; - - case SQL_SCROLL_CONCURRENCY: /* ODBC 1.0 */ - len = 4; - value = SQL_SCCO_READ_ONLY; -#ifdef DRIVER_CURSOR_IMPLEMENT - if (ci->updatable_cursors) - value |= SQL_SCCO_OPT_ROWVER; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - if (ci->drivers.lie) - value |= (SQL_SCCO_LOCK | SQL_SCCO_OPT_VALUES); - break; - - case SQL_SCROLL_OPTIONS: /* ODBC 1.0 */ - len = 4; - value = SQL_SO_FORWARD_ONLY; - if (!ci->drivers.use_declarefetch) - value |= SQL_SO_STATIC; - if (ci->updatable_cursors) - value |= SQL_SO_KEYSET_DRIVEN; - if (ci->drivers.lie) - value |= (SQL_SO_DYNAMIC | SQL_SO_MIXED); - break; - - case SQL_SEARCH_PATTERN_ESCAPE: /* ODBC 1.0 */ - if (PG_VERSION_GE(conn, 6.5)) - p = "\\"; - else - p = ""; - break; - - case SQL_SERVER_NAME: /* ODBC 1.0 */ - p = CC_get_server(conn); - break; - - case SQL_SPECIAL_CHARACTERS: /* ODBC 2.0 */ - p = "_"; - break; - - case SQL_STATIC_SENSITIVITY: /* ODBC 2.0 */ - len = 4; - value = 0; -#ifdef DRIVER_CURSOR_IMPLEMENT - if (ci->updatable_cursors) - value |= (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - break; - - case SQL_STRING_FUNCTIONS: /* ODBC 1.0 */ - len = 4; - value = (SQL_FN_STR_CONCAT | - SQL_FN_STR_LCASE | - SQL_FN_STR_LENGTH | - SQL_FN_STR_LOCATE | - SQL_FN_STR_LTRIM | - SQL_FN_STR_RTRIM | - SQL_FN_STR_SUBSTRING | - SQL_FN_STR_UCASE); - break; - - case SQL_SUBQUERIES: /* ODBC 2.0 */ - /* postgres 6.3 supports subqueries */ - len = 4; - value = (SQL_SQ_QUANTIFIED | - SQL_SQ_IN | - SQL_SQ_EXISTS | - SQL_SQ_COMPARISON); - break; - - case SQL_SYSTEM_FUNCTIONS: /* ODBC 1.0 */ - len = 4; - value = 0; - break; - - case SQL_TABLE_TERM: /* ODBC 1.0 */ - p = "table"; - break; - - case SQL_TIMEDATE_ADD_INTERVALS: /* ODBC 2.0 */ - len = 4; - value = 0; - break; - - case SQL_TIMEDATE_DIFF_INTERVALS: /* ODBC 2.0 */ - len = 4; - value = 0; - break; - - case SQL_TIMEDATE_FUNCTIONS: /* ODBC 1.0 */ - len = 4; - value = (SQL_FN_TD_NOW); - break; - - case SQL_TXN_CAPABLE: /* ODBC 1.0 */ - - /* - * Postgres can deal with create or drop table statements in a - * transaction - */ - len = 2; - value = SQL_TC_ALL; - break; - - case SQL_TXN_ISOLATION_OPTION: /* ODBC 1.0 */ - len = 4; - if (PG_VERSION_LT(conn, 6.5)) - value = SQL_TXN_SERIALIZABLE; - else if (PG_VERSION_GE(conn, 7.1)) - value = SQL_TXN_READ_COMMITTED | SQL_TXN_SERIALIZABLE; - else - value = SQL_TXN_READ_COMMITTED; - break; - - case SQL_UNION: /* ODBC 2.0 */ - /* unions with all supported in postgres 6.3 */ - len = 4; - value = (SQL_U_UNION | SQL_U_UNION_ALL); - break; - - case SQL_USER_NAME: /* ODBC 1.0 */ - p = CC_get_username(conn); - break; - - default: - /* unrecognized key */ - conn->errormsg = "Unrecognized key passed to PGAPI_GetInfo."; - conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR; - return SQL_ERROR; - } - - result = SQL_SUCCESS; - - mylog("%s: p='%s', len=%d, value=%d, cbMax=%d\n", func, p ? p : "", len, value, cbInfoValueMax); - - /* - * NOTE, that if rgbInfoValue is NULL, then no warnings or errors - * should result and just pcbInfoValue is returned, which indicates - * what length would be required if a real buffer had been passed in. - */ - if (p) - { - /* char/binary data */ - len = strlen(p); - - if (rgbInfoValue) - { -#ifdef UNICODE_SUPPORT - if (conn->unicode) - { - len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2); - len *= 2; - } - else -#endif /* UNICODE_SUPPORT */ - strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax); - - if (len >= cbInfoValueMax) - { - result = SQL_SUCCESS_WITH_INFO; - conn->errornumber = CONN_TRUNCATED; - conn->errormsg = "The buffer was too small for tthe InfoValue."; - } - } - } - else - { - /* numeric data */ - if (rgbInfoValue) - { - if (len == 2) - *((WORD *) rgbInfoValue) = (WORD) value; - else if (len == 4) - *((DWORD *) rgbInfoValue) = (DWORD) value; - } - } - - if (pcbInfoValue) - *pcbInfoValue = len; - - return result; -} - - -RETCODE SQL_API -PGAPI_GetTypeInfo( - HSTMT hstmt, - SWORD fSqlType) -{ - static char *func = "PGAPI_GetTypeInfo"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - TupleNode *row; - int i; - - /* Int4 type; */ - Int4 pgType; - Int2 sqlType; - - mylog("%s: entering...fSqlType = %d\n", func, fSqlType); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - stmt->manual_result = TRUE; - if (res = QR_Constructor(), !res) - { - SC_log_error(func, "Error creating result.", stmt); - return SQL_ERROR; - } - SC_set_Result(stmt, res); - -#if (ODBCVER >= 0x0399) - extend_column_bindings(SC_get_ARD(stmt), 19); -#else - extend_column_bindings(SC_get_ARD(stmt), 15); -#endif /* ODBCVER */ - - QR_set_num_fields(res, 15); - QR_set_field_info(res, 0, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "DATA_TYPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 2, "PRECISION", PG_TYPE_INT4, 4); - QR_set_field_info(res, 3, "LITERAL_PREFIX", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "LITERAL_SUFFIX", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 5, "CREATE_PARAMS", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 6, "NULLABLE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 7, "CASE_SENSITIVE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 8, "SEARCHABLE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 9, "UNSIGNED_ATTRIBUTE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 10, "MONEY", PG_TYPE_INT2, 2); - QR_set_field_info(res, 11, "AUTO_INCREMENT", PG_TYPE_INT2, 2); - QR_set_field_info(res, 12, "LOCAL_TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 13, "MINIMUM_SCALE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 14, "MAXIMUM_SCALE", PG_TYPE_INT2, 2); -#if (ODBCVER >=0x0399) - QR_set_field_info(res, 15, "SQL_DATA_TYPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 16, "SQL_DATATIME_SUB", PG_TYPE_INT2, 2); - QR_set_field_info(res, 17, "NUM_PREC_RADIX", PG_TYPE_INT4, 4); - QR_set_field_info(res, 18, "INTERVAL_PRECISION", PG_TYPE_INT2, 2); -#endif /* ODBCVER */ - - for (i = 0, sqlType = sqlTypes[0]; sqlType; sqlType = sqlTypes[++i]) - { - pgType = sqltype_to_pgtype(stmt, sqlType); - - if (fSqlType == SQL_ALL_TYPES || fSqlType == sqlType) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (15 - 1) *sizeof(TupleField)); - - /* These values can't be NULL */ - set_tuplefield_string(&row->tuple[0], pgtype_to_name(stmt, pgType)); - set_tuplefield_int2(&row->tuple[1], (Int2) sqlType); - set_tuplefield_int2(&row->tuple[6], pgtype_nullable(stmt, pgType)); - set_tuplefield_int2(&row->tuple[7], pgtype_case_sensitive(stmt, pgType)); - set_tuplefield_int2(&row->tuple[8], pgtype_searchable(stmt, pgType)); - set_tuplefield_int2(&row->tuple[10], pgtype_money(stmt, pgType)); - - /* - * Localized data-source dependent data type name (always - * NULL) - */ - set_tuplefield_null(&row->tuple[12]); - - /* These values can be NULL */ - set_nullfield_int4(&row->tuple[2], pgtype_column_size(stmt, pgType, PG_STATIC, PG_STATIC)); - set_nullfield_string(&row->tuple[3], pgtype_literal_prefix(stmt, pgType)); - set_nullfield_string(&row->tuple[4], pgtype_literal_suffix(stmt, pgType)); - set_nullfield_string(&row->tuple[5], pgtype_create_params(stmt, pgType)); - set_nullfield_int2(&row->tuple[9], pgtype_unsigned(stmt, pgType)); - set_nullfield_int2(&row->tuple[11], pgtype_auto_increment(stmt, pgType)); - set_nullfield_int2(&row->tuple[13], pgtype_scale(stmt, pgType, PG_STATIC)); - set_nullfield_int2(&row->tuple[14], pgtype_scale(stmt, pgType, PG_STATIC)); -#if (ODBCVER >=0x0399) - set_nullfield_int2(&row->tuple[15], pgtype_sqldesctype(stmt, pgType)); - set_nullfield_int2(&row->tuple[16], pgtype_datetime_sub(stmt, pgType)); - set_nullfield_int4(&row->tuple[17], pgtype_radix(stmt, pgType)); - set_nullfield_int4(&row->tuple[18], 0); -#endif /* ODBCVER */ - - QR_add_tuple(res, row); - } - } - - stmt->status = STMT_FINISHED; - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_GetFunctions( - HDBC hdbc, - UWORD fFunction, - UWORD FAR * pfExists) -{ - static char *func = "PGAPI_GetFunctions"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci = &(conn->connInfo); - - mylog("%s: entering...%u\n", func, fFunction); - - if (fFunction == SQL_API_ALL_FUNCTIONS) - { -#if (ODBCVER < 0x0300) - if (ci->drivers.lie) - { - int i; - - memset(pfExists, 0, sizeof(UWORD) * 100); - - pfExists[SQL_API_SQLALLOCENV] = TRUE; - pfExists[SQL_API_SQLFREEENV] = TRUE; - for (i = SQL_API_SQLALLOCCONNECT; i <= SQL_NUM_FUNCTIONS; i++) - pfExists[i] = TRUE; - for (i = SQL_EXT_API_START; i <= SQL_EXT_API_LAST; i++) - pfExists[i] = TRUE; - } - else -#endif - { - memset(pfExists, 0, sizeof(UWORD) * 100); - - /* ODBC core functions */ - pfExists[SQL_API_SQLALLOCCONNECT] = TRUE; - pfExists[SQL_API_SQLALLOCENV] = TRUE; - pfExists[SQL_API_SQLALLOCSTMT] = TRUE; - pfExists[SQL_API_SQLBINDCOL] = TRUE; - pfExists[SQL_API_SQLCANCEL] = TRUE; - pfExists[SQL_API_SQLCOLATTRIBUTES] = TRUE; - pfExists[SQL_API_SQLCONNECT] = TRUE; - pfExists[SQL_API_SQLDESCRIBECOL] = TRUE; /* partial */ - pfExists[SQL_API_SQLDISCONNECT] = TRUE; - pfExists[SQL_API_SQLERROR] = TRUE; - pfExists[SQL_API_SQLEXECDIRECT] = TRUE; - pfExists[SQL_API_SQLEXECUTE] = TRUE; - pfExists[SQL_API_SQLFETCH] = TRUE; - pfExists[SQL_API_SQLFREECONNECT] = TRUE; - pfExists[SQL_API_SQLFREEENV] = TRUE; - pfExists[SQL_API_SQLFREESTMT] = TRUE; - pfExists[SQL_API_SQLGETCURSORNAME] = TRUE; - pfExists[SQL_API_SQLNUMRESULTCOLS] = TRUE; - pfExists[SQL_API_SQLPREPARE] = TRUE; /* complete? */ - pfExists[SQL_API_SQLROWCOUNT] = TRUE; - pfExists[SQL_API_SQLSETCURSORNAME] = TRUE; - pfExists[SQL_API_SQLSETPARAM] = FALSE; /* odbc 1.0 */ - pfExists[SQL_API_SQLTRANSACT] = TRUE; - - /* ODBC level 1 functions */ - pfExists[SQL_API_SQLBINDPARAMETER] = TRUE; - pfExists[SQL_API_SQLCOLUMNS] = TRUE; - pfExists[SQL_API_SQLDRIVERCONNECT] = TRUE; - pfExists[SQL_API_SQLGETCONNECTOPTION] = TRUE; /* partial */ - pfExists[SQL_API_SQLGETDATA] = TRUE; - pfExists[SQL_API_SQLGETFUNCTIONS] = TRUE; - pfExists[SQL_API_SQLGETINFO] = TRUE; - pfExists[SQL_API_SQLGETSTMTOPTION] = TRUE; /* partial */ - pfExists[SQL_API_SQLGETTYPEINFO] = TRUE; - pfExists[SQL_API_SQLPARAMDATA] = TRUE; - pfExists[SQL_API_SQLPUTDATA] = TRUE; - pfExists[SQL_API_SQLSETCONNECTOPTION] = TRUE; /* partial */ - pfExists[SQL_API_SQLSETSTMTOPTION] = TRUE; - pfExists[SQL_API_SQLSPECIALCOLUMNS] = TRUE; - pfExists[SQL_API_SQLSTATISTICS] = TRUE; - pfExists[SQL_API_SQLTABLES] = TRUE; - - /* ODBC level 2 functions */ - pfExists[SQL_API_SQLBROWSECONNECT] = FALSE; - pfExists[SQL_API_SQLCOLUMNPRIVILEGES] = FALSE; - pfExists[SQL_API_SQLDATASOURCES] = FALSE; /* only implemented by - * DM */ - pfExists[SQL_API_SQLDESCRIBEPARAM] = FALSE; /* not properly - * implemented */ - pfExists[SQL_API_SQLDRIVERS] = FALSE; /* only implemented by - * DM */ - pfExists[SQL_API_SQLEXTENDEDFETCH] = TRUE; - pfExists[SQL_API_SQLFOREIGNKEYS] = TRUE; - pfExists[SQL_API_SQLMORERESULTS] = TRUE; - pfExists[SQL_API_SQLNATIVESQL] = TRUE; - pfExists[SQL_API_SQLNUMPARAMS] = TRUE; - pfExists[SQL_API_SQLPARAMOPTIONS] = TRUE; - pfExists[SQL_API_SQLPRIMARYKEYS] = TRUE; - pfExists[SQL_API_SQLPROCEDURECOLUMNS] = FALSE; - if (PG_VERSION_LT(conn, 6.5)) - pfExists[SQL_API_SQLPROCEDURES] = FALSE; - else - pfExists[SQL_API_SQLPROCEDURES] = TRUE; - pfExists[SQL_API_SQLSETPOS] = TRUE; - pfExists[SQL_API_SQLSETSCROLLOPTIONS] = TRUE; /* odbc 1.0 */ - pfExists[SQL_API_SQLTABLEPRIVILEGES] = TRUE; - } - } - else - { - if (ci->drivers.lie) - *pfExists = TRUE; - else - { - switch (fFunction) - { - case SQL_API_SQLALLOCCONNECT: - *pfExists = TRUE; - break; - case SQL_API_SQLALLOCENV: - *pfExists = TRUE; - break; - case SQL_API_SQLALLOCSTMT: - *pfExists = TRUE; - break; - case SQL_API_SQLBINDCOL: - *pfExists = TRUE; - break; - case SQL_API_SQLCANCEL: - *pfExists = TRUE; - break; - case SQL_API_SQLCOLATTRIBUTES: - *pfExists = TRUE; - break; - case SQL_API_SQLCONNECT: - *pfExists = TRUE; - break; - case SQL_API_SQLDESCRIBECOL: - *pfExists = TRUE; - break; /* partial */ - case SQL_API_SQLDISCONNECT: - *pfExists = TRUE; - break; - case SQL_API_SQLERROR: - *pfExists = TRUE; - break; - case SQL_API_SQLEXECDIRECT: - *pfExists = TRUE; - break; - case SQL_API_SQLEXECUTE: - *pfExists = TRUE; - break; - case SQL_API_SQLFETCH: - *pfExists = TRUE; - break; - case SQL_API_SQLFREECONNECT: - *pfExists = TRUE; - break; - case SQL_API_SQLFREEENV: - *pfExists = TRUE; - break; - case SQL_API_SQLFREESTMT: - *pfExists = TRUE; - break; - case SQL_API_SQLGETCURSORNAME: - *pfExists = TRUE; - break; - case SQL_API_SQLNUMRESULTCOLS: - *pfExists = TRUE; - break; - case SQL_API_SQLPREPARE: - *pfExists = TRUE; - break; - case SQL_API_SQLROWCOUNT: - *pfExists = TRUE; - break; - case SQL_API_SQLSETCURSORNAME: - *pfExists = TRUE; - break; - case SQL_API_SQLSETPARAM: - *pfExists = FALSE; - break; /* odbc 1.0 */ - case SQL_API_SQLTRANSACT: - *pfExists = TRUE; - break; - - /* ODBC level 1 functions */ - case SQL_API_SQLBINDPARAMETER: - *pfExists = TRUE; - break; - case SQL_API_SQLCOLUMNS: - *pfExists = TRUE; - break; - case SQL_API_SQLDRIVERCONNECT: - *pfExists = TRUE; - break; - case SQL_API_SQLGETCONNECTOPTION: - *pfExists = TRUE; - break; /* partial */ - case SQL_API_SQLGETDATA: - *pfExists = TRUE; - break; - case SQL_API_SQLGETFUNCTIONS: - *pfExists = TRUE; - break; - case SQL_API_SQLGETINFO: - *pfExists = TRUE; - break; - case SQL_API_SQLGETSTMTOPTION: - *pfExists = TRUE; - break; /* partial */ - case SQL_API_SQLGETTYPEINFO: - *pfExists = TRUE; - break; - case SQL_API_SQLPARAMDATA: - *pfExists = TRUE; - break; - case SQL_API_SQLPUTDATA: - *pfExists = TRUE; - break; - case SQL_API_SQLSETCONNECTOPTION: - *pfExists = TRUE; - break; /* partial */ - case SQL_API_SQLSETSTMTOPTION: - *pfExists = TRUE; - break; - case SQL_API_SQLSPECIALCOLUMNS: - *pfExists = TRUE; - break; - case SQL_API_SQLSTATISTICS: - *pfExists = TRUE; - break; - case SQL_API_SQLTABLES: - *pfExists = TRUE; - break; - - /* ODBC level 2 functions */ - case SQL_API_SQLBROWSECONNECT: - *pfExists = FALSE; - break; - case SQL_API_SQLCOLUMNPRIVILEGES: - *pfExists = FALSE; - break; - case SQL_API_SQLDATASOURCES: - *pfExists = FALSE; - break; /* only implemented by DM */ - case SQL_API_SQLDESCRIBEPARAM: - *pfExists = FALSE; - break; /* not properly implemented */ - case SQL_API_SQLDRIVERS: - *pfExists = FALSE; - break; /* only implemented by DM */ - case SQL_API_SQLEXTENDEDFETCH: - *pfExists = TRUE; - break; - case SQL_API_SQLFOREIGNKEYS: - *pfExists = TRUE; - break; - case SQL_API_SQLMORERESULTS: - *pfExists = TRUE; - break; - case SQL_API_SQLNATIVESQL: - *pfExists = TRUE; - break; - case SQL_API_SQLNUMPARAMS: - *pfExists = TRUE; - break; - case SQL_API_SQLPARAMOPTIONS: - *pfExists = TRUE; - break; - case SQL_API_SQLPRIMARYKEYS: - *pfExists = TRUE; - break; - case SQL_API_SQLPROCEDURECOLUMNS: - *pfExists = FALSE; - break; - case SQL_API_SQLPROCEDURES: - if (PG_VERSION_LT(conn, 6.5)) - *pfExists = FALSE; - else - *pfExists = TRUE; - break; - case SQL_API_SQLSETPOS: - *pfExists = TRUE; - break; - case SQL_API_SQLSETSCROLLOPTIONS: - *pfExists = TRUE; - break; /* odbc 1.0 */ - case SQL_API_SQLTABLEPRIVILEGES: - *pfExists = TRUE; - break; - } - } - } - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_Tables( - HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UCHAR FAR * szTableType, - SWORD cbTableType) -{ - static char *func = "PGAPI_Tables"; - StatementClass *stmt = (StatementClass *) hstmt; - StatementClass *tbl_stmt; - QResultClass *res; - TupleNode *row; - HSTMT htbl_stmt; - RETCODE result; - char *tableType; - char tables_query[INFO_INQUIRY_LEN]; - char table_name[MAX_INFO_STRING], - table_owner[MAX_INFO_STRING], - relkind_or_hasrules[MAX_INFO_STRING]; - ConnectionClass *conn; - ConnInfo *ci; - char *prefix[32], - prefixes[MEDIUM_REGISTRY_LEN]; - char *table_type[32], - table_types[MAX_INFO_STRING]; - char show_system_tables, - show_regular_tables, - show_views; - char regular_table, - view, - systable; - int i; - - mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - stmt->manual_result = TRUE; - stmt->errormsg_created = TRUE; - - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for PGAPI_Tables result."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - tbl_stmt = (StatementClass *) htbl_stmt; - - /* - * Create the query to find out the tables - */ - if (conn->schema_support) - { - /* view is represented by its relkind since 7.1 */ - strcpy(tables_query, "select relname, nspname, relkind from pg_class, pg_namespace"); - strcat(tables_query, " where relkind in ('r', 'v')"); - } - else if (PG_VERSION_GE(conn, 7.1)) - { - /* view is represented by its relkind since 7.1 */ - strcpy(tables_query, "select relname, usename, relkind from pg_class, pg_user"); - strcat(tables_query, " where relkind in ('r', 'v')"); - } - else - { - strcpy(tables_query, "select relname, usename, relhasrules from pg_class, pg_user"); - strcat(tables_query, " where relkind = 'r'"); - } - - if (conn->schema_support) - schema_strcat(tables_query, " and nspname like '%.*s'", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - else - my_strcat(tables_query, " and usename like '%.*s'", szTableOwner, cbTableOwner); - my_strcat(tables_query, " and relname like '%.*s'", szTableName, cbTableName); - - /* Parse the extra systable prefix */ - strcpy(prefixes, ci->drivers.extra_systable_prefixes); - i = 0; - prefix[i] = strtok(prefixes, ";"); - while (prefix[i] && i < 32) - prefix[++i] = strtok(NULL, ";"); - - /* Parse the desired table types to return */ - show_system_tables = FALSE; - show_regular_tables = FALSE; - show_views = FALSE; - - /* make_string mallocs memory */ - tableType = make_string(szTableType, cbTableType, NULL); - if (tableType) - { - strcpy(table_types, tableType); - free(tableType); - i = 0; - table_type[i] = strtok(table_types, ","); - while (table_type[i] && i < 32) - table_type[++i] = strtok(NULL, ","); - - /* Check for desired table types to return */ - i = 0; - while (table_type[i]) - { - if (strstr(table_type[i], "SYSTEM TABLE")) - show_system_tables = TRUE; - else if (strstr(table_type[i], "TABLE")) - show_regular_tables = TRUE; - else if (strstr(table_type[i], "VIEW")) - show_views = TRUE; - i++; - } - } - else - { - show_regular_tables = TRUE; - show_views = TRUE; - } - - /* - * If not interested in SYSTEM TABLES then filter them out to save - * some time on the query. If treating system tables as regular - * tables, then dont filter either. - */ - if (!atoi(ci->show_system_tables) && !show_system_tables) - { - strcat(tables_query, " and relname !~ '^" POSTGRES_SYS_PREFIX); - - /* Also filter out user-defined system table types */ - i = 0; - while (prefix[i]) - { - strcat(tables_query, "|^"); - strcat(tables_query, prefix[i]); - i++; - } - strcat(tables_query, "'"); - } - - /* match users */ - if (PG_VERSION_LT(conn, 7.1)) - /* filter out large objects in older versions */ - strcat(tables_query, " and relname !~ '^xinv[0-9]+'"); - - if (conn->schema_support) - strcat(tables_query, " and pg_namespace.oid = relnamespace order by nspname, relname"); - else - strcat(tables_query, " and usesysid = relowner order by relname"); - - result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_CHAR, - table_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_CHAR, - table_owner, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - result = PGAPI_BindCol(htbl_stmt, 3, SQL_C_CHAR, - relkind_or_hasrules, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - if (res = QR_Constructor(), !res) - { - stmt->errormsg = "Couldn't allocate memory for PGAPI_Tables result."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - SC_set_Result(stmt, res); - - /* the binding structure for a statement is not set up until */ - - /* - * a statement is actually executed, so we'll have to do this - * ourselves. - */ - extend_column_bindings(SC_get_ARD(stmt), 5); - - /* set the field names */ - QR_set_num_fields(res, 5); - QR_set_field_info(res, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 3, "TABLE_TYPE", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "REMARKS", PG_TYPE_TEXT, 254); - - /* add the tuples */ - result = PGAPI_Fetch(htbl_stmt); - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) - { - /* - * Determine if this table name is a system table. If treating - * system tables as regular tables, then no need to do this test. - */ - systable = FALSE; - if (!atoi(ci->show_system_tables)) - { - if (strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0) - systable = TRUE; - - else - { - /* Check extra system table prefixes */ - i = 0; - while (prefix[i]) - { - mylog("table_name='%s', prefix[%d]='%s'\n", table_name, i, prefix[i]); - if (strncmp(table_name, prefix[i], strlen(prefix[i])) == 0) - { - systable = TRUE; - break; - } - i++; - } - } - } - - /* Determine if the table name is a view */ - if (PG_VERSION_GE(conn, 7.1)) - /* view is represented by its relkind since 7.1 */ - view = (relkind_or_hasrules[0] == 'v'); - else - view = (relkind_or_hasrules[0] == '1'); - - /* It must be a regular table */ - regular_table = (!systable && !view); - - - /* Include the row in the result set if meets all criteria */ - - /* - * NOTE: Unsupported table types (i.e., LOCAL TEMPORARY, ALIAS, - * etc) will return nothing - */ - if ((systable && show_system_tables) || - (view && show_views) || - (regular_table && show_regular_tables)) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (5 - 1) *sizeof(TupleField)); - - /*set_tuplefield_string(&row->tuple[0], "");*/ - set_tuplefield_null(&row->tuple[0]); - - /* - * I have to hide the table owner from Access, otherwise it - * insists on referring to the table as 'owner.table'. (this - * is valid according to the ODBC SQL grammar, but Postgres - * won't support it.) - * - * set_tuplefield_string(&row->tuple[1], table_owner); - */ - - mylog("%s: table_name = '%s'\n", func, table_name); - - if (conn->schema_support) - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(table_owner)); - else - /* set_tuplefield_string(&row->tuple[1], ""); */ - set_tuplefield_null(&row->tuple[1]); - set_tuplefield_string(&row->tuple[2], table_name); - set_tuplefield_string(&row->tuple[3], systable ? "SYSTEM TABLE" : (view ? "VIEW" : "TABLE")); - /*set_tuplefield_string(&row->tuple[4], "");*/ - set_tuplefield_string(&row->tuple[4], "TABLE"); - - QR_add_tuple(res, row); - } - result = PGAPI_Fetch(htbl_stmt); - } - if (result != SQL_NO_DATA_FOUND) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - mylog("%s: EXIT, stmt=%u\n", func, stmt); - return SQL_SUCCESS; -} - - -/* - * PostgreSQL needs 2 '\\' to escape '_' and '%'. - */ -static int -reallyEscapeCatalogEscapes(const char *src, int srclen, char *dest, int dst_len, int ccsc) -{ - int i, outlen; - const char *in; - BOOL escape_in = FALSE; -#ifdef MULTIBYTE - encoded_str encstr; -#endif - - if (srclen == SQL_NULL_DATA) - { - dest[0] = '\0'; - return STRCPY_NULL; - } - else if (srclen == SQL_NTS) - srclen = strlen(src); - if (srclen <= 0) - return STRCPY_FAIL; -#ifdef MULTIBYTE - encoded_str_constr(&encstr, ccsc, src); -#endif - for (i = 0, in = src, outlen = 0; i < srclen && outlen < dst_len; i++, in++) - { -#ifdef MULTIBYTE - encoded_nextchar(&encstr); - if (ENCODE_STATUS(encstr) != 0) - { - dest[outlen++] = *in; - continue; - } -#endif - if (escape_in) - { - switch (*in) - { - case '%': - case '_': - dest[outlen++] = '\\'; /* needs 1 more */ - break; - default: - dest[outlen++] = '\\'; - if (outlen < dst_len) - dest[outlen++] = '\\'; - if (outlen < dst_len) - dest[outlen++] = '\\'; - break; - } - } - if (*in == '\\') - escape_in = TRUE; - else - escape_in = FALSE; - if (outlen < dst_len) - dest[outlen++] = *in; - } - if (outlen < dst_len) - dest[outlen] = '\0'; - return outlen; -} - -RETCODE SQL_API -PGAPI_Columns( - HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UCHAR FAR * szColumnName, - SWORD cbColumnName, - UWORD flag) -{ - static char *func = "PGAPI_Columns"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - TupleNode *row; - HSTMT hcol_stmt; - StatementClass *col_stmt; - char columns_query[INFO_INQUIRY_LEN]; - RETCODE result; - char table_owner[MAX_INFO_STRING], - table_name[MAX_INFO_STRING], - field_name[MAX_INFO_STRING], - field_type_name[MAX_INFO_STRING]; - Int2 field_number, sqltype, - reserved_cols, - result_cols, - decimal_digits; - Int4 field_type, - the_type, - field_length, - mod_length, - column_size, - ordinal; - char useStaticPrecision; - char not_null[MAX_INFO_STRING], - relhasrules[MAX_INFO_STRING]; - ConnInfo *ci; - ConnectionClass *conn; - - - mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - stmt->manual_result = TRUE; - stmt->errormsg_created = TRUE; - - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - /* - * Create the query to find out the columns (Note: pre 6.3 did not - * have the atttypmod field) - */ - if (conn->schema_support) - sprintf(columns_query, "select u.nspname, c.relname, a.attname, a.atttypid" - ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules" - " from pg_namespace u, pg_class c, pg_attribute a, pg_type t" - " where u.oid = c.relnamespace" - " and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)", - "a.atttypmod"); - else - sprintf(columns_query, "select u.usename, c.relname, a.attname, a.atttypid" - ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules" - " from pg_user u, pg_class c, pg_attribute a, pg_type t" - " where u.usesysid = c.relowner" - " and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)", - PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod"); - - if ((flag & PODBC_NOT_SEARCH_PATTERN) != 0) - { - my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); - if (conn->schema_support) - schema_strcat(columns_query, " and u.nspname = '%.*s'", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - else - my_strcat(columns_query, " and u.usename = '%.*s'", szTableOwner, cbTableOwner); - my_strcat(columns_query, " and a.attname = '%.*s'", szColumnName, cbColumnName); - } - else - { - char esc_table_name[MAX_TABLE_LEN * 2]; - int escTbnamelen; - - escTbnamelen = reallyEscapeCatalogEscapes(szTableName, cbTableName, esc_table_name, sizeof(esc_table_name), conn->ccsc); - my_strcat(columns_query, " and c.relname like '%.*s'", esc_table_name, escTbnamelen); - if (conn->schema_support) - schema_strcat(columns_query, " and u.nspname like '%.*s'", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - else - my_strcat(columns_query, " and u.usename like '%.*s'", szTableOwner, cbTableOwner); - my_strcat(columns_query, " and a.attname like '%.*s'", szColumnName, cbColumnName); - } - - /* - * give the output in the order the columns were defined when the - * table was created - */ - if (conn->schema_support) - strcat(columns_query, " order by u.nspname, c.relname, attnum"); - else - strcat(columns_query, " order by c.relname, attnum"); - - result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for PGAPI_Columns result."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - col_stmt = (StatementClass *) hcol_stmt; - - mylog("%s: hcol_stmt = %u, col_stmt = %u\n", func, hcol_stmt, col_stmt); - - result = PGAPI_ExecDirect(hcol_stmt, columns_query, - strlen(columns_query)); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = SC_create_errormsg(hcol_stmt); - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 1, SQL_C_CHAR, - table_owner, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 2, SQL_C_CHAR, - table_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 3, SQL_C_CHAR, - field_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_LONG, - &field_type, 4, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 5, SQL_C_CHAR, - field_type_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 6, SQL_C_SHORT, - &field_number, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 7, SQL_C_LONG, - &field_length, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 8, SQL_C_LONG, - &mod_length, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 9, SQL_C_CHAR, - not_null, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 10, SQL_C_CHAR, - relhasrules, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - if (res = QR_Constructor(), !res) - { - stmt->errormsg = "Couldn't allocate memory for PGAPI_Columns result."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - SC_set_Result(stmt, res); - - /* the binding structure for a statement is not set up until */ - - /* - * a statement is actually executed, so we'll have to do this - * ourselves. - */ -#if (ODBCVER >= 0x0300) - reserved_cols = 18; -#else - reserved_cols = 12; -#endif /* ODBCVER */ - result_cols = reserved_cols + 2; - extend_column_bindings(SC_get_ARD(stmt), result_cols); - - /* set the field names */ - QR_set_num_fields(res, result_cols); - QR_set_field_info(res, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "DATA_TYPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 6, "PRECISION", PG_TYPE_INT4, 4); /* COLUMN_SIZE */ - QR_set_field_info(res, 7, "LENGTH", PG_TYPE_INT4, 4); /* BUFFER_LENGTH */ - QR_set_field_info(res, 8, "SCALE", PG_TYPE_INT2, 2); /* DECIMAL_DIGITS ***/ - QR_set_field_info(res, 9, "RADIX", PG_TYPE_INT2, 2); - QR_set_field_info(res, 10, "NULLABLE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 11, "REMARKS", PG_TYPE_TEXT, 254); - - /* User defined fields */ -#if (ODBCVER >= 0x0300) - QR_set_field_info(res, 12, "COLUMN_DEF", PG_TYPE_INT4, 254); - QR_set_field_info(res, 13, "SQL_DATA_TYPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 14, "SQL_DATETIME_SUB", PG_TYPE_INT2, 2); - QR_set_field_info(res, 15, "CHAR_OCTET_LENGTH", PG_TYPE_INT4, 4); - QR_set_field_info(res, 16, "ORDINAL_POSITION", PG_TYPE_INT4, 4); - QR_set_field_info(res, 17, "IS_NULLABLE", PG_TYPE_TEXT, 254); -#endif /* ODBCVER */ - QR_set_field_info(res, reserved_cols, "DISPLAY_SIZE", PG_TYPE_INT4, 4); - QR_set_field_info(res, reserved_cols + 1, "FIELD_TYPE", PG_TYPE_INT4, 4); - - ordinal = 1; - result = PGAPI_Fetch(hcol_stmt); - - /* - * Only show oid if option AND there are other columns AND it's not - * being called by SQLStatistics . Always show OID if it's a system - * table - */ - - if (result != SQL_ERROR && !stmt->internal) - { - if (relhasrules[0] != '1' && - (atoi(ci->show_oid_column) || - strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0)) - { - /* For OID fields */ - the_type = PG_TYPE_OID; - row = (TupleNode *) malloc(sizeof(TupleNode) + - (result_cols - 1) *sizeof(TupleField)); - - set_tuplefield_string(&row->tuple[0], ""); - /* see note in SQLTables() */ - if (conn->schema_support) - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(table_owner)); - else - set_tuplefield_string(&row->tuple[1], ""); - set_tuplefield_string(&row->tuple[2], table_name); - set_tuplefield_string(&row->tuple[3], "oid"); - sqltype = pgtype_to_concise_type(stmt, the_type); - set_tuplefield_int2(&row->tuple[4], sqltype); - set_tuplefield_string(&row->tuple[5], "OID"); - - set_tuplefield_int4(&row->tuple[6], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[7], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC)); - set_nullfield_int2(&row->tuple[8], pgtype_decimal_digits(stmt, the_type, PG_STATIC)); - set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type)); - set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS); - set_tuplefield_string(&row->tuple[11], ""); - -#if (ODBCVER >= 0x0300) - set_tuplefield_null(&row->tuple[12]); - set_tuplefield_int2(&row->tuple[13], sqltype); - set_tuplefield_null(&row->tuple[14]); - set_tuplefield_int4(&row->tuple[15], pgtype_transfer_octet_length(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[16], ordinal); - set_tuplefield_string(&row->tuple[17], "No"); -#endif /* ODBCVER */ - set_tuplefield_int4(&row->tuple[reserved_cols], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[reserved_cols + 1], the_type); - - QR_add_tuple(res, row); - ordinal++; - } - } - - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + - (result_cols - 1) *sizeof(TupleField)); - - - set_tuplefield_string(&row->tuple[0], ""); - /* see note in SQLTables() */ - if (conn->schema_support) - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(table_owner)); - else - set_tuplefield_string(&row->tuple[1], ""); - set_tuplefield_string(&row->tuple[2], table_name); - set_tuplefield_string(&row->tuple[3], field_name); - sqltype = pgtype_to_concise_type(stmt, field_type); - set_tuplefield_int2(&row->tuple[4], sqltype); - set_tuplefield_string(&row->tuple[5], field_type_name); - - - /*---------- - * Some Notes about Postgres Data Types: - * - * VARCHAR - the length is stored in the pg_attribute.atttypmod field - * BPCHAR - the length is also stored as varchar is - * - * NUMERIC - the decimal_digits is stored in atttypmod as follows: - * - * column_size =((atttypmod - VARHDRSZ) >> 16) & 0xffff - * decimal_digits = (atttypmod - VARHDRSZ) & 0xffff - * - *---------- - */ - qlog("PGAPI_Columns: table='%s',field_name='%s',type=%d,name='%s'\n", - table_name, field_name, field_type, field_type_name); - - useStaticPrecision = TRUE; - - if (field_type == PG_TYPE_NUMERIC) - { - if (mod_length >= 4) - mod_length -= 4; /* the length is in atttypmod - 4 */ - - if (mod_length >= 0) - { - useStaticPrecision = FALSE; - - column_size = (mod_length >> 16) & 0xffff; - decimal_digits = mod_length & 0xffff; - - mylog("%s: field type is NUMERIC: field_type = %d, mod_length=%d, precision=%d, scale=%d\n", func, field_type, mod_length, column_size, decimal_digits); - - set_tuplefield_int4(&row->tuple[6], column_size); - set_tuplefield_int4(&row->tuple[7], column_size + 2); /* sign+dec.point */ - set_nullfield_int2(&row->tuple[8], decimal_digits); -#if (ODBCVER >= 0x0300) - set_tuplefield_null(&row->tuple[15]); -#endif /* ODBCVER */ - set_tuplefield_int4(&row->tuple[reserved_cols], column_size + 2); /* sign+dec.point */ - } - } - - if ((field_type == PG_TYPE_VARCHAR) || - (field_type == PG_TYPE_BPCHAR)) - { - useStaticPrecision = FALSE; - - if (mod_length >= 4) - mod_length -= 4; /* the length is in atttypmod - 4 */ - - if (mod_length > ci->drivers.max_varchar_size || mod_length <= 0) - mod_length = ci->drivers.max_varchar_size; - - mylog("%s: field type is VARCHAR,BPCHAR: field_type = %d, mod_length = %d\n", func, field_type, mod_length); - - set_tuplefield_int4(&row->tuple[6], mod_length); - set_tuplefield_int4(&row->tuple[7], mod_length); - set_nullfield_int2(&row->tuple[8], pgtype_decimal_digits(stmt, field_type, PG_STATIC)); -#if (ODBCVER >= 0x0300) - set_tuplefield_int4(&row->tuple[15], pgtype_transfer_octet_length(stmt, field_type, PG_STATIC, PG_STATIC)); -#endif /* ODBCVER */ - set_tuplefield_int4(&row->tuple[reserved_cols], mod_length); - } - - if (useStaticPrecision) - { - mylog("%s: field type is OTHER: field_type = %d, pgtype_length = %d\n", func, field_type, pgtype_buffer_length(stmt, field_type, PG_STATIC, PG_STATIC)); - - set_tuplefield_int4(&row->tuple[6], pgtype_column_size(stmt, field_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[7], pgtype_buffer_length(stmt, field_type, PG_STATIC, PG_STATIC)); - set_nullfield_int2(&row->tuple[8], pgtype_decimal_digits(stmt, field_type, PG_STATIC)); -#if (ODBCVER >= 0x0300) - set_tuplefield_null(&row->tuple[15]); -#endif /* ODBCVER */ - set_tuplefield_int4(&row->tuple[reserved_cols], pgtype_display_size(stmt, field_type, PG_STATIC, PG_STATIC)); - } - - set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, field_type)); - set_tuplefield_int2(&row->tuple[10], (Int2) (not_null[0] == '1' ? SQL_NO_NULLS : pgtype_nullable(stmt, field_type))); - set_tuplefield_string(&row->tuple[11], ""); -#if (ODBCVER >= 0x0300) - set_tuplefield_null(&row->tuple[12]); - set_tuplefield_int2(&row->tuple[13], pgtype_to_sqldesctype(stmt, field_type)); - set_nullfield_int2(&row->tuple[14], pgtype_to_datetime_sub(stmt, field_type)); - set_tuplefield_int4(&row->tuple[16], ordinal); - set_tuplefield_null(&row->tuple[17]); -#endif /* ODBCVER */ - set_tuplefield_int4(&row->tuple[reserved_cols + 1], field_type); - - QR_add_tuple(res, row); - ordinal++; - - result = PGAPI_Fetch(hcol_stmt); - - } - if (result != SQL_NO_DATA_FOUND) - { - stmt->errormsg = SC_create_errormsg(hcol_stmt); - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - /* - * Put the row version column at the end so it might not be mistaken - * for a key field. - */ - if (relhasrules[0] != '1' && !stmt->internal && atoi(ci->row_versioning)) - { - /* For Row Versioning fields */ - the_type = PG_TYPE_INT4; - - row = (TupleNode *) malloc(sizeof(TupleNode) + - (result_cols - 1) *sizeof(TupleField)); - - set_tuplefield_string(&row->tuple[0], ""); - if (conn->schema_support) - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(table_owner)); - else - set_tuplefield_string(&row->tuple[1], ""); - set_tuplefield_string(&row->tuple[2], table_name); - set_tuplefield_string(&row->tuple[3], "xmin"); - sqltype = pgtype_to_concise_type(stmt, the_type); - set_tuplefield_int2(&row->tuple[4], sqltype); - set_tuplefield_string(&row->tuple[5], pgtype_to_name(stmt, the_type)); - set_tuplefield_int4(&row->tuple[6], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[7], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC)); - set_nullfield_int2(&row->tuple[8], pgtype_decimal_digits(stmt, the_type, PG_STATIC)); - set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type)); - set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS); - set_tuplefield_string(&row->tuple[11], ""); -#if (ODBCVER >= 0x0300) - set_tuplefield_null(&row->tuple[12]); - set_tuplefield_int2(&row->tuple[13], sqltype); - set_tuplefield_null(&row->tuple[14]); - set_tuplefield_int4(&row->tuple[15], pgtype_transfer_octet_length(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[16], ordinal); - set_tuplefield_string(&row->tuple[17], "No"); -#endif /* ODBCVER */ - set_tuplefield_int4(&row->tuple[reserved_cols], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[reserved_cols + 1], the_type); - - QR_add_tuple(res, row); - ordinal++; - } - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - mylog("%s: EXIT, stmt=%u\n", func, stmt); - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_SpecialColumns( - HSTMT hstmt, - UWORD fColType, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UWORD fScope, - UWORD fNullable) -{ - static char *func = "PGAPI_SpecialColumns"; - TupleNode *row; - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn; - QResultClass *res; - ConnInfo *ci; - HSTMT hcol_stmt; - StatementClass *col_stmt; - char columns_query[INFO_INQUIRY_LEN]; - RETCODE result; - char relhasrules[MAX_INFO_STRING]; - - mylog("%s: entering...stmt=%u scnm=%x len=%d colType=%d\n", func, stmt, szTableOwner, cbTableOwner, fColType); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - stmt->manual_result = TRUE; - - /* - * Create the query to find out if this is a view or not... - */ - if (conn->schema_support) - sprintf(columns_query, "select c.relhasrules " - "from pg_namespace u, pg_class c where " - "u.oid = c.relnamespace"); - else - sprintf(columns_query, "select c.relhasrules " - "from pg_user u, pg_class c where " - "u.usesysid = c.relowner"); - - /* TableName cannot contain a string search pattern */ - my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); - /* SchemaName cannot contain a string search pattern */ - if (conn->schema_support) - schema_strcat(columns_query, " and u.nspname = '%.*s'", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - else - my_strcat(columns_query, " and u.usename = '%.*s'", szTableOwner, cbTableOwner); - - - result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for SQLSpecialColumns result."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - col_stmt = (StatementClass *) hcol_stmt; - - mylog("%s: hcol_stmt = %u, col_stmt = %u\n", func, hcol_stmt, col_stmt); - - result = PGAPI_ExecDirect(hcol_stmt, columns_query, - strlen(columns_query)); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = SC_create_errormsg(hcol_stmt); - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(hcol_stmt, 1, SQL_C_CHAR, - relhasrules, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_Fetch(hcol_stmt); - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - - res = QR_Constructor(); - SC_set_Result(stmt, res); - extend_column_bindings(SC_get_ARD(stmt), 8); - - QR_set_num_fields(res, 8); - QR_set_field_info(res, 0, "SCOPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 1, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "DATA_TYPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 3, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "PRECISION", PG_TYPE_INT4, 4); - QR_set_field_info(res, 5, "LENGTH", PG_TYPE_INT4, 4); - QR_set_field_info(res, 6, "SCALE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 7, "PSEUDO_COLUMN", PG_TYPE_INT2, 2); - - if (relhasrules[0] != '1') - { - /* use the oid value for the rowid */ - if (fColType == SQL_BEST_ROWID) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (8 - 1) *sizeof(TupleField)); - - set_tuplefield_int2(&row->tuple[0], SQL_SCOPE_SESSION); - set_tuplefield_string(&row->tuple[1], "oid"); - set_tuplefield_int2(&row->tuple[2], pgtype_to_concise_type(stmt, PG_TYPE_OID)); - set_tuplefield_string(&row->tuple[3], "OID"); - set_tuplefield_int4(&row->tuple[4], pgtype_column_size(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[5], pgtype_buffer_length(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC)); - set_tuplefield_int2(&row->tuple[6], pgtype_decimal_digits(stmt, PG_TYPE_OID, PG_STATIC)); - set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO); - - QR_add_tuple(res, row); - - } - else if (fColType == SQL_ROWVER) - { - Int2 the_type = PG_TYPE_INT4; - - if (atoi(ci->row_versioning)) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (8 - 1) *sizeof(TupleField)); - - set_tuplefield_null(&row->tuple[0]); - set_tuplefield_string(&row->tuple[1], "xmin"); - set_tuplefield_int2(&row->tuple[2], pgtype_to_concise_type(stmt, the_type)); - set_tuplefield_string(&row->tuple[3], pgtype_to_name(stmt, the_type)); - set_tuplefield_int4(&row->tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int2(&row->tuple[6], pgtype_decimal_digits(stmt, the_type, PG_STATIC)); - set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO); - - QR_add_tuple(res, row); - } - } - } - else - { - /* use the oid value for the rowid */ - if (fColType == SQL_BEST_ROWID) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (8 - 1) *sizeof(TupleField)); - - set_tuplefield_int2(&row->tuple[0], SQL_SCOPE_SESSION); - set_tuplefield_string(&row->tuple[1], "oid"); - set_tuplefield_int2(&row->tuple[2], pgtype_to_concise_type(stmt, PG_TYPE_OID)); - set_tuplefield_string(&row->tuple[3], "OID"); - set_tuplefield_int4(&row->tuple[4], pgtype_column_size(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[5], pgtype_buffer_length(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC)); - set_tuplefield_int2(&row->tuple[6], pgtype_decimal_digits(stmt, PG_TYPE_OID, PG_STATIC)); - set_tuplefield_int2(&row->tuple[7], SQL_PC_NOT_PSEUDO); - - QR_add_tuple(res, row); - - } - else if (fColType == SQL_ROWVER) - { - Int2 the_type = PG_TYPE_TID; - - row = (TupleNode *) malloc(sizeof(TupleNode) + (8 - 1) *sizeof(TupleField)); - - set_tuplefield_null(&row->tuple[0]); - set_tuplefield_string(&row->tuple[1], "ctid"); - set_tuplefield_int2(&row->tuple[2], pgtype_to_concise_type(stmt, the_type)); - set_tuplefield_string(&row->tuple[3], pgtype_to_name(stmt, the_type)); - set_tuplefield_int4(&row->tuple[4], pgtype_column_size(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int4(&row->tuple[5], pgtype_buffer_length(stmt, the_type, PG_STATIC, PG_STATIC)); - set_tuplefield_int2(&row->tuple[6], pgtype_decimal_digits(stmt, the_type, PG_STATIC)); - set_tuplefield_int2(&row->tuple[7], SQL_PC_NOT_PSEUDO); - - QR_add_tuple(res, row); - } - } - - stmt->status = STMT_FINISHED; - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - mylog("%s: EXIT, stmt=%u\n", func, stmt); - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_Statistics( - HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UWORD fUnique, - UWORD fAccuracy) -{ - static char *func = "PGAPI_Statistics"; - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn; - QResultClass *res; - char index_query[INFO_INQUIRY_LEN]; - HSTMT hindx_stmt; - RETCODE result; - char *table_name; - char index_name[MAX_INFO_STRING]; - short fields_vector[16]; - char isunique[10], - isclustered[10], - ishash[MAX_INFO_STRING]; - SDWORD index_name_len, - fields_vector_len; - TupleNode *row; - int i; - HSTMT hcol_stmt; - StatementClass *col_stmt, - *indx_stmt; - char column_name[MAX_INFO_STRING], - table_qualifier[MAX_INFO_STRING], - relhasrules[10]; - char **column_names = 0; - SQLINTEGER column_name_len; - int total_columns = 0; - char error = TRUE; - ConnInfo *ci; - char buf[256]; - - mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - stmt->manual_result = TRUE; - stmt->errormsg_created = TRUE; - - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - if (res = QR_Constructor(), !res) - { - stmt->errormsg = "Couldn't allocate memory for PGAPI_Statistics result."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - SC_set_Result(stmt, res); - - /* the binding structure for a statement is not set up until */ - - /* - * a statement is actually executed, so we'll have to do this - * ourselves. - */ - extend_column_bindings(SC_get_ARD(stmt), 13); - - /* set the field names */ - QR_set_num_fields(res, 13); - QR_set_field_info(res, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 3, "NON_UNIQUE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 4, "INDEX_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 5, "INDEX_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 6, "TYPE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 7, "SEQ_IN_INDEX", PG_TYPE_INT2, 2); - QR_set_field_info(res, 8, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 9, "COLLATION", PG_TYPE_CHAR, 1); - QR_set_field_info(res, 10, "CARDINALITY", PG_TYPE_INT4, 4); - QR_set_field_info(res, 11, "PAGES", PG_TYPE_INT4, 4); - QR_set_field_info(res, 12, "FILTER_CONDITION", PG_TYPE_TEXT, MAX_INFO_STRING); - - /* - * only use the table name... the owner should be redundant, and we - * never use qualifiers. - */ - table_name = make_string(szTableName, cbTableName, NULL); - if (!table_name) - { - stmt->errormsg = "No table name passed to PGAPI_Statistics."; - stmt->errornumber = STMT_INTERNAL_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - table_qualifier[0] = '\0'; - if (conn->schema_support) - schema_strcat(table_qualifier, "%.*s", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - - /* - * we need to get a list of the field names first, so we can return - * them later. - */ - result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = "PGAPI_AllocStmt failed in PGAPI_Statistics for columns."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - goto SEEYA; - } - - col_stmt = (StatementClass *) hcol_stmt; - - /* - * "internal" prevents SQLColumns from returning the oid if it is - * being shown. This would throw everything off. - */ - col_stmt->internal = TRUE; - /* - * table_name parameter cannot contain a string search pattern. - */ - result = PGAPI_Columns(hcol_stmt, "", 0, table_qualifier, SQL_NTS, - table_name, SQL_NTS, "", 0, PODBC_NOT_SEARCH_PATTERN); - col_stmt->internal = FALSE; - - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; /* "SQLColumns failed in - * SQLStatistics."; */ - stmt->errornumber = col_stmt->errornumber; /* STMT_EXEC_ERROR; */ - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - goto SEEYA; - } - result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_CHAR, - column_name, sizeof(column_name), &column_name_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = col_stmt->errormsg; - stmt->errornumber = col_stmt->errornumber; - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - goto SEEYA; - - } - - result = PGAPI_Fetch(hcol_stmt); - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) - { - total_columns++; - - column_names = - (char **) realloc(column_names, - total_columns * sizeof(char *)); - column_names[total_columns - 1] = - (char *) malloc(strlen(column_name) + 1); - strcpy(column_names[total_columns - 1], column_name); - - mylog("%s: column_name = '%s'\n", func, column_name); - - result = PGAPI_Fetch(hcol_stmt); - } - - if (result != SQL_NO_DATA_FOUND || total_columns == 0) - { - stmt->errormsg = SC_create_errormsg(hcol_stmt); /* "Couldn't get column - * names in - * SQLStatistics."; */ - stmt->errornumber = col_stmt->errornumber; - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - goto SEEYA; - - } - - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - - /* get a list of indexes on this table */ - result = PGAPI_AllocStmt(stmt->hdbc, &hindx_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = "PGAPI_AllocStmt failed in SQLStatistics for indices."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - goto SEEYA; - - } - indx_stmt = (StatementClass *) hindx_stmt; - - if (conn->schema_support) - sprintf(index_query, "select c.relname, i.indkey, i.indisunique" - ", i.indisclustered, a.amname, c.relhasrules, n.nspname" - " from pg_index i, pg_class c, pg_class d, pg_am a, pg_namespace n" - " where d.relname = '%s'" - " and n.nspname = '%s'" - " and n.oid = d.relnamespace" - " and d.oid = i.indrelid" - " and i.indexrelid = c.oid" - " and c.relam = a.oid order by" - ,table_name, table_qualifier); - else - sprintf(index_query, "select c.relname, i.indkey, i.indisunique" - ", i.indisclustered, a.amname, c.relhasrules" - " from pg_index i, pg_class c, pg_class d, pg_am a" - " where d.relname = '%s'" - " and d.oid = i.indrelid" - " and i.indexrelid = c.oid" - " and c.relam = a.oid order by" - ,table_name); - if (PG_VERSION_GT(SC_get_conn(stmt), 6.4)) - strcat(index_query, " i.indisprimary desc,"); - if (conn->schema_support) - strcat(index_query, " i.indisunique, n.nspname, c.relname"); - else - strcat(index_query, " i.indisunique, c.relname"); - - result = PGAPI_ExecDirect(hindx_stmt, index_query, strlen(index_query)); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - /* - * "Couldn't execute index query (w/SQLExecDirect) in - * SQLStatistics."; - */ - stmt->errormsg = SC_create_errormsg(hindx_stmt); - - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - } - - /* bind the index name column */ - result = PGAPI_BindCol(hindx_stmt, 1, SQL_C_CHAR, - index_name, MAX_INFO_STRING, &index_name_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column - * in SQLStatistics."; */ - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - - } - /* bind the vector column */ - result = PGAPI_BindCol(hindx_stmt, 2, SQL_C_DEFAULT, - fields_vector, 32, &fields_vector_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column - * in SQLStatistics."; */ - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - - } - /* bind the "is unique" column */ - result = PGAPI_BindCol(hindx_stmt, 3, SQL_C_CHAR, - isunique, sizeof(isunique), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column - * in SQLStatistics."; */ - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - } - - /* bind the "is clustered" column */ - result = PGAPI_BindCol(hindx_stmt, 4, SQL_C_CHAR, - isclustered, sizeof(isclustered), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column - * in SQLStatistics."; */ - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - - } - - /* bind the "is hash" column */ - result = PGAPI_BindCol(hindx_stmt, 5, SQL_C_CHAR, - ishash, sizeof(ishash), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column - * in SQLStatistics."; */ - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - - } - - result = PGAPI_BindCol(hindx_stmt, 6, SQL_C_CHAR, - relhasrules, sizeof(relhasrules), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = indx_stmt->errormsg; - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - } - - /* fake index of OID */ - if (relhasrules[0] != '1' && atoi(ci->show_oid_column) && atoi(ci->fake_oid_index)) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + - (13 - 1) *sizeof(TupleField)); - - /* no table qualifier */ - set_tuplefield_string(&row->tuple[0], ""); - /* don't set the table owner, else Access tries to use it */ - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(table_qualifier)); - set_tuplefield_string(&row->tuple[2], table_name); - - /* non-unique index? */ - set_tuplefield_int2(&row->tuple[3], (Int2) (ci->drivers.unique_index ? FALSE : TRUE)); - - /* no index qualifier */ - set_tuplefield_string(&row->tuple[4], ""); - - sprintf(buf, "%s_idx_fake_oid", table_name); - set_tuplefield_string(&row->tuple[5], buf); - - /* - * Clustered/HASH index? - */ - set_tuplefield_int2(&row->tuple[6], (Int2) SQL_INDEX_OTHER); - set_tuplefield_int2(&row->tuple[7], (Int2) 1); - - set_tuplefield_string(&row->tuple[8], "oid"); - set_tuplefield_string(&row->tuple[9], "A"); - set_tuplefield_null(&row->tuple[10]); - set_tuplefield_null(&row->tuple[11]); - set_tuplefield_null(&row->tuple[12]); - - QR_add_tuple(res, row); - } - - result = PGAPI_Fetch(hindx_stmt); - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) - { - /* If only requesting unique indexs, then just return those. */ - if (fUnique == SQL_INDEX_ALL || - (fUnique == SQL_INDEX_UNIQUE && atoi(isunique))) - { - i = 0; - /* add a row in this table for each field in the index */ - while (i < 16 && fields_vector[i] != 0) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + - (13 - 1) *sizeof(TupleField)); - - /* no table qualifier */ - set_tuplefield_string(&row->tuple[0], ""); - /* don't set the table owner, else Access tries to use it */ - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(table_qualifier)); - set_tuplefield_string(&row->tuple[2], table_name); - - /* non-unique index? */ - if (ci->drivers.unique_index) - set_tuplefield_int2(&row->tuple[3], (Int2) (atoi(isunique) ? FALSE : TRUE)); - else - set_tuplefield_int2(&row->tuple[3], TRUE); - - /* no index qualifier */ - set_tuplefield_string(&row->tuple[4], ""); - set_tuplefield_string(&row->tuple[5], index_name); - - /* - * Clustered/HASH index? - */ - set_tuplefield_int2(&row->tuple[6], (Int2) - (atoi(isclustered) ? SQL_INDEX_CLUSTERED : - (!strncmp(ishash, "hash", 4)) ? SQL_INDEX_HASHED : SQL_INDEX_OTHER)); - set_tuplefield_int2(&row->tuple[7], (Int2) (i + 1)); - - if (fields_vector[i] == OID_ATTNUM) - { - set_tuplefield_string(&row->tuple[8], "oid"); - mylog("%s: column name = oid\n", func); - } - else if (fields_vector[i] < 0 || fields_vector[i] > total_columns) - { - set_tuplefield_string(&row->tuple[8], "UNKNOWN"); - mylog("%s: column name = UNKNOWN\n", func); - } - else - { - set_tuplefield_string(&row->tuple[8], column_names[fields_vector[i] - 1]); - mylog("%s: column name = '%s'\n", func, column_names[fields_vector[i] - 1]); - } - - set_tuplefield_string(&row->tuple[9], "A"); - set_tuplefield_null(&row->tuple[10]); - set_tuplefield_null(&row->tuple[11]); - set_tuplefield_null(&row->tuple[12]); - - QR_add_tuple(res, row); - i++; - } - } - - result = PGAPI_Fetch(hindx_stmt); - } - if (result != SQL_NO_DATA_FOUND) - { - /* "SQLFetch failed in SQLStatistics."; */ - stmt->errormsg = SC_create_errormsg(hindx_stmt); - stmt->errornumber = indx_stmt->errornumber; - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - goto SEEYA; - } - - PGAPI_FreeStmt(hindx_stmt, SQL_DROP); - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - error = FALSE; - -SEEYA: - /* These things should be freed on any error ALSO! */ - free(table_name); - for (i = 0; i < total_columns; i++) - free(column_names[i]); - free(column_names); - - mylog("%s: EXIT, %s, stmt=%u\n", func, error ? "error" : "success", stmt); - - if (error) - { - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - else - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_ColumnPrivileges( - HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UCHAR FAR * szColumnName, - SWORD cbColumnName) -{ - static char *func = "PGAPI_ColumnPrivileges"; - StatementClass *stmt = (StatementClass *) hstmt; - - mylog("%s: entering...\n", func); - - /* Neither Access or Borland care about this. */ - - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "not implemented"; - SC_log_error(func, "Function not implemented", stmt); - return SQL_ERROR; -} - - -/* - * SQLPrimaryKeys() - * - * Retrieve the primary key columns for the specified table. - */ -RETCODE SQL_API -PGAPI_PrimaryKeys( - HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName) -{ - static char *func = "PGAPI_PrimaryKeys"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - ConnectionClass *conn; - TupleNode *row; - RETCODE result; - int seq = 0; - HSTMT htbl_stmt; - StatementClass *tbl_stmt; - char tables_query[INFO_INQUIRY_LEN]; - char attname[MAX_INFO_STRING]; - SDWORD attname_len; - char pktab[MAX_TABLE_LEN + 1], pkscm[MAX_TABLE_LEN + 1]; - Int2 result_cols; - int qno, - qstart, - qend; - - mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - stmt->manual_result = TRUE; - stmt->errormsg_created = TRUE; - - if (res = QR_Constructor(), !res) - { - stmt->errormsg = "Couldn't allocate memory for PGAPI_PrimaryKeys result."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - SC_set_Result(stmt, res); - - /* the binding structure for a statement is not set up until */ - - /* - * a statement is actually executed, so we'll have to do this - * ourselves. - */ - result_cols = 6; - extend_column_bindings(SC_get_ARD(stmt), result_cols); - - /* set the field names */ - QR_set_num_fields(res, result_cols); - QR_set_field_info(res, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "KEY_SEQ", PG_TYPE_INT2, 2); - QR_set_field_info(res, 5, "PK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - - - result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for Primary Key result."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - tbl_stmt = (StatementClass *) htbl_stmt; - - conn = SC_get_conn(stmt); - pktab[0] = '\0'; - make_string(szTableName, cbTableName, pktab); - if (pktab[0] == '\0') - { - stmt->errormsg = "No Table specified to PGAPI_PrimaryKeys."; - stmt->errornumber = STMT_INTERNAL_ERROR; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - pkscm[0] = '\0'; - if (conn->schema_support) - schema_strcat(pkscm, "%.*s", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - - result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_CHAR, - attname, MAX_INFO_STRING, &attname_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - if (PG_VERSION_LE(conn, 6.4)) - qstart = 2; - else - qstart = 1; - qend = 2; - for (qno = qstart; qno <= qend; qno++) - { - switch (qno) - { - case 1: - - /* - * Simplified query to remove assumptions about number of - * possible index columns. Courtesy of Tom Lane - thomas - * 2000-03-21 - */ - if (conn->schema_support) - sprintf(tables_query, "select ta.attname, ia.attnum" - " from pg_attribute ta, pg_attribute ia, pg_class c, pg_index i, pg_namespace n" - " where c.relname = '%s'" - " AND n.nspname = '%s'" - " AND c.oid = i.indrelid" - " AND n.oid = c.relnamespace" - " AND i.indisprimary = 't'" - " AND ia.attrelid = i.indexrelid" - " AND ta.attrelid = i.indrelid" - " AND ta.attnum = i.indkey[ia.attnum-1]" - " order by ia.attnum", pktab, pkscm); - else - sprintf(tables_query, "select ta.attname, ia.attnum" - " from pg_attribute ta, pg_attribute ia, pg_class c, pg_index i" - " where c.relname = '%s'" - " AND c.oid = i.indrelid" - " AND i.indisprimary = 't'" - " AND ia.attrelid = i.indexrelid" - " AND ta.attrelid = i.indrelid" - " AND ta.attnum = i.indkey[ia.attnum-1]" - " order by ia.attnum", pktab); - break; - case 2: - - /* - * Simplified query to search old fashoned primary key - */ - if (conn->schema_support) - sprintf(tables_query, "select ta.attname, ia.attnum" - " from pg_attribute ta, pg_attribute ia, pg_class c, pg_index i, pg_namespace n" - " where c.relname = '%s_pkey'" - " AND n.nspname = '%s'" - " AND c.oid = i.indexrelid" - " AND n.oid = c.relnamespace" - " AND ia.attrelid = i.indexrelid" - " AND ta.attrelid = i.indrelid" - " AND ta.attnum = i.indkey[ia.attnum-1]" - " order by ia.attnum", pktab, pkscm); - else - sprintf(tables_query, "select ta.attname, ia.attnum" - " from pg_attribute ta, pg_attribute ia, pg_class c, pg_index i" - " where c.relname = '%s_pkey'" - " AND c.oid = i.indexrelid" - " AND ia.attrelid = i.indexrelid" - " AND ta.attrelid = i.indrelid" - " AND ta.attnum = i.indkey[ia.attnum-1]" - " order by ia.attnum", pktab); - break; - } - mylog("%s: tables_query='%s'\n", func, tables_query); - - result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_Fetch(htbl_stmt); - if (result != SQL_NO_DATA_FOUND) - break; - } - - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField)); - - set_tuplefield_null(&row->tuple[0]); - - /* - * I have to hide the table owner from Access, otherwise it - * insists on referring to the table as 'owner.table'. (this is - * valid according to the ODBC SQL grammar, but Postgres won't - * support it.) - */ - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(pkscm)); - set_tuplefield_string(&row->tuple[2], pktab); - set_tuplefield_string(&row->tuple[3], attname); - set_tuplefield_int2(&row->tuple[4], (Int2) (++seq)); - set_tuplefield_null(&row->tuple[5]); - - QR_add_tuple(res, row); - - mylog(">> primaryKeys: pktab = '%s', attname = '%s', seq = %d\n", pktab, attname, seq); - - result = PGAPI_Fetch(htbl_stmt); - } - - if (result != SQL_NO_DATA_FOUND) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - mylog("%s: EXIT, stmt=%u\n", func, stmt); - return SQL_SUCCESS; -} - - -#ifdef MULTIBYTE -/* - * Multibyte support stuff for SQLForeignKeys(). - * There may be much more effective way in the - * future version. The way is very forcible currently. - */ -static BOOL -isMultibyte(const unsigned char *str) -{ - for (; *str; str++) - { - if (*str >= 0x80) - return TRUE; - } - return FALSE; -} -#ifdef NOT_USED -static char * -getClientTableName(ConnectionClass *conn, const char *serverSchemaName, char *serverTableName, BOOL *nameAlloced) -{ - char query[1024], - saveoid[24], - *ret = serverTableName; - BOOL continueExec = TRUE, - bError = FALSE; - QResultClass *res; - - *nameAlloced = FALSE; - if (!conn->client_encoding || !isMultibyte(serverTableName)) - return ret; - if (!conn->server_encoding) - { - if (res = CC_send_query(conn, "select getdatabaseencoding()", NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_tuples(res) > 0) - conn->server_encoding = strdup(QR_get_value_backend_row(res, 0, 0)); - QR_Destructor(res); - } - } - if (!conn->server_encoding) - return ret; - sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->server_encoding); - bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); - if (!bError && continueExec) - { - if (conn->schema_support) - sprintf(query, "select OID from pg_class where relname = '%s' and pg_namespace.oid = relnamespace and pg_namespace.nspname = '%s'", serverTableName, serverSchemaName); - else - sprintf(query, "select OID from pg_class where relname = '%s'", serverTableName); - if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_tuples(res) > 0) - strcpy(saveoid, QR_get_value_backend_row(res, 0, 0)); - else - continueExec = FALSE; - QR_Destructor(res); - } - else - bError = TRUE; - } - continueExec = (continueExec && !bError); - if (bError && CC_is_in_trans(conn)) - { - CC_abort(conn); - bError = FALSE; - } - /* restore the client encoding */ - sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->client_encoding); - bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); - if (bError || !continueExec) - return ret; - sprintf(query, "select relname from pg_class where OID = %s", saveoid); - if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_tuples(res) > 0) - { - ret = strdup(QR_get_value_backend_row(res, 0, 0)); - *nameAlloced = TRUE; - } - QR_Destructor(res); - } - return ret; -} -static char * -getClientColumnName(ConnectionClass *conn, const char * serverSchemaName, const char *serverTableName, char *serverColumnName, BOOL *nameAlloced) -{ - char query[1024], - saveattrelid[24], - saveattnum[16], - *ret = serverColumnName; - BOOL continueExec = TRUE, - bError = FALSE; - QResultClass *res; - - *nameAlloced = FALSE; - if (!conn->client_encoding || !isMultibyte(serverColumnName)) - return ret; - if (!conn->server_encoding) - { - if (res = CC_send_query(conn, "select getdatabaseencoding()", NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_tuples(res) > 0) - conn->server_encoding = strdup(QR_get_value_backend_row(res, 0, 0)); - QR_Destructor(res); - } - } - if (!conn->server_encoding) - return ret; - sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->server_encoding); - bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); - if (!bError && continueExec) - { - if (conn->schema_support) - sprintf(query, "select attrelid, attnum from pg_class, pg_attribute " - "where relname = '%s' and attrelid = pg_class.oid " - "and attname = '%s' and pg_namespace.oid = relnamespace and pg_namespace.nspname = '%s'", serverTableName, serverColumnName, serverSchemaName); - else - sprintf(query, "select attrelid, attnum from pg_class, pg_attribute " - "where relname = '%s' and attrelid = pg_class.oid " - "and attname = '%s'", serverTableName, serverColumnName); - if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_tuples(res) > 0) - { - strcpy(saveattrelid, QR_get_value_backend_row(res, 0, 0)); - strcpy(saveattnum, QR_get_value_backend_row(res, 0, 1)); - } - else - continueExec = FALSE; - QR_Destructor(res); - } - else - bError = TRUE; - } - continueExec = (continueExec && !bError); - if (bError && CC_is_in_trans(conn)) - { - CC_abort(conn); - bError = FALSE; - } - /* restore the cleint encoding */ - sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->client_encoding); - bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); - if (bError || !continueExec) - return ret; - sprintf(query, "select attname from pg_attribute where attrelid = %s and attnum = %s", saveattrelid, saveattnum); - if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_tuples(res) > 0) - { - ret = strdup(QR_get_value_backend_row(res, 0, 0)); - *nameAlloced = TRUE; - } - QR_Destructor(res); - } - return ret; -} -#endif /* NOT_USED */ -static char * -getClientColumnName(ConnectionClass *conn, UInt4 relid, char *serverColumnName, BOOL *nameAlloced) -{ - char query[1024], saveattnum[16], - *ret = serverColumnName; - BOOL continueExec = TRUE, - bError = FALSE; - QResultClass *res; - - *nameAlloced = FALSE; - if (!conn->client_encoding || !isMultibyte(serverColumnName)) - return ret; - if (!conn->server_encoding) - { - if (res = CC_send_query(conn, "select getdatabaseencoding()", NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_backend_tuples(res) > 0) - conn->server_encoding = strdup(QR_get_value_backend_row(res, 0, 0)); - QR_Destructor(res); - } - } - if (!conn->server_encoding) - return ret; - sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->server_encoding); - bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); - if (!bError && continueExec) - { - sprintf(query, "select attnum from pg_attribute " - "where attrelid = %u and attname = '%s'", - relid, serverColumnName); - if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_backend_tuples(res) > 0) - { - strcpy(saveattnum, QR_get_value_backend_row(res, 0, 0)); - } - else - continueExec = FALSE; - QR_Destructor(res); - } - else - bError = TRUE; - } - continueExec = (continueExec && !bError); - if (bError && CC_is_in_trans(conn)) - { - CC_abort(conn); - bError = FALSE; - } - /* restore the cleint encoding */ - sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->client_encoding); - bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); - if (bError || !continueExec) - return ret; - sprintf(query, "select attname from pg_attribute where attrelid = %u and attnum = %s", relid, saveattnum); - if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) - { - if (QR_get_num_backend_tuples(res) > 0) - { - ret = strdup(QR_get_value_backend_row(res, 0, 0)); - *nameAlloced = TRUE; - } - QR_Destructor(res); - } - return ret; -} -#endif /* MULTIBYTE */ - -RETCODE SQL_API -PGAPI_ForeignKeys( - HSTMT hstmt, - UCHAR FAR * szPkTableQualifier, - SWORD cbPkTableQualifier, - UCHAR FAR * szPkTableOwner, - SWORD cbPkTableOwner, - UCHAR FAR * szPkTableName, - SWORD cbPkTableName, - UCHAR FAR * szFkTableQualifier, - SWORD cbFkTableQualifier, - UCHAR FAR * szFkTableOwner, - SWORD cbFkTableOwner, - UCHAR FAR * szFkTableName, - SWORD cbFkTableName) -{ - static char *func = "PGAPI_ForeignKeys"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - TupleNode *row; - HSTMT htbl_stmt, - hpkey_stmt; - StatementClass *tbl_stmt; - RETCODE result, - keyresult; - char tables_query[INFO_INQUIRY_LEN]; - char trig_deferrable[2]; - char trig_initdeferred[2]; - char trig_args[1024]; - char upd_rule[MAX_TABLE_LEN], - del_rule[MAX_TABLE_LEN]; - char pk_table_needed[MAX_TABLE_LEN + 1]; -char fk_table_fetched[MAX_TABLE_LEN + 1]; - char fk_table_needed[MAX_TABLE_LEN + 1]; -char pk_table_fetched[MAX_TABLE_LEN + 1]; - char schema_needed[MAX_SCHEMA_LEN + 1]; -char schema_fetched[MAX_SCHEMA_LEN + 1]; - char *pkey_ptr, - *pkey_text, - *fkey_ptr, - *fkey_text; - - ConnectionClass *conn; -#ifdef MULTIBYTE - BOOL pkey_alloced, - fkey_alloced; -#endif /* MULTIBYTE */ - int i, - j, - k, - num_keys; - SWORD trig_nargs, - upd_rule_type = 0, - del_rule_type = 0; - -#if (ODBCVER >= 0x0300) - SWORD defer_type; -#endif - char pkey[MAX_INFO_STRING]; - Int2 result_cols; - UInt4 relid1, relid2; - - mylog("%s: entering...stmt=%u\n", func, stmt); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - stmt->manual_result = TRUE; - stmt->errormsg_created = TRUE; - - if (res = QR_Constructor(), !res) - { - stmt->errormsg = "Couldn't allocate memory for PGAPI_ForeignKeys result."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - SC_set_Result(stmt, res); - - /* the binding structure for a statement is not set up until */ - - /* - * a statement is actually executed, so we'll have to do this - * ourselves. - */ -#if (ODBCVER >= 0x0300) - result_cols = 15; -#else - result_cols = 14; -#endif /* ODBCVER */ - extend_column_bindings(SC_get_ARD(stmt), result_cols); - - /* set the field names */ - QR_set_num_fields(res, result_cols); - QR_set_field_info(res, 0, "PKTABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "PKTABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "PKTABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 3, "PKCOLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "FKTABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 5, "FKTABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 6, "FKTABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 7, "FKCOLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 8, "KEY_SEQ", PG_TYPE_INT2, 2); - QR_set_field_info(res, 9, "UPDATE_RULE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 10, "DELETE_RULE", PG_TYPE_INT2, 2); - QR_set_field_info(res, 11, "FK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 12, "PK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 13, "TRIGGER_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); -#if (ODBCVER >= 0x0300) - QR_set_field_info(res, 14, "DEFERRABILITY", PG_TYPE_INT2, 2); -#endif /* ODBCVER >= 0x0300 */ - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - - result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for PGAPI_ForeignKeys result."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - tbl_stmt = (StatementClass *) htbl_stmt; - - pk_table_needed[0] = '\0'; - fk_table_needed[0] = '\0'; - schema_needed[0] = '\0'; - schema_fetched[0] = '\0'; - - make_string(szPkTableName, cbPkTableName, pk_table_needed); - make_string(szFkTableName, cbFkTableName, fk_table_needed); - - conn = SC_get_conn(stmt); -#ifdef MULTIBYTE - pkey_text = fkey_text = NULL; - pkey_alloced = fkey_alloced = FALSE; -#endif /* MULTIBYTE */ - - /* - * Case #2 -- Get the foreign keys in the specified table (fktab) that - * refer to the primary keys of other table(s). - */ - if (fk_table_needed[0] != '\0') - { - mylog("%s: entering Foreign Key Case #2", func); - if (conn->schema_support) - { - schema_strcat(schema_needed, "%.*s", szFkTableOwner, cbFkTableOwner, szFkTableName, cbFkTableName, conn); - sprintf(tables_query, "SELECT pt.tgargs, " - " pt.tgnargs, " - " pt.tgdeferrable, " - " pt.tginitdeferred, " - " pp1.proname, " - " pp2.proname, " - " pc.oid, " - " pc1.oid, " - " pc1.relname, " - " pn.nspname " - "FROM pg_class pc, " - " pg_proc pp1, " - " pg_proc pp2, " - " pg_trigger pt1, " - " pg_trigger pt2, " - " pg_proc pp, " - " pg_trigger pt, " - " pg_class pc1, " - " pg_namespace pn " - "WHERE pt.tgrelid = pc.oid " - "AND pp.oid = pt.tgfoid " - "AND pt1.tgconstrrelid = pc.oid " - "AND pp1.oid = pt1.tgfoid " - "AND pt2.tgfoid = pp2.oid " - "AND pt2.tgconstrrelid = pc.oid " - "AND ((pc.relname='%s') " - "AND (pg_namespace.oid = pc.relnamespace) " - "AND (pg_namespace.nspname = '%s') " - "AND (pp.proname LIKE '%%ins') " - "AND (pp1.proname LIKE '%%upd') " - "AND (pp2.proname LIKE '%%del') " - "AND (pt1.tgrelid=pt.tgconstrrelid) " - "AND (pt1.tgconstrname=pt.tgconstrname) " - "AND (pt2.tgrelid=pt.tgconstrrelid) " - "AND (pt2.tgconstrname=pt.tgconstrname) " - "AND (pt.tgconstrrelid=pc1.oid) " - "AND (pc1.relnamespace=pn.oid))", - fk_table_needed, schema_needed); - } - else - sprintf(tables_query, "SELECT pt.tgargs, " - " pt.tgnargs, " - " pt.tgdeferrable, " - " pt.tginitdeferred, " - " pp1.proname, " - " pp2.proname, " - " pc.oid, " - " pc1.oid, " - " pc1.relname " - "FROM pg_class pc, " - " pg_proc pp1, " - " pg_proc pp2, " - " pg_trigger pt1, " - " pg_trigger pt2, " - " pg_proc pp, " - " pg_trigger pt, " - " pg_class pc1 " - "WHERE pt.tgrelid = pc.oid " - "AND pp.oid = pt.tgfoid " - "AND pt1.tgconstrrelid = pc.oid " - "AND pp1.oid = pt1.tgfoid " - "AND pt2.tgfoid = pp2.oid " - "AND pt2.tgconstrrelid = pc.oid " - "AND ((pc.relname='%s') " - "AND (pp.proname LIKE '%%ins') " - "AND (pp1.proname LIKE '%%upd') " - "AND (pp2.proname LIKE '%%del') " - "AND (pt1.tgrelid=pt.tgconstrrelid) " - "AND (pt1.tgconstrname=pt.tgconstrname) " - "AND (pt2.tgrelid=pt.tgconstrrelid) " - "AND (pt2.tgconstrname=pt.tgconstrname) " - "AND (pt.tgconstrrelid=pc1.oid)) ", - fk_table_needed); - - result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); - - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_BINARY, - trig_args, sizeof(trig_args), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_SHORT, - &trig_nargs, 0, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 3, SQL_C_CHAR, - trig_deferrable, sizeof(trig_deferrable), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 4, SQL_C_CHAR, - trig_initdeferred, sizeof(trig_initdeferred), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 5, SQL_C_CHAR, - upd_rule, sizeof(upd_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 6, SQL_C_CHAR, - del_rule, sizeof(del_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 7, SQL_C_ULONG, - &relid1, sizeof(relid1), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - result = PGAPI_BindCol(htbl_stmt, 8, SQL_C_ULONG, - &relid2, sizeof(relid2), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - result = PGAPI_BindCol(htbl_stmt, 9, SQL_C_CHAR, - pk_table_fetched, MAX_TABLE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - -if (conn->schema_support) -{ - result = PGAPI_BindCol(htbl_stmt, 10, SQL_C_CHAR, - schema_fetched, MAX_SCHEMA_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } -} - - result = PGAPI_Fetch(htbl_stmt); - if (result == SQL_NO_DATA_FOUND) - return SQL_SUCCESS; - - if (result != SQL_SUCCESS) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - keyresult = PGAPI_AllocStmt(stmt->hdbc, &hpkey_stmt); - if ((keyresult != SQL_SUCCESS) && (keyresult != SQL_SUCCESS_WITH_INFO)) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for PGAPI_ForeignKeys (pkeys) result."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - keyresult = PGAPI_BindCol(hpkey_stmt, 4, SQL_C_CHAR, - pkey, sizeof(pkey), NULL); - if (keyresult != SQL_SUCCESS) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't bindcol for primary keys for PGAPI_ForeignKeys result."; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hpkey_stmt, SQL_DROP); - return SQL_ERROR; - } - - while (result == SQL_SUCCESS) - { - /* Compute the number of keyparts. */ - num_keys = (trig_nargs - 4) / 2; - - mylog("Foreign Key Case#2: trig_nargs = %d, num_keys = %d\n", trig_nargs, num_keys); - - /* If there is a pk table specified, then check it. */ - if (pk_table_needed[0] != '\0') - { - /* If it doesn't match, then continue */ - if (strcmp(pk_table_fetched, pk_table_needed)) - { - result = PGAPI_Fetch(htbl_stmt); - continue; - } - } - - keyresult = PGAPI_PrimaryKeys(hpkey_stmt, NULL, 0, schema_fetched, SQL_NTS, pk_table_fetched, SQL_NTS); - if (keyresult != SQL_SUCCESS) - { - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't get primary keys for PGAPI_ForeignKeys result."; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(hpkey_stmt, SQL_DROP); - return SQL_ERROR; - } - - - /* Get to first primary key */ - pkey_ptr = trig_args; - for (i = 0; i < 5; i++) - pkey_ptr += strlen(pkey_ptr) + 1; - - for (k = 0; k < num_keys; k++) - { - /* Check that the key listed is the primary key */ - keyresult = PGAPI_Fetch(hpkey_stmt); - if (keyresult != SQL_SUCCESS) - { - num_keys = 0; - break; - } -#ifdef MULTIBYTE - pkey_text = getClientColumnName(conn, relid2, pkey_ptr, &pkey_alloced); -#else - pkey_text = pkey_ptr; -#endif /* MULTIBYTE */ - mylog("%s: pkey_ptr='%s', pkey='%s'\n", func, pkey_text, pkey); - if (strcmp(pkey_text, pkey)) - { - num_keys = 0; - break; - } -#ifdef MULTIBYTE - if (pkey_alloced) - free(pkey_text); -#endif /* MULTIBYTE */ - /* Get to next primary key */ - for (k = 0; k < 2; k++) - pkey_ptr += strlen(pkey_ptr) + 1; - - } - - /* Set to first fk column */ - fkey_ptr = trig_args; - for (k = 0; k < 4; k++) - fkey_ptr += strlen(fkey_ptr) + 1; - - /* Set update and delete actions for foreign keys */ - if (!strcmp(upd_rule, "RI_FKey_cascade_upd")) - upd_rule_type = SQL_CASCADE; - else if (!strcmp(upd_rule, "RI_FKey_noaction_upd")) - upd_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_restrict_upd")) - upd_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_setdefault_upd")) - upd_rule_type = SQL_SET_DEFAULT; - else if (!strcmp(upd_rule, "RI_FKey_setnull_upd")) - upd_rule_type = SQL_SET_NULL; - - if (!strcmp(upd_rule, "RI_FKey_cascade_del")) - del_rule_type = SQL_CASCADE; - else if (!strcmp(upd_rule, "RI_FKey_noaction_del")) - del_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_restrict_del")) - del_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_setdefault_del")) - del_rule_type = SQL_SET_DEFAULT; - else if (!strcmp(upd_rule, "RI_FKey_setnull_del")) - del_rule_type = SQL_SET_NULL; - -#if (ODBCVER >= 0x0300) - /* Set deferrability type */ - if (!strcmp(trig_initdeferred, "y")) - defer_type = SQL_INITIALLY_DEFERRED; - else if (!strcmp(trig_deferrable, "y")) - defer_type = SQL_INITIALLY_IMMEDIATE; - else - defer_type = SQL_NOT_DEFERRABLE; -#endif /* ODBCVER >= 0x0300 */ - - /* Get to first primary key */ - pkey_ptr = trig_args; - for (i = 0; i < 5; i++) - pkey_ptr += strlen(pkey_ptr) + 1; - - for (k = 0; k < num_keys; k++) - { - row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField)); - -#ifdef MULTIBYTE - pkey_text = getClientColumnName(conn, relid2, pkey_ptr, &pkey_alloced); - fkey_text = getClientColumnName(conn, relid1, fkey_ptr, &fkey_alloced); -#else - pkey_text = pkey_ptr; - fkey_text = fkey_ptr; -#endif /* MULTIBYTE */ - mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pk_table_fetched, pkey_text); - set_tuplefield_null(&row->tuple[0]); - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(schema_fetched)); - set_tuplefield_string(&row->tuple[2], pk_table_fetched); - set_tuplefield_string(&row->tuple[3], pkey_text); - - mylog("%s: fk_table_needed = '%s', fkey_ptr = '%s'\n", func, fk_table_needed, fkey_text); - set_tuplefield_null(&row->tuple[4]); - set_tuplefield_string(&row->tuple[5], GET_SCHEMA_NAME(schema_needed)); - set_tuplefield_string(&row->tuple[6], fk_table_needed); - set_tuplefield_string(&row->tuple[7], fkey_text); - - mylog("%s: upd_rule_type = '%i', del_rule_type = '%i'\n, trig_name = '%s'", func, upd_rule_type, del_rule_type, trig_args); - set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1)); - set_tuplefield_int2(&row->tuple[9], (Int2) upd_rule_type); - set_tuplefield_int2(&row->tuple[10], (Int2) del_rule_type); - set_tuplefield_null(&row->tuple[11]); - set_tuplefield_null(&row->tuple[12]); - set_tuplefield_string(&row->tuple[13], trig_args); -#if (ODBCVER >= 0x0300) - set_tuplefield_int2(&row->tuple[14], defer_type); -#endif /* ODBCVER >= 0x0300 */ - - QR_add_tuple(res, row); -#ifdef MULTIBYTE - if (fkey_alloced) - free(fkey_text); - fkey_alloced = FALSE; - if (pkey_alloced) - free(pkey_text); - pkey_alloced = FALSE; -#endif /* MULTIBYTE */ - /* next primary/foreign key */ - for (i = 0; i < 2; i++) - { - fkey_ptr += strlen(fkey_ptr) + 1; - pkey_ptr += strlen(pkey_ptr) + 1; - } - } - - result = PGAPI_Fetch(htbl_stmt); - } - PGAPI_FreeStmt(hpkey_stmt, SQL_DROP); - } - - /* - * Case #1 -- Get the foreign keys in other tables that refer to the - * primary key in the specified table (pktab). i.e., Who points to - * me? - */ - else if (pk_table_needed[0] != '\0') - { - if (conn->schema_support) - { - schema_strcat(schema_needed, "%.*s", szPkTableOwner, cbPkTableOwner, szPkTableName, cbPkTableName, conn); - sprintf(tables_query, "SELECT pt.tgargs, " - " pt.tgnargs, " - " pt.tgdeferrable, " - " pt.tginitdeferred, " - " pp.proname, " - " pp1.proname, " - " pc.oid, " - " pc1.oid, " - " pc1.relname, " - " pn.nspname " - "FROM pg_class pc, " - " pg_class pc1, " - " pg_class pc2, " - " pg_proc pp, " - " pg_proc pp1, " - " pg_trigger pt, " - " pg_trigger pt1, " - " pg_trigger pt2, " - " pg_namespace pn " - "WHERE pt.tgconstrrelid = pc.oid " - " AND pt.tgrelid = pc1.oid " - " AND pt1.tgfoid = pp1.oid " - " AND pt1.tgconstrrelid = pc1.oid " - " AND pt2.tgconstrrelid = pc2.oid " - " AND pt2.tgfoid = pp.oid " - " AND pc2.oid = pt.tgrelid " - " AND (" - " (pc.relname='%s') " - " AND (pg_namespace.oid = pc.relnamespace) " - " AND (pg_namespace.nspname = '%s') " - " AND (pp.proname Like '%%upd') " - " AND (pp1.proname Like '%%del')" - " AND (pt1.tgrelid = pt.tgconstrrelid) " - " AND (pt2.tgrelid = pt.tgconstrrelid) " - " AND (pn.oid = pc1.relnamespace) " - " )", - pk_table_needed, schema_needed); - } - else - sprintf(tables_query, "SELECT pt.tgargs, " - " pt.tgnargs, " - " pt.tgdeferrable, " - " pt.tginitdeferred, " - " pp.proname, " - " pp1.proname, " - " pc.oid, " - " pc1.oid, " - " pc1.relname " - "FROM pg_class pc, " - " pg_class pc1, " - " pg_class pc2, " - " pg_proc pp, " - " pg_proc pp1, " - " pg_trigger pt, " - " pg_trigger pt1, " - " pg_trigger pt2 " - "WHERE pt.tgconstrrelid = pc.oid " - " AND pt.tgrelid = pc1.oid " - " AND pt1.tgfoid = pp1.oid " - " AND pt1.tgconstrrelid = pc1.oid " - " AND pt2.tgconstrrelid = pc2.oid " - " AND pt2.tgfoid = pp.oid " - " AND pc2.oid = pt.tgrelid " - " AND (" - " (pc.relname='%s') " - " AND (pp.proname Like '%%upd') " - " AND (pp1.proname Like '%%del')" - " AND (pt1.tgrelid = pt.tgconstrrelid) " - " AND (pt2.tgrelid = pt.tgconstrrelid) " - " )", - pk_table_needed); - - result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_BINARY, - trig_args, sizeof(trig_args), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_SHORT, - &trig_nargs, 0, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 3, SQL_C_CHAR, - trig_deferrable, sizeof(trig_deferrable), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 4, SQL_C_CHAR, - trig_initdeferred, sizeof(trig_initdeferred), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 5, SQL_C_CHAR, - upd_rule, sizeof(upd_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 6, SQL_C_CHAR, - del_rule, sizeof(del_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - result = PGAPI_BindCol(htbl_stmt, 7, SQL_C_ULONG, - &relid1, sizeof(relid1), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - result = PGAPI_BindCol(htbl_stmt, 8, SQL_C_ULONG, - &relid2, sizeof(relid2), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - result = PGAPI_BindCol(htbl_stmt, 9, SQL_C_CHAR, - fk_table_fetched, MAX_TABLE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - -if (conn->schema_support) -{ - result = PGAPI_BindCol(htbl_stmt, 10, SQL_C_CHAR, - schema_fetched, MAX_SCHEMA_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = tbl_stmt->errormsg; - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } -} - - result = PGAPI_Fetch(htbl_stmt); - if (result == SQL_NO_DATA_FOUND) - return SQL_SUCCESS; - - if (result != SQL_SUCCESS) - { - stmt->errormsg = SC_create_errormsg(htbl_stmt); - stmt->errornumber = tbl_stmt->errornumber; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } - - while (result == SQL_SUCCESS) - { - /* Calculate the number of key parts */ - num_keys = (trig_nargs - 4) / 2;; - - /* Handle action (i.e., 'cascade', 'restrict', 'setnull') */ - if (!strcmp(upd_rule, "RI_FKey_cascade_upd")) - upd_rule_type = SQL_CASCADE; - else if (!strcmp(upd_rule, "RI_FKey_noaction_upd")) - upd_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_restrict_upd")) - upd_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_setdefault_upd")) - upd_rule_type = SQL_SET_DEFAULT; - else if (!strcmp(upd_rule, "RI_FKey_setnull_upd")) - upd_rule_type = SQL_SET_NULL; - - if (!strcmp(upd_rule, "RI_FKey_cascade_del")) - del_rule_type = SQL_CASCADE; - else if (!strcmp(upd_rule, "RI_FKey_noaction_del")) - del_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_restrict_del")) - del_rule_type = SQL_NO_ACTION; - else if (!strcmp(upd_rule, "RI_FKey_setdefault_del")) - del_rule_type = SQL_SET_DEFAULT; - else if (!strcmp(upd_rule, "RI_FKey_setnull_del")) - del_rule_type = SQL_SET_NULL; - -#if (ODBCVER >= 0x0300) - /* Set deferrability type */ - if (!strcmp(trig_initdeferred, "y")) - defer_type = SQL_INITIALLY_DEFERRED; - else if (!strcmp(trig_deferrable, "y")) - defer_type = SQL_INITIALLY_IMMEDIATE; - else - defer_type = SQL_NOT_DEFERRABLE; -#endif /* ODBCVER >= 0x0300 */ - - mylog("Foreign Key Case#1: trig_nargs = %d, num_keys = %d\n", trig_nargs, num_keys); - - /* Get to first primary key */ - pkey_ptr = trig_args; - for (i = 0; i < 5; i++) - pkey_ptr += strlen(pkey_ptr) + 1; - - /* Get to first foreign key */ - fkey_ptr = trig_args; - for (k = 0; k < 4; k++) - fkey_ptr += strlen(fkey_ptr) + 1; - - for (k = 0; k < num_keys; k++) - { -#ifdef MULTIBYTE - pkey_text = getClientColumnName(conn, relid1, pkey_ptr, &pkey_alloced); - fkey_text = getClientColumnName(conn, relid2, fkey_ptr, &fkey_alloced); -#else - pkey_text = pkey_ptr; - fkey_text = fkey_ptr; -#endif /* MULTIBYTE */ - mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_text, fk_table_fetched, fkey_text); - - row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField)); - - mylog("pk_table_needed = '%s', pkey_ptr = '%s'\n", pk_table_needed, pkey_text); - set_tuplefield_null(&row->tuple[0]); - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(schema_needed)); - set_tuplefield_string(&row->tuple[2], pk_table_needed); - set_tuplefield_string(&row->tuple[3], pkey_text); - - mylog("fk_table = '%s', fkey_ptr = '%s'\n", fk_table_fetched, fkey_text); - set_tuplefield_null(&row->tuple[4]); - set_tuplefield_string(&row->tuple[5], GET_SCHEMA_NAME(schema_fetched)); - set_tuplefield_string(&row->tuple[6], fk_table_fetched); - set_tuplefield_string(&row->tuple[7], fkey_text); - - set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1)); - - mylog("upd_rule = %d, del_rule= %d", upd_rule_type, del_rule_type); - set_nullfield_int2(&row->tuple[9], (Int2) upd_rule_type); - set_nullfield_int2(&row->tuple[10], (Int2) del_rule_type); - - set_tuplefield_null(&row->tuple[11]); - set_tuplefield_null(&row->tuple[12]); - - set_tuplefield_string(&row->tuple[13], trig_args); - -#if (ODBCVER >= 0x0300) - mylog(" defer_type = %d\n", defer_type); - set_tuplefield_int2(&row->tuple[14], defer_type); -#endif /* ODBCVER >= 0x0300 */ - - QR_add_tuple(res, row); -#ifdef MULTIBYTE - if (pkey_alloced) - free(pkey_text); - pkey_alloced = FALSE; - if (fkey_alloced) - free(fkey_text); - fkey_alloced = FALSE; -#endif /* MULTIBYTE */ - - /* next primary/foreign key */ - for (j = 0; j < 2; j++) - { - pkey_ptr += strlen(pkey_ptr) + 1; - fkey_ptr += strlen(fkey_ptr) + 1; - } - } - result = PGAPI_Fetch(htbl_stmt); - } - } - else - { - stmt->errormsg = "No tables specified to PGAPI_ForeignKeys."; - stmt->errornumber = STMT_INTERNAL_ERROR; - SC_log_error(func, "", stmt); - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - return SQL_ERROR; - } -#ifdef MULTIBYTE - if (pkey_alloced) - free(pkey_text); - if (fkey_alloced) - free(fkey_text); -#endif /* MULTIBYTE */ - - PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - - mylog("PGAPI_ForeignKeys(): EXIT, stmt=%u\n", stmt); - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_ProcedureColumns( - HSTMT hstmt, - UCHAR FAR * szProcQualifier, - SWORD cbProcQualifier, - UCHAR FAR * szProcOwner, - SWORD cbProcOwner, - UCHAR FAR * szProcName, - SWORD cbProcName, - UCHAR FAR * szColumnName, - SWORD cbColumnName) -{ - static char *func = "PGAPI_ProcedureColumns"; - StatementClass *stmt = (StatementClass *) hstmt; - - mylog("%s: entering...\n", func); - - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "not implemented"; - SC_log_error(func, "Function not implemented", stmt); - return SQL_ERROR; -} - - -RETCODE SQL_API -PGAPI_Procedures( - HSTMT hstmt, - UCHAR FAR * szProcQualifier, - SWORD cbProcQualifier, - UCHAR FAR * szProcOwner, - SWORD cbProcOwner, - UCHAR FAR * szProcName, - SWORD cbProcName) -{ - static char *func = "PGAPI_Procedures"; - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn = SC_get_conn(stmt); - char proc_query[INFO_INQUIRY_LEN]; - QResultClass *res; - - mylog("%s: entering... scnm=%x len=%d\n", func, szProcOwner, cbProcOwner); - - if (PG_VERSION_LT(conn, 6.5)) - { - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Version is too old"; - SC_log_error(func, "Function not implemented", stmt); - return SQL_ERROR; - } - if (!SC_recycle_statement(stmt)) - return SQL_ERROR; - - /* - * The following seems the simplest implementation - */ - if (conn->schema_support) - strcpy(proc_query, "select '' as " "PROCEDURE_CAT" ", nspname as " "PROCEDURE_SCHEM" "," - " proname as " "PROCEDURE_NAME" ", '' as " "NUM_INPUT_PARAMS" "," - " '' as " "NUM_OUTPUT_PARAMS" ", '' as " "NUM_RESULT_SETS" "," - " '' as " "REMARKS" "," - " case when prorettype = 0 then 1::int2 else 2::int2 end as " "PROCEDURE_TYPE" " from pg_namespace, pg_proc where"); - else - strcpy(proc_query, "select '' as " "PROCEDURE_CAT" ", '' as " "PROCEDURE_SCHEM" "," - " proname as " "PROCEDURE_NAME" ", '' as " "NUM_INPUT_PARAMS" "," - " '' as " "NUM_OUTPUT_PARAMS" ", '' as " "NUM_RESULT_SETS" "," - " '' as " "REMARKS" "," - " case when prorettype = 0 then 1::int2 else 2::int2 end as " "PROCEDURE_TYPE" " from pg_proc"); - if (conn->schema_support) - { - strcat(proc_query, " where pg_proc.pronamespace = pg_namespace.oid"); - schema_strcat(proc_query, " and nspname like '%.*s'", szProcOwner, cbProcOwner, szProcName, cbProcName, conn); - my_strcat(proc_query, " and proname like '%.*s'", szProcName, cbProcName); - } - else - my_strcat(proc_query, " where proname like '%.*s'", szProcName, cbProcName); - - if (res = CC_send_query(conn, proc_query, NULL, CLEAR_RESULT_ON_ABORT), !res) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "PGAPI_Procedures query error"; - return SQL_ERROR; - } - SC_set_Result(stmt, res); - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - extend_column_bindings(SC_get_ARD(stmt), 8); - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - - return SQL_SUCCESS; -} - - -#define ACLMAX 8 -#define ALL_PRIVILIGES "arwdRxt" -static int -usracl_auth(char *usracl, const char *auth) -{ - int i, j, addcnt = 0; - - for (i = 0; auth[i]; i++) - { - for (j = 0; j < ACLMAX; j++) - { - if (usracl[j] == auth[i]) - break; - else if (!usracl[j]) - { - usracl[j]= auth[i]; - addcnt++; - break; - } - } - } - return addcnt; -} -static void -useracl_upd(char (*useracl)[ACLMAX], QResultClass *allures, const char *user, const char *auth) -{ - int usercount = QR_get_num_backend_tuples(allures), i, addcnt = 0; - -mylog("user=%s auth=%s\n", user, auth); - if (user[0]) - for (i = 0; i < usercount; i++) - { - if (strcmp(QR_get_value_backend_row(allures, i, 0), user) == 0) - { - addcnt += usracl_auth(useracl[i], auth); - break; - } - } - else - for (i = 0; i < usercount; i++) - { - addcnt += usracl_auth(useracl[i], auth); - } - mylog("addcnt=%d\n", addcnt); -} - -RETCODE SQL_API -PGAPI_TablePrivileges( - HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UWORD flag) -{ - StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "PGAPI_TablePrivileges"; - ConnectionClass *conn = SC_get_conn(stmt); - Int2 result_cols; - char proc_query[INFO_INQUIRY_LEN]; - QResultClass *res, *allures = NULL; - TupleNode *row; - int tablecount, usercount, i, j, k; - BOOL grpauth, sys, su; - char (*useracl)[ACLMAX], *acl, *user, *delim, *auth; - char *reln, *owner, *priv, *schnm = NULL; - - mylog("%s: entering... scnm=%x len-%d\n", func, szTableOwner, cbTableOwner); - if (!SC_recycle_statement(stmt)) - return SQL_ERROR; - - /* - * a statement is actually executed, so we'll have to do this - * ourselves. - */ - result_cols = 7; - extend_column_bindings(SC_get_ARD(stmt), result_cols); - - /* set the field names */ - stmt->manual_result = TRUE; - res = QR_Constructor(); - SC_set_Result(stmt, res); - QR_set_num_fields(res, result_cols); - QR_set_field_info(res, 0, "TABLE_CAT", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 1, "TABLE_SCHEM", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 3, "GRANTOR", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 4, "GRANTEE", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 5, "PRIVILEGE", PG_TYPE_TEXT, MAX_INFO_STRING); - QR_set_field_info(res, 6, "IS_GRANTABLE", PG_TYPE_TEXT, MAX_INFO_STRING); - - /* - * also, things need to think that this statement is finished so the - * results can be retrieved. - */ - stmt->status = STMT_FINISHED; - /* set up the current tuple pointer for SQLFetch */ - stmt->currTuple = -1; - stmt->rowset_start = -1; - stmt->current_col = -1; - if (conn->schema_support) - strncpy_null(proc_query, "select relname, usename, relacl, nspname from pg_namespace, pg_class , pg_user where", sizeof(proc_query)); - else - strncpy_null(proc_query, "select relname, usename, relacl from pg_class , pg_user where", sizeof(proc_query)); - if ((flag & PODBC_NOT_SEARCH_PATTERN) != 0) - { - if (conn->schema_support) - { - schema_strcat(proc_query, " nspname = '%.*s' and", szTableOwner, cbTableOwner, szTableName, cbTableName, conn); - } - my_strcat(proc_query, " relname = '%.*s' and", szTableName, cbTableName); - } - else - { - char esc_table_name[MAX_TABLE_LEN * 2]; - int escTbnamelen; - - if (conn->schema_support) - { - escTbnamelen = reallyEscapeCatalogEscapes(szTableOwner, cbTableOwner, esc_table_name, sizeof(esc_table_name), conn->ccsc); - schema_strcat(proc_query, " nspname like '%.*s' and", esc_table_name, escTbnamelen, szTableName, cbTableName, conn); - } - escTbnamelen = reallyEscapeCatalogEscapes(szTableName, cbTableName, esc_table_name, sizeof(esc_table_name), conn->ccsc); - my_strcat(proc_query, " relname like '%.*s' and", esc_table_name, escTbnamelen); - } - if (conn->schema_support) - strcat(proc_query, " pg_namespace.oid = relnamespace and"); - strcat(proc_query, " pg_user.usesysid = relowner"); - if (res = CC_send_query(conn, proc_query, NULL, CLEAR_RESULT_ON_ABORT), !res) - { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "PGAPI_TablePrivileges query error"; - return SQL_ERROR; - } - strncpy_null(proc_query, "select usename, usesysid, usesuper from pg_user", sizeof(proc_query)); - tablecount = QR_get_num_backend_tuples(res); - if (allures = CC_send_query(conn, proc_query, NULL, CLEAR_RESULT_ON_ABORT), !allures) - { - QR_Destructor(res); - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "PGAPI_TablePrivileges query error"; - return SQL_ERROR; - } - usercount = QR_get_num_backend_tuples(allures); - useracl = (char (*)[ACLMAX]) malloc(usercount * sizeof(char [ACLMAX])); - for (i = 0; i < tablecount; i++) - { - memset(useracl, 0, usercount * sizeof(char[ACLMAX])); - acl = (char *) QR_get_value_backend_row(res, i, 2); - if (acl && acl[0] == '{') - user = acl + 1; - else - user = NULL; - for (; user && *user;) - { - grpauth = FALSE; - if (user[0] == '"' && strncmp(user + 1, "group ", 6) == 0) - { - user += 7; - grpauth = TRUE; - } - if (delim = strchr(user, '='), !delim) - break; - *delim = '\0'; - auth = delim + 1; - if (grpauth) - { - if (delim = strchr(auth, '"'), delim) - { - *delim = '\0'; - delim++; - } - } - else if (delim = strchr(auth, ','), delim) - *delim = '\0'; - else if (delim = strchr(auth, '}'), delim) - *delim = '\0'; - if (grpauth) /* handle group privilege */ - { - QResultClass *gres; - int i; - char *grolist, *uid, *delm; - - snprintf(proc_query, sizeof(proc_query) - 1, "select grolist from pg_group where groname = '%s'", user); - if (gres = CC_send_query(conn, proc_query, NULL, CLEAR_RESULT_ON_ABORT), gres != NULL) - { - grolist = QR_get_value_backend_row(gres, 0, 0); - if (grolist && grolist[0] == '{') - { - for (uid = grolist + 1; *uid;) - { - if (delm = strchr(uid, ','), delm) - *delm = '\0'; - else if (delm = strchr(uid, '}'), delm) - *delm = '\0'; -mylog("guid=%s\n", uid); - for (i = 0; i < usercount; i++) - { - if (strcmp(QR_get_value_backend_row(allures, i, 1), uid) == 0) - useracl_upd(useracl, allures, QR_get_value_backend_row(allures, i, 0), auth); - } - uid = delm + 1; - } - } - QR_Destructor(gres); - } - } - else - useracl_upd(useracl, allures, user, auth); - if (!delim) - break; - user = delim + 1; - } - reln = QR_get_value_backend_row(res, i, 0); - owner = QR_get_value_backend_row(res, i, 1); - if (conn->schema_support) - schnm = QR_get_value_backend_row(res, i, 3); - /* The owner has all privileges */ - useracl_upd(useracl, allures, owner, ALL_PRIVILIGES); - for (j = 0; j < usercount; j++) - { - user = QR_get_value_backend_row(allures, j, 0); - su = (strcmp(QR_get_value_backend_row(allures, j, 2), "t") == 0); - sys = (strcmp(user, owner) == 0); - /* Super user has all privileges */ - if (su) - useracl_upd(useracl, allures, user, ALL_PRIVILIGES); - for (k = 0; k < ACLMAX; k++) - { - if (!useracl[j][k]) - break; - switch (useracl[j][k]) - { - case 'R': /* rule */ - case 't': /* trigger */ - continue; - } - row = (TupleNode *) malloc(sizeof(TupleNode) + (7 - 1) *sizeof(TupleField)); - set_tuplefield_string(&row->tuple[0], ""); - if (conn->schema_support) - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(schnm)); - else - set_tuplefield_string(&row->tuple[1], ""); - set_tuplefield_string(&row->tuple[2], reln); - if (su || sys) - set_tuplefield_string(&row->tuple[3], "_SYSTEM"); - else - set_tuplefield_string(&row->tuple[3], owner); - mylog("user=%s\n", user); - set_tuplefield_string(&row->tuple[4], user); - switch (useracl[j][k]) - { - case 'a': - priv = "INSERT"; - break; - case 'r': - priv = "SELECT"; - break; - case 'w': - priv = "UPDATE"; - break; - case 'd': - priv = "DELETE"; - break; - case 'x': - priv = "REFERENCES"; - break; - default: - priv = ""; - } - set_tuplefield_string(&row->tuple[5], priv); - /* The owner and the super user are grantable */ - if (sys || su) - set_tuplefield_string(&row->tuple[6], "YES"); - else - set_tuplefield_string(&row->tuple[6], "NO"); - QR_add_tuple(SC_get_Result(stmt), row); - } - } - } - free(useracl); - QR_Destructor(res); - QR_Destructor(allures); - return SQL_SUCCESS; -} diff --git a/src/interfaces/odbc/info30.c b/src/interfaces/odbc/info30.c deleted file mode 100644 index 5e5b834690..0000000000 --- a/src/interfaces/odbc/info30.c +++ /dev/null @@ -1,396 +0,0 @@ -/*------- - * Module: info30.c - * - * Description: This module contains routines related to ODBC 3.0 - * SQLGetInfo(). - * - */ - -#ifndef ODBCVER -#define ODBCVER 0x0300 -#endif - -#include "connection.h" -#include "pgapifunc.h" - -RETCODE SQL_API -PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, - SWORD cbInfoValueMax, SWORD FAR * pcbInfoValue) -{ - static char *func = "PGAPI_GetInfo30"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci = &(conn->connInfo); - char *p = NULL; - int len = 0, - value = 0; - RETCODE result; - - switch (fInfoType) - { - case SQL_DYNAMIC_CURSOR_ATTRIBUTES1: - len = 4; - value = 0; - break; - case SQL_DYNAMIC_CURSOR_ATTRIBUTES2: - len = 4; - value = 0; - break; - - case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1: - len = 4; - value = SQL_CA1_NEXT; /* others aren't allowed in ODBC spec */ - break; - case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2: - len = 4; - value = SQL_CA2_READ_ONLY_CONCURRENCY; - break; - case SQL_KEYSET_CURSOR_ATTRIBUTES1: - len = 4; - value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE - | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK - | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION - | SQL_CA1_POS_REFRESH; - if (ci->updatable_cursors || ci->drivers.lie) - value |= (SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE - | SQL_CA1_BULK_ADD - | SQL_CA1_BULK_UPDATE_BY_BOOKMARK - | SQL_CA1_BULK_DELETE_BY_BOOKMARK - | SQL_CA1_BULK_FETCH_BY_BOOKMARK - ); - if (ci->drivers.lie) - value |= (SQL_CA1_LOCK_EXCLUSIVE - | SQL_CA1_LOCK_UNLOCK - | SQL_CA1_POSITIONED_UPDATE - | SQL_CA1_POSITIONED_DELETE - | SQL_CA1_SELECT_FOR_UPDATE - ); - break; - case SQL_KEYSET_CURSOR_ATTRIBUTES2: - len = 4; - value = SQL_CA2_READ_ONLY_CONCURRENCY; - if (ci->updatable_cursors || ci->drivers.lie) - value |= (SQL_CA2_OPT_ROWVER_CONCURRENCY - /*| SQL_CA2_CRC_APPROXIMATE*/ - | SQL_CA2_CRC_EXACT - | SQL_CA2_SENSITIVITY_DELETIONS - | SQL_CA2_SENSITIVITY_UPDATES - /* | SQL_CA2_SENSITIVITY_ADDITIONS */ - ); - if (ci->drivers.lie) - value |= (SQL_CA2_READ_ONLY_CONCURRENCY - | SQL_CA2_LOCK_CONCURRENCY - | SQL_CA2_OPT_VALUES_CONCURRENCY - | SQL_CA2_MAX_ROWS_SELECT - | SQL_CA2_MAX_ROWS_INSERT - | SQL_CA2_MAX_ROWS_DELETE - | SQL_CA2_MAX_ROWS_UPDATE - | SQL_CA2_MAX_ROWS_CATALOG - | SQL_CA2_MAX_ROWS_AFFECTS_ALL - | SQL_CA2_SIMULATE_NON_UNIQUE - | SQL_CA2_SIMULATE_TRY_UNIQUE - | SQL_CA2_SIMULATE_UNIQUE - ); - break; - - case SQL_STATIC_CURSOR_ATTRIBUTES1: - len = 4; - value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE - | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK - | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION - | SQL_CA1_POS_REFRESH; - if (ci->updatable_cursors) - value |= (SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE - | SQL_CA1_BULK_ADD - ); - break; - case SQL_STATIC_CURSOR_ATTRIBUTES2: - len = 4; - value = SQL_CA2_READ_ONLY_CONCURRENCY; - if (ci->updatable_cursors) - value |= (SQL_CA2_OPT_ROWVER_CONCURRENCY - | SQL_CA2_CRC_EXACT - /* | SQL_CA2_SENSITIVITY_ADDITIONS - | SQL_CA2_SENSITIVITY_DELETIONS - | SQL_CA2_SENSITIVITY_UPDATES */ - ); - break; - - case SQL_ODBC_INTERFACE_CONFORMANCE: - len = 4; - value = SQL_OIC_CORE; - if (ci->drivers.lie) - value = SQL_OIC_LEVEL2; - break; - case SQL_ACTIVE_ENVIRONMENTS: - len = 2; - value = 0; - break; - case SQL_AGGREGATE_FUNCTIONS: - len = 4; - value = SQL_AF_ALL; - break; - case SQL_ALTER_DOMAIN: - len = 4; - value = 0; - break; - case SQL_ASYNC_MODE: - len = 4; - value = SQL_AM_NONE; - break; - case SQL_BATCH_ROW_COUNT: - len = 4; - value = SQL_BRC_EXPLICIT; - break; - case SQL_BATCH_SUPPORT: - len = 4; - value = SQL_BS_SELECT_EXPLICIT | SQL_BS_ROW_COUNT_EXPLICIT; - break; - case SQL_CATALOG_NAME: - len = 0; - if (PG_VERSION_LE(conn, 7.2)) - p = "N"; - else - p = "Y"; /* hopefully */ - break; - case SQL_COLLATION_SEQ: - len = 0; - p = ""; - break; - case SQL_CREATE_ASSERTION: - len = 4; - value = 0; - break; - case SQL_CREATE_CHARACTER_SET: - len = 4; - value = 0; - break; - case SQL_CREATE_COLLATION: - len = 4; - value = 0; - break; - case SQL_CREATE_DOMAIN: - len = 4; - value = 0; - break; - case SQL_CREATE_SCHEMA: - len = 4; - if (conn->schema_support) - value = SQL_CS_CREATE_SCHEMA | SQL_CS_AUTHORIZATION; - else - value = 0; - break; - case SQL_CREATE_TABLE: - len = 4; - value = SQL_CT_CREATE_TABLE | SQL_CT_TABLE_CONSTRAINT - | SQL_CT_CONSTRAINT_NAME_DEFINITION - | SQL_CT_LOCAL_TEMPORARY | SQL_CT_COLUMN_CONSTRAINT - | SQL_CT_COLUMN_DEFAULT | SQL_CT_CONSTRAINT_INITIALLY_DEFERRED - | SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE | SQL_CT_CONSTRAINT_DEFERRABLE; - break; - case SQL_CREATE_TRANSLATION: - len = 4; - value = 0; - break; - case SQL_CREATE_VIEW: - len = 4; - value = SQL_CV_CREATE_VIEW; - break; - case SQL_DDL_INDEX: - len = 4; - value = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX; - break; - case SQL_DESCRIBE_PARAMETER: - len = 0; - p = "N"; - break; - case SQL_DROP_ASSERTION: - len = 4; - value = 0; - break; - case SQL_DROP_CHARACTER_SET: - len = 4; - value = 0; - break; - case SQL_DROP_COLLATION: - len = 4; - value = 0; - break; - case SQL_DROP_DOMAIN: - len = 4; - value = 0; - break; - case SQL_DROP_SCHEMA: - len = 4; - if (conn->schema_support) - value = SQL_DS_DROP_SCHEMA | SQL_DS_RESTRICT | SQL_DS_CASCADE; - else - value = 0; - break; - case SQL_DROP_TABLE: - len = 4; - value = SQL_DT_DROP_TABLE; - if (PG_VERSION_GT(conn, 7.2)) /* hopefully */ - value |= (SQL_DT_RESTRICT | SQL_DT_CASCADE); - break; - case SQL_DROP_TRANSLATION: - len = 4; - value = 0; - break; - case SQL_DROP_VIEW: - len = 4; - value = SQL_DV_DROP_VIEW; - if (PG_VERSION_GT(conn, 7.2)) /* hopefully */ - value |= (SQL_DV_RESTRICT | SQL_DV_CASCADE); - break; - case SQL_INDEX_KEYWORDS: - len = 4; - value = SQL_IK_NONE; - case SQL_INFO_SCHEMA_VIEWS: - len = 4; - value = 0; - break; - case SQL_INSERT_STATEMENT: - len = 4; - value = SQL_IS_INSERT_LITERALS | SQL_IS_INSERT_SEARCHED | SQL_IS_SELECT_INTO; - break; - case SQL_MAX_IDENTIFIER_LEN: - len = 4; - value = 32; - break; - case SQL_MAX_ROW_SIZE_INCLUDES_LONG: - len = 0; - p = "Y"; - break; - case SQL_PARAM_ARRAY_ROW_COUNTS: - len = 4; - value = SQL_PARC_BATCH; - break; - case SQL_PARAM_ARRAY_SELECTS: - len = 4; - value = SQL_PAS_BATCH; - break; - case SQL_SQL_CONFORMANCE: - len = 4; - value = SQL_SC_SQL92_ENTRY; - break; - case SQL_SQL92_DATETIME_FUNCTIONS: - len = 4; - value = SQL_SDF_CURRENT_DATE | SQL_SDF_CURRENT_TIME | SQL_SDF_CURRENT_TIMESTAMP; - break; - case SQL_SQL92_FOREIGN_KEY_DELETE_RULE: - len = 4; - value = SQL_SFKD_CASCADE | SQL_SFKD_NO_ACTION | SQL_SFKD_SET_DEFAULT | SQL_SFKD_SET_NULL; - break; - case SQL_SQL92_FOREIGN_KEY_UPDATE_RULE: - len = 4; - value = SQL_SFKU_CASCADE | SQL_SFKU_NO_ACTION | SQL_SFKU_SET_DEFAULT | SQL_SFKU_SET_NULL; - break; - case SQL_SQL92_GRANT: - len = 4; - value = SQL_SG_DELETE_TABLE | SQL_SG_INSERT_TABLE | SQL_SG_REFERENCES_TABLE | SQL_SG_SELECT_TABLE | SQL_SG_UPDATE_TABLE; - break; - case SQL_SQL92_NUMERIC_VALUE_FUNCTIONS: - len = 4; - value = SQL_SNVF_BIT_LENGTH | SQL_SNVF_CHAR_LENGTH - | SQL_SNVF_CHARACTER_LENGTH | SQL_SNVF_EXTRACT - | SQL_SNVF_OCTET_LENGTH | SQL_SNVF_POSITION; - break; - case SQL_SQL92_PREDICATES: - len = 4; - value = SQL_SP_BETWEEN | SQL_SP_COMPARISON - | SQL_SP_EXISTS | SQL_SP_IN - | SQL_SP_ISNOTNULL | SQL_SP_ISNULL - | SQL_SP_LIKE | SQL_SP_OVERLAPS - | SQL_SP_QUANTIFIED_COMPARISON; - break; - case SQL_SQL92_RELATIONAL_JOIN_OPERATORS: - len = 4; - if (PG_VERSION_GE(conn, 7.1)) - value = SQL_SRJO_CROSS_JOIN | SQL_SRJO_EXCEPT_JOIN - | SQL_SRJO_FULL_OUTER_JOIN | SQL_SRJO_INNER_JOIN - | SQL_SRJO_INTERSECT_JOIN | SQL_SRJO_LEFT_OUTER_JOIN - | SQL_SRJO_NATURAL_JOIN | SQL_SRJO_RIGHT_OUTER_JOIN - | SQL_SRJO_UNION_JOIN; - break; - case SQL_SQL92_REVOKE: - len = 4; - value = SQL_SR_DELETE_TABLE | SQL_SR_INSERT_TABLE | SQL_SR_REFERENCES_TABLE | SQL_SR_SELECT_TABLE | SQL_SR_UPDATE_TABLE; - break; - case SQL_SQL92_ROW_VALUE_CONSTRUCTOR: - len = 4; - value = SQL_SRVC_VALUE_EXPRESSION | SQL_SRVC_NULL; - break; - case SQL_SQL92_STRING_FUNCTIONS: - len = 4; - value = SQL_SSF_CONVERT | SQL_SSF_LOWER - | SQL_SSF_UPPER | SQL_SSF_SUBSTRING - | SQL_SSF_TRANSLATE | SQL_SSF_TRIM_BOTH - | SQL_SSF_TRIM_LEADING | SQL_SSF_TRIM_TRAILING; - break; - case SQL_SQL92_VALUE_EXPRESSIONS: - len = 4; - value = SQL_SVE_CASE | SQL_SVE_CAST | SQL_SVE_COALESCE | SQL_SVE_NULLIF; - break; - /* The followings aren't implemented yet */ - case SQL_DATETIME_LITERALS: - len = 4; - case SQL_DM_VER: - len = 0; - case SQL_DRIVER_HDESC: - len = 4; - case SQL_MAX_ASYNC_CONCURRENT_STATEMENTS: - len = 4; - case SQL_STANDARD_CLI_CONFORMANCE: - len = 4; - case SQL_XOPEN_CLI_YEAR: - len = 0; - default: - /* unrecognized key */ - conn->errormsg = "Unrecognized key passed to SQLGetInfo30."; - conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - result = SQL_SUCCESS; - mylog("%s: p='%s', len=%d, value=%d, cbMax=%d\n", func, p ? p : "", len, value, cbInfoValueMax); - if (p) - { - /* char/binary data */ - len = strlen(p); - - if (rgbInfoValue) - { -#ifdef UNICODE_SUPPORT - if (conn->unicode) - { - len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2); - len *= 2; - } - else -#endif /* UNICODE_SUPPORT */ - strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax); - - if (len >= cbInfoValueMax) - { - result = SQL_SUCCESS_WITH_INFO; - conn->errornumber = CONN_TRUNCATED; - conn->errormsg = "The buffer was too small for tthe InfoValue."; - } - } - } - else - { - /* numeric data */ - if (rgbInfoValue) - { - if (len == 2) - *((WORD *) rgbInfoValue) = (WORD) value; - else if (len == 4) - *((DWORD *) rgbInfoValue) = (DWORD) value; - } - } - - if (pcbInfoValue) - *pcbInfoValue = len; - return result; -} diff --git a/src/interfaces/odbc/iodbc.h b/src/interfaces/odbc/iodbc.h deleted file mode 100644 index f8e7d248b1..0000000000 --- a/src/interfaces/odbc/iodbc.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _IODBC_H -#define _IODBC_H - -#if !defined(WIN32) && !defined(WIN32_SYSTEM) -#define _UNIX_ - -#include -#include - -#define MEM_ALLOC(size) (malloc((size_t)(size))) -#define MEM_FREE(ptr) \ -do { \ - if(ptr) \ - free(ptr); \ -} while (0) - -#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(WIN32) || defined(WIN32_SYSTEM) - -#include -#include - -#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 /* WIN32 */ - -#define SYSERR (-1) - -#ifndef NULL -#define NULL ((void FAR*)0UL) -#endif - -#endif diff --git a/src/interfaces/odbc/isql.h b/src/interfaces/odbc/isql.h deleted file mode 100644 index f27c087d52..0000000000 --- a/src/interfaces/odbc/isql.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Modified isql.h file from iodbc. This file should be placed in the - * include path to be used to create ODBC compliant applications. - */ - -#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 0x0250 */ - -#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 - -/* All code below has been added to the original isql.h coming from iodbc */ -typedef unsigned char BYTE; - -/* More SQLColAttributes flag values */ -#define SQL_COLUMN_NAME 1 -#define SQL_COLUMN_TYPE 2 -#define SQL_COLUMN_LENGTH 3 -#define SQL_COLUMN_PRECISION 4 -#define SQL_COLUMN_SCALE 5 -#define SQL_COLUMN_DISPLAY_SIZE 6 -#define SQL_COLUMN_NULLABLE 7 -#define SQL_COLUMN_UNSIGNED 8 -#define SQL_COLUMN_MONEY 9 -#define SQL_COLUMN_UPDATABLE 10 -#define SQL_COLUMN_AUTO_INCREMENT 11 -#define SQL_COLUMN_CASE_SENSITIVE 12 -#define SQL_COLUMN_SEARCHABLE 13 -#define SQL_COLUMN_TYPE_NAME 14 -#define SQL_COLUMN_TABLE_NAME 15 -#define SQL_COLUMN_OWNER_NAME 16 -#define SQL_COLUMN_QUALIFIER_NAME 17 - -/* SQLColAttributes Searchable flags */ -#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 - -/* SQLColAttributes Updateable flags */ -#define SQL_ATTR_READONLY 0 -#define SQL_ATTR_WRITE 1 -#define SQL_ATTR_READWRITE_UNKNOWN 2 - -/* - * function prototypes previously not contained in isql.h - */ -#ifdef __cplusplus -extern "C" -{ -#endif - -RETCODE SQL_API SQLAllocConnect(HENV henv, - HDBC FAR * phdbc); -RETCODE SQL_API SQLAllocEnv(HENV FAR * phenv); -RETCODE SQL_API SQLAllocStmt(HDBC hdbc, - HSTMT FAR * phstmt); -RETCODE SQL_API SQLBindCol(HSTMT hstmt, - UWORD icol, - SWORD fCType, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR * pcbValue); - -RETCODE SQL_API SQLCancel(HSTMT hstmt); - -RETCODE SQL_API SQLColAttributes(HSTMT hstmt, - UWORD icol, - UWORD fDescType, - PTR rgbDesc, - SWORD cbDescMax, - SWORD FAR * pcbDesc, - SDWORD FAR * pfDesc); - -RETCODE SQL_API SQLConnect(HDBC hdbc, - UCHAR FAR * szDSN, - SWORD cbDSN, - UCHAR FAR * szUID, - SWORD cbUID, - UCHAR FAR * szAuthStr, - SWORD cbAuthStr); - -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); - -RETCODE SQL_API SQLDisconnect(HDBC hdbc); - -RETCODE SQL_API SQLError(HENV henv, - HDBC hdbc, - HSTMT hstmt, - UCHAR FAR * szSqlState, - SDWORD FAR * pfNativeError, - UCHAR FAR * szErrorMsg, - SWORD cbErrorMsgMax, - SWORD FAR * pcbErrorMsg); - -RETCODE SQL_API SQLExecDirect(HSTMT hstmt, - UCHAR FAR * szSqlStr, - SDWORD cbSqlStr); - -RETCODE SQL_API SQLExecute(HSTMT hstmt); - -RETCODE SQL_API SQLFetch(HSTMT hstmt); - -RETCODE SQL_API SQLFreeConnect(HDBC hdbc); - -RETCODE SQL_API SQLFreeEnv(HENV henv); - -RETCODE SQL_API SQLFreeStmt(HSTMT hstmt, - UWORD fOption); - -RETCODE SQL_API SQLGetCursorName(HSTMT hstmt, - UCHAR FAR * szCursor, - SWORD cbCursorMax, - SWORD FAR * pcbCursor); - -RETCODE SQL_API SQLNumResultCols(HSTMT hstmt, - SWORD FAR * pccol); - -RETCODE SQL_API SQLPrepare(HSTMT hstmt, - UCHAR FAR * szSqlStr, - SDWORD cbSqlStr); - -RETCODE SQL_API SQLRowCount(HSTMT hstmt, - SDWORD FAR * pcrow); - -RETCODE SQL_API SQLSetCursorName(HSTMT hstmt, - UCHAR FAR * szCursor, - SWORD cbCursor); - -RETCODE SQL_API SQLTransact(HENV henv, - HDBC hdbc, - UWORD fType); - -RETCODE SQL_API SQLSetParam(HSTMT hstmt, - UWORD ipar, - SWORD fCType, - SWORD fSqlType, - UDWORD cbColDef, - SWORD ibScale, - PTR rgbValue, - SDWORD FAR * pcbValue); - -RETCODE SQL_API SQLDataSources(HENV henv, - UWORD Direction, UCHAR FAR * ServerName, - WORD BufferLength1, WORD *NameLength1, - UCHAR FAR * Description, WORD BufferLength2, - WORD *NameLength2); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/interfaces/odbc/isqlext.h b/src/interfaces/odbc/isqlext.h deleted file mode 100644 index 989860b615..0000000000 --- a/src/interfaces/odbc/isqlext.h +++ /dev/null @@ -1,1560 +0,0 @@ -/* - * This file has been modified from the original isqlext.h to add the - * missing function prototypes and appropriate #defines. It is designed - * to be a drop in replacement for isqlext.h from iodbc. - */ - -#ifndef _INTRINSIC_SQLEXT_H -#define _INTRINSIC_SQLEXT_H - -#include "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_NUM_EXTENSIONS (SQL_EXT_API_LAST - SQL_EXT_API_START + 1) - -#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 - -/* - * ODBC 3.0 renames the above to SQL_ATTR_ values. At this time I don't - * know if they have also been renumbered or not, I will assume not. - */ -#define SQL_ATTR_QUERY_TIMEOUT 0 -#define SQL_ATTR_MAX_ROWS 1 -#define SQL_ATTR_NOSCAN 2 -#define SQL_ATTR_MAX_LENGTH 3 -#define SQL_ATTR_ASYNC_ENABLE 4 -#define SQL_ATTR_BIND_TYPE 5 -#define SQL_ATTR_CURSOR_TYPE 6 -#define SQL_ATTR_CONCURRENCY 7 -#define SQL_ATTR_KEYSET_SIZE 8 -#define SQL_ATTR_ROWSET_SIZE 9 -#define SQL_ATTR_SIMULATE_CURSOR 10 -#define SQL_ATTR_RETRIEVE_DATA 11 -#define SQL_ATTR_USE_BOOKMARKS 12 -#define SQL_ATTR_GET_BOOKMARK 13 /* GetStmtOption Only */ -#define SQL_ATTR_ROW_NUMBER 14 /* GetStmtOption Only */ - -/* New in ODBC 3.0 */ -#define SQL_ATTR_APP_PARAM_DESC 15 -#define SQL_ATTR_APP_ROW_DESC 16 -#define SQL_ATTR_CURSOR_SCROLLABLE 17 -#define SQL_ATTR_CURSOR_SENSITITY 18 -#define SQL_ATTR_ENABLE_AUTO_IPD 19 -#define SQL_ATTR_FETCH_BOOKMARK_PTR 20 -#define SQL_ATTR_IMP_PARAM_DESC 21 -#define SQL_ATTR_IMP_ROW_DESC 22 -#define SQL_ATTR_METADATA_ID 23 -#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 24 -#define SQL_ATTR_PARAM_BIND_TYPE 25 -#define SQL_ATTR_PARAM_OPERATION_PTR 26 -#define SQL_ATTR_PARAM_STATUS_PTR 27 -#define SQL_ATTR_PARAMS_PROCESSED_PTR 28 -#define SQL_ATTR_PARAMSET_SIZE 29 -#define SQL_ATTR_ROW_ARRAY_SIZE 30 -#define SQL_ATTR_ROW_BIND_OFFSET_PTR 31 -#define SQL_ATTR_ROW_OPERATION_PTR 32 -#define SQL_ATTR_ROW_STATUS_PTR 33 -#define SQL_ATTR_ROWS_FETCHED_PTR 34 - -#define SQL_STMT_ATTR_MIN SQL_ATTR_QUERY_TIMEOUT -#define SQL_STMT_ATTR_MAX SQL_ATTR_ROWS_FETCHED_PTR - -/* 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 - - -/* 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 -#define SQL_RETURN_VALUE 5 - -/* 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) - -/* Everything below has been added to the original isqlext.h that comes - * with iodbc. -*/ - -#define SCHAR signed char -#define FLOAT float -#define DOUBLE double - -/* SQL DATA TYPES */ -typedef UCHAR SQLCHAR; -typedef SWORD SQLSMALLINT; -typedef UWORD SQLUSMALLINT; -typedef SDWORD SQLINTEGER; -typedef UDWORD SQLUINTEGER; -typedef FLOAT SQLREAL; -typedef DOUBLE SQLDOUBLE; -typedef DOUBLE SQLFLOAT; -typedef SCHAR SQLSCHAR; -typedef UDWORD BOOKMARK; - -#ifdef GCC /* Because I know GCC supports 64 bit ints */ - -typedef long long int ODBCINT64; -typedef unsigned ODBCINT64 SQLUBIGINT; -typedef ODBCINT64 SQLBIGINT; - -#else /* Used even on platforms with 64 bit ints - * but not GCC */ - -typedef struct -{ - SQLUINTEGER dwLowWord; - SQLUINTEGER dwHighWord; -} SQLUBIGINT; - -typedef struct -{ - SQLUINTEGER dwLowWord; - SQLINTEGER dwHighWord; -} SQLBIGINT; -#endif /* GCC */ - -typedef struct tagDATE_STRUCT -{ - SQLSMALLINT year; - SQLUSMALLINT month; - SQLUSMALLINT day; -} DATE_STRUCT, - -SQL_DATE_STRUCT; - -typedef struct tagTIME_STRUCT -{ - SQLUSMALLINT hour; - SQLUSMALLINT minute; - SQLUSMALLINT second; -} TIME_STRUCT, - -SQL_TIME_STRUCT; - -typedef struct tagTIMESTAMP_STRUCT -{ - SQLSMALLINT year; - SQLUSMALLINT month; - SQLUSMALLINT day; - SQLUSMALLINT hour; - SQLUSMALLINT minute; - SQLUSMALLINT second; - SQLUINTEGER fraction; -} TIMESTAMP_STRUCT, - -SQL_TIMESTAMP_STRUCT; - -/* postodbc doesn't use these but what the heck */ -/* Don't know what SQL_MAX_NUMERIC_LEN should be so I can't include this. It's - * ODBC 3.0 anyway. - -typedef struct tagSQL_NUMERIC_STRUCT { - SQLCHAR precision; - SQLSCHAR scale; - SQLCHAR sign; - SQLCHAR val[SQL_MAX_NUMERIC_LEN]; -} SQL_NUMERIC_STRUCT; - -*/ - -typedef struct tagSQLGUID -{ - DWORD Data1; - WORD Data2; - WORD Data3; - BYTE Data4[8]; -} SQLGUID; - -typedef enum -{ - SQL_IS_YEAR = 1, - SQL_IS_MONTH = 2, - SQL_IS_DAY = 3, - SQL_IS_HOUR = 4, - SQL_IS_MINUTE = 5, - SQL_IS_SECOND = 6, - SQL_IS_YEAR_TO_MONTH = 7, - SQL_IS_DAY_TO_HOUR = 8, - SQL_IS_DAY_TO_MINUTE = 9, - SQL_IS_DAY_TO_SECOND = 10, - SQL_IS_HOUR_TO_MINUTE = 11, - SQL_IS_HOUR_TO_SECOND = 12, - SQL_IS_MINUTE_TO_SECOND = 13 -} SQLINTERVAL; - -typedef struct tagSQL_YEAR_MONTH -{ - SQLUINTEGER year; - SQLUINTEGER month; -} SQL_YEAR_MONTH_STRUCT; - -typedef struct tagSQL_DAY_SECOND -{ - SQLUINTEGER day; - SQLUINTEGER hour; - SQLUINTEGER minute; - SQLUINTEGER second; - SQLUINTEGER fraction; -} SQL_DAY_SECOND_STRUCT; - -typedef struct tagSQL_INTERVAL_STRUCT -{ - SQLINTERVAL interval_type; - SQLSMALLINT interval_sign; - union - { - SQL_YEAR_MONTH_STRUCT year_month; - SQL_DAY_SECOND_STRUCT day_second; - } intval; -} SQL_INTERVAL_STRUCT; - -#define SQL_MAX_OPTION_STRING_LENGTH 256 -#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST - SQL_EXT_API_START + 1) - -/* defines for SQL datatypes */ -/* -#define SQL_TYPE_DATE -#define SQL_TYPE_TIME -#define SQL_TYPE_TIMESTAMP -#define SQL_CODE_DATE -#define SQL_CODE_TIME -#define SQL_CODE_TIMESTAMP -#define SQL_CODE_MONTH -#define SQL_CODE_YEAR -#define SQL_CODE_YEAR_TO_MONTH -#define SQL_CODE_DAY -#define SQL_CODE_HOUR -#define SQL_CODE_MINUTE -#define SQL_CODE_SECOND -#define SQL_CODE_DAY_TO_HOUR -#define SQL_CODE_DAY_TO_MINUTE -#define SQL_CODE_DAY_TO_SECOND -#define SQL_CODE_HOUR_TO_MINUTE -#define SQL_CODE_HOUR_TO_SECOND -#define SQL_CODE_MINUTE_TO_SECOND -*/ -#define SQL_INTERVAL_YEAR (-80) -#define SQL_INTERVAL_MONTH (-81) -#define SQL_INTERVAL_YEAR_TO_MONTH (-82) -#define SQL_INTERVAL_DAY (-83) -#define SQL_INTERVAL_HOUR (-84) -#define SQL_INTERVAL_MINUTE (-85) -#define SQL_INTERVAL_SECOND (-86) -#define SQL_INTERVAL_DAY_TO_HOUR (-87) -#define SQL_INTERVAL_DAY_TO_MINUTE (-88) -#define SQL_INTERVAL_DAY_TO_SECOND (-89) -#define SQL_INTERVAL_HOUR_TO_MINUTE (-90) -#define SQL_INTERVAL_HOUR_TO_SECOND (-91) -#define SQL_INTERVAL_MINUTE_TO_SECOND (-92) - -#define SQL_UNICODE (-95) -#define SQL_UNICODE_VARCHAR (-96) -#define SQL_UNICODE_LONGVARCHAR (-97) -#define SQL_UNICODE_CHAR SQL_UNICODE - -/* C to SQL data types */ -/* -#define SQL_C_TYPE_DATE SQL_TYPE_DATE -#define SQL_C_TYPE_TIME SQL_TYPE_TIME -#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP -#define SQL_C_GUID SQLGUID -*/ -#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH -#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR -#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH -#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY -#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR -#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE -#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND -#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR -#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE -#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND -#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE -#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND -#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND -#define SQL_C_NUMERIC SQL_NUMERIC -#define SQL_C_VARBOOKMARK SQL_C_BINARY -#define SQL_C_SBIGINT (SQL_BIGINT + SQL_SIGNED_OFFSET) -#define SQL_C_UBIGINT (SQL_BIGINT + SQL_UNSIGNED_OFFSET) - -#define SQL_TRUE 1UL -#define SQL_FALSE 0UL - -/* SQLGetData */ -#define SQL_NO_TOTAL (-4) - -/* SQLBindParameter */ -#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) -#define SQL_LEN_DATA_AT_EXEC(length) (-length+SQL_LEN_DATA_AT_EXEC_OFFSET) - -#define SQL_LEN_BINARY_ATTR_OFFSET (-100) -#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) - -/* SQLExtendedFetch - row status */ -#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 - -/* SQLForeignKeys - rule flags */ -#define SQL_CASCADE 0 -#define SQL_RESTRICT 1 -#define SQL_SET_NULL 2 -#define SQL_NO_ACTION 3 /* ODBC 3.0 */ -#define SQL_SET_DEFAULT 4 - -/* SQLForeignKeys - Deferrability (ODBC 3.0) */ -#define SQL_INITIALLY_DEFERRED 5 -#define SQL_INITIALLY_IMMEDIATE 6 -#define SQL_NOT_DEFFERABLE 2 - -/* Constants not in isqlext.h but needed by the driver. I have no idea -* if these correspond correctly with those from Microsoft or not. I don't -* know that it matters as long as the symbolic names are used. I simply -* assigned the numbers in the order they appear in the SQLGetInfo function -* of postodbc. -*/ - -/* - * SQLGetInfo - */ -#define SQL_ACTIVE_CONNECTIONS 0 -#define SQL_ACTIVE_STATEMENTS 1 -#define SQL_DATA_SOURCE_NAME 2 -#define SQL_DRIVER_VER 7 -#define SQL_FETCH_DIRECTION 8 -#define SQL_ODBC_API_CONFORMANCE 9 -#define SQL_ROW_UPDATES 11 -#define SQL_ODBC_SAG_CLI_CONFORMANCE 12 -#define SQL_SERVER_NAME 13 -#define SQL_SEARCH_PATTERN_ESCAPE 14 -#define SQL_ODBC_SQL_CONFORMANCE 15 -#define SQL_DBMS_NAME 17 -#define SQL_DBMS_VER 18 -#define SQL_ACCESSIBLE_TABLES 19 -#define SQL_ACCESSIBLE_PROCEDURES 20 -#define SQL_PROCEDURES 21 -#define SQL_CONCAT_NULL_BEHAVIOR 22 -#define SQL_DATA_SOURCE_READ_ONLY 25 -#define SQL_EXPRESSIONS_IN_ORDERBY 27 -#define SQL_IDENTIFIER_CASE 28 -#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_OUTER_JOINS 38 -#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_NUMERIC_FUNCTIONS 49 -#define SQL_STRING_FUNCTIONS 50 -#define SQL_SYSTEM_FUNCTIONS 51 -#define SQL_TIMEDATE_FUNCTIONS 52 -#define SQL_CONVERT_BIGINT 53 -#define SQL_CONVERT_BINARY 54 -#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_TINYINT 68 -#define SQL_CONVERT_VARBINARY 69 -#define SQL_CONVERT_VARCHAR 70 -#define SQL_CONVERT_LONGVARBINARY 71 -#define SQL_ODBC_SQL_OPT_IEF 73 -#define SQL_CORRELATION_NAME 74 -#define SQL_LOCK_TYPES 78 -#define SQL_POS_OPERATIONS 79 -#define SQL_POSITIONED_STATEMENTS 80 -#define SQL_GETDATA_EXTENSIONS 81 -#define SQL_BOOKMARK_PERSISTENCE 82 -#define SQL_STATIC_SENSITIVITY 83 -#define SQL_FILE_USAGE 84 -#define SQL_NULL_COLLATION 85 -#define SQL_ALTER_TABLE 86 -#define SQL_COLUMN_ALIAS 87 -#define SQL_GROUP_BY 88 -#define SQL_KEYWORDS 89 -#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 -#define SQL_OWNER_USAGE 91 -#define SQL_QUALIFIER_USAGE 92 -#define SQL_QUOTED_IDENTIFIER_CASE 93 -#define SQL_SPECIAL_CHARACTERS 94 -#define SQL_SUBQUERIES 95 -#define SQL_UNION 96 -#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 -#define SQL_MAX_COLUMNS_IN_INDEX 98 -#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_INDEX_SIZE 102 -#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 -#define SQL_MAX_ROW_SIZE 104 -#define SQL_MAX_STATEMENT_LEN 105 -#define SQL_MAX_TABLES_IN_SELECT 106 -#define SQL_MAX_USER_NAME_LEN 107 -#define SQL_MAX_CHAR_LITERAL_LEN 108 -#define SQL_TIMEDATE_ADD_INTERVALS 109 -#define SQL_TIMEDATE_DIFF_INTERVALS 110 -#define SQL_NEED_LONG_DATA_LEN 111 -#define SQL_MAX_BINARY_LITERAL_LEN 112 -#define SQL_LIKE_ESCAPE_CLAUSE 113 - -#define SQL_OJ_CAPABILITIES 65003 -/* ODBC 3.0 alias */ -#define SQL_MAX_SCHEMA_NAME_LEN SQL_MAX_OWNER_NAME_LEN - -/* Bit Masks describing the behaviour of the GetInfo functions named above */ -/* - * alter table behaviour(4 byte val) - */ -#define SQL_AT_ADD_COLUMN 0x00000001L -#define SQL_AT_DROP_COLUMN 0x00000002L - -/* - * BookMark Persistence, a SQLUINTEGER bitmask(ie 4 bytes) -*/ -#define SQL_BP_CLOSE 0x00000001L -#define SQL_BP_DELETE 0x00000002L -#define SQL_BP_DROP 0x00000004L -#define SQL_BP_TRANSACTION 0x00000008L -#define SQL_BP_UPDATE 0x00000010L -#define SQL_BP_OTHER_HSTMT 0x00000020L -#define SQL_BP_SCROLL 0x00000040L - -/* - * Conversion bitmasks for testing which conversions are supported by - * the driver. An application compares the returned bitmask with these - * to determine which conversions are supported. The driver ANDS these - * for the returned bitmask to indicate the supported conversions.(type - * is SQLUINTEGER, i.e. 4 bytes). Note that these masks are defined in - * alphabetical order, I have no idea if this maps to MS's SDK. - */ -#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_BINARY 0x00000400L -#define SQL_CVT_VARBINARY 0x00000800L -#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_LONGVARBINARY 0x00040000L - - -/* extras added in ODBC 3.0 */ -#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L -#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L - -/* - * concat null behaviour(2 byte val) - */ -#define SQL_CB_NULL 0x0000 -#define SQL_CB_NON_NULL 0x0001 - -/* - * correlation name - */ -#define SQL_CN_NONE 0x0000 -#define SQL_CN_DIFFERENT 0x0001 -#define SQL_CN_ANY 0x0002 - -/* - * Fetch Direction. A SQLINTEGER bitmask enumerating the supported fetch - * direction options. This information type has been deprecated in - * ODBC 3.0. - */ -#define SQL_FD_FETCH_NEXT 0x00000001L -#define SQL_FD_FETCH_FIRST 0x00000002L -#define SQL_FD_FETCH_LAST 0x00000004L -#define SQL_FD_FETCH_PRIOR 0x00000008L -#define SQL_FD_FETCH_ABSOLUTE 0x00000010L -#define SQL_FD_FETCH_RELATIVE 0x00000020L -#define SQL_FD_FETCH_RESUME 0x00000040L -#define SQL_FD_FETCH_BOOKMARK 0x00000080L - -/* - * Conversion bitmasks for testing which function conversions are supported by - * the driver. An application compares the returned bitmask with these - * to determine which conversions are supported. The driver ANDS these - * for the returned bitmask to indicate the supported conversions.(type - * is SQLUINTEGER, i.e. 4 bytes). Note that these masks are defined in - * alphabetical order, I have no idea if this maps to MS's SDK. - */ -#define SQL_FN_CVT_CONVERT 0x00000001L -#define SQL_FN_CVT_CAST 0x00000002L - -/* - * File Usage. A SQLUSMALLINT indicating how a singel-tier driver treats - * files in a data source. - */ -#define SQL_FILE_NOT_SUPPORTED 0x0000 -#define SQL_FILE_TABLE 0x0001 -#define SQL_FILE_QUALIFIER 0x0002 -#define SQL_FILE_CATALOG SQL_FILE_CATALOG - -/* - * GetData Extensions. A SQLUINTEGER(4 bytes) bitmask enumerating extensions - * to SQLGetData. - */ -#define SQL_GD_ANY_COLUMN 0x00000001L -#define SQL_GD_ANY_ORDER 0x00000002L -#define SQL_GD_BLOCK 0x00000004L -#define SQL_GD_BOUND 0x00000008L - -/* - * Group By. A SQLUSMALLINT value specifying the relationship between the - * columns in the GROUP BY clause and the non-aggregated columns in the - * select list. -*/ -#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 - -/* added in ODBC 3.0 */ -#define SQL_GB_COLLATE 0x0004 - -/* - * Identifier Case. A SQLUSMALLINT indicating how identifiers are handled. - */ -#define SQL_IC_UPPER 0x0001 -#define SQL_IC_LOWER 0x0002 -#define SQL_IC_SENSITIVE 0x0003 -#define SQL_IC_MIXED 0x0004 - -/* - * Lock types. A SQLINTEGER bitmask enumerating the supported lock types for - * the fLock argument in SQLSetPos. Depreciated in 3.0. - */ -#define SQL_LCK_NO_CHANGE 0x00000001L -#define SQL_LCK_EXCLUSIVE 0x00000002L -#define SQL_LCK_UNLOCK 0x00000004L - -/* - * Non Nullable Columns. A SQLUSMALLINT value indicating if the data source - * supports NOT NULL in columns. - */ -#define SQL_NNC_NULL 0x0000 -#define SQL_NNC_NON_NULL 0x0001 - -/* - * Null Collation. A SQLUSMALLINT value specifying where NULLS are sorted in - * a result set. - */ -#define SQL_NC_HIGH 0x0001 -#define SQL_NC_LOW 0x0003 -#define SQL_NC_START 0x0002 -#define SQL_NC_END 0x0004 - -/* - * Numeric Functions. A SQLUINTEGER bitmask enumerating the scalar numeric - * functions supported by the driver and associated data source. - */ -#define SQL_FN_NUM_ABS 0x00000001L -#define SQL_FN_NUM_ACOS 0x00000002L -#define SQL_FN_NUM_ASIN 0x00000004L -#define SQL_FN_NUM_ATAN 0x00000008L -#define SQL_FN_NUM_ATAN2 0x00000010L -#define SQL_FN_NUM_CEILING 0x00000020L -#define SQL_FN_NUM_COS 0x00000040L -#define SQL_FN_NUM_COT 0x00000080L -#define SQL_FN_NUM_EXP 0x00000100L -#define SQL_FN_NUM_FLOOR 0x00000200L -#define SQL_FN_NUM_LOG 0x00000400L -#define SQL_FN_NUM_MOD 0x00000800L -#define SQL_FN_NUM_SIGN 0x00001000L -#define SQL_FN_NUM_SIN 0x00002000L -#define SQL_FN_NUM_SQRT 0x00004000L -#define SQL_FN_NUM_TAN 0x00008000L -#define SQL_FN_NUM_PI 0x00010000L -#define SQL_FN_NUM_RAND 0x00020000L - -/* Added in ODBC 2.0 */ -#define SQL_FN_NUM_DEGREES 0x00040000L -#define SQL_FN_NUM_LOG10 0x00080000L -#define SQL_FN_NUM_POWER 0x00100000L -#define SQL_FN_NUM_RADIANS 0x00200000L -#define SQL_FN_NUM_ROUND 0x00400000L -#define SQL_FN_NUM_TRUNCATE 0x00800000L - -/* - * Outer Join Capabilites. A SQLUINTEGER bitmask enumerating the types of - * outer joins supported by the driver and data source. - */ -#define SQL_OJ_LEFT 0x00000001L -#define SQL_OJ_RIGHT 0x00000002L -#define SQL_OJ_FULL 0x00000004L -#define SQL_OJ_NESTED 0x00000008L -#define SQL_OJ_NOT_ORDERED 0x00000010L -#define SQL_OJ_INNER 0x00000020L -#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L - -/* - * ODBC API Conformance. A SQLSMALLINT value indicating a drivers ODBC - * level conformance. Depreciated in 3.0. - */ -#define SQL_OAC_NONE 0x0000 -#define SQL_OAC_LEVEL1 0x0001 -#define SQL_OAC_LEVEL2 0x0002 - -/* - * ODBC SAG CLI Conformance. A SQLSMALLINT value indicating a drivers - * SAG CLI conformance. - */ -#define SQL_OSCC_NOT_COMPLIANT 0x0000 -#define SQL_OSCC_COMPLIANT 0x0001 - -/* - * ODBC SQL Conformance. A SQLSMALLINT value indicating a drivers SQL - * grammar support. Depreciated in 3.0. - */ -#define SQL_OSC_MINIMUM 0x0000 -#define SQL_OSC_CORE 0x0001 -#define SQL_OSC_EXTENDED 0x0002 - -/* - * Owner Usage. A SQLUINTEGER bitmask. - */ -#define SQL_OU_DML_STATEMENTS 0x00000001L -#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L -#define SQL_OU_TABLE_DEFINITION 0x00000004L -#define SQL_OU_INDEX_DEFINITION 0x00000008L -#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L - -/* - * Schema Usage. A SQLUINTEGER bitmask enumerating the statements in which - * schemas can be used. Renamed in ODBC 3.0 from SQL_OWNER_USAGE - */ -#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS -#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION -#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION -#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION -#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION - -/* - * Pos. Operations. A SQLINTEGER bitmask enumerating the supported operations - * in SQLSetPos. Depreciated in ODBC 3.0. - */ -#define SQL_POS_POSITION 0x00000001L -#define SQL_POS_REFRESH 0x00000002L -#define SQL_POS_UPDATE 0x00000004L -#define SQL_POS_DELETE 0x00000008L -#define SQL_POS_ADD 0x00000010L - -/* - * SQLSetPos - */ -#define SQL_ENTIRE_ROWSET 0 - -#define SQL_POSITION 0 -#define SQL_REFRESH 1 -#define SQL_UPDATE 2 -#define SQL_DELETE 3 -#define SQL_ADD 4 - -/* - * SQLSetPos Lock options -*/ -#define SQL_LOCK_NO_CHANGE 0 -#define SQL_LOCK_EXCLUSIVE 1 -#define SQL_LOCK_UNLOCK 2 - -#define SQL_POSITION_TO(hstmt,irow) \ - SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) -#define SQL_LOCK_RECORD(hstmt,irow,fLock) \ - SQLSetPos(hstmt,irow,SQL_POSITION,fLock) -#define SQL_REFRESH_RECORD(hstmt,irow,fLock) \ - SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) -#define SQL_UPDATE_RECORD(hstmt,irow) \ - SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) -#define SQL_DELETE_RECORD(hstmt,irow) \ - SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) -#define SQL_ADD_RECORD(hstmt,irow) \ - SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) - -/* - * Positioned Statements. A SQLINTEGER bitmask enumerating the supported - * positioned SQL statements. - */ -#define SQL_PS_POSITIONED_DELETE 0x00000001L -#define SQL_PS_POSITIONED_UPDATE 0x00000002L -#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L - -/* Qualifier Location. A SQLUSMALLINT value indicating the position of the - * catalog in a qualified table name. - */ -#define SQL_QL_START 0x0001 -#define SQL_QL_END 0x0002 - -/* - * Qualifier Usage. A SQLUINTEGER bitmask. - */ -#define SQL_QU_DML_STATEMENTS 0x00000001L -#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L -#define SQL_QU_TABLE_DEFINITION 0x00000004L -#define SQL_QU_INDEX_DEFINITION 0x00000008L -#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L - -/* The above is renamed in ODBC 3.0 to Catalog Usage. */ -#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS -#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION -#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION -#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION -#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION - -/* ODBC 3.0 renamed the above to Catalog Location. */ -#define SQL_CL_START SQL_QL_START -#define SQL_CL_END SQL_QL_END - -/* - * Scroll Concurrency. A SQLINTEGER bitmask enumerating the concurrency - * control options supported for the cursor. Depreciated in ODBC 3.0. - */ -#define SQL_SCCO_READ_ONLY 0x00000001L -#define SQL_SCCO_LOCK 0x00000002L -#define SQL_SCCO_OPT_ROWVER 0x00000004L -#define SQL_SCCO_OPT_VALUES 0x00000008L - - -/* - * Scroll Options. A SQLUINTEGER bitmask enumerating the scroll options - * supported for scrollable cursors. - */ -#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 - -/* - * Static Sensitity. A SQLINTEGER bitmask enumerating whether changes made - * by an application to a static or keyset-driven cursor through SQLSetPos - * or positioned update or delete statements can be detected by that - * application. - */ -#define SQL_SS_ADDITIONS 0x00000001L -#define SQL_SS_DELETIONS 0x00000002L -#define SQL_SS_UPDATES 0x00000004L - -/* - * String Functions. A SQLUINTEGER bitmask enumerating the scalar string - * functions supported by the driver and associated data source. - */ -#define SQL_FN_STR_CONCAT 0x00000001L -#define SQL_FN_STR_INSERT 0x00000002L -#define SQL_FN_STR_LEFT 0x00000004L -#define SQL_FN_STR_LTRIM 0x00000008L -#define SQL_FN_STR_LENGTH 0x00000010L -#define SQL_FN_STR_LOCATE 0x00000020L -#define SQL_FN_STR_LCASE 0x00000040L -#define SQL_FN_STR_REPEAT 0x00000080L -#define SQL_FN_STR_REPLACE 0x00000100L -#define SQL_FN_STR_RIGHT 0x00000200L -#define SQL_FN_STR_RTRIM 0x00000400L -#define SQL_FN_STR_SUBSTRING 0x00000800L -#define SQL_FN_STR_UCASE 0x00001000L -#define SQL_FN_STR_ASCII 0x00002000L -#define SQL_FN_STR_CHAR 0x00004000L -#define SQL_FN_STR_DIFFERENCE 0x00008000L -#define SQL_FN_STR_LOCATE_2 0x00010000L -#define SQL_FN_STR_SOUNDEX 0x00020000L -#define SQL_FN_STR_SPACE 0x00040000L - -/* introduced in ODBC 3.0 */ -#define SQL_FN_STR_BIT_LENGTH 0x00080000L -#define SQL_FN_STR_CHAR_LENGTH 0x00100000L -#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L -#define SQL_FN_STR_OCTET_LENGTH 0x00400000L -#define SQL_FN_STR_POSITION 0x00800000L - -/* - * Subqueries. A SQLUINTEGER bitmask enumerating the predicates that support - * subqueries. - */ -#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 - -/* - * System Functions. A SQLUINTEGER bitmask enumerating the scalar system - * functions supported by the driver and associated data source. - */ -#define SQL_FN_SYS_USERNAME 0x00000001L -#define SQL_FN_SYS_DBNAME 0x00000002L -#define SQL_FN_SYS_IFNULL 0x00000004L - -/* - * Time-Date add and diff intervals. A SQLUINTEGER bitmask enumerating the - * timestamp intervals supported by the driver and associated data source - * for the TIMESTAMPADD and TIMESTAMPDIFF scalar function. - */ -#define SQL_FN_TSI_FRAC_SECOND 0x00000001L -#define SQL_FN_TSI_SECOND 0x00000002L -#define SQL_FN_TSI_MINUTE 0x00000004L -#define SQL_FN_TSI_HOUR 0x00000008L -#define SQL_FN_TSI_DAY 0x00000010L -#define SQL_FN_TSI_WEEK 0x00000020L -#define SQL_FN_TSI_MONTH 0x00000040L -#define SQL_FN_TSI_QUARTER 0x00000080L -#define SQL_FN_TSI_YEAR 0x00000100L - -/* - * Time/Date functions. A SQLUINTEGER bitmask enumerating the scalar date - * and time functions supported by the driver and associated data source. - */ -#define SQL_FN_TD_NOW 0x00000001L -#define SQL_FN_TD_CURDATE 0x00000002L -#define SQL_FN_TD_DAYOFMONTH 0x00000004L -#define SQL_FN_TD_DAYOFWEEK 0x00000008L -#define SQL_FN_TD_DAYOFYEAR 0x00000010L -#define SQL_FN_TD_MONTH 0x00000020L -#define SQL_FN_TD_QUARTER 0x00000040L -#define SQL_FN_TD_WEEK 0x00000080L -#define SQL_FN_TD_YEAR 0x00000100L -#define SQL_FN_TD_CURTIME 0x00000200L -#define SQL_FN_TD_HOUR 0x00000400L -#define SQL_FN_TD_MINUTE 0x00000800L -#define SQL_FN_TD_SECOND 0x00001000L -#define SQL_FN_TD_TIMESTAMPADD 0x00002000L -#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L -#define SQL_FN_TD_DAYNAME 0x00008000L -#define SQL_FN_TD_MONTHNAME 0x00010000L - -/* Added in ODBC 3.0 */ -#define SQL_FN_TD_CURRENT_DATE 0x00020000L -#define SQL_FN_TD_CURRENT_TIME 0x00040000L -#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L -#define SQL_FN_TD_EXTRACT 0x00100000L - -/* - * Transaction Capable. A SQLUSMALLINT value describing the transaction - * support in the driver or data source. - */ -#define SQL_TC_NONE 0x0000 -#define SQL_TC_DML 0x0001 -#define SQL_TC_ALL 0x0002 -#define SQL_TC_DDL_COMMIT 0x0003 -#define SQL_TC_DDL_IGNORE 0x0004 - -/* - * Unions. A SQLUINTEGER bitmask enumerating the support for the UNION - * clause. - */ -#define SQL_U_UNION 0x00000001L -#define SQL_U_UNION_ALL 0x00000002L - - -/* SQLStatistics: Type, Smallint */ -#define SQL_TABLE_STAT 0 -#define SQL_INDEX_CLUSTERED 1 -#define SQL_INDEX_HASHED 2 -#define SQL_INDEX_OTHER 3 - -/* SQLProcedures: Type: Smallint */ -#define SQL_PT_UNKNOWN 0 -#define SQL_PT_PROCEDURE 1 -#define SQL_PT_FUNCTION 2 - -/* SQLSpecialColumns: PSEUDO_COLUMN: Smallint */ -#define SQL_PC_UNKNOWN 0 -#define SQL_PC_PSEUDO 1 -#define SQL_PC_NOT_PSEUDO 2 - -/* SQLSet/Get/StmtOptions: ASYNC_ENABLE. A SQLUINTEGER */ -#define SQL_ASYNC_ENABLE_OFF 0UL -#define SQL_ASYNC_ENABLE_ON 1UL -#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF - -/* - * SQLSet/GetStmtOptions: CONCURRENCY. A SQLUINTEGER. Note most of these - * are above in the original isqlext.h code. - */ -#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY - -/* - * SQLSet/GetStmtOptions: CURSOR_SCROLLABLE. A SQLUINTEGER. Added in ODBC - * 3.0. - */ -#define SQL_NONSCROLLABLE 0UL -#define SQL_SCROLLABLE 1UL -#define SQL_CURSOR_SCROLLABLE_DEFAULT SQL_NONSCROLLABLE - -/* - * SQLSet/GetStmtOptions: CURSOR_SENSITITY. A SQLUINTEGER. Added in ODBC - * 3.0. - */ -#define SQL_UNSPECIFIED 0UL -#define SQL_INSENSITIVE 1UL -#define SQL_SENSITIVIE 2UL -#define SQL_CURSOR_SENSITIVITY_DEFAULT SQL_UNSPECIFIED - -/* - * SQLSet/GetStmtOptions: CURSOR_TYPE: A SQLUINTEGER value that specifies the - * cursor type - */ -#define SQL_CURSOR_FORWARD_ONLY 0UL -#define SQL_CURSOR_KEYSET_DRIVEN 1UL -#define SQL_CURSOR_DYNAMIC 2UL -#define SQL_CURSOR_STATIC 3UL -#define SQL_CURSOR_DEFAULT SQL_CURSOR_FORWARD_ONLY - -/* - * ENABLE_AUTO_IPD: A SQLUINTEGER, either SQL_TRUE or SQL_FALSE. Default - * dependent on connection option SQL_ATTR_AUTO_IPD. Added in ODBC 3.0. - */ - -/* - * METADATA_ID: A SQLUINTEGER, either SQL_TRUE or SQL_FALSE. Added in - * ODBC 3.0. - */ -#define SQL_ATTR_METADATA_ID_DEFAULT SQL_FALSE - -/* - * SQLSet/GetStmtOptions: NOSCAN. A SQLUINTEGER value that indicates whether - * the driver should scan SQL strings for escape sequences. - */ -#define SQL_NOSCAN_OFF 0UL -#define SQL_NOSCAN_ON 1UL -#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF - -/* - * SQLSet/GetStmtOptions: PARAM_OPERATION: SQLUSMALLINT *. Added in ODBC 3.0 - * - */ -#define SQL_PARAM_PROCEED 0 -#define SQL_PARAM_IGNORE 1 - -/* - * SQLSet/GetStmtOptions: PARAM_STATUS: SQLUSMALLINT *. Added in ODBC 3.0 - * -*/ -#define SQL_PARAM_SUCCESS 0 -#define SQL_PARAM_SUCCESS_WITH_INFO 6 -#define SQL_PARAM_ERROR 5 -#define SQL_PARAM_UNUSED 7 -#define SQL_PARAM_DIAG_UNAVAILABLE 1 - -/* - * SQLSet/GetStmtOptions: RETRIEVE_DATA: SQLUINTEGER value. - */ -#define SQL_RD_OFF 0UL -#define SQL_RD_ON 1UL -#define SQL_RD_DEFAULT SQL_RD_ON - -/* - * SQLSet/GetStmtOptions: BIND_TYPE: SQLUINTEGER. sets binding orientation. - */ -#define SQL_BIND_BY_COLUMN 0UL -#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN - -/* - * SQLSet/GetStmtOptions: ROW_OPERATION: SQLUSMALLINT *. Added in ODBC 3.0 - */ -#define SQL_ROW_PROCEED 0 -#define SQL_ROW_IGNORE 1 - -/* - * SQL_ROWSET_SIZE - */ -#define SQL_ROWSET_SIZE_DEFAULT 1UL - -/* - * SQL_KEYSET_SIZE - */ -#define SQL_KEYSET_SIZE_DEFAULT 0UL - -/* - * SQLSet/GetStmtOptions: SIMULATE_CURSOR: SQLUINTEGER value that specifies - * whether drivers that simulate positioned update and delete statements - * guarantee that such statements affect only a single row. - */ -#define SQL_SC_NON_UNIQUE 0UL -#define SQL_SC_TRY_UNIQUE 1UL -#define SQL_SC_UNIQUE 2UL - -/* - * SQLSet/GetStmtOptions: USE_BOOKMARKS: SQLUINTEGER value that specifies - * whether an application will use bookmarks with a cursor. - */ -#define SQL_UB_OFF 0UL -#define SQL_UB_ON 1UL -#define SQL_UB_FIXED SQL_UB_ON /* Deprecated in ODBC - * 3.0 */ -#define SQL_UB_VARIABLE 2UL /* Added in ODBC 3.0 */ -#define SQL_UB_DEFAULT SQL_UB_OFF - -/* Deprecated */ -#define SQL_DATABASE_NAME 16 -#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR -#define SQL_FETCH_PREV SQL_FETCH_PRIOR -#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER -#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER -#define SQL_CC_DELETE SQL_CB_DELETE -#define SQL_CR_DELETE SQL_CB_DELETE -#define SQL_CC_CLOSE SQL_CB_CLOSE -#define SQL_CR_CLOSE SQL_CB_CLOSE -#define SQL_CC_PRESERVE SQL_CB_PRESERVE -#define SQL_CR_PRESERVE SQL_CB_PRESERVE -#define SQL_FETCH_RESUME 7 -#define SQL_SCROLL_FORWARD_ONLY 0L -#define SQL_SCROLL_KEYSET_DRIVEN (-1L) -#define SQL_SCROLL_DYNAMIC (-2L) -#define SQL_SCROLL_STATIC (-3L) - -/* - * ODBC keywords - */ -#define SQL_ODBC_KEYWORDS \ -"ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ -"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ -"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ -"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ -"COBOL,COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ -"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ -"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ -"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ -"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ -"DISTINCT,DOMAIN,DOUBLE,DROP,"\ -"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ -"EXISTS,EXTERNAL,EXTRACT,"\ -"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ -"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ -"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ -"INPUT,INSENSITIVE,INSERT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ -"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ -"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,MUMPS,"\ -"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ -"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ -"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ -"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ -"REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS,"\ -"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SEQUENCE,SESSION,SESSION_USER,SET,SIZE,"\ -"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ -"SUBSTRING,SUM,SYSTEM_USER,"\ -"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ -"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ -"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ -"VALUE,,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,YEAR" - -#ifdef __cplusplus -extern "C" -{ -#endif - -RETCODE SQL_API SQLSetConnectOption(HDBC, UWORD, UDWORD); -RETCODE SQL_API SQLNumResultCols(HSTMT, SWORD FAR *); - -/* - * function prototypes previously missing from isqlext.h - */ -RETCODE SQL_API SQLColumns(HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UCHAR FAR * szColumnName, - SWORD cbColumnName); - -RETCODE SQL_API SQLDriverConnect(HDBC hdbc, - HWND hwnd, - UCHAR FAR * szConnStrIn, - SWORD cbConnStrIn, - UCHAR FAR * szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR * pcbConnStrOut, - UWORD fDriverCompletion); - -RETCODE SQL_API SQLGetConnectOption(HDBC hdbc, - UWORD fOption, - PTR pvParam); - -RETCODE SQL_API SQLGetData(HSTMT hstmt, - UWORD icol, - SWORD fCType, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR * pcbValue); - -RETCODE SQL_API SQLGetFunctions(HDBC hdbc, - UWORD fFunction, - UWORD FAR * pfExists); - -RETCODE SQL_API SQLGetInfo(HDBC hdbc, - UWORD fInfoType, - PTR rgbInfoValue, - SWORD cbInfoValueMax, - SWORD FAR * pcbInfoValue); - -RETCODE SQL_API SQLGetStmtOption(HSTMT hstmt, - UWORD fOption, - PTR pvParam); - -RETCODE SQL_API SQLGetTypeInfo(HSTMT hstmt, - SWORD fSqlType); - -RETCODE SQL_API SQLParamData(HSTMT hstmt, - PTR FAR * prgbValue); - -RETCODE SQL_API SQLPutData(HSTMT hstmt, - PTR rgbValue, - SDWORD cbValue); - -RETCODE SQL_API SQLSetStmtOption(HSTMT hstmt, - UWORD fOption, - UDWORD vParam); - -RETCODE SQL_API SQLSpecialColumns(HSTMT hstmt, - UWORD fColType, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UWORD fScope, - UWORD fNullable); - -RETCODE SQL_API SQLStatistics(HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UWORD fUnique, - UWORD fAccuracy); - -RETCODE SQL_API SQLTables(HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UCHAR FAR * szTableType, - SWORD cbTableType); - -RETCODE SQL_API SQLBrowseConnect(HDBC hdbc, - UCHAR FAR * szConnStrIn, - SWORD cbConnStrIn, - UCHAR FAR * szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR * pcbConnStrOut); - -RETCODE SQL_API SQLColumnPrivileges(HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName, - UCHAR FAR * szColumnName, - SWORD cbColumnName); - -RETCODE SQL_API SQLDescribeParam(HSTMT hstmt, - UWORD ipar, - SWORD FAR * pfSqlType, - UDWORD FAR * pcbColDef, - SWORD FAR * pibScale, - SWORD FAR * pfNullable); - -RETCODE SQL_API SQLExtendedFetch(HSTMT hstmt, - UWORD fFetchType, - SDWORD irow, - UDWORD FAR * pcrow, - UWORD FAR * rgfRowStatus); - -RETCODE SQL_API SQLForeignKeys(HSTMT hstmt, - UCHAR FAR * szPkTableQualifier, - SWORD cbPkTableQualifier, - UCHAR FAR * szPkTableOwner, - SWORD cbPkTableOwner, - UCHAR FAR * szPkTableName, - SWORD cbPkTableName, - UCHAR FAR * szFkTableQualifier, - SWORD cbFkTableQualifier, - UCHAR FAR * szFkTableOwner, - SWORD cbFkTableOwner, - UCHAR FAR * szFkTableName, - SWORD cbFkTableName); - -RETCODE SQL_API SQLMoreResults(HSTMT hstmt); - -RETCODE SQL_API SQLNativeSql(HDBC hdbc, - UCHAR FAR * szSqlStrIn, - SDWORD cbSqlStrIn, - UCHAR FAR * szSqlStr, - SDWORD cbSqlStrMax, - SDWORD FAR * pcbSqlStr); - -RETCODE SQL_API SQLNumParams(HSTMT hstmt, - SWORD FAR * pcpar); - -RETCODE SQL_API SQLParamOptions(HSTMT hstmt, - UDWORD crow, - UDWORD FAR * pirow); - -RETCODE SQL_API SQLPrimaryKeys(HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName); - -RETCODE SQL_API SQLProcedureColumns(HSTMT hstmt, - UCHAR FAR * szProcQualifier, - SWORD cbProcQualifier, - UCHAR FAR * szProcOwner, - SWORD cbProcOwner, - UCHAR FAR * szProcName, - SWORD cbProcName, - UCHAR FAR * szColumnName, - SWORD cbColumnName); - -RETCODE SQL_API SQLProcedures(HSTMT hstmt, - UCHAR FAR * szProcQualifier, - SWORD cbProcQualifier, - UCHAR FAR * szProcOwner, - SWORD cbProcOwner, - UCHAR FAR * szProcName, - SWORD cbProcName); - -RETCODE SQL_API SQLSetPos(HSTMT hstmt, - UWORD irow, - UWORD fOption, - UWORD fLock); - -RETCODE SQL_API SQLTablePrivileges(HSTMT hstmt, - UCHAR FAR * szTableQualifier, - SWORD cbTableQualifier, - UCHAR FAR * szTableOwner, - SWORD cbTableOwner, - UCHAR FAR * szTableName, - SWORD cbTableName); - -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); - -RETCODE SQL_API SQLSetScrollOptions(HSTMT hstmt, - UWORD fConcurrency, - SDWORD crowKeyset, - UWORD crowRowset); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/interfaces/odbc/license.txt b/src/interfaces/odbc/license.txt deleted file mode 100644 index bdf8ab0cb3..0000000000 --- a/src/interfaces/odbc/license.txt +++ /dev/null @@ -1,962 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - - Version 2, June 1991 - - - - Copyright (C) 1991 Free Software Foundation, Inc. - - 675 Mass Ave, Cambridge, MA 02139, USA - - Everyone is permitted to copy and distribute verbatim copies - - of this license document, but changing it is not allowed. - - - -[This is the first released version of the library GPL. It is - - numbered 2 because it goes with version 2 of the ordinary GPL.] - - - - Preamble - - - - The licenses for most software are designed to take away your - -freedom to share and change it. By contrast, the GNU General Public - -Licenses are intended to guarantee your freedom to share and change - -free software--to make sure the software is free for all its users. - - - - This license, the Library General Public License, applies to some - -specially designated Free Software Foundation software, and to any - -other libraries whose authors decide to use it. You can use it for - -your libraries, too. - - - - When we speak of free software, we are referring to freedom, not - -price. Our General Public Licenses are designed to make sure that you - -have the freedom to distribute copies of free software (and charge for - -this service if you wish), that you receive source code or can get it - -if you want it, that you can change the software or use pieces of it - -in new free programs; and that you know you can do these things. - - - - To protect your rights, we need to make restrictions that forbid - -anyone to deny you these rights or to ask you to surrender the rights. - -These restrictions translate to certain responsibilities for you if - -you distribute copies of the library, or if you modify it. - - - - For example, if you distribute copies of the library, whether gratis - -or for a fee, you must give the recipients all the rights that we gave - -you. You must make sure that they, too, receive or can get the source - -code. If you link a program with the library, you must provide - -complete object files to the recipients so that they can relink them - -with the library, after making changes to the library and recompiling - -it. And you must show them these terms so they know their rights. - - - - Our method of protecting your rights has two steps: (1) copyright - -the library, and (2) offer you this license which gives you legal - -permission to copy, distribute and/or modify the library. - - - - Also, for each distributor's protection, we want to make certain - -that everyone understands that there is no warranty for this free - -library. If the library is modified by someone else and passed on, we - -want its recipients to know that what they have is not the original - -version, so that any problems introduced by others will not reflect on - -the original authors' reputations. - - - - Finally, any free program is threatened constantly by software - -patents. We wish to avoid the danger that companies distributing free - -software will individually obtain patent licenses, thus in effect - -transforming the program into proprietary software. To prevent this, - -we have made it clear that any patent must be licensed for everyone's - -free use or not licensed at all. - - - - Most GNU software, including some libraries, is covered by the ordinary - -GNU General Public License, which was designed for utility programs. This - -license, the GNU Library General Public License, applies to certain - -designated libraries. This license is quite different from the ordinary - -one; be sure to read it in full, and don't assume that anything in it is - -the same as in the ordinary license. - - - - The reason we have a separate public license for some libraries is that - -they blur the distinction we usually make between modifying or adding to a - -program and simply using it. Linking a program with a library, without - -changing the library, is in some sense simply using the library, and is - -analogous to running a utility program or application program. However, in - -a textual and legal sense, the linked executable is a combined work, a - -derivative of the original library, and the ordinary General Public License - -treats it as such. - - - - Because of this blurred distinction, using the ordinary General - -Public License for libraries did not effectively promote software - -sharing, because most developers did not use the libraries. We - -concluded that weaker conditions might promote sharing better. - - - - However, unrestricted linking of non-free programs would deprive the - -users of those programs of all benefit from the free status of the - -libraries themselves. This Library General Public License is intended to - -permit developers of non-free programs to use free libraries, while - -preserving your freedom as a user of such programs to change the free - -libraries that are incorporated in them. (We have not seen how to achieve - -this as regards changes in header files, but we have achieved it as regards - -changes in the actual functions of the Library.) The hope is that this - -will lead to faster development of free libraries. - - - - The precise terms and conditions for copying, distribution and - -modification follow. Pay close attention to the difference between a - -"work based on the library" and a "work that uses the library". The - -former contains code derived from the library, while the latter only - -works together with the library. - - - - Note that it is possible for a library to be covered by the ordinary - -General Public License rather than by this special one. - - - - GNU LIBRARY GENERAL PUBLIC LICENSE - - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - - - 0. This License Agreement applies to any software library which - -contains a notice placed by the copyright holder or other authorized - -party saying it may be distributed under the terms of this Library - -General Public License (also called "this License"). Each licensee is - -addressed as "you". - - - - A "library" means a collection of software functions and/or data - -prepared so as to be conveniently linked with application programs - -(which use some of those functions and data) to form executables. - - - - The "Library", below, refers to any such software library or work - -which has been distributed under these terms. A "work based on the - -Library" means either the Library or any derivative work under - -copyright law: that is to say, a work containing the Library or a - -portion of it, either verbatim or with modifications and/or translated - -straightforwardly into another language. (Hereinafter, translation is - -included without limitation in the term "modification".) - - - - "Source code" for a work means the preferred form of the work for - -making modifications to it. For a library, complete source code means - -all the source code for all modules it contains, plus any associated - -interface definition files, plus the scripts used to control compilation - -and installation of the library. - - - - Activities other than copying, distribution and modification are not - -covered by this License; they are outside its scope. The act of - -running a program using the Library is not restricted, and output from - -such a program is covered only if its contents constitute a work based - -on the Library (independent of the use of the Library in a tool for - -writing it). Whether that is true depends on what the Library does - -and what the program that uses the Library does. - - - - 1. You may copy and distribute verbatim copies of the Library's - -complete source code as you receive it, in any medium, provided that - -you conspicuously and appropriately publish on each copy an - -appropriate copyright notice and disclaimer of warranty; keep intact - -all the notices that refer to this License and to the absence of any - -warranty; and distribute a copy of this License along with the - -Library. - - - - You may charge a fee for the physical act of transferring a copy, - -and you may at your option offer warranty protection in exchange for a - -fee. - - - - 2. You may modify your copy or copies of the Library or any portion - -of it, thus forming a work based on the Library, and copy and - -distribute such modifications or work under the terms of Section 1 - -above, provided that you also meet all of these conditions: - - - - a) The modified work must itself be a software library. - - - - b) You must cause the files modified to carry prominent notices - - stating that you changed the files and the date of any change. - - - - c) You must cause the whole of the work to be licensed at no - - charge to all third parties under the terms of this License. - - - - d) If a facility in the modified Library refers to a function or a - - table of data to be supplied by an application program that uses - - the facility, other than as an argument passed when the facility - - is invoked, then you must make a good faith effort to ensure that, - - in the event an application does not supply such function or - - table, the facility still operates, and performs whatever part of - - its purpose remains meaningful. - - - - (For example, a function in a library to compute square roots has - - a purpose that is entirely well-defined independent of the - - application. Therefore, Subsection 2d requires that any - - application-supplied function or table used by this function must - - be optional: if the application does not supply it, the square - - root function must still compute square roots.) - - - -These requirements apply to the modified work as a whole. If - -identifiable sections of that work are not derived from the Library, - -and can be reasonably considered independent and separate works in - -themselves, then this License, and its terms, do not apply to those - -sections when you distribute them as separate works. But when you - -distribute the same sections as part of a whole which is a work based - -on the Library, the distribution of the whole must be on the terms of - -this License, whose permissions for other licensees extend to the - -entire whole, and thus to each and every part regardless of who wrote - -it. - - - -Thus, it is not the intent of this section to claim rights or contest - -your rights to work written entirely by you; rather, the intent is to - -exercise the right to control the distribution of derivative or - -collective works based on the Library. - - - -In addition, mere aggregation of another work not based on the Library - -with the Library (or with a work based on the Library) on a volume of - -a storage or distribution medium does not bring the other work under - -the scope of this License. - - - - 3. You may opt to apply the terms of the ordinary GNU General Public - -License instead of this License to a given copy of the Library. To do - -this, you must alter all the notices that refer to this License, so - -that they refer to the ordinary GNU General Public License, version 2, - -instead of to this License. (If a newer version than version 2 of the - -ordinary GNU General Public License has appeared, then you can specify - -that version instead if you wish.) Do not make any other change in - -these notices. - - - - Once this change is made in a given copy, it is irreversible for - -that copy, so the ordinary GNU General Public License applies to all - -subsequent copies and derivative works made from that copy. - - - - This option is useful when you wish to copy part of the code of - -the Library into a program that is not a library. - - - - 4. You may copy and distribute the Library (or a portion or - -derivative of it, under Section 2) in object code or executable form - -under the terms of Sections 1 and 2 above provided that you accompany - -it with the complete corresponding machine-readable source code, which - -must be distributed under the terms of Sections 1 and 2 above on a - -medium customarily used for software interchange. - - - - If distribution of object code is made by offering access to copy - -from a designated place, then offering equivalent access to copy the - -source code from the same place satisfies the requirement to - -distribute the source code, even though third parties are not - -compelled to copy the source along with the object code. - - - - 5. A program that contains no derivative of any portion of the - -Library, but is designed to work with the Library by being compiled or - -linked with it, is called a "work that uses the Library". Such a - -work, in isolation, is not a derivative work of the Library, and - -therefore falls outside the scope of this License. - - - - However, linking a "work that uses the Library" with the Library - -creates an executable that is a derivative of the Library (because it - -contains portions of the Library), rather than a "work that uses the - -library". The executable is therefore covered by this License. - -Section 6 states terms for distribution of such executables. - - - - When a "work that uses the Library" uses material from a header file - -that is part of the Library, the object code for the work may be a - -derivative work of the Library even though the source code is not. - -Whether this is true is especially significant if the work can be - -linked without the Library, or if the work is itself a library. The - -threshold for this to be true is not precisely defined by law. - - - - If such an object file uses only numerical parameters, data - -structure layouts and accessors, and small macros and small inline - -functions (ten lines or less in length), then the use of the object - -file is unrestricted, regardless of whether it is legally a derivative - -work. (Executables containing this object code plus portions of the - -Library will still fall under Section 6.) - - - - Otherwise, if the work is a derivative of the Library, you may - -distribute the object code for the work under the terms of Section 6. - -Any executables containing that work also fall under Section 6, - -whether or not they are linked directly with the Library itself. - - - - 6. As an exception to the Sections above, you may also compile or - -link a "work that uses the Library" with the Library to produce a - -work containing portions of the Library, and distribute that work - -under terms of your choice, provided that the terms permit - -modification of the work for the customer's own use and reverse - -engineering for debugging such modifications. - - - - You must give prominent notice with each copy of the work that the - -Library is used in it and that the Library and its use are covered by - -this License. You must supply a copy of this License. If the work - -during execution displays copyright notices, you must include the - -copyright notice for the Library among them, as well as a reference - -directing the user to the copy of this License. Also, you must do one - -of these things: - - - - a) Accompany the work with the complete corresponding - - machine-readable source code for the Library including whatever - - changes were used in the work (which must be distributed under - - Sections 1 and 2 above); and, if the work is an executable linked - - with the Library, with the complete machine-readable "work that - - uses the Library", as object code and/or source code, so that the - - user can modify the Library and then relink to produce a modified - - executable containing the modified Library. (It is understood - - that the user who changes the contents of definitions files in the - - Library will not necessarily be able to recompile the application - - to use the modified definitions.) - - - - b) Accompany the work with a written offer, valid for at - - least three years, to give the same user the materials - - specified in Subsection 6a, above, for a charge no more - - than the cost of performing this distribution. - - - - c) If distribution of the work is made by offering access to copy - - from a designated place, offer equivalent access to copy the above - - specified materials from the same place. - - - - d) Verify that the user has already received a copy of these - - materials or that you have already sent this user a copy. - - - - For an executable, the required form of the "work that uses the - -Library" must include any data and utility programs needed for - -reproducing the executable from it. However, as a special exception, - -the source code distributed need not include anything that is normally - -distributed (in either source or binary form) with the major - -components (compiler, kernel, and so on) of the operating system on - -which the executable runs, unless that component itself accompanies - -the executable. - - - - It may happen that this requirement contradicts the license - -restrictions of other proprietary libraries that do not normally - -accompany the operating system. Such a contradiction means you cannot - -use both them and the Library together in an executable that you - -distribute. - - - - 7. You may place library facilities that are a work based on the - -Library side-by-side in a single library together with other library - -facilities not covered by this License, and distribute such a combined - -library, provided that the separate distribution of the work based on - -the Library and of the other library facilities is otherwise - -permitted, and provided that you do these two things: - - - - a) Accompany the combined library with a copy of the same work - - based on the Library, uncombined with any other library - - facilities. This must be distributed under the terms of the - - Sections above. - - - - b) Give prominent notice with the combined library of the fact - - that part of it is a work based on the Library, and explaining - - where to find the accompanying uncombined form of the same work. - - - - 8. You may not copy, modify, sublicense, link with, or distribute - -the Library except as expressly provided under this License. Any - -attempt otherwise to copy, modify, sublicense, link with, or - -distribute the Library is void, and will automatically terminate your - -rights under this License. However, parties who have received copies, - -or rights, from you under this License will not have their licenses - -terminated so long as such parties remain in full compliance. - - - - 9. You are not required to accept this License, since you have not - -signed it. However, nothing else grants you permission to modify or - -distribute the Library or its derivative works. These actions are - -prohibited by law if you do not accept this License. Therefore, by - -modifying or distributing the Library (or any work based on the - -Library), you indicate your acceptance of this License to do so, and - -all its terms and conditions for copying, distributing or modifying - -the Library or works based on it. - - - - 10. Each time you redistribute the Library (or any work based on the - -Library), the recipient automatically receives a license from the - -original licensor to copy, distribute, link with or modify the Library - -subject to these terms and conditions. You may not impose any further - -restrictions on the recipients' exercise of the rights granted herein. - -You are not responsible for enforcing compliance by third parties to - -this License. - - - - 11. If, as a consequence of a court judgment or allegation of patent - -infringement or for any other reason (not limited to patent issues), - -conditions are imposed on you (whether by court order, agreement or - -otherwise) that contradict the conditions of this License, they do not - -excuse you from the conditions of this License. If you cannot - -distribute so as to satisfy simultaneously your obligations under this - -License and any other pertinent obligations, then as a consequence you - -may not distribute the Library at all. For example, if a patent - -license would not permit royalty-free redistribution of the Library by - -all those who receive copies directly or indirectly through you, then - -the only way you could satisfy both it and this License would be to - -refrain entirely from distribution of the Library. - - - -If any portion of this section is held invalid or unenforceable under any - -particular circumstance, the balance of the section is intended to apply, - -and the section as a whole is intended to apply in other circumstances. - - - -It is not the purpose of this section to induce you to infringe any - -patents or other property right claims or to contest validity of any - -such claims; this section has the sole purpose of protecting the - -integrity of the free software distribution system which is - -implemented by public license practices. Many people have made - -generous contributions to the wide range of software distributed - -through that system in reliance on consistent application of that - -system; it is up to the author/donor to decide if he or she is willing - -to distribute software through any other system and a licensee cannot - -impose that choice. - - - -This section is intended to make thoroughly clear what is believed to - -be a consequence of the rest of this License. - - - - 12. If the distribution and/or use of the Library is restricted in - -certain countries either by patents or by copyrighted interfaces, the - -original copyright holder who places the Library under this License may add - -an explicit geographical distribution limitation excluding those countries, - -so that distribution is permitted only in or among countries not thus - -excluded. In such case, this License incorporates the limitation as if - -written in the body of this License. - - - - 13. The Free Software Foundation may publish revised and/or new - -versions of the Library General Public License from time to time. - -Such new versions will be similar in spirit to the present version, - -but may differ in detail to address new problems or concerns. - - - -Each version is given a distinguishing version number. If the Library - -specifies a version number of this License which applies to it and - -"any later version", you have the option of following the terms and - -conditions either of that version or of any later version published by - -the Free Software Foundation. If the Library does not specify a - -license version number, you may choose any version ever published by - -the Free Software Foundation. - - - - 14. If you wish to incorporate parts of the Library into other free - -programs whose distribution conditions are incompatible with these, - -write to the author to ask for permission. For software which is - -copyrighted by the Free Software Foundation, write to the Free - -Software Foundation; we sometimes make exceptions for this. Our - -decision will be guided by the two goals of preserving the free status - -of all derivatives of our free software and of promoting the sharing - -and reuse of software generally. - - - - NO WARRANTY - - - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO - -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. - -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR - -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY - -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE - -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE - -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME - -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN - -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY - -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU - -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR - -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE - -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING - -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A - -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF - -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - -DAMAGES. - - - - END OF TERMS AND CONDITIONS - - - - Appendix: How to Apply These Terms to Your New Libraries - - - - If you develop a new library, and you want it to be of the greatest - -possible use to the public, we recommend making it free software that - -everyone can redistribute and change. You can do so by permitting - -redistribution under these terms (or, alternatively, under the terms of the - -ordinary General Public License). - - - - To apply these terms, attach the following notices to the library. It is - -safest to attach them to the start of each source file to most effectively - -convey the exclusion of warranty; and each file should have at least the - -"copyright" line and a pointer to where the full notice is found. - - - - - - Copyright (C) - - - - This library is free software; you can redistribute it and/or - - modify it under the terms of the GNU Library General Public - - License as published by the Free Software Foundation; either - - version 2 of the License, or (at your option) any later version. - - - - This library 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 - - Library General Public License for more details. - - - - You should have received a copy of the GNU Library General Public - - License along with this library; if not, write to the Free - - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - - -Also add information on how to contact you by electronic and paper mail. - - - -You should also get your employer (if you work as a programmer) or your - -school, if any, to sign a "copyright disclaimer" for the library, if - -necessary. Here is a sample; alter the names: - - - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - - - , 1 April 1990 - - Ty Coon, President of Vice - - - -That's all there is to it! - diff --git a/src/interfaces/odbc/lobj.c b/src/interfaces/odbc/lobj.c deleted file mode 100644 index 6b55b82d54..0000000000 --- a/src/interfaces/odbc/lobj.c +++ /dev/null @@ -1,186 +0,0 @@ -/*-------- - * Module: lobj.c - * - * Description: This module contains routines related to manipulating - * large objects. - * - * Classes: none - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ - -#include "lobj.h" - -#include "connection.h" - - -Oid -lo_creat(ConnectionClass *conn, int mode) -{ - LO_ARG argv[1]; - int retval, - result_len; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = mode; - - if (!CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1)) - return 0; /* invalid oid */ - else - return retval; -} - - -int -lo_open(ConnectionClass *conn, int lobjId, int mode) -{ - int fd; - int result_len; - LO_ARG argv[2]; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = lobjId; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = mode; - - if (!CC_send_function(conn, LO_OPEN, &fd, &result_len, 1, argv, 2)) - return -1; - - if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0) - return -1; - - return fd; -} - - -int -lo_close(ConnectionClass *conn, int fd) -{ - LO_ARG argv[1]; - int retval, - result_len; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - if (!CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1)) - return -1; - else - return retval; -} - - -int -lo_read(ConnectionClass *conn, int fd, char *buf, int len) -{ - LO_ARG argv[2]; - int result_len; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = len; - - if (!CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2)) - return -1; - else - return result_len; -} - - -int -lo_write(ConnectionClass *conn, int fd, char *buf, int len) -{ - LO_ARG argv[2]; - int retval, - result_len; - - if (len <= 0) - return 0; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 0; - argv[1].len = len; - argv[1].u.ptr = (char *) buf; - - if (!CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2)) - return -1; - else - return retval; -} - - -int -lo_lseek(ConnectionClass *conn, int fd, int offset, int whence) -{ - LO_ARG argv[3]; - int retval, - result_len; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = offset; - - argv[2].isint = 1; - argv[2].len = 4; - argv[2].u.integer = whence; - - if (!CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3)) - return -1; - else - return retval; -} - - -int -lo_tell(ConnectionClass *conn, int fd) -{ - LO_ARG argv[1]; - int retval, - result_len; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - if (!CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1)) - return -1; - else - return retval; -} - - -int -lo_unlink(ConnectionClass *conn, Oid lobjId) -{ - LO_ARG argv[1]; - int retval, - result_len; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = lobjId; - - if (!CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1)) - return -1; - else - return retval; -} diff --git a/src/interfaces/odbc/lobj.h b/src/interfaces/odbc/lobj.h deleted file mode 100644 index 4d720488a0..0000000000 --- a/src/interfaces/odbc/lobj.h +++ /dev/null @@ -1,47 +0,0 @@ -/* File: lobj.h - * - * Description: See "lobj.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __LOBJ_H__ -#define __LOBJ_H__ - - -#include "psqlodbc.h" - -struct lo_arg -{ - int isint; - int len; - union - { - int integer; - char *ptr; - } u; -}; - -#define LO_CREAT 957 -#define LO_OPEN 952 -#define LO_CLOSE 953 -#define LO_READ 954 -#define LO_WRITE 955 -#define LO_LSEEK 956 -#define LO_TELL 958 -#define LO_UNLINK 964 - -#define INV_WRITE 0x00020000 -#define INV_READ 0x00040000 - -Oid lo_creat(ConnectionClass *conn, int mode); -int lo_open(ConnectionClass *conn, int lobjId, int mode); -int lo_close(ConnectionClass *conn, int fd); -int lo_read(ConnectionClass *conn, int fd, char *buf, int len); -int lo_write(ConnectionClass *conn, int fd, char *buf, int len); -int lo_lseek(ConnectionClass *conn, int fd, int offset, int len); -int lo_tell(ConnectionClass *conn, int fd); -int lo_unlink(ConnectionClass *conn, Oid lobjId); - -#endif diff --git a/src/interfaces/odbc/md5.c b/src/interfaces/odbc/md5.c deleted file mode 100644 index 1fd69056d1..0000000000 --- a/src/interfaces/odbc/md5.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * md5.c - * - * Implements the MD5 Message-Digest Algorithm as specified in - * RFC 1321. This implementation is a simple one, in that it - * needs every input byte to be buffered before doing any - * calculations. I do not expect this file to be used for - * general purpose MD5'ing of large amounts of data, only for - * generating hashed passwords from limited input. - * - * Sverre H. Huseby - * - * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/odbc/Attic/md5.c,v 1.8 2002/06/20 20:29:54 momjian Exp $ - */ - - -/* - * NOTE: - * - * There are two copies of this file, one in backend/libpq and another - * in interfaces/odbc. They should be identical. This is done so ODBC - * can be compiled stand-alone. - */ - -#ifndef MD5_ODBC -#include "postgres.h" -#include "libpq/crypt.h" -#else -#include "md5.h" -#endif - -#ifdef FRONTEND -#undef palloc -#define palloc malloc -#undef pfree -#define pfree free -#endif - - -/* - * PRIVATE FUNCTIONS - */ - - -/* - * The returned array is allocated using malloc. the caller should free it - * when it is no longer needed. - */ -static uint8 * -createPaddedCopyWithLength(uint8 *b, uint32 *l) -{ - uint8 *ret; - uint32 q; - uint32 len, - newLen448; - uint32 len_high, - len_low; /* 64-bit value split into 32-bit sections */ - - len = ((b == NULL) ? 0 : *l); - newLen448 = len + 64 - (len % 64) - 8; - if (newLen448 <= len) - newLen448 += 64; - - *l = newLen448 + 8; - if ((ret = (uint8 *) malloc(sizeof(uint8) * *l)) == NULL) - return NULL; - - if (b != NULL) - memcpy(ret, b, sizeof(uint8) * len); - - /* pad */ - ret[len] = 0x80; - for (q = len + 1; q < newLen448; q++) - ret[q] = 0x00; - - /* append length as a 64 bit bitcount */ - len_low = len; - /* split into two 32-bit values */ - /* we only look at the bottom 32-bits */ - len_high = len >> 29; - len_low <<= 3; - q = newLen448; - ret[q++] = (len_low & 0xff); - len_low >>= 8; - ret[q++] = (len_low & 0xff); - len_low >>= 8; - ret[q++] = (len_low & 0xff); - len_low >>= 8; - ret[q++] = (len_low & 0xff); - ret[q++] = (len_high & 0xff); - len_high >>= 8; - ret[q++] = (len_high & 0xff); - len_high >>= 8; - ret[q++] = (len_high & 0xff); - len_high >>= 8; - ret[q] = (len_high & 0xff); - - return ret; -} - -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define ROT_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -static void -doTheRounds(uint32 X[16], uint32 state[4]) -{ - uint32 a, - b, - c, - d; - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - - /* round 1 */ - a = b + ROT_LEFT((a + F(b, c, d) + X[0] + 0xd76aa478), 7); /* 1 */ - d = a + ROT_LEFT((d + F(a, b, c) + X[1] + 0xe8c7b756), 12); /* 2 */ - c = d + ROT_LEFT((c + F(d, a, b) + X[2] + 0x242070db), 17); /* 3 */ - b = c + ROT_LEFT((b + F(c, d, a) + X[3] + 0xc1bdceee), 22); /* 4 */ - a = b + ROT_LEFT((a + F(b, c, d) + X[4] + 0xf57c0faf), 7); /* 5 */ - d = a + ROT_LEFT((d + F(a, b, c) + X[5] + 0x4787c62a), 12); /* 6 */ - c = d + ROT_LEFT((c + F(d, a, b) + X[6] + 0xa8304613), 17); /* 7 */ - b = c + ROT_LEFT((b + F(c, d, a) + X[7] + 0xfd469501), 22); /* 8 */ - a = b + ROT_LEFT((a + F(b, c, d) + X[8] + 0x698098d8), 7); /* 9 */ - d = a + ROT_LEFT((d + F(a, b, c) + X[9] + 0x8b44f7af), 12); /* 10 */ - c = d + ROT_LEFT((c + F(d, a, b) + X[10] + 0xffff5bb1), 17); /* 11 */ - b = c + ROT_LEFT((b + F(c, d, a) + X[11] + 0x895cd7be), 22); /* 12 */ - a = b + ROT_LEFT((a + F(b, c, d) + X[12] + 0x6b901122), 7); /* 13 */ - d = a + ROT_LEFT((d + F(a, b, c) + X[13] + 0xfd987193), 12); /* 14 */ - c = d + ROT_LEFT((c + F(d, a, b) + X[14] + 0xa679438e), 17); /* 15 */ - b = c + ROT_LEFT((b + F(c, d, a) + X[15] + 0x49b40821), 22); /* 16 */ - - /* round 2 */ - a = b + ROT_LEFT((a + G(b, c, d) + X[1] + 0xf61e2562), 5); /* 17 */ - d = a + ROT_LEFT((d + G(a, b, c) + X[6] + 0xc040b340), 9); /* 18 */ - c = d + ROT_LEFT((c + G(d, a, b) + X[11] + 0x265e5a51), 14); /* 19 */ - b = c + ROT_LEFT((b + G(c, d, a) + X[0] + 0xe9b6c7aa), 20); /* 20 */ - a = b + ROT_LEFT((a + G(b, c, d) + X[5] + 0xd62f105d), 5); /* 21 */ - d = a + ROT_LEFT((d + G(a, b, c) + X[10] + 0x02441453), 9); /* 22 */ - c = d + ROT_LEFT((c + G(d, a, b) + X[15] + 0xd8a1e681), 14); /* 23 */ - b = c + ROT_LEFT((b + G(c, d, a) + X[4] + 0xe7d3fbc8), 20); /* 24 */ - a = b + ROT_LEFT((a + G(b, c, d) + X[9] + 0x21e1cde6), 5); /* 25 */ - d = a + ROT_LEFT((d + G(a, b, c) + X[14] + 0xc33707d6), 9); /* 26 */ - c = d + ROT_LEFT((c + G(d, a, b) + X[3] + 0xf4d50d87), 14); /* 27 */ - b = c + ROT_LEFT((b + G(c, d, a) + X[8] + 0x455a14ed), 20); /* 28 */ - a = b + ROT_LEFT((a + G(b, c, d) + X[13] + 0xa9e3e905), 5); /* 29 */ - d = a + ROT_LEFT((d + G(a, b, c) + X[2] + 0xfcefa3f8), 9); /* 30 */ - c = d + ROT_LEFT((c + G(d, a, b) + X[7] + 0x676f02d9), 14); /* 31 */ - b = c + ROT_LEFT((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20); /* 32 */ - - /* round 3 */ - a = b + ROT_LEFT((a + H(b, c, d) + X[5] + 0xfffa3942), 4); /* 33 */ - d = a + ROT_LEFT((d + H(a, b, c) + X[8] + 0x8771f681), 11); /* 34 */ - c = d + ROT_LEFT((c + H(d, a, b) + X[11] + 0x6d9d6122), 16); /* 35 */ - b = c + ROT_LEFT((b + H(c, d, a) + X[14] + 0xfde5380c), 23); /* 36 */ - a = b + ROT_LEFT((a + H(b, c, d) + X[1] + 0xa4beea44), 4); /* 37 */ - d = a + ROT_LEFT((d + H(a, b, c) + X[4] + 0x4bdecfa9), 11); /* 38 */ - c = d + ROT_LEFT((c + H(d, a, b) + X[7] + 0xf6bb4b60), 16); /* 39 */ - b = c + ROT_LEFT((b + H(c, d, a) + X[10] + 0xbebfbc70), 23); /* 40 */ - a = b + ROT_LEFT((a + H(b, c, d) + X[13] + 0x289b7ec6), 4); /* 41 */ - d = a + ROT_LEFT((d + H(a, b, c) + X[0] + 0xeaa127fa), 11); /* 42 */ - c = d + ROT_LEFT((c + H(d, a, b) + X[3] + 0xd4ef3085), 16); /* 43 */ - b = c + ROT_LEFT((b + H(c, d, a) + X[6] + 0x04881d05), 23); /* 44 */ - a = b + ROT_LEFT((a + H(b, c, d) + X[9] + 0xd9d4d039), 4); /* 45 */ - d = a + ROT_LEFT((d + H(a, b, c) + X[12] + 0xe6db99e5), 11); /* 46 */ - c = d + ROT_LEFT((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16); /* 47 */ - b = c + ROT_LEFT((b + H(c, d, a) + X[2] + 0xc4ac5665), 23); /* 48 */ - - /* round 4 */ - a = b + ROT_LEFT((a + I(b, c, d) + X[0] + 0xf4292244), 6); /* 49 */ - d = a + ROT_LEFT((d + I(a, b, c) + X[7] + 0x432aff97), 10); /* 50 */ - c = d + ROT_LEFT((c + I(d, a, b) + X[14] + 0xab9423a7), 15); /* 51 */ - b = c + ROT_LEFT((b + I(c, d, a) + X[5] + 0xfc93a039), 21); /* 52 */ - a = b + ROT_LEFT((a + I(b, c, d) + X[12] + 0x655b59c3), 6); /* 53 */ - d = a + ROT_LEFT((d + I(a, b, c) + X[3] + 0x8f0ccc92), 10); /* 54 */ - c = d + ROT_LEFT((c + I(d, a, b) + X[10] + 0xffeff47d), 15); /* 55 */ - b = c + ROT_LEFT((b + I(c, d, a) + X[1] + 0x85845dd1), 21); /* 56 */ - a = b + ROT_LEFT((a + I(b, c, d) + X[8] + 0x6fa87e4f), 6); /* 57 */ - d = a + ROT_LEFT((d + I(a, b, c) + X[15] + 0xfe2ce6e0), 10); /* 58 */ - c = d + ROT_LEFT((c + I(d, a, b) + X[6] + 0xa3014314), 15); /* 59 */ - b = c + ROT_LEFT((b + I(c, d, a) + X[13] + 0x4e0811a1), 21); /* 60 */ - a = b + ROT_LEFT((a + I(b, c, d) + X[4] + 0xf7537e82), 6); /* 61 */ - d = a + ROT_LEFT((d + I(a, b, c) + X[11] + 0xbd3af235), 10); /* 62 */ - c = d + ROT_LEFT((c + I(d, a, b) + X[2] + 0x2ad7d2bb), 15); /* 63 */ - b = c + ROT_LEFT((b + I(c, d, a) + X[9] + 0xeb86d391), 21); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; -} - -static int -calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16]) -{ - register uint32 i, - j, - k, - newI; - uint32 l; - uint8 *input; - register uint32 *wbp; - uint32 workBuff[16], - state[4]; - - l = len; - - state[0] = 0x67452301; - state[1] = 0xEFCDAB89; - state[2] = 0x98BADCFE; - state[3] = 0x10325476; - - if ((input = createPaddedCopyWithLength(b, &l)) == NULL) - return 0; - - for (i = 0;;) - { - if ((newI = i + 16 * 4) > l) - break; - k = i + 3; - for (j = 0; j < 16; j++) - { - wbp = (workBuff + j); - *wbp = input[k--]; - *wbp <<= 8; - *wbp |= input[k--]; - *wbp <<= 8; - *wbp |= input[k--]; - *wbp <<= 8; - *wbp |= input[k]; - k += 7; - } - doTheRounds(workBuff, state); - i = newI; - } - free(input); - - j = 0; - for (i = 0; i < 4; i++) - { - k = state[i]; - sum[j++] = (k & 0xff); - k >>= 8; - sum[j++] = (k & 0xff); - k >>= 8; - sum[j++] = (k & 0xff); - k >>= 8; - sum[j++] = (k & 0xff); - } - return 1; -} - -static void -bytesToHex(uint8 b[16], char *s) -{ - static char *hex = "0123456789abcdef"; - int q, - w; - - for (q = 0, w = 0; q < 16; q++) - { - s[w++] = hex[(b[q] >> 4) & 0x0F]; - s[w++] = hex[b[q] & 0x0F]; - } - s[w] = '\0'; -} - -/* - * PUBLIC FUNCTIONS - */ - -/* - * md5_hash - * - * Calculates the MD5 sum of the bytes in a buffer. - * - * SYNOPSIS #include "crypt.h" - * int md5_hash(const void *buff, size_t len, char *hexsum) - * - * INPUT buff the buffer containing the bytes that you want - * the MD5 sum of. - * len number of bytes in the buffer. - * - * OUTPUT hexsum the MD5 sum as a '\0'-terminated string of - * hexadecimal digits. an MD5 sum is 16 bytes long. - * each byte is represented by two heaxadecimal - * characters. you thus need to provide an array - * of 33 characters, including the trailing '\0'. - * - * RETURNS 0 on failure (out of memory for internal buffers) or - * non-zero on success. - * - * STANDARDS MD5 is described in RFC 1321. - * - * AUTHOR Sverre H. Huseby - * - */ -bool -md5_hash(const void *buff, size_t len, char *hexsum) -{ - uint8 sum[16]; - - if (!calculateDigestFromBuffer((uint8 *) buff, len, sum)) - return false; - - bytesToHex(sum, hexsum); - return true; -} - - - -/* - * Computes MD5 checksum of "passwd" (a null-terminated string) followed - * by "salt" (which need not be null-terminated). - * - * Output format is "md5" followed by a 32-hex-digit MD5 checksum. - * Hence, the output buffer "buf" must be at least 36 bytes long. - * - * Returns TRUE if okay, FALSE on error (out of memory). - */ -bool -EncryptMD5(const char *passwd, const char *salt, size_t salt_len, - char *buf) -{ - size_t passwd_len = strlen(passwd); - char *crypt_buf = palloc(passwd_len + salt_len); - bool ret; - - /* - * Place salt at the end because it may be known by users trying to - * crack the MD5 output. - */ - strcpy(crypt_buf, passwd); - memcpy(crypt_buf + passwd_len, salt, salt_len); - - strcpy(buf, "md5"); - ret = md5_hash(crypt_buf, passwd_len + salt_len, buf + 3); - - pfree(crypt_buf); - - return ret; -} diff --git a/src/interfaces/odbc/md5.h b/src/interfaces/odbc/md5.h deleted file mode 100644 index 2e2429d33d..0000000000 --- a/src/interfaces/odbc/md5.h +++ /dev/null @@ -1,49 +0,0 @@ -/* File: md5.h - * - * Description: See "md5.h" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __MD5_H__ -#define __MD5_H__ - -#include "psqlodbc.h" - -#include -#include - -#define MD5_PASSWD_LEN 35 - -/* From c.h */ -#ifndef __BEOS__ - -#ifndef __cplusplus - -#ifndef bool -typedef char bool; -#endif - -#ifndef true -#define true ((bool) 1) -#endif - -#ifndef false -#define false ((bool) 0) -#endif -#endif /* not C++ */ -#endif /* __BEOS__ */ - -/* Also defined in include/c.h */ -#ifndef HAVE_UINT8 -typedef unsigned char uint8; /* == 8 bits */ -typedef unsigned short uint16; /* == 16 bits */ -typedef unsigned int uint32; /* == 32 bits */ -#endif /* not HAVE_UINT8 */ - -extern bool md5_hash(const void *buff, size_t len, char *hexsum); -extern bool EncryptMD5(const char *passwd, const char *salt, - size_t salt_len, char *buf); - -#endif diff --git a/src/interfaces/odbc/misc.c b/src/interfaces/odbc/misc.c deleted file mode 100644 index 9a10c951e0..0000000000 --- a/src/interfaces/odbc/misc.c +++ /dev/null @@ -1,329 +0,0 @@ -/*------- - * Module: misc.c - * - * Description: This module contains miscellaneous routines - * such as for debugging/logging and string functions. - * - * Classes: n/a - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "psqlodbc.h" - -#include -#include -#include - -#ifndef WIN32 -#if HAVE_PWD_H -#include -#endif -#include -#include -#else -#include /* Byron: is this where Windows keeps def. - * of getpid ? */ -#endif -#include "connection.h" - -extern GLOBAL_VALUES globals; -void generate_filename(const char *, const char *, char *); - - -void -generate_filename(const char *dirname, const char *prefix, char *filename) -{ - int pid = 0; - -#ifndef WIN32 - struct passwd *ptr = 0; - - ptr = getpwuid(getuid()); -#endif - pid = getpid(); - if (dirname == 0 || filename == 0) - return; - - strcpy(filename, dirname); - strcat(filename, DIRSEPARATOR); - if (prefix != 0) - strcat(filename, prefix); -#ifndef WIN32 - strcat(filename, ptr->pw_name); -#endif - sprintf(filename, "%s%u%s", filename, pid, ".log"); - return; -} - -static int mylog_on = 0, - qlog_on = 0; -void -logs_on_off(int cnopen, int mylog_onoff, int qlog_onoff) -{ - static int mylog_on_count = 0, - mylog_off_count = 0, - qlog_on_count = 0, - qlog_off_count = 0; - - if (mylog_onoff) - mylog_on_count += cnopen; - else - mylog_off_count += cnopen; - if (mylog_on_count > 0) - mylog_on = 1; - else if (mylog_off_count > 0) - mylog_on = 0; - else - mylog_on = globals.debug; - if (qlog_onoff) - qlog_on_count += cnopen; - else - qlog_off_count += cnopen; - if (qlog_on_count > 0) - qlog_on = 1; - else if (qlog_off_count > 0) - qlog_on = 0; - else - qlog_on = globals.commlog; -} - -#ifdef MY_LOG -void -mylog(char *fmt,...) -{ - va_list args; - char filebuf[80]; - static FILE *LOGFP = NULL; - - if (mylog_on) - { - va_start(args, fmt); - - if (!LOGFP) - { - generate_filename(MYLOGDIR, MYLOGFILE, filebuf); - LOGFP = fopen(filebuf, PG_BINARY_A); - setbuf(LOGFP, NULL); - } - - if (LOGFP) - vfprintf(LOGFP, fmt, args); - - va_end(args); - } -} -#else -void -MyLog(char *fmt,...) -{ -} -#endif - - -#ifdef Q_LOG -void -qlog(char *fmt,...) -{ - va_list args; - char filebuf[80]; - static FILE *LOGFP = NULL; - - if (qlog_on) - { - va_start(args, fmt); - - if (!LOGFP) - { - generate_filename(QLOGDIR, QLOGFILE, filebuf); - LOGFP = fopen(filebuf, PG_BINARY_A); - setbuf(LOGFP, NULL); - } - - if (LOGFP) - vfprintf(LOGFP, fmt, args); - - va_end(args); - } -} -#endif - - -/* - * returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied - * (not including null term) - */ -int -my_strcpy(char *dst, int dst_len, const char *src, int src_len) -{ - if (dst_len <= 0) - return STRCPY_FAIL; - - if (src_len == SQL_NULL_DATA) - { - dst[0] = '\0'; - return STRCPY_NULL; - } - else if (src_len == SQL_NTS) - src_len = strlen(src); - - if (src_len <= 0) - return STRCPY_FAIL; - else - { - if (src_len < dst_len) - { - memcpy(dst, src, src_len); - dst[src_len] = '\0'; - } - else - { - memcpy(dst, src, dst_len - 1); - dst[dst_len - 1] = '\0'; /* truncated */ - return STRCPY_TRUNCATED; - } - } - - return strlen(dst); -} - - -/* - * strncpy copies up to len characters, and doesn't terminate - * the destination string if src has len characters or more. - * instead, I want it to copy up to len-1 characters and always - * terminate the destination string. - */ -char * -strncpy_null(char *dst, const char *src, int len) -{ - int i; - - - if (NULL != dst) - { - /* Just in case, check for special lengths */ - if (len == SQL_NULL_DATA) - { - dst[0] = '\0'; - return NULL; - } - else if (len == SQL_NTS) - len = strlen(src) + 1; - - for (i = 0; src[i] && i < len - 1; i++) - dst[i] = src[i]; - - if (len > 0) - dst[i] = '\0'; - } - return dst; -} - - -/*------ - * Create a null terminated string (handling the SQL_NTS thing): - * 1. If buf is supplied, place the string in there - * (assumes enough space) and return buf. - * 2. If buf is not supplied, malloc space and return this string - *------ - */ -char * -make_string(const char *s, int len, char *buf) -{ - int length; - char *str; - - if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) - { - length = (len > 0) ? len : strlen(s); - - if (buf) - { - strncpy_null(buf, s, length + 1); - return buf; - } - - str = malloc(length + 1); - if (!str) - return NULL; - - strncpy_null(str, s, length + 1); - return str; - } - - return NULL; -} - - -/* - * Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing. - * "fmt" must contain somewhere in it the single form '%.*s'. - * This is heavily used in creating queries for info routines (SQLTables, SQLColumns). - * This routine could be modified to use vsprintf() to handle multiple arguments. - */ -char * -my_strcat(char *buf, const char *fmt, const char *s, int len) -{ - if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) - { - int length = (len > 0) ? len : strlen(s); - - int pos = strlen(buf); - - sprintf(&buf[pos], fmt, length, s); - return buf; - } - return NULL; -} - -char * -schema_strcat(char *buf, const char *fmt, const char *s, int len, const char *tbname, int tbnmlen, ConnectionClass *conn) -{ - if (!s || 0 == len) - { - /* - * Note that this driver assumes the implicit schema is - * the CURRENT_SCHEMA() though it doesn't worth the - * naming. - */ - if (conn->schema_support && tbname && (tbnmlen > 0 || tbnmlen == SQL_NTS)) - return my_strcat(buf, fmt, CC_get_current_schema(conn), SQL_NTS); - return NULL; - } - return my_strcat(buf, fmt, s, len); -} - - -void -remove_newlines(char *string) -{ - unsigned int i; - - for (i = 0; i < strlen(string); i++) - { - if ((string[i] == '\n') || - (string[i] == '\r')) - string[i] = ' '; - } -} - - -char * -trim(char *s) -{ - int i; - - for (i = strlen(s) - 1; i >= 0; i--) - { - if (s[i] == ' ') - s[i] = '\0'; - else - break; - } - - return s; -} diff --git a/src/interfaces/odbc/misc.h b/src/interfaces/odbc/misc.h deleted file mode 100644 index e2e34ce956..0000000000 --- a/src/interfaces/odbc/misc.h +++ /dev/null @@ -1,107 +0,0 @@ -/* File: misc.h - * - * Description: See "misc.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __MISC_H__ -#define __MISC_H__ - -#include "psqlodbc.h" - -#include - -/* Uncomment MY_LOG define to compile in the mylog() statements. - Then, debug logging will occur if 'Debug' is set to 1 in the ODBCINST.INI - portion of the registry. You may have to manually add this key. - This logfile is intended for development use, not for an end user! -*/ -#define MY_LOG - - -/* Uncomment Q_LOG to compile in the qlog() statements (Communications log, i.e. CommLog). - This logfile contains serious log statements that are intended for an - end user to be able to read and understand. It is controlled by the - 'CommLog' flag in the ODBCINST.INI portion of the registry (see above), - which is manipulated on the setup/connection dialog boxes. -*/ -#define Q_LOG - - -#ifdef MY_LOG -#define MYLOGFILE "mylog_" -#ifndef WIN32 -#define MYLOGDIR "/tmp" -#else -#define MYLOGDIR "c:" -#endif /* WIN32 */ -extern void mylog(char *fmt,...); - -#else -#ifndef WIN32 -#define mylog(args...) /* GNU convention for variable arguments */ -#else -extern void MyLog(char *fmt,...); -#define mylog if (0) MyLog /* mylog */ -#endif /* WIN32 */ -#endif /* MY_LOG */ -#define inolog mylog /* for really temporary debug */ - -#ifdef Q_LOG -#define QLOGFILE "psqlodbc_" -#ifndef WIN32 -#define QLOGDIR "/tmp" -#else -#define QLOGDIR "c:" -#endif -extern void qlog(char *fmt,...); - -#else -#ifndef WIN32 -#define qlog(args...) /* GNU convention for variable arguments */ -#else -#define qlog /* qlog */ -#endif -#endif -#define inoqlog qlog - -#ifndef WIN32 -#define DIRSEPARATOR "/" -#else -#define DIRSEPARATOR "\\" -#endif - -#ifdef WIN32 -#define PG_BINARY O_BINARY -#define PG_BINARY_R "rb" -#define PG_BINARY_W "wb" -#define PG_BINARY_A "ab" -#else -#define PG_BINARY 0 -#define PG_BINARY_R "r" -#define PG_BINARY_W "w" -#define PG_BINARY_A "a" -#endif - - -void remove_newlines(char *string); -char *strncpy_null(char *dst, const char *src, int len); -char *trim(char *string); -char *make_string(const char *s, int len, char *buf); -char *my_strcat(char *buf, const char *fmt, const char *s, int len); -char *schema_strcat(char *buf, const char *fmt, const char *s, int len, - const char *, int, ConnectionClass *conn); -/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */ -#define GET_SCHEMA_NAME(nspname) (nspname) - -/* defines for return value of my_strcpy */ -#define STRCPY_SUCCESS 1 -#define STRCPY_FAIL 0 -#define STRCPY_TRUNCATED (-1) -#define STRCPY_NULL (-2) - -int my_strcpy(char *dst, int dst_len, const char *src, int src_len); - -#endif diff --git a/src/interfaces/odbc/multibyte.c b/src/interfaces/odbc/multibyte.c deleted file mode 100644 index a31f2e9b4b..0000000000 --- a/src/interfaces/odbc/multibyte.c +++ /dev/null @@ -1,454 +0,0 @@ -/*-------- - * Module : multibyte.c - * - * Description: New Mlutibyte related additional function. - * - * Create 2001-03-03 Eiji Tokuya - * New Create 2001-09-16 Eiji Tokuya - *-------- - */ - -#include "multibyte.h" -#include "connection.h" -#include "pgapifunc.h" -#include -#include -#include -#include -#ifndef TRUE -#define TRUE 1 -#endif - -pg_CS CS_Table[] = -{ - { "SQL_ASCII", SQL_ASCII }, - { "EUC_JP", EUC_JP }, - { "EUC_CN", EUC_CN }, - { "EUC_KR", EUC_KR }, - { "EUC_TW", EUC_TW }, - { "JOHAB", JOHAB }, - { "UNICODE", UTF8 }, - { "MULE_INTERNAL",MULE_INTERNAL }, - { "LATIN1", LATIN1 }, - { "LATIN2", LATIN2 }, - { "LATIN3", LATIN3 }, - { "LATIN4", LATIN4 }, - { "LATIN5", LATIN5 }, - { "LATIN6", LATIN6 }, - { "LATIN7", LATIN7 }, - { "LATIN8", LATIN8 }, - { "LATIN9", LATIN9 }, - { "LATIN10", LATIN10 }, - { "WIN1256", WIN1256 }, - { "TCVN", TCVN }, - { "WIN874", WIN874 }, - { "KOI8", KOI8R }, - { "WIN", WIN1251 }, - { "ALT", ALT }, - { "ISO_8859_5", ISO_8859_5 }, - { "ISO_8859_6", ISO_8859_6 }, - { "ISO_8859_7", ISO_8859_7 }, - { "ISO_8859_8", ISO_8859_8 }, - - - { "SJIS", SJIS }, - { "BIG5", BIG5 }, - { "GBK", GBK }, - { "UHC", UHC }, - { "WIN1250", WIN1250 }, - { "GB18030", GB18030 }, - { "OTHER", OTHER } -}; - -#ifdef NOT_USED -static int -pg_ismb(int characterset_code) -{ - int i=0,MB_CHARACTERSET[]={EUC_JP,EUC_CN,EUC_KR,EUC_TW,UTF8,MULE_INTERNAL,SJIS,BIG5,GBK,UHC,JOHAB}; - - while (MB_CHARACTERSET[i] != characterset_code || OTHER != MB_CHARACTERSET[i] ) - { - i++; - } - return (MB_CHARACTERSET[i]); -} -#endif - -int -pg_CS_code(const unsigned char *characterset_string) -{ - int i = 0, c = -1; - unsigned len = 0; - for(i = 0; CS_Table[i].code != OTHER; i++) - { - if (strstr(characterset_string,CS_Table[i].name)) - { - if(strlen(CS_Table[i].name) >= len) - { - len = strlen(CS_Table[i].name); - c = CS_Table[i].code; - } - - } - } - if (c < 0) - c = i; - return (c); -} - -unsigned char * -pg_CS_name(int characterset_code) -{ - int i; - for (i = 0; CS_Table[i].code != OTHER; i++) - { - if (CS_Table[i].code == characterset_code) - return CS_Table[i].name; - } - return ("OTHER"); -} - -int -pg_CS_stat(int stat,unsigned int character,int characterset_code) -{ - if (character == 0) - stat = 0; - switch (characterset_code) - { - case UTF8: - { - if (stat < 2 && - character >= 0x80) - { - if (character >= 0xfc) - stat = 6; - else if (character >= 0xf8) - stat = 5; - else if (character >= 0xf0) - stat = 4; - else if (character >= 0xe0) - stat = 3; - else if (character >= 0xc0) - stat = 2; - } - else if (stat > 2 && - character > 0x7f) - stat--; - else - stat=0; - } - break; -/* Shift-JIS Support. */ - case SJIS: - { - if (stat < 2 && - character > 0x80 && - !(character > 0x9f && - character < 0xe0)) - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; -/* Chinese Big5 Support. */ - case BIG5: - { - if (stat < 2 && - character > 0xA0) - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; -/* Chinese GBK Support. */ - case GBK: - { - if (stat < 2 && - character > 0x7F) - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; - -/* Korian UHC Support. */ - case UHC: - { - if (stat < 2 && - character > 0x7F) - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; - -/* EUC_JP Support */ - case EUC_JP: - { - if (stat < 3 && - character == 0x8f) /* JIS X 0212 */ - stat = 3; - else - if (stat != 2 && - (character == 0x8e || - character > 0xa0)) /* Half Katakana HighByte & Kanji HighByte */ - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; - -/* EUC_CN, EUC_KR, JOHAB Support */ - case EUC_CN: - case EUC_KR: - case JOHAB: - { - if (stat < 2 && - character > 0xa0) - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; - case EUC_TW: - { - if (stat < 4 && - character == 0x8e) - stat = 4; - else if (stat == 4 && - character > 0xa0) - stat = 3; - else if ((stat == 3 || - stat < 2) && - character > 0xa0) - stat = 2; - else if (stat == 2) - stat = 1; - else - stat = 0; - } - break; - /*Chinese GB18030 support.Added by Bill Huang */ - case GB18030: - { - if (stat < 2 && character > 0x80) - stat = 2; - else if (stat = 2) - if (character >= 0x30 && character <= 0x39) - stat = 3; - else - stat = 1; - else if (stat = 3) - if (character >= 0x30 && character <= 0x39) - stat = 1; - else - stat = 3; - else - stat = 0; - } - break; - default: - { - stat = 0; - } - break; - } - return stat; -} - - -unsigned char * -pg_mbschr(int csc, const unsigned char *string, unsigned int character) -{ - int mb_st = 0; - const unsigned char *s, *rs = NULL; - - for(s = string; *s ; s++) - { - mb_st = pg_CS_stat(mb_st, (unsigned char) *s, csc); - if (mb_st == 0 && (*s == character)) - { - rs = s; - break; - } - } - return (rs); -} - -int -pg_mbslen(int csc, const unsigned char *string) -{ - unsigned char *s; - int len, cs_stat; - for (len = 0, cs_stat = 0, s = (unsigned char *) string; *s != 0; s++) - { - cs_stat = pg_CS_stat(cs_stat,(unsigned int) *s, csc); - if (cs_stat < 2) - len++; - } - return len; -} - -unsigned char * -pg_mbsinc(int csc, const unsigned char *current ) -{ - int mb_stat = 0; - if (*current != 0) - { - mb_stat = (int) pg_CS_stat(mb_stat, *current, csc); - if (mb_stat == 0) - mb_stat = 1; - return ((unsigned char *) current + mb_stat); - } - else - return NULL; -} - -static char * -CC_lookup_cs_new(ConnectionClass *self) -{ - char *encstr = NULL; - QResultClass *res; - - res = CC_send_query(self, "select pg_client_encoding()", NULL, CLEAR_RESULT_ON_ABORT); - if (res) - { - char *enc = QR_get_value_backend_row(res, 0, 0); - - if (enc) - encstr = strdup(enc); - QR_Destructor(res); - } - return encstr; -} -static char * -CC_lookup_cs_old(ConnectionClass *self) -{ - char *encstr = NULL; - HSTMT hstmt; - RETCODE result; - - result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - return encstr; - - result = PGAPI_ExecDirect(hstmt, "Show Client_Encoding", SQL_NTS); - if (result == SQL_SUCCESS_WITH_INFO) - { - char sqlState[8], errormsg[128], enc[32]; - - if (PGAPI_Error(NULL, NULL, hstmt, sqlState, NULL, errormsg, - sizeof(errormsg), NULL) == SQL_SUCCESS && - sscanf(errormsg, "%*s %*s %*s %*s %*s %s", enc) > 0) - encstr = strdup(enc); - } - PGAPI_FreeStmt(hstmt, SQL_DROP); - return encstr; -} - -void -CC_lookup_characterset(ConnectionClass *self) -{ - char *encstr; - static char *func = "CC_lookup_characterset"; - - mylog("%s: entering...\n", func); - if (PG_VERSION_LT(self, 7.2)) - encstr = CC_lookup_cs_old(self); - else - encstr = CC_lookup_cs_new(self); - if (self->client_encoding) - free(self->client_encoding); -#ifndef UNICODE_SUPPORT -#ifdef WIN32 - else - { - const char *wenc = NULL; - switch (GetACP()) - { - case 932: - wenc = "SJIS"; - break; - case 936: - wenc = "GBK"; - break; - case 949: - wenc = "UHC"; - break; - case 950: - wenc = "BIG5"; - break; - } - if (wenc && stricmp(encstr, wenc)) - { - QResultClass *res; - char query[64]; - - sprintf(query, "set client_encoding to '%s'", wenc); - res = CC_send_query(self, query, NULL, CLEAR_RESULT_ON_ABORT); - if (res) - { - self->client_encoding = strdup(wenc); - self->ccsc = pg_CS_code(self->client_encoding); - QR_Destructor(res); - free(encstr); - return; - } - } - } -#endif /* WIN32 */ -#endif /* UNICODE_SUPPORT */ - if (encstr) - { - self->client_encoding = encstr; - self->ccsc = pg_CS_code(encstr); - qlog(" [ Client encoding = '%s' (code = %d) ]\n", self->client_encoding, self->ccsc); - if (stricmp(pg_CS_name(self->ccsc), encstr)) - { - qlog(" Client encoding = '%s' and %s\n", self->client_encoding, pg_CS_name(self->ccsc)); - self->errornumber = CONN_VALUE_OUT_OF_RANGE; - self->errormsg = "client encoding mismatch"; - } - } - else - { - self->ccsc = SQL_ASCII; - self->client_encoding = NULL; - } -} - -void encoded_str_constr(encoded_str *encstr, int ccsc, const char *str) -{ - encstr->ccsc = ccsc; - encstr->encstr = str; - encstr->pos = -1; - encstr->ccst = 0; -} -int encoded_nextchar(encoded_str *encstr) -{ - int chr; - - chr = encstr->encstr[++encstr->pos]; - encstr->ccst = pg_CS_stat(encstr->ccst, (unsigned int) chr, encstr->ccsc); - return chr; -} -int encoded_byte_check(encoded_str *encstr, int abspos) -{ - int chr; - - chr = encstr->encstr[encstr->pos = abspos]; - encstr->ccst = pg_CS_stat(encstr->ccst, (unsigned int) chr, encstr->ccsc); - return chr; -} diff --git a/src/interfaces/odbc/multibyte.h b/src/interfaces/odbc/multibyte.h deleted file mode 100644 index bd85747c0d..0000000000 --- a/src/interfaces/odbc/multibyte.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Multibyte library header ( psqlODBC Only ) - * - */ -#include "psqlodbc.h" -#include "qresult.h" - -/* PostgreSQL client encoding */ -#define SQL_ASCII 0 /* SQL/ASCII */ -#define EUC_JP 1 /* EUC for Japanese */ -#define EUC_CN 2 /* EUC for Chinese */ -#define EUC_KR 3 /* EUC for Korean */ -#define EUC_TW 4 /* EUC for Taiwan */ -#define JOHAB 5 -#define UTF8 6 /* Unicode UTF-8 */ -#define MULE_INTERNAL 7 /* Mule internal code */ -#define LATIN1 8 /* ISO-8859 Latin 1 */ -#define LATIN2 9 /* ISO-8859 Latin 2 */ -#define LATIN3 10 /* ISO-8859 Latin 3 */ -#define LATIN4 11 /* ISO-8859 Latin 4 */ -#define LATIN5 12 /* ISO-8859 Latin 5 */ -#define LATIN6 13 /* ISO-8859 Latin 6 */ -#define LATIN7 14 /* ISO-8859 Latin 7 */ -#define LATIN8 15 /* ISO-8859 Latin 8 */ -#define LATIN9 16 /* ISO-8859 Latin 9 */ -#define LATIN10 17 /* ISO-8859 Latin 10 */ -#define WIN1256 18 /* Arabic Windows */ -#define TCVN 19 /* Vietnamese Windows */ -#define WIN874 20 /* Thai Windows */ -#define KOI8R 21 /* KOI8-R/U */ -#define WIN1251 22 /* windows-1251 */ -#define ALT 23 /* Alternativny Variant (MS-DOS CP866) */ -#define ISO_8859_5 24 /* ISO-8859-5 */ -#define ISO_8859_6 25 /* ISO-8859-6 */ -#define ISO_8859_7 26 /* ISO-8859-7 */ -#define ISO_8859_8 27 /* ISO-8859-8 */ - -#define SJIS 28 /* Shift JIS */ -#define BIG5 29 /* Big5 */ -#define GBK 30 /* GBK */ -#define UHC 31 /* UHC */ -#define WIN1250 32 /* windows-1250 */ -#define GB18030 33 /* GB18030 */ -#define OTHER -1 - -#define MAX_CHARACTERSET_NAME 24 -#define MAX_CHARACTER_LEN 6 - -/* OLD Type */ -// extern int multibyte_client_encoding; /* Multibyte client encoding. */ -// extern int multibyte_status; /* Multibyte charcter status. */ -// -// void multibyte_init(void); -// unsigned char *check_client_encoding(unsigned char *sql_string); -// int multibyte_char_check(unsigned char s); -// unsigned char *multibyte_strchr(const unsigned char *string, unsigned int c); - -/* New Type */ - -extern void CC_lookup_characterset(ConnectionClass *self); - -extern int pg_CS_stat(int stat,unsigned int charcter,int characterset_code); -extern int pg_CS_code(const unsigned char *stat_string); -extern unsigned char *pg_CS_name(int code); - -typedef struct pg_CS -{ - unsigned char *name; - int code; -}pg_CS; -extern int pg_mbslen(int ccsc, const unsigned char *string); -extern unsigned char *pg_mbschr(int ccsc, const unsigned char *string, unsigned int character); -extern unsigned char *pg_mbsinc(int ccsc, const unsigned char *current ); - -/* Old Type Compatible */ -typedef struct -{ - int ccsc; - const char *encstr; - int pos; - int ccst; -} encoded_str; -#define ENCODE_STATUS(enc) ((enc).ccst) - -void encoded_str_constr(encoded_str *encstr, int ccsc, const char *str); -#define make_encoded_str(encstr, conn, str) encoded_str_constr(encstr, conn->ccsc, str) -extern int encoded_nextchar(encoded_str *encstr); -extern int encoded_byte_check(encoded_str *encstr, int abspos); -#define check_client_encoding(X) pg_CS_name(pg_CS_code(X)) diff --git a/src/interfaces/odbc/notice.txt b/src/interfaces/odbc/notice.txt deleted file mode 100644 index 42ce8a946d..0000000000 --- a/src/interfaces/odbc/notice.txt +++ /dev/null @@ -1,38 +0,0 @@ - -/******************************************************************** - - PSQLODBC.DLL - A library to talk to the PostgreSQL DBMS using ODBC. - - - Copyright (C) 1998 Insight Distribution Systems - Copyright (C) 1998 - 2002 The PostgreSQL Global Development Group - - Multibyte support was added by Sankyo Unyu Service, (C) 2001. - - The code contained in this library is based on code written by - Christian Czezatke and Dan McGuirk, (C) 1996. - - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library (see "license.txt"); if not, write to - the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA - 02139, USA. - - - How to contact the authors: - - email: pgsql-odbc@postgresql.org - - -***********************************************************************/ - diff --git a/src/interfaces/odbc/odbc.sql b/src/interfaces/odbc/odbc.sql deleted file mode 100644 index d3ea9202da..0000000000 --- a/src/interfaces/odbc/odbc.sql +++ /dev/null @@ -1,228 +0,0 @@ --- PostgreSQL catalog extensions for ODBC compatibility --- $Header: /cvsroot/pgsql/src/interfaces/odbc/Attic/odbc.sql,v 1.7 2001/12/21 06:01:36 thomas Exp $ - --- ODBC functions are described here: --- - --- Note: If we format this file consistently we can automatically --- generate a corresponding "drop script". Start "CREATE" in the first --- column, and keep everything up to and including the argument list on --- the same line. See also the makefile rule. - - --- String Functions --- ++++++++++++++++ --- --- Built-in: ASCII, BIT_LENGTH, CHAR_LENGTH, CHARACTER_LENGTH, LTRIM, --- OCTET_LENGTH, POSITION, REPEAT, RTRIM, SUBSTRING --- Missing: DIFFERENCE, REPLACE, SOUNDEX, LENGTH (ODBC sense) --- Keyword problems: CHAR - - --- CHAR(code) -CREATE OR REPLACE FUNCTION "char"(integer) RETURNS text AS ' - SELECT chr($1); -' LANGUAGE SQL; - - --- CONCAT(string1, string2) -CREATE OR REPLACE FUNCTION concat(text, text) RETURNS text AS ' - SELECT $1 || $2; -' LANGUAGE SQL; - - --- INSERT(string1, start, len, string2) -CREATE OR REPLACE FUNCTION insert(text, integer, integer, text) RETURNS text AS ' - SELECT substring($1 from 1 for $2 - 1) || $4 || substring($1 from $2 + $3); -' LANGUAGE SQL; - - --- LCASE(string) -CREATE OR REPLACE FUNCTION lcase(text) RETURNS text AS ' - SELECT lower($1); -' LANGUAGE SQL; - - --- LEFT(string, count) -CREATE OR REPLACE FUNCTION left(text, integer) RETURNS text AS ' - SELECT substring($1 for $2); -' LANGUAGE SQL; - - --- LOCATE(substring, string[, start]) -CREATE OR REPLACE FUNCTION locate(text, text) RETURNS integer AS ' - SELECT position($1 in $2); -' LANGUAGE SQL; -CREATE OR REPLACE FUNCTION locate(text, text, integer) RETURNS integer AS ' - SELECT position($1 in substring($2 from $3)) + $3 - 1; -' LANGUAGE SQL; - - --- RIGHT(string, count) -CREATE OR REPLACE FUNCTION right(text, integer) RETURNS text AS ' - SELECT substring($1 from char_length($1) - $2 + 1); -' LANGUAGE SQL; - - --- SPACE(count) -CREATE OR REPLACE FUNCTION space(integer) RETURNS text AS ' - SELECT repeat('' '', $1); -' LANGUAGE SQL; - - --- UCASE(string) -CREATE OR REPLACE FUNCTION ucase(text) RETURNS text AS ' - SELECT upper($1); -' LANGUAGE SQL; - - --- Numeric Functions --- +++++++++++++++++ --- --- Built-in: ABS, ACOS, ASIN, ATAN, ATAN2, COS, COT, DEGRESS, EXP, --- FLOOR, MOD, PI, RADIANS, ROUND, SIGN, SIN, SQRT, TAN --- Missing: LOG (ODBC sense) - - --- CEILING(num) -CREATE OR REPLACE FUNCTION ceiling(numeric) RETURNS numeric AS ' - SELECT ceil($1); -' LANGUAGE SQL; - - --- LOG10(num) -CREATE OR REPLACE FUNCTION log10(double precision) RETURNS double precision AS ' - SELECT log($1); -' LANGUAGE SQL; -CREATE OR REPLACE FUNCTION log10(numeric) RETURNS numeric AS ' - SELECT log($1); -' LANGUAGE SQL; - - --- POWER(num, num) -CREATE OR REPLACE FUNCTION power(double precision, double precision) - RETURNS double precision AS ' - SELECT pow($1, $2); -' LANGUAGE SQL; -CREATE OR REPLACE FUNCTION power(numeric, numeric) - RETURNS numeric AS ' - SELECT pow($1, $2); -' LANGUAGE SQL; - - --- RAND([seed]) -CREATE OR REPLACE FUNCTION rand() RETURNS double precision AS ' - SELECT random(); -' LANGUAGE SQL; -CREATE OR REPLACE FUNCTION rand(double precision) RETURNS double precision AS ' - SELECT setseed($1); - SELECT random(); -' LANGUAGE SQL; - - --- TRUNCATE(num, places) -CREATE OR REPLACE FUNCTION truncate(numeric, integer) RETURNS numeric AS ' - SELECT trunc($1, $2); -' LANGUAGE SQL; - - --- Time, Date, and Interval Functions --- ++++++++++++++++++++++++++++++++++ --- --- Built-in: CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, EXTRACT, NOW --- Missing: none - - -CREATE OR REPLACE FUNCTION curdate() RETURNS date AS ' - SELECT current_date; -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION curtime() RETURNS time with time zone AS ' - SELECT current_time; -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION odbc_timestamp() RETURNS timestamp with time zone AS ' - SELECT current_timestamp; -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION dayname(timestamp) RETURNS text AS ' - SELECT to_char($1,''Day''); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION dayofmonth(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(day FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION dayofweek(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(dow FROM $1) AS integer) + 1; -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION dayofyear(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(doy FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION hour(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(hour FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION minute(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(minute FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION month(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(month FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION monthname(timestamp) RETURNS text AS ' - SELECT to_char($1, ''Month''); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION quarter(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(quarter FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION second(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(second FROM $1) AS integer); -' LANGUAGE SQL; - -/* --- The first argument is an integer constant denoting the units --- of the second argument. Until we know the actual values, we --- cannot implement these. - thomas 2000-04-11 -xCREATE OR REPLACE FUNCTION timestampadd(integer, integer, timestamp) - RETURNS timestamp AS ' - SELECT CAST(($3 + ($2 * $1)) AS timestamp); -' LANGUAGE SQL; - -xCREATE OR REPLACE FUNCTION timestampdiff(integer, integer, timestamp) - RETURNS timestamp AS ' - SELECT CAST(($3 + ($2 * $1)) AS timestamp); -' LANGUAGE SQL; -*/ - -CREATE OR REPLACE FUNCTION week(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(week FROM $1) AS integer); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION year(timestamp) RETURNS integer AS ' - SELECT CAST(EXTRACT(year FROM $1) AS integer); -' LANGUAGE SQL; - - --- System Functions --- ++++++++++++++++ --- --- Built-in: USER --- Missing: DATABASE, IFNULL - -CREATE OR REPLACE FUNCTION odbc_user() RETURNS text AS ' - SELECT CAST(current_user AS TEXT); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION odbc_current_user() RETURNS text AS ' - SELECT CAST(current_user AS TEXT); -' LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION odbc_session_user() RETURNS text AS ' - SELECT CAST(session_user AS TEXT); -' LANGUAGE SQL; diff --git a/src/interfaces/odbc/odbcapi.c b/src/interfaces/odbc/odbcapi.c deleted file mode 100644 index 6a4a618b38..0000000000 --- a/src/interfaces/odbc/odbcapi.c +++ /dev/null @@ -1,716 +0,0 @@ -/*------- - * Module: odbcapi.c - * - * Description: This module contains routines related to - * preparing and executing an SQL statement. - * - * Classes: n/a - * - * API functions: SQLAllocConnect, SQLAllocEnv, SQLAllocStmt, - SQLBindCol, SQLCancel, SQLColumns, SQLConnect, - SQLDataSources, SQLDescribeCol, SQLDisconnect, - SQLError, SQLExecDirect, SQLExecute, SQLFetch, - SQLFreeConnect, SQLFreeEnv, SQLFreeStmt, - SQLGetConnectOption, SQLGetCursorName, SQLGetData, - SQLGetFunctions, SQLGetInfo, SQLGetStmtOption, - SQLGetTypeInfo, SQLNumResultCols, SQLParamData, - SQLPrepare, SQLPutData, SQLRowCount, - SQLSetConnectOption, SQLSetCursorName, SQLSetParam, - SQLSetStmtOption, SQLSpecialColumns, SQLStatistics, - SQLTables, SQLTransact, SQLColAttributes, - SQLColumnPrivileges, SQLDescribeParam, SQLExtendedFetch, - SQLForeignKeys, SQLMoreResults, SQLNativeSql, - SQLNumParams, SQLParamOptions, SQLPrimaryKeys, - SQLProcedureColumns, SQLProcedures, SQLSetPos, - SQLTablePrivileges, SQLBindParameter - *------- - */ - -#include "psqlodbc.h" -#include -#include - -#include "pgapifunc.h" -#include "connection.h" -#include "statement.h" - -RETCODE SQL_API -SQLAllocConnect(HENV EnvironmentHandle, - HDBC FAR * ConnectionHandle) -{ - mylog("[SQLAllocConnect]"); - return PGAPI_AllocConnect(EnvironmentHandle, ConnectionHandle); -} - -RETCODE SQL_API -SQLAllocEnv(HENV FAR * EnvironmentHandle) -{ - mylog("[SQLAllocEnv]"); - return PGAPI_AllocEnv(EnvironmentHandle); -} - -RETCODE SQL_API -SQLAllocStmt(HDBC ConnectionHandle, - HSTMT *StatementHandle) -{ - mylog("[SQLAllocStmt]"); - CC_clear_error((ConnectionClass *) ConnectionHandle); - return PGAPI_AllocStmt(ConnectionHandle, StatementHandle); -} - -RETCODE SQL_API -SQLBindCol(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, - PTR TargetValue, SQLINTEGER BufferLength, - SQLINTEGER *StrLen_or_Ind) -{ - mylog("[SQLBindCol]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_BindCol(StatementHandle, ColumnNumber, - TargetType, TargetValue, BufferLength, StrLen_or_Ind); -} - -RETCODE SQL_API -SQLCancel(HSTMT StatementHandle) -{ - mylog("[SQLCancel]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_Cancel(StatementHandle); -} - -RETCODE SQL_API -SQLColumns(HSTMT StatementHandle, - SQLCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLCHAR *TableName, SQLSMALLINT NameLength3, - SQLCHAR *ColumnName, SQLSMALLINT NameLength4) -{ - mylog("[SQLColumns]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_Columns(StatementHandle, CatalogName, NameLength1, - SchemaName, NameLength2, TableName, NameLength3, - ColumnName, NameLength4, 0); -} - - -RETCODE SQL_API -SQLConnect(HDBC ConnectionHandle, - SQLCHAR *ServerName, SQLSMALLINT NameLength1, - SQLCHAR *UserName, SQLSMALLINT NameLength2, - SQLCHAR *Authentication, SQLSMALLINT NameLength3) -{ - mylog("[SQLConnect]"); - CC_clear_error((ConnectionClass *) ConnectionHandle); - return PGAPI_Connect(ConnectionHandle, ServerName, NameLength1, - UserName, NameLength2, Authentication, NameLength3); -} - -RETCODE SQL_API -SQLDriverConnect(HDBC hdbc, - HWND hwnd, - UCHAR FAR * szConnStrIn, - SWORD cbConnStrIn, - UCHAR FAR * szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR * pcbConnStrOut, - UWORD fDriverCompletion) -{ - mylog("[SQLDriverConnect]"); - CC_clear_error((ConnectionClass *) hdbc); - return PGAPI_DriverConnect(hdbc, hwnd, szConnStrIn, cbConnStrIn, - szConnStrOut, cbConnStrOutMax, pcbConnStrOut, fDriverCompletion); -} -RETCODE SQL_API -SQLBrowseConnect( - HDBC hdbc, - SQLCHAR *szConnStrIn, - SQLSMALLINT cbConnStrIn, - SQLCHAR *szConnStrOut, - SQLSMALLINT cbConnStrOutMax, - SQLSMALLINT *pcbConnStrOut) -{ - mylog("[SQLBrowseConnect]"); - CC_clear_error((ConnectionClass *) hdbc); - return PGAPI_BrowseConnect(hdbc, szConnStrIn, cbConnStrIn, - szConnStrOut, cbConnStrOutMax, pcbConnStrOut); -} - -RETCODE SQL_API -SQLDataSources(HENV EnvironmentHandle, - SQLUSMALLINT Direction, SQLCHAR *ServerName, - SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, - SQLCHAR *Description, SQLSMALLINT BufferLength2, - SQLSMALLINT *NameLength2) -{ - mylog("[SQLDataSources]"); - - /* - * return PGAPI_DataSources(EnvironmentHandle, Direction, ServerName, - * BufferLength1, NameLength1, Description, BufferLength2, - * NameLength2); - */ - return SQL_ERROR; -} - -RETCODE SQL_API -SQLDescribeCol(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, - SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, - SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize, - SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) -{ - mylog("[SQLDescribeCol]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_DescribeCol(StatementHandle, ColumnNumber, - ColumnName, BufferLength, NameLength, - DataType, ColumnSize, DecimalDigits, Nullable); -} - -RETCODE SQL_API -SQLDisconnect(HDBC ConnectionHandle) -{ - mylog("[SQLDisconnect]"); - CC_clear_error((ConnectionClass *) ConnectionHandle); - return PGAPI_Disconnect(ConnectionHandle); -} - -RETCODE SQL_API -SQLError(HENV EnvironmentHandle, - HDBC ConnectionHandle, HSTMT StatementHandle, - SQLCHAR *Sqlstate, SQLINTEGER *NativeError, - SQLCHAR *MessageText, SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength) -{ - mylog("[SQLError]"); - return PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle, - Sqlstate, NativeError, MessageText, BufferLength, - TextLength); -} - -RETCODE SQL_API -SQLExecDirect(HSTMT StatementHandle, - SQLCHAR *StatementText, SQLINTEGER TextLength) -{ - mylog("[SQLExecDirect]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_ExecDirect(StatementHandle, StatementText, TextLength); -} - -RETCODE SQL_API -SQLExecute(HSTMT StatementHandle) -{ - mylog("[SQLExecute]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_Execute(StatementHandle); -} - -RETCODE SQL_API -SQLFetch(HSTMT StatementHandle) -{ - static char *func = "SQLFetch"; - -#if (ODBCVER >= 0x0300) - StatementClass *stmt = (StatementClass *) StatementHandle; - ConnectionClass *conn = SC_get_conn(stmt); - - SC_clear_error(stmt); - if (conn->driver_version >= 0x0300) - { - IRDFields *irdopts = SC_get_IRD(stmt); - SQLUSMALLINT *rowStatusArray = irdopts->rowStatusArray; - SQLINTEGER *pcRow = irdopts->rowsFetched; - - mylog("[[%s]]", func); - return PGAPI_ExtendedFetch(StatementHandle, SQL_FETCH_NEXT, 0, - pcRow, rowStatusArray, 0); - } -#endif - mylog("[%s]", func); - return PGAPI_Fetch(StatementHandle); -} - -RETCODE SQL_API -SQLFreeConnect(HDBC ConnectionHandle) -{ - mylog("[SQLFreeConnect]"); - return PGAPI_FreeConnect(ConnectionHandle); -} - -RETCODE SQL_API -SQLFreeEnv(HENV EnvironmentHandle) -{ - mylog("[SQLFreeEnv]"); - return PGAPI_FreeEnv(EnvironmentHandle); -} - -RETCODE SQL_API -SQLFreeStmt(HSTMT StatementHandle, - SQLUSMALLINT Option) -{ - mylog("[SQLFreeStmt]"); - return PGAPI_FreeStmt(StatementHandle, Option); -} - -RETCODE SQL_API -SQLGetConnectOption(HDBC ConnectionHandle, - SQLUSMALLINT Option, PTR Value) -{ - mylog("[SQLGetConnectOption]"); - CC_clear_error((ConnectionClass *) ConnectionHandle); - return PGAPI_GetConnectOption(ConnectionHandle, Option, Value); -} -RETCODE SQL_API -SQLGetCursorName(HSTMT StatementHandle, - SQLCHAR *CursorName, SQLSMALLINT BufferLength, - SQLSMALLINT *NameLength) -{ - mylog("[SQLGetCursorName]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_GetCursorName(StatementHandle, CursorName, BufferLength, - NameLength); -} - -RETCODE SQL_API -SQLGetData(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, - PTR TargetValue, SQLINTEGER BufferLength, - SQLINTEGER *StrLen_or_Ind) -{ - mylog("[SQLGetData]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_GetData(StatementHandle, ColumnNumber, TargetType, - TargetValue, BufferLength, StrLen_or_Ind); -} - -RETCODE SQL_API -SQLGetFunctions(HDBC ConnectionHandle, - SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported) -{ - mylog("[SQLGetFunctions]"); - CC_clear_error((ConnectionClass *) ConnectionHandle); -#if (ODBCVER >= 0x0300) - if (FunctionId == SQL_API_ODBC3_ALL_FUNCTIONS) - return PGAPI_GetFunctions30(ConnectionHandle, FunctionId, Supported); -#endif - return PGAPI_GetFunctions(ConnectionHandle, FunctionId, Supported); -} -RETCODE SQL_API -SQLGetInfo(HDBC ConnectionHandle, - SQLUSMALLINT InfoType, PTR InfoValue, - SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) -{ - RETCODE ret; - ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; - - CC_clear_error(conn); -#if (ODBCVER >= 0x0300) - mylog("[SQLGetInfo(30)]"); - if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, - BufferLength, StringLength)) == SQL_ERROR) - { - if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300) - { - CC_clear_error(conn); - ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, - BufferLength, StringLength); - } - } - if (SQL_ERROR == ret) - CC_log_error("SQLGetInfo30", "", conn); -#else - mylog("[SQLGetInfo]"); - if (ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, - BufferLength, StringLength), SQL_ERROR == ret) - CC_log_error("PGAPI_GetInfo", "", conn); -#endif - return ret; -} - -RETCODE SQL_API -SQLGetStmtOption(HSTMT StatementHandle, - SQLUSMALLINT Option, PTR Value) -{ - mylog("[SQLGetStmtOption]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_GetStmtOption(StatementHandle, Option, Value); -} - -RETCODE SQL_API -SQLGetTypeInfo(HSTMT StatementHandle, - SQLSMALLINT DataType) -{ - mylog("[SQLGetTypeInfo]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_GetTypeInfo(StatementHandle, DataType); -} - -RETCODE SQL_API -SQLNumResultCols(HSTMT StatementHandle, - SQLSMALLINT *ColumnCount) -{ - mylog("[SQLNumResultCols]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_NumResultCols(StatementHandle, ColumnCount); -} - -RETCODE SQL_API -SQLParamData(HSTMT StatementHandle, - PTR *Value) -{ - mylog("[SQLParamData]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_ParamData(StatementHandle, Value); -} - -RETCODE SQL_API -SQLPrepare(HSTMT StatementHandle, - SQLCHAR *StatementText, SQLINTEGER TextLength) -{ - mylog("[SQLPrepare]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_Prepare(StatementHandle, StatementText, TextLength); -} - -RETCODE SQL_API -SQLPutData(HSTMT StatementHandle, - PTR Data, SQLINTEGER StrLen_or_Ind) -{ - mylog("[SQLPutData]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_PutData(StatementHandle, Data, StrLen_or_Ind); -} - -RETCODE SQL_API -SQLRowCount(HSTMT StatementHandle, - SQLINTEGER *RowCount) -{ - mylog("[SQLRowCount]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_RowCount(StatementHandle, RowCount); -} - -RETCODE SQL_API -SQLSetConnectOption(HDBC ConnectionHandle, - SQLUSMALLINT Option, SQLUINTEGER Value) -{ - mylog("[SQLSetConnectionOption]"); - CC_clear_error((ConnectionClass *) ConnectionHandle); - return PGAPI_SetConnectOption(ConnectionHandle, Option, Value); -} - -RETCODE SQL_API -SQLSetCursorName(HSTMT StatementHandle, - SQLCHAR *CursorName, SQLSMALLINT NameLength) -{ - mylog("[SQLSetCursorName]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_SetCursorName(StatementHandle, CursorName, NameLength); -} - -RETCODE SQL_API -SQLSetParam(HSTMT StatementHandle, - SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, - SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision, - SQLSMALLINT ParameterScale, PTR ParameterValue, - SQLINTEGER *StrLen_or_Ind) -{ - mylog("[SQLSetParam]"); - SC_clear_error((StatementClass *) StatementHandle); - - /* - * return PGAPI_SetParam(StatementHandle, ParameterNumber, ValueType, - * ParameterType, LengthPrecision, ParameterScale, ParameterValue, - * StrLen_or_Ind); - */ - return SQL_ERROR; -} - -RETCODE SQL_API -SQLSetStmtOption(HSTMT StatementHandle, - SQLUSMALLINT Option, SQLUINTEGER Value) -{ - mylog("[SQLSetStmtOption]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_SetStmtOption(StatementHandle, Option, Value); -} - -RETCODE SQL_API -SQLSpecialColumns(HSTMT StatementHandle, - SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName, - SQLSMALLINT NameLength1, SQLCHAR *SchemaName, - SQLSMALLINT NameLength2, SQLCHAR *TableName, - SQLSMALLINT NameLength3, SQLUSMALLINT Scope, - SQLUSMALLINT Nullable) -{ - mylog("[SQLSpecialColumns]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_SpecialColumns(StatementHandle, IdentifierType, CatalogName, - NameLength1, SchemaName, NameLength2, TableName, NameLength3, - Scope, Nullable); -} - -RETCODE SQL_API -SQLStatistics(HSTMT StatementHandle, - SQLCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLCHAR *TableName, SQLSMALLINT NameLength3, - SQLUSMALLINT Unique, SQLUSMALLINT Reserved) -{ - mylog("[SQLStatistics]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_Statistics(StatementHandle, CatalogName, NameLength1, - SchemaName, NameLength2, TableName, NameLength3, Unique, - Reserved); -} - -RETCODE SQL_API -SQLTables(HSTMT StatementHandle, - SQLCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLCHAR *TableName, SQLSMALLINT NameLength3, - SQLCHAR *TableType, SQLSMALLINT NameLength4) -{ - mylog("[SQLTables]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_Tables(StatementHandle, CatalogName, NameLength1, - SchemaName, NameLength2, TableName, NameLength3, - TableType, NameLength4); -} - -RETCODE SQL_API -SQLTransact(HENV EnvironmentHandle, - HDBC ConnectionHandle, SQLUSMALLINT CompletionType) -{ - mylog("[SQLTransact]"); - return PGAPI_Transact(EnvironmentHandle, ConnectionHandle, CompletionType); -} - -RETCODE SQL_API -SQLColAttributes( - HSTMT hstmt, - SQLUSMALLINT icol, - SQLUSMALLINT fDescType, - PTR rgbDesc, - SQLSMALLINT cbDescMax, - SQLSMALLINT *pcbDesc, - SQLINTEGER *pfDesc) -{ - mylog("[SQLColAttributes]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_ColAttributes(hstmt, icol, fDescType, rgbDesc, - cbDescMax, pcbDesc, pfDesc); -} - -RETCODE SQL_API -SQLColumnPrivileges( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szTableName, - SQLSMALLINT cbTableName, - SQLCHAR *szColumnName, - SQLSMALLINT cbColumnName) -{ - mylog("[SQLColumnPrivileges]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_ColumnPrivileges(hstmt, szCatalogName, cbCatalogName, - szSchemaName, cbSchemaName, szTableName, cbTableName, - szColumnName, cbColumnName); -} - -RETCODE SQL_API -SQLDescribeParam( - HSTMT hstmt, - SQLUSMALLINT ipar, - SQLSMALLINT *pfSqlType, - SQLUINTEGER *pcbParamDef, - SQLSMALLINT *pibScale, - SQLSMALLINT *pfNullable) -{ - mylog("[SQLDescribeParam]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_DescribeParam(hstmt, ipar, pfSqlType, pcbParamDef, - pibScale, pfNullable); -} - -RETCODE SQL_API -SQLExtendedFetch( - HSTMT hstmt, - SQLUSMALLINT fFetchType, - SQLINTEGER irow, - SQLUINTEGER *pcrow, - SQLUSMALLINT *rgfRowStatus) -{ - mylog("[SQLExtendedFetch]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_ExtendedFetch(hstmt, fFetchType, irow, pcrow, rgfRowStatus, 0); -} - -RETCODE SQL_API -SQLForeignKeys( - HSTMT hstmt, - SQLCHAR *szPkCatalogName, - SQLSMALLINT cbPkCatalogName, - SQLCHAR *szPkSchemaName, - SQLSMALLINT cbPkSchemaName, - SQLCHAR *szPkTableName, - SQLSMALLINT cbPkTableName, - SQLCHAR *szFkCatalogName, - SQLSMALLINT cbFkCatalogName, - SQLCHAR *szFkSchemaName, - SQLSMALLINT cbFkSchemaName, - SQLCHAR *szFkTableName, - SQLSMALLINT cbFkTableName) -{ - mylog("[SQLForeignKeys]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_ForeignKeys(hstmt, szPkCatalogName, cbPkCatalogName, - szPkSchemaName, cbPkSchemaName, szPkTableName, - cbPkTableName, szFkCatalogName, cbFkCatalogName, - szFkSchemaName, cbFkSchemaName, szFkTableName, cbFkTableName); -} - -RETCODE SQL_API -SQLMoreResults(HSTMT hstmt) -{ - mylog("[SQLMoreResults]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_MoreResults(hstmt); -} - -RETCODE SQL_API -SQLNativeSql( - HDBC hdbc, - SQLCHAR *szSqlStrIn, - SQLINTEGER cbSqlStrIn, - SQLCHAR *szSqlStr, - SQLINTEGER cbSqlStrMax, - SQLINTEGER *pcbSqlStr) -{ - mylog("[SQLNativeSql]"); - CC_clear_error((ConnectionClass *) hdbc); - return PGAPI_NativeSql(hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, - cbSqlStrMax, pcbSqlStr); -} - -RETCODE SQL_API -SQLNumParams( - HSTMT hstmt, - SQLSMALLINT *pcpar) -{ - mylog("[SQLNumParams]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_NumParams(hstmt, pcpar); -} - -RETCODE SQL_API -SQLParamOptions( - HSTMT hstmt, - SQLUINTEGER crow, - SQLUINTEGER *pirow) -{ - mylog("[SQLParamOptions]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_ParamOptions(hstmt, crow, pirow); -} - -RETCODE SQL_API -SQLPrimaryKeys( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szTableName, - SQLSMALLINT cbTableName) -{ - mylog("[SQLPrimaryKeys]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_PrimaryKeys(hstmt, szCatalogName, cbCatalogName, - szSchemaName, cbSchemaName, szTableName, cbTableName); -} - -RETCODE SQL_API -SQLProcedureColumns( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szProcName, - SQLSMALLINT cbProcName, - SQLCHAR *szColumnName, - SQLSMALLINT cbColumnName) -{ - mylog("[SQLProcedureColumns]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_ProcedureColumns(hstmt, szCatalogName, cbCatalogName, - szSchemaName, cbSchemaName, szProcName, cbProcName, - szColumnName, cbColumnName); -} - -RETCODE SQL_API -SQLProcedures( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szProcName, - SQLSMALLINT cbProcName) -{ - mylog("[SQLProcedures]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_Procedures(hstmt, szCatalogName, cbCatalogName, - szSchemaName, cbSchemaName, szProcName, cbProcName); -} - -RETCODE SQL_API -SQLSetPos( - HSTMT hstmt, - SQLUSMALLINT irow, - SQLUSMALLINT fOption, - SQLUSMALLINT fLock) -{ - mylog("[SQLSetPos]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_SetPos(hstmt, irow, fOption, fLock); -} - -RETCODE SQL_API -SQLTablePrivileges( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szTableName, - SQLSMALLINT cbTableName) -{ - mylog("[SQLTablePrivileges]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_TablePrivileges(hstmt, szCatalogName, cbCatalogName, - szSchemaName, cbSchemaName, szTableName, cbTableName, 0); -} - -RETCODE SQL_API -SQLBindParameter( - HSTMT hstmt, - SQLUSMALLINT ipar, - SQLSMALLINT fParamType, - SQLSMALLINT fCType, - SQLSMALLINT fSqlType, - SQLUINTEGER cbColDef, - SQLSMALLINT ibScale, - PTR rgbValue, - SQLINTEGER cbValueMax, - SQLINTEGER *pcbValue) -{ - mylog("[SQLBindParameter]"); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_BindParameter(hstmt, ipar, fParamType, fCType, - fSqlType, cbColDef, ibScale, rgbValue, cbValueMax, - pcbValue); -} diff --git a/src/interfaces/odbc/odbcapi25w.c b/src/interfaces/odbc/odbcapi25w.c deleted file mode 100644 index 47015a2322..0000000000 --- a/src/interfaces/odbc/odbcapi25w.c +++ /dev/null @@ -1,81 +0,0 @@ -/*------- - * Module: odbcapi25w.c - * - * Description: This module contains UNICODE routines - * - * Classes: n/a - * - * API functions: SQLColAttributesW, SQLErrorW, SQLGetConnectOptionW, - SQLSetConnectOptionW - *------- - */ - -#include "psqlodbc.h" -#include -#include - -#include "pgapifunc.h" -#include "connection.h" -#include "statement.h" - -RETCODE SQL_API SQLErrorW(HENV EnvironmentHandle, - HDBC ConnectionHandle, HSTMT StatementHandle, - SQLWCHAR *Sqlstate, SQLINTEGER *NativeError, - SQLWCHAR *MessageText, SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength) -{ - RETCODE ret; - SWORD tlen, buflen; - char *qst = NULL, *mtxt = NULL; - - mylog("[SQLErrorW]"); - if (Sqlstate) - qst = malloc(8); - buflen = 0; - if (MessageText && BufferLength > 0) - { - buflen = BufferLength * 3 + 1; - mtxt = malloc(buflen); - } - ret = PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle, - qst, NativeError, mtxt, buflen, &tlen); - if (qst) - utf8_to_ucs2(qst, strlen(qst), Sqlstate, 5); - if (TextLength) - *TextLength = utf8_to_ucs2(mtxt, tlen, MessageText, BufferLength); - free(qst); - if (mtxt) - free(mtxt); - return ret; -} - -RETCODE SQL_API SQLGetConnectOptionW(HDBC ConnectionHandle, - SQLUSMALLINT Option, PTR Value) -{ - mylog("[SQLGetConnectOptionW]"); - ((ConnectionClass *) ConnectionHandle)->unicode = 1; - return PGAPI_GetConnectOption(ConnectionHandle, Option, Value); -} - -RETCODE SQL_API SQLSetConnectOptionW(HDBC ConnectionHandle, - SQLUSMALLINT Option, SQLUINTEGER Value) -{ - mylog("[SQLSetConnectionOptionW]"); -if (!ConnectionHandle) return SQL_ERROR; - ((ConnectionClass *) ConnectionHandle)->unicode = 1; - return PGAPI_SetConnectOption(ConnectionHandle, Option, Value); -} - -RETCODE SQL_API SQLColAttributesW( - HSTMT hstmt, - SQLUSMALLINT icol, - SQLUSMALLINT fDescType, - PTR rgbDesc, - SQLSMALLINT cbDescMax, - SQLSMALLINT *pcbDesc, - SQLINTEGER *pfDesc) -{ - mylog("[SQLColAttributesW]"); - return PGAPI_ColAttributes(hstmt, icol, fDescType, rgbDesc, - cbDescMax, pcbDesc, pfDesc); -} diff --git a/src/interfaces/odbc/odbcapi30.c b/src/interfaces/odbc/odbcapi30.c deleted file mode 100644 index cf73924065..0000000000 --- a/src/interfaces/odbc/odbcapi30.c +++ /dev/null @@ -1,550 +0,0 @@ -/*------- - * Module: odbcapi30.c - * - * Description: This module contains routines related to ODBC 3.0 - * most of their implementations are temporary - * and must be rewritten properly. - * 2001/07/23 inoue - * - * Classes: n/a - * - * API functions: SQLAllocHandle, SQLBindParam, SQLCloseCursor, - SQLColAttribute, SQLCopyDesc, SQLEndTran, - SQLFetchScroll, SQLFreeHandle, SQLGetDescField, - SQLGetDescRec, SQLGetDiagField, SQLGetDiagRec, - SQLGetEnvAttr, SQLGetConnectAttr, SQLGetStmtAttr, - SQLSetConnectAttr, SQLSetDescField, SQLSetDescRec, - SQLSetEnvAttr, SQLSetStmtAttr, SQLBulkOperations - *------- - */ - -#ifndef ODBCVER -#define ODBCVER 0x0300 -#endif -#include "psqlodbc.h" -#include -#include - -#include "environ.h" -#include "connection.h" -#include "statement.h" -#include "pgapifunc.h" - -/* SQLAllocConnect/SQLAllocEnv/SQLAllocStmt -> SQLAllocHandle */ -RETCODE SQL_API -SQLAllocHandle(SQLSMALLINT HandleType, - SQLHANDLE InputHandle, SQLHANDLE * OutputHandle) -{ - mylog("[[SQLAllocHandle]]"); - switch (HandleType) - { - case SQL_HANDLE_ENV: - return PGAPI_AllocEnv(OutputHandle); - case SQL_HANDLE_DBC: - return PGAPI_AllocConnect(InputHandle, OutputHandle); - case SQL_HANDLE_STMT: - return PGAPI_AllocStmt(InputHandle, OutputHandle); - default: - break; - } - return SQL_ERROR; -} - -/* SQLBindParameter/SQLSetParam -> SQLBindParam */ -RETCODE SQL_API -SQLBindParam(HSTMT StatementHandle, - SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, - SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision, - SQLSMALLINT ParameterScale, PTR ParameterValue, - SQLINTEGER *StrLen_or_Ind) -{ - int BufferLength = 512; /* Is it OK ? */ - - mylog("[[SQLBindParam]]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_BindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, BufferLength, StrLen_or_Ind); -} - -/* New function */ -RETCODE SQL_API -SQLCloseCursor(HSTMT StatementHandle) -{ - mylog("[[SQLCloseCursor]]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_FreeStmt(StatementHandle, SQL_CLOSE); -} - -/* SQLColAttributes -> SQLColAttribute */ -RETCODE SQL_API -SQLColAttribute(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, - PTR CharacterAttribute, SQLSMALLINT BufferLength, - SQLSMALLINT *StringLength, PTR NumericAttribute) -{ - mylog("[[SQLColAttribute]]"); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_ColAttributes(StatementHandle, ColumnNumber, - FieldIdentifier, CharacterAttribute, BufferLength, - StringLength, NumericAttribute); -} - -static HSTMT -descHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType) -{ - switch (descType) - { - case SQL_ATTR_APP_ROW_DESC: /* 10010 */ - return StatementHandle; /* this is bogus */ - case SQL_ATTR_APP_PARAM_DESC: /* 10011 */ - return (HSTMT) ((SQLUINTEGER) StatementHandle + 1) ; /* this is bogus */ - case SQL_ATTR_IMP_ROW_DESC: /* 10012 */ - return (HSTMT) ((SQLUINTEGER) StatementHandle + 2); /* this is bogus */ - case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */ - return (HSTMT) ((SQLUINTEGER) StatementHandle + 3); /* this is bogus */ - } - return (HSTMT) 0; -} -static HSTMT -statementHandleFromDescHandle(HSTMT DescHandle, SQLINTEGER *descType) -{ - SQLUINTEGER res = (SQLUINTEGER) DescHandle % 4; - switch (res) - { - case 0: *descType = SQL_ATTR_APP_ROW_DESC; /* 10010 */ - break; - case 1: *descType = SQL_ATTR_APP_PARAM_DESC; /* 10011 */ - break; - case 2: *descType = SQL_ATTR_IMP_ROW_DESC; /* 10012 */ - break; - case 3: *descType = SQL_ATTR_IMP_PARAM_DESC; /* 10013 */ - break; - } - return (HSTMT) ((SQLUINTEGER) DescHandle - res); -} - -/* new function */ -RETCODE SQL_API -SQLCopyDesc(SQLHDESC SourceDescHandle, - SQLHDESC TargetDescHandle) -{ - mylog("[[SQLCopyDesc]]\n"); - mylog("Error not implemented\n"); - return SQL_ERROR; -} - -/* SQLTransact -> SQLEndTran */ -RETCODE SQL_API -SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT CompletionType) -{ - mylog("[[SQLEndTran]]"); - switch (HandleType) - { - case SQL_HANDLE_ENV: - return PGAPI_Transact(Handle, SQL_NULL_HDBC, CompletionType); - case SQL_HANDLE_DBC: - CC_clear_error((ConnectionClass *) Handle); - return PGAPI_Transact(SQL_NULL_HENV, Handle, CompletionType); - default: - break; - } - return SQL_ERROR; -} - -/* SQLExtendedFetch -> SQLFetchScroll */ -RETCODE SQL_API -SQLFetchScroll(HSTMT StatementHandle, - SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset) -{ - static char *func = "SQLFetchScroll"; - StatementClass *stmt = (StatementClass *) StatementHandle; - RETCODE ret; - IRDFields *irdopts = SC_get_IRD(stmt); - SQLUSMALLINT *rowStatusArray = irdopts->rowStatusArray; - SQLINTEGER *pcRow = irdopts->rowsFetched, bkmarkoff = 0; - - mylog("[[%s]] %d,%d\n", func, FetchOrientation, FetchOffset); - SC_clear_error(stmt); - if (FetchOrientation == SQL_FETCH_BOOKMARK) - { - if (stmt->options.bookmark_ptr) - { - bkmarkoff = FetchOffset; - FetchOffset = *((Int4 *) stmt->options.bookmark_ptr); -mylog("bookmark=%u FetchOffset = %d\n", FetchOffset, bkmarkoff); - } - else - { - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "Bookmark isn't specifed yet"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - ret = PGAPI_ExtendedFetch(StatementHandle, FetchOrientation, FetchOffset, - pcRow, rowStatusArray, bkmarkoff); - if (ret != SQL_SUCCESS) - mylog("%s return = %d\n", func, ret); - return ret; -} - -/* SQLFree(Connect/Env/Stmt) -> SQLFreeHandle */ -RETCODE SQL_API -SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle) -{ - mylog("[[SQLFreeHandle]]"); - switch (HandleType) - { - case SQL_HANDLE_ENV: - return PGAPI_FreeEnv(Handle); - case SQL_HANDLE_DBC: - return PGAPI_FreeConnect(Handle); - case SQL_HANDLE_STMT: - return PGAPI_FreeStmt(Handle, SQL_DROP); - default: - break; - } - return SQL_ERROR; -} - -/* new function */ -RETCODE SQL_API -SQLGetDescField(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, - PTR Value, SQLINTEGER BufferLength, - SQLINTEGER *StringLength) -{ - mylog("[[SQLGetDescField]]\n"); - return PGAPI_GetDescField(DescriptorHandle, RecNumber, FieldIdentifier, - Value, BufferLength, StringLength); -} - -/* new function */ -RETCODE SQL_API -SQLGetDescRec(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLCHAR *Name, - SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, - SQLSMALLINT *Type, SQLSMALLINT *SubType, - SQLINTEGER *Length, SQLSMALLINT *Precision, - SQLSMALLINT *Scale, SQLSMALLINT *Nullable) -{ - mylog("[[SQLGetDescRec]]\n"); - mylog("Error not implemented\n"); - return SQL_ERROR; -} - -/* new function */ -RETCODE SQL_API -SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, - PTR DiagInfo, SQLSMALLINT BufferLength, - SQLSMALLINT *StringLength) -{ - mylog("[[SQLGetDiagField]] Handle=(%u,%x) Rec=%d Id=%d\n", HandleType, Handle, RecNumber, DiagIdentifier); - return PGAPI_GetDiagField(HandleType, Handle, RecNumber, DiagIdentifier, - DiagInfo, BufferLength, StringLength); -} - -/* SQLError -> SQLDiagRec */ -RETCODE SQL_API -SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, - SQLINTEGER *NativeError, SQLCHAR *MessageText, - SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) -{ - mylog("[[SQLGetDiagRec]]\n"); - return PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate, - NativeError, MessageText, BufferLength, TextLength); -} - -/* new function */ -RETCODE SQL_API -SQLGetEnvAttr(HENV EnvironmentHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength) -{ - EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle; - - mylog("[[SQLGetEnvAttr]] %d\n", Attribute); - switch (Attribute) - { - case SQL_ATTR_CONNECTION_POOLING: - *((unsigned int *) Value) = SQL_CP_OFF; - break; - case SQL_ATTR_CP_MATCH: - *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; - break; - case SQL_ATTR_ODBC_VERSION: - *((unsigned int *) Value) = EN_is_odbc2(env) ? SQL_OV_ODBC2 : SQL_OV_ODBC3; - break; - case SQL_ATTR_OUTPUT_NTS: - *((unsigned int *) Value) = SQL_TRUE; - break; - default: - env->errornumber = CONN_INVALID_ARGUMENT_NO; - return SQL_ERROR; - } - return SQL_SUCCESS; -} - -/* SQLGetConnectOption -> SQLGetconnectAttr */ -RETCODE SQL_API -SQLGetConnectAttr(HDBC ConnectionHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength) -{ - mylog("[[SQLGetConnectAttr]] %d\n", Attribute); - CC_clear_error((ConnectionClass *) ConnectionHandle); - return PGAPI_GetConnectAttr(ConnectionHandle, Attribute,Value, - BufferLength, StringLength); -} - -/* SQLGetStmtOption -> SQLGetStmtAttr */ -RETCODE SQL_API -SQLGetStmtAttr(HSTMT StatementHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength) -{ - static char *func = "SQLGetStmtAttr"; - - mylog("[[%s]] Handle=%u %d\n", func, StatementHandle, Attribute); - SC_clear_error((StatementClass *) StatementHandle); - return PGAPI_GetStmtAttr(StatementHandle, Attribute, Value, - BufferLength, StringLength); -} - -/* SQLSetConnectOption -> SQLSetConnectAttr */ -RETCODE SQL_API -SQLSetConnectAttr(HDBC ConnectionHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength) -{ - ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; - - mylog("[[SQLSetConnectAttr]] %d\n", Attribute); - CC_clear_error(conn); - return PGAPI_SetConnectAttr(ConnectionHandle, Attribute, Value, - StringLength); -} - -/* new function */ -RETCODE SQL_API -SQLSetDescField(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, - PTR Value, SQLINTEGER BufferLength) -{ - RETCODE ret; - - mylog("[[SQLSetDescField]] h=%u rec=%d field=%d val=%x\n", DescriptorHandle, RecNumber, FieldIdentifier, Value); - ret = PGAPI_SetDescField(DescriptorHandle, RecNumber, FieldIdentifier, - Value, BufferLength); - return ret; -} - -/* new fucntion */ -RETCODE SQL_API -SQLSetDescRec(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT Type, - SQLSMALLINT SubType, SQLINTEGER Length, - SQLSMALLINT Precision, SQLSMALLINT Scale, - PTR Data, SQLINTEGER *StringLength, - SQLINTEGER *Indicator) -{ - const char *func = "SQLSetDescRec"; - - mylog("[[SQLSetDescRec]]\n"); - mylog("Error not implemented\n"); - return SQL_ERROR; -} - -/* new function */ -RETCODE SQL_API -SQLSetEnvAttr(HENV EnvironmentHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength) -{ - EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle; - - mylog("[[SQLSetEnvAttr]] att=%d,%u\n", Attribute, Value); - switch (Attribute) - { - case SQL_ATTR_CONNECTION_POOLING: - if ((SQLUINTEGER) Value == SQL_CP_OFF) - return SQL_SUCCESS; - break; - case SQL_ATTR_CP_MATCH: - /* *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; */ - return SQL_SUCCESS; - case SQL_ATTR_ODBC_VERSION: - if ((SQLUINTEGER) Value == SQL_OV_ODBC2) - EN_set_odbc2(env); - else - EN_set_odbc3(env); - return SQL_SUCCESS; - break; - case SQL_ATTR_OUTPUT_NTS: - if ((SQLUINTEGER) Value == SQL_TRUE) - return SQL_SUCCESS; - break; - default: - env->errornumber = CONN_INVALID_ARGUMENT_NO; - return SQL_ERROR; - } - env->errornumber = CONN_OPTION_VALUE_CHANGED; - env->errormsg = "SetEnv changed to "; - return SQL_SUCCESS_WITH_INFO; -} - -/* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */ -RETCODE SQL_API -SQLSetStmtAttr(HSTMT StatementHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength) -{ - static char *func = "SQLSetStmtAttr"; - StatementClass *stmt = (StatementClass *) StatementHandle; - - mylog("[[%s]] Handle=%u %d,%u\n", func, StatementHandle, Attribute, Value); - SC_clear_error(stmt); - return PGAPI_SetStmtAttr(StatementHandle, Attribute, Value, StringLength); -} - -#define SQL_FUNC_ESET(pfExists, uwAPI) \ - (*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \ - |= (1 << ((uwAPI) & 0x000F)) \ - ) -RETCODE SQL_API -PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists) -{ - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci = &(conn->connInfo); - - CC_clear_error(conn); - if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS) - return SQL_ERROR; - memset(pfExists, 0, sizeof(UWORD) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE); - - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCCONNECT); 1 deprecated */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCENV); 2 deprecated */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCSTMT); 3 deprecated */ - - /* - * for (i = SQL_API_SQLBINDCOL; i <= 23; i++) SQL_FUNC_ESET(pfExists, - * i); - */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDCOL); /* 4 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLCANCEL); /* 5 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLATTRIBUTE); /* 6 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLCONNECT); /* 7 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBECOL); /* 8 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLDISCONNECT); /* 9 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLERROR); 10 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECDIRECT); /* 11 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECUTE); /* 12 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCH); /* 13 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREECONNECT); 14 deprecated */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEENV); 15 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLFREESTMT); /* 16 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCURSORNAME); /* 17 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMRESULTCOLS); /* 18 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLPREPARE); /* 19 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLROWCOUNT); /* 20 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCURSORNAME); /* 21 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPARAM); 22 deprecated */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLTRANSACT); 23 deprecated */ - - /* - * for (i = 40; i < SQL_API_SQLEXTENDEDFETCH; i++) - * SQL_FUNC_ESET(pfExists, i); - */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNS); /* 40 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERCONNECT); /* 41 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTOPTION); 42 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDATA); /* 43 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETFUNCTIONS); /* 44 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETINFO); /* 45 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTOPTION); 46 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETTYPEINFO); /* 47 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */ - - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */ - if (ci->drivers.lie) - SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implemented yet */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */ - if (ci->drivers.lie) - SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 not properly implemented */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); /* 59 deprecated ? */ - - /* - * for (++i; i < SQL_API_SQLBINDPARAMETER; i++) - * SQL_FUNC_ESET(pfExists, i); - */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLFOREIGNKEYS); /* 60 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLMORERESULTS); /* 61 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLNATIVESQL); /* 62 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMPARAMS); /* 63 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */ - if (ci->drivers.lie) - SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 not implemeted yet */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES); /* 67 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); 69 deprecated */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 */ - /* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */ /* 71 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */ - - SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCHANDLE); /* 1001 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAM); /* 1002 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLCLOSECURSOR); /* 1003 */ - if (ci->drivers.lie) - SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC); /* 1004 not implemented yet */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLENDTRAN); /* 1005 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEHANDLE); /* 1006 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR); /* 1007 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD); /* 1008 */ - if (ci->drivers.lie) - { - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC); /* 1009 not implemented yet */ - } - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD); /* 1010 minimal implementation */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC); /* 1011 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETENVATTR); /* 1012 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTATTR); /* 1014 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 */ - if (ci->drivers.lie) - { - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */ - } - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR); /* 1019 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */ - SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */ - if (ci->updatable_cursors) - SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS); /* 24 */ - - return SQL_SUCCESS; -} - -RETCODE SQL_API -SQLBulkOperations(HSTMT hstmt, SQLSMALLINT operation) -{ - static char *func = "SQLBulkOperations"; -#ifndef DRIVER_CURSOR_IMPLEMENT - StatementClass *stmt = (StatementClass *) hstmt; - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "driver must be compiled with the DRIVER_CURSOR_IMPLEMENT option"; - SC_log_error(func, "", stmt); - return SQL_ERROR; -#else - mylog("[[%s]] Handle=%u %d\n", func, hstmt, operation); - SC_clear_error((StatementClass *) hstmt); - return PGAPI_BulkOperations(hstmt, operation); -#endif /* DRIVER_CURSOR_IMPLEMENT */ -} diff --git a/src/interfaces/odbc/odbcapi30w.c b/src/interfaces/odbc/odbcapi30w.c deleted file mode 100644 index 8992353b31..0000000000 --- a/src/interfaces/odbc/odbcapi30w.c +++ /dev/null @@ -1,282 +0,0 @@ -/*------- - * Module: odbcapi30w.c - * - * Description: This module contains UNICODE routines - * - * Classes: n/a - * - * API functions: SQLColAttributeW, SQLGetStmtAttrW, SQLSetStmtAttrW, - SQLSetConnectAttrW, SQLGetConnectAttrW, - SQLGetDescFieldW, SQLGetDescRecW, SQLGetDiagFieldW, - SQLGetDiagRecW, - *------- - */ - -#include "psqlodbc.h" -#include -#include - -#include "pgapifunc.h" -#include "connection.h" -#include "statement.h" - - -RETCODE SQL_API SQLGetStmtAttrW(SQLHSTMT hstmt, - SQLINTEGER fAttribute, - PTR rgbValue, - SQLINTEGER cbValueMax, - SQLINTEGER *pcbValue) -{ - RETCODE ret; - - mylog("[SQLGetStmtAttrW]"); - SC_clear_error((StatementClass *) hstmt); - ret = PGAPI_GetStmtAttr(hstmt, fAttribute, rgbValue, - cbValueMax, pcbValue); - return ret; -} - -RETCODE SQL_API SQLSetStmtAttrW(SQLHSTMT hstmt, - SQLINTEGER fAttribute, - PTR rgbValue, - SQLINTEGER cbValueMax) -{ - RETCODE ret; - - mylog("[SQLSetStmtAttrW]"); - SC_clear_error((StatementClass *) hstmt); - ret = PGAPI_SetStmtAttr(hstmt, fAttribute, rgbValue, - cbValueMax); - return ret; -} - -RETCODE SQL_API SQLGetConnectAttrW(HDBC hdbc, - SQLINTEGER fAttribute, - PTR rgbValue, - SQLINTEGER cbValueMax, - SQLINTEGER *pcbValue) -{ - RETCODE ret; - - mylog("[SQLGetConnectAttrW]"); - CC_clear_error((ConnectionClass *) hdbc); - ret = PGAPI_GetConnectAttr(hdbc, fAttribute, rgbValue, - cbValueMax, pcbValue); - return ret; -} - -RETCODE SQL_API SQLSetConnectAttrW(HDBC hdbc, - SQLINTEGER fAttribute, - PTR rgbValue, - SQLINTEGER cbValue) -{ - RETCODE ret; - - mylog("[SQLSetConnectAttrW]"); - CC_clear_error((ConnectionClass *) hdbc); - ret = PGAPI_SetConnectAttr(hdbc, fAttribute, rgbValue, - cbValue); - return ret; -} - -/* new function */ -RETCODE SQL_API -SQLSetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, - SQLINTEGER BufferLength) -{ - RETCODE ret; - UInt4 vallen; - char *uval = NULL; - BOOL val_alloced = FALSE; - - mylog("[SQLSetDescFieldW]"); - if (BufferLength > 0) - { - switch (FieldIdentifier) - { - case SQL_DESC_BASE_COLUMN_NAME: - case SQL_DESC_BASE_TABLE_NAME: - case SQL_DESC_CATALOG_NAME: - case SQL_DESC_LABEL: - case SQL_DESC_LITERAL_PREFIX: - case SQL_DESC_LITERAL_SUFFIX: - case SQL_DESC_LOCAL_TYPE_NAME: - case SQL_DESC_NAME: - case SQL_DESC_SCHEMA_NAME: - case SQL_DESC_TABLE_NAME: - case SQL_DESC_TYPE_NAME: - uval = ucs2_to_utf8(Value, BufferLength / 2, &vallen); - val_alloced = TRUE; - break; - } - } - if (!val_alloced) - { - uval = Value; - vallen = BufferLength; - } - ret = PGAPI_SetDescField(DescriptorHandle, RecNumber, FieldIdentifier, - uval, vallen); - if (val_alloced) - free(uval); - return ret; -} -RETCODE SQL_API -SQLGetDescFieldW(SQLHDESC hdesc, SQLSMALLINT iRecord, SQLSMALLINT iField, - PTR rgbValue, SQLINTEGER cbValueMax, - SQLINTEGER *pcbValue) -{ - RETCODE ret; - BOOL alloced = FALSE; - SQLINTEGER blen, bMax, *pcbV; - char *rgbV = NULL; - - mylog("[SQLGetDescFieldW]"); - switch (iField) - { - case SQL_DESC_BASE_COLUMN_NAME: - case SQL_DESC_BASE_TABLE_NAME: - case SQL_DESC_CATALOG_NAME: - case SQL_DESC_LABEL: - case SQL_DESC_LITERAL_PREFIX: - case SQL_DESC_LITERAL_SUFFIX: - case SQL_DESC_LOCAL_TYPE_NAME: - case SQL_DESC_NAME: - case SQL_DESC_SCHEMA_NAME: - case SQL_DESC_TABLE_NAME: - case SQL_DESC_TYPE_NAME: - alloced = TRUE; - bMax = cbValueMax * 3 / 2; - rgbV = malloc(bMax + 1); - pcbV = &blen; - break; - default: - rgbV = rgbValue; - bMax = cbValueMax; - pcbV = pcbValue; - break; - } - ret = PGAPI_GetDescField(hdesc, iRecord, iField, rgbV, bMax, pcbV); - if (alloced) - { - blen = utf8_to_ucs2(rgbV, blen, (SQLWCHAR *) rgbValue, cbValueMax / 2); - if (SQL_SUCCESS == ret && blen * 2 > cbValueMax) - { - ret = SQL_SUCCESS_WITH_INFO; - Desc_set_error(hdesc, STMT_TRUNCATED, "The buffer was too small for the rgbDesc."); - } - if (pcbValue) - *pcbValue = blen * 2; - free(rgbV); - } - - return ret; -} - -RETCODE SQL_API SQLGetDiagRecW(SWORD fHandleType, - SQLHANDLE handle, - SQLSMALLINT iRecord, - SQLWCHAR *szSqlState, - SQLINTEGER *pfNativeError, - SQLWCHAR *szErrorMsg, - SQLSMALLINT cbErrorMsgMax, - SQLSMALLINT *pcbErrorMsg) -{ - RETCODE ret; - SWORD buflen, tlen; - char *qstr = NULL, *mtxt = NULL; - - mylog("[SQLGetDiagRecW]"); - if (szSqlState) - qstr = malloc(8); - buflen = 0; - if (szErrorMsg && cbErrorMsgMax > 0) - { - buflen = cbErrorMsgMax; - mtxt = malloc(buflen); - } - ret = PGAPI_GetDiagRec(fHandleType, handle, iRecord, qstr, - pfNativeError, mtxt, buflen, &tlen); - if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) - { - if (qstr) - utf8_to_ucs2(qstr, strlen(qstr), szSqlState, 6); - if (mtxt && tlen <= cbErrorMsgMax) - { - tlen = utf8_to_ucs2(mtxt, tlen, szErrorMsg, cbErrorMsgMax); - if (tlen >= cbErrorMsgMax) - ret = SQL_SUCCESS_WITH_INFO; - } - if (pcbErrorMsg) - *pcbErrorMsg = tlen; - } - if (qstr); - free(qstr); - if (mtxt) - free(mtxt); - return ret; -} - -RETCODE SQL_API SQLColAttributeW( - HSTMT hstmt, - SQLUSMALLINT icol, - SQLUSMALLINT fDescType, - PTR rgbDesc, - SQLSMALLINT cbDescMax, - SQLSMALLINT *pcbDesc, - SQLINTEGER *pfDesc) -{ - RETCODE ret; - BOOL alloced = FALSE; - SQLSMALLINT *rgbL, blen, bMax; - char *rgbD = NULL; - - mylog("[SQLColAttributeW]"); - SC_clear_error((StatementClass *) hstmt); - switch (fDescType) - { - case SQL_DESC_BASE_COLUMN_NAME: - case SQL_DESC_BASE_TABLE_NAME: - case SQL_DESC_CATALOG_NAME: - case SQL_DESC_LABEL: - case SQL_DESC_LITERAL_PREFIX: - case SQL_DESC_LITERAL_SUFFIX: - case SQL_DESC_LOCAL_TYPE_NAME: - case SQL_DESC_NAME: - case SQL_DESC_SCHEMA_NAME: - case SQL_DESC_TABLE_NAME: - case SQL_DESC_TYPE_NAME: - case SQL_COLUMN_NAME: - alloced = TRUE; - bMax = cbDescMax * 3 / 2; - rgbD = malloc(bMax + 1); - rgbL = &blen; - break; - default: - rgbD = rgbDesc; - bMax = cbDescMax; - rgbL = pcbDesc; - break; - } - - ret = PGAPI_ColAttributes(hstmt, icol, fDescType, rgbD, - bMax, rgbL, pfDesc); - if (alloced) - { - blen = utf8_to_ucs2(rgbD, blen, (SQLWCHAR *) rgbDesc, cbDescMax / 2); - if (SQL_SUCCESS == ret && blen * 2 > cbDescMax) - { - StatementClass *stmt = (StatementClass *) hstmt; - - ret = SQL_SUCCESS_WITH_INFO; - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "The buffer was too small for the rgbDesc."; - } - if (pcbDesc) - *pcbDesc = blen * 2; - free(rgbD); - } - - return ret; -} diff --git a/src/interfaces/odbc/odbcapiw.c b/src/interfaces/odbc/odbcapiw.c deleted file mode 100755 index ac1e3f28f4..0000000000 --- a/src/interfaces/odbc/odbcapiw.c +++ /dev/null @@ -1,626 +0,0 @@ -/*------- - * Module: odbcapiw.c - * - * Description: This module contains UNICODE routines - * - * Classes: n/a - * - * API functions: SQLColumnPrivilegesW, SQLColumnsW, - SQLConnectW, SQLDataSourcesW, SQLDescribeColW, - SQLDriverConnectW, SQLExecDirectW, - SQLForeignKeysW, - SQLGetCursorNameW, SQLGetInfoW, SQLNativeSqlW, - SQLPrepareW, SQLPrimaryKeysW, SQLProcedureColumnsW, - SQLProceduresW, SQLSetCursorNameW, - SQLSpecialColumnsW, SQLStatisticsW, SQLTablesW, - SQLTablePrivilegesW, SQLGetTypeInfoW - *------- - */ - -#include "psqlodbc.h" -#include -#include - -#include "pgapifunc.h" -#include "connection.h" -#include "statement.h" - -RETCODE SQL_API SQLColumnsW(HSTMT StatementHandle, - SQLWCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLWCHAR *TableName, SQLSMALLINT NameLength3, - SQLWCHAR *ColumnName, SQLSMALLINT NameLength4) -{ - RETCODE ret; - char *ctName, *scName, *tbName, *clName; - UInt4 nmlen1, nmlen2, nmlen3, nmlen4; - - mylog("[SQLColumnsW]"); - ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1); - scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2); - tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3); - clName = ucs2_to_utf8(ColumnName, NameLength4, &nmlen4); - ret = PGAPI_Columns(StatementHandle, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, - clName, (SWORD) nmlen4, 0); - if (ctName) - free(ctName); - if (scName); - free(scName); - if (tbName) - free(tbName); - if (clName); - free(clName); - return ret; -} - - -RETCODE SQL_API SQLConnectW(HDBC ConnectionHandle, - SQLWCHAR *ServerName, SQLSMALLINT NameLength1, - SQLWCHAR *UserName, SQLSMALLINT NameLength2, - SQLWCHAR *Authentication, SQLSMALLINT NameLength3) -{ - char *svName, *usName, *auth; - UInt4 nmlen1, nmlen2, nmlen3; - RETCODE ret; - - mylog("[SQLConnectW]"); - ((ConnectionClass *) ConnectionHandle)->unicode = 1; - svName = ucs2_to_utf8(ServerName, NameLength1, &nmlen1); - usName = ucs2_to_utf8(UserName, NameLength2, &nmlen2); - auth = ucs2_to_utf8(Authentication, NameLength3, &nmlen3); - ret = PGAPI_Connect(ConnectionHandle, svName, (SWORD) nmlen1, - usName, (SWORD) nmlen2, auth, (SWORD) nmlen3); - if (svName); - free(svName); - if (usName); - free(usName); - if (auth); - free(auth); - return ret; -} - -RETCODE SQL_API SQLDriverConnectW(HDBC hdbc, - HWND hwnd, - SQLWCHAR *szConnStrIn, - SWORD cbConnStrIn, - SQLWCHAR *szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR *pcbConnStrOut, - UWORD fDriverCompletion) -{ - char *szIn, *szOut; - UInt4 inlen, obuflen; - SWORD olen; - RETCODE ret; - - mylog("[SQLDriverConnectW]"); - ((ConnectionClass *) hdbc)->unicode = 1; - szIn = ucs2_to_utf8(szConnStrIn, cbConnStrIn, &inlen); - obuflen = cbConnStrOutMax + 1; - szOut = malloc(obuflen); - ret = PGAPI_DriverConnect(hdbc, hwnd, szIn, (SWORD) inlen, - szOut, cbConnStrOutMax, &olen, fDriverCompletion); - if (ret != SQL_ERROR) - { - UInt4 outlen = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax); - if (pcbConnStrOut) - *pcbConnStrOut = outlen; - } - free(szOut); - if (szIn); - free(szIn); - return ret; -} -RETCODE SQL_API SQLBrowseConnectW( - HDBC hdbc, - SQLWCHAR *szConnStrIn, - SQLSMALLINT cbConnStrIn, - SQLWCHAR *szConnStrOut, - SQLSMALLINT cbConnStrOutMax, - SQLSMALLINT *pcbConnStrOut) -{ - char *szIn, *szOut; - UInt4 inlen, obuflen; - SWORD olen; - RETCODE ret; - - mylog("[SQLBrowseConnectW]"); - ((ConnectionClass *) hdbc)->unicode = 1; - szIn = ucs2_to_utf8(szConnStrIn, cbConnStrIn, &inlen); - obuflen = cbConnStrOutMax + 1; - szOut = malloc(obuflen); - ret = PGAPI_BrowseConnect(hdbc, szIn, (SWORD) inlen, - szOut, cbConnStrOutMax, &olen); - if (ret != SQL_ERROR) - { - UInt4 outlen = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax); - if (pcbConnStrOut) - *pcbConnStrOut = outlen; - } - free(szOut); - if (szIn); - free(szIn); - return ret; -} - -RETCODE SQL_API SQLDataSourcesW(HENV EnvironmentHandle, - SQLUSMALLINT Direction, SQLWCHAR *ServerName, - SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, - SQLWCHAR *Description, SQLSMALLINT BufferLength2, - SQLSMALLINT *NameLength2) -{ - mylog("[SQLDataSourcesW]"); - /* - return PGAPI_DataSources(EnvironmentHandle, Direction, ServerName, - BufferLength1, NameLength1, Description, BufferLength2, - NameLength2); - */ - return SQL_ERROR; -} - -RETCODE SQL_API SQLDescribeColW(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLWCHAR *ColumnName, - SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, - SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize, - SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) -{ - RETCODE ret; - SWORD buflen, nmlen; - char *clName; - - mylog("[SQLDescribeColW]"); - buflen = BufferLength * 3 + 1; - clName = malloc(buflen); - ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber, - clName, buflen, &nmlen, DataType, ColumnSize, - DecimalDigits, Nullable); - if (ret == SQL_SUCCESS) - { - UInt4 nmcount = utf8_to_ucs2(clName, nmlen, ColumnName, BufferLength); - if (nmcount > (UInt4) BufferLength) - { - StatementClass *stmt = (StatementClass *) StatementHandle; - ret = SQL_SUCCESS_WITH_INFO; - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "Column name too large"; - } - if (NameLength) - *NameLength = nmcount; - } - free(clName); - return ret; -} - -RETCODE SQL_API SQLExecDirectW(HSTMT StatementHandle, - SQLWCHAR *StatementText, SQLINTEGER TextLength) -{ - RETCODE ret; - char *stxt; - UInt4 slen; - - mylog("[SQLExecDirectW]"); - stxt = ucs2_to_utf8(StatementText, TextLength, &slen); - ret = PGAPI_ExecDirect(StatementHandle, stxt, slen); - if (stxt); - free(stxt); - return ret; -} - -RETCODE SQL_API SQLGetCursorNameW(HSTMT StatementHandle, - SQLWCHAR *CursorName, SQLSMALLINT BufferLength, - SQLSMALLINT *NameLength) -{ - RETCODE ret; - char *crName; - SWORD clen, buflen; - - mylog("[SQLGetCursorNameW]"); - buflen = BufferLength * 3 + 1; - crName = malloc(buflen); - ret = PGAPI_GetCursorName(StatementHandle, crName, buflen, &clen); - if (ret == SQL_SUCCESS) - { - UInt4 nmcount = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength); - if (nmcount > (UInt4) BufferLength) - { - StatementClass *stmt = (StatementClass *) StatementHandle; - ret = SQL_SUCCESS_WITH_INFO; - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "Cursor name too large"; - } - if (NameLength) - *NameLength = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength); - } - free(crName); - return ret; -} - -RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle, - SQLUSMALLINT InfoType, PTR InfoValue, - SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) -{ - ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; - RETCODE ret; - - conn->unicode = 1; - CC_clear_error(conn); -#if (ODBCVER >= 0x0300) - mylog("[SQLGetInfoW(30)]"); - if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, - BufferLength, StringLength)) == SQL_ERROR) - { - if (conn->driver_version >= 0x0300) - { - CC_clear_error(conn); - ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, - BufferLength, StringLength); - } - } - if (SQL_ERROR == ret) - CC_log_error("SQLGetInfoW(30)", "", conn); -#else - mylog("[SQLGetInfoW]"); - ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, - BufferLength, StringLength); - if (SQL_ERROR == ret) - CC_log_error("SQLGetInfoW", "", conn); -#endif - return ret; -} - -RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle, - SQLWCHAR *StatementText, SQLINTEGER TextLength) -{ - RETCODE ret; - char *stxt; - UInt4 slen; - - mylog("[SQLPrepareW]"); - stxt = ucs2_to_utf8(StatementText, TextLength, &slen); - ret = PGAPI_Prepare(StatementHandle, stxt, slen); - if (stxt); - free(stxt); - return ret; -} - -RETCODE SQL_API SQLSetCursorNameW(HSTMT StatementHandle, - SQLWCHAR *CursorName, SQLSMALLINT NameLength) -{ - RETCODE ret; - char *crName; - UInt4 nlen; - - mylog("[SQLSetCursorNameW]"); - crName = ucs2_to_utf8(CursorName, NameLength, &nlen); - ret = PGAPI_SetCursorName(StatementHandle, crName, (SWORD) nlen); - if (crName); - free(crName); - return ret; -} - -RETCODE SQL_API SQLSpecialColumnsW(HSTMT StatementHandle, - SQLUSMALLINT IdentifierType, SQLWCHAR *CatalogName, - SQLSMALLINT NameLength1, SQLWCHAR *SchemaName, - SQLSMALLINT NameLength2, SQLWCHAR *TableName, - SQLSMALLINT NameLength3, SQLUSMALLINT Scope, - SQLUSMALLINT Nullable) -{ - RETCODE ret; - char *ctName, *scName, *tbName; - UInt4 nmlen1, nmlen2, nmlen3; - - mylog("[SQLSpecialColumnsW]"); - ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1); - scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2); - tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3); - ret = PGAPI_SpecialColumns(StatementHandle, IdentifierType, ctName, - (SWORD) nmlen1, scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, - Scope, Nullable); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - return ret; -} - -RETCODE SQL_API SQLStatisticsW(HSTMT StatementHandle, - SQLWCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLWCHAR *TableName, SQLSMALLINT NameLength3, - SQLUSMALLINT Unique, SQLUSMALLINT Reserved) -{ - RETCODE ret; - char *ctName, *scName, *tbName; - UInt4 nmlen1, nmlen2, nmlen3; - - mylog("[SQLStatisticsW]"); - ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1); - scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2); - tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3); - return PGAPI_Statistics(StatementHandle, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, Unique, - Reserved); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - return ret; -} - -RETCODE SQL_API SQLTablesW(HSTMT StatementHandle, - SQLWCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLWCHAR *TableName, SQLSMALLINT NameLength3, - SQLWCHAR *TableType, SQLSMALLINT NameLength4) -{ - RETCODE ret; - char *ctName, *scName, *tbName, *tbType; - UInt4 nmlen1, nmlen2, nmlen3, nmlen4; - - mylog("[SQLTablesW]"); - ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1); - scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2); - tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3); - tbType = ucs2_to_utf8(TableType, NameLength4, &nmlen4); - return PGAPI_Tables(StatementHandle, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, - tbType, (SWORD) nmlen4); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - if (tbType); - free(tbType); - return ret; -} - -RETCODE SQL_API SQLColumnPrivilegesW( - HSTMT hstmt, - SQLWCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLWCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLWCHAR *szTableName, - SQLSMALLINT cbTableName, - SQLWCHAR *szColumnName, - SQLSMALLINT cbColumnName) -{ - RETCODE ret; - char *ctName, *scName, *tbName, *clName; - UInt4 nmlen1, nmlen2, nmlen3, nmlen4; - - mylog("[SQLColumnPrivilegesW]"); - ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1); - scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2); - tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3); - clName = ucs2_to_utf8(szColumnName, cbColumnName, &nmlen4); - ret = PGAPI_ColumnPrivileges(hstmt, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, - clName, (SWORD) nmlen4); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - if (clName); - free(clName); - return ret; -} - -RETCODE SQL_API SQLForeignKeysW( - HSTMT hstmt, - SQLWCHAR *szPkCatalogName, - SQLSMALLINT cbPkCatalogName, - SQLWCHAR *szPkSchemaName, - SQLSMALLINT cbPkSchemaName, - SQLWCHAR *szPkTableName, - SQLSMALLINT cbPkTableName, - SQLWCHAR *szFkCatalogName, - SQLSMALLINT cbFkCatalogName, - SQLWCHAR *szFkSchemaName, - SQLSMALLINT cbFkSchemaName, - SQLWCHAR *szFkTableName, - SQLSMALLINT cbFkTableName) -{ - RETCODE ret; - char *ctName, *scName, *tbName, *fkctName, *fkscName, *fktbName; - UInt4 nmlen1, nmlen2, nmlen3, nmlen4, nmlen5, nmlen6; - - mylog("[SQLForeignKeysW]"); - ctName = ucs2_to_utf8(szPkCatalogName, cbPkCatalogName, &nmlen1); - scName = ucs2_to_utf8(szPkSchemaName, cbPkSchemaName, &nmlen2); - tbName = ucs2_to_utf8(szPkTableName, cbPkTableName, &nmlen3); - fkctName = ucs2_to_utf8(szFkCatalogName, cbFkCatalogName, &nmlen4); - fkscName = ucs2_to_utf8(szFkSchemaName, cbFkSchemaName, &nmlen5); - fktbName = ucs2_to_utf8(szFkTableName, cbFkTableName, &nmlen6); - ret = PGAPI_ForeignKeys(hstmt, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, - fkctName, (SWORD) nmlen4, fkscName, (SWORD) nmlen5, - fktbName, (SWORD) nmlen6); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - if (fkctName); - free(fkctName); - if (fkscName); - free(fkscName); - if (fktbName); - free(fktbName); - return ret; -} - -RETCODE SQL_API SQLNativeSqlW( - HDBC hdbc, - SQLWCHAR *szSqlStrIn, - SQLINTEGER cbSqlStrIn, - SQLWCHAR *szSqlStr, - SQLINTEGER cbSqlStrMax, - SQLINTEGER *pcbSqlStr) -{ - RETCODE ret; - char *szIn, *szOut; - UInt4 slen; - SQLINTEGER buflen, olen; - - mylog("[SQLNativeSqlW]"); - ((ConnectionClass *) hdbc)->unicode = 1; - szIn = ucs2_to_utf8(szSqlStrIn, cbSqlStrIn, &slen); - buflen = 3 * cbSqlStrMax + 1; - szOut = malloc(buflen); - ret = PGAPI_NativeSql(hdbc, szIn, (SQLINTEGER) slen, - szOut, buflen, &olen); - if (szIn); - free(szIn); - if (ret == SQL_SUCCESS) - { - UInt4 szcount = utf8_to_ucs2(szOut, olen, szSqlStr, cbSqlStrMax); - if (szcount > (UInt4) cbSqlStrMax) - { - ConnectionClass *conn = (ConnectionClass *) hdbc; - - ret = SQL_SUCCESS_WITH_INFO; - conn->errornumber = CONN_TRUNCATED; - conn->errormsg = "Sql string too large"; - } - if (pcbSqlStr) - *pcbSqlStr = szcount; - } - free(szOut); - return ret; -} - -RETCODE SQL_API SQLPrimaryKeysW( - HSTMT hstmt, - SQLWCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLWCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLWCHAR *szTableName, - SQLSMALLINT cbTableName) -{ - RETCODE ret; - char *ctName, *scName, *tbName; - UInt4 nmlen1, nmlen2, nmlen3; - - mylog("[SQLPrimaryKeysW]"); - ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1); - scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2); - tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3); - return PGAPI_PrimaryKeys(hstmt, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - return ret; -} - -RETCODE SQL_API SQLProcedureColumnsW( - HSTMT hstmt, - SQLWCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLWCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLWCHAR *szProcName, - SQLSMALLINT cbProcName, - SQLWCHAR *szColumnName, - SQLSMALLINT cbColumnName) -{ - RETCODE ret; - char *ctName, *scName, *prName, *clName; - UInt4 nmlen1, nmlen2, nmlen3, nmlen4; - - mylog("[SQLProcedureColumnsW]"); - ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1); - scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2); - prName = ucs2_to_utf8(szProcName, cbProcName, &nmlen3); - clName = ucs2_to_utf8(szColumnName, cbColumnName, &nmlen4); - ret = PGAPI_ProcedureColumns(hstmt, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, prName, (SWORD) nmlen3, - clName, (SWORD) nmlen4); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (prName); - free(prName); - if (clName); - free(clName); - return ret; -} - -RETCODE SQL_API SQLProceduresW( - HSTMT hstmt, - SQLWCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLWCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLWCHAR *szProcName, - SQLSMALLINT cbProcName) -{ - RETCODE ret; - char *ctName, *scName, *prName; - UInt4 nmlen1, nmlen2, nmlen3; - - mylog("[SQLProceduresW]"); - ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1); - scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2); - prName = ucs2_to_utf8(szProcName, cbProcName, &nmlen3); - ret = PGAPI_Procedures(hstmt, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, prName, (SWORD) nmlen3); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (prName); - free(prName); - return ret; -} - -RETCODE SQL_API SQLTablePrivilegesW( - HSTMT hstmt, - SQLWCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLWCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLWCHAR *szTableName, - SQLSMALLINT cbTableName) -{ - RETCODE ret; - char *ctName, *scName, *tbName; - UInt4 nmlen1, nmlen2, nmlen3; - - mylog("[SQLTablePrivilegesW]"); - ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1); - scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2); - tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3); - ret = PGAPI_TablePrivileges(hstmt, ctName, (SWORD) nmlen1, - scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, 0); - if (ctName); - free(ctName); - if (scName); - free(scName); - if (tbName); - free(tbName); - return ret; -} - -RETCODE SQL_API SQLGetTypeInfoW( - SQLHSTMT StatementHandle, - SQLSMALLINT DataType) -{ - return PGAPI_GetTypeInfo(StatementHandle, DataType); -} diff --git a/src/interfaces/odbc/odbcinst.ini b/src/interfaces/odbc/odbcinst.ini deleted file mode 100644 index 825e7a0f5b..0000000000 --- a/src/interfaces/odbc/odbcinst.ini +++ /dev/null @@ -1,3 +0,0 @@ -[PostgreSQL] -Debug = 0 -CommLog = 1 diff --git a/src/interfaces/odbc/options.c b/src/interfaces/odbc/options.c deleted file mode 100644 index f4a510a587..0000000000 --- a/src/interfaces/odbc/options.c +++ /dev/null @@ -1,728 +0,0 @@ -/*-------- - * Module: options.c - * - * Description: This module contains routines for getting/setting - * connection and statement options. - * - * Classes: n/a - * - * API functions: SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption, - * SQLGetStmtOption - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ - -#include "psqlodbc.h" -#include - -#include "environ.h" -#include "connection.h" -#include "statement.h" -#include "qresult.h" -#include "pgapifunc.h" - - - -RETCODE set_statement_option(ConnectionClass *conn, - StatementClass *stmt, - UWORD fOption, - UDWORD vParam); - - -RETCODE -set_statement_option(ConnectionClass *conn, - StatementClass *stmt, - UWORD fOption, - UDWORD vParam) -{ - static char *func = "set_statement_option"; - char changed = FALSE; - ConnInfo *ci = NULL; - UDWORD setval; - - if (conn) - ci = &(conn->connInfo); - else if (stmt) - ci = &(SC_get_conn(stmt)->connInfo); - switch (fOption) - { - case SQL_ASYNC_ENABLE: /* ignored */ - break; - - case SQL_BIND_TYPE: - /* now support multi-column and multi-row binding */ - if (conn) - conn->ardOptions.bind_size = vParam; - if (stmt) - SC_get_ARD(stmt)->bind_size = vParam; - break; - - case SQL_CONCURRENCY: - - /* - * positioned update isn't supported so cursor concurrency is - * read-only - */ - mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam); - setval = SQL_CONCUR_READ_ONLY; - if (SQL_CONCUR_READ_ONLY == vParam) - ; - if (ci->drivers.lie) - setval = vParam; - else if (ci->updatable_cursors) - setval = SQL_CONCUR_ROWVER; - if (conn) - conn->stmtOptions.scroll_concurrency = setval; - else if (stmt) - stmt->options.scroll_concurrency = setval; - if (setval != vParam) - changed = TRUE; - mylog("-> %d\n", setval); - break; - - case SQL_CURSOR_TYPE: - - /* - * if declare/fetch, then type can only be forward. otherwise, - * it can only be forward or static. - */ - mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam); - setval = SQL_CURSOR_FORWARD_ONLY; - if (ci->drivers.lie) - setval = vParam; - else if (ci->drivers.use_declarefetch) - ; - else if (SQL_CURSOR_STATIC == vParam) - setval = vParam; - else if (SQL_CURSOR_KEYSET_DRIVEN == vParam) - { - if (ci->updatable_cursors) - setval = vParam; - else - setval = SQL_CURSOR_STATIC; /* at least scrollable */ - } - if (conn) - conn->stmtOptions.cursor_type = setval; - else if (stmt) - stmt->options.cursor_type = setval; - if (setval != vParam) - changed = TRUE; - mylog("-> %d\n", setval); - break; - - case SQL_KEYSET_SIZE: /* ignored, but saved and returned */ - mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam); - - if (conn) - conn->stmtOptions.keyset_size = vParam; - if (stmt) - stmt->options.keyset_size = vParam; - - break; - - /*------- - * if (ci->drivers.lie) - * stmt->keyset_size = vParam; - * else - * { - * stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - * stmt->errormsg = "Driver does not support keyset size option"; - * SC_log_error(func, "", stmt); - * return SQL_ERROR; - * } - *------- - */ - - case SQL_MAX_LENGTH: /* ignored, but saved */ - mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam); - if (conn) - conn->stmtOptions.maxLength = vParam; - if (stmt) - stmt->options.maxLength = vParam; - break; - - case SQL_MAX_ROWS: /* ignored, but saved */ - mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam); - if (conn) - conn->stmtOptions.maxRows = vParam; - if (stmt) - stmt->options.maxRows = vParam; - break; - - case SQL_NOSCAN: /* ignored */ - mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam); - break; - - case SQL_QUERY_TIMEOUT: /* ignored */ - mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam); - /* "0" returned in SQLGetStmtOption */ - break; - - case SQL_RETRIEVE_DATA: - mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam); - if (conn) - conn->stmtOptions.retrieve_data = vParam; - if (stmt) - stmt->options.retrieve_data = vParam; - break; - - case SQL_ROWSET_SIZE: - mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam); - - /* - * Save old rowset size for SQLExtendedFetch purposes If the - * rowset_size is being changed since the last call to fetch - * rows. - */ - - if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0) - stmt->save_rowset_size = SC_get_ARD(stmt)->rowset_size; - - if (vParam < 1) - { - vParam = 1; - changed = TRUE; - } - - if (conn) - conn->ardOptions.rowset_size = vParam; - if (stmt) - SC_get_ARD(stmt)->rowset_size = vParam; - break; - - case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */ - if (stmt) - { - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library."; - SC_log_error(func, "", stmt); - } - if (conn) - { - conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - conn->errormsg = "Simulated positioned update/delete not supported. Use the cursor library."; - CC_log_error(func, "", conn); - } - return SQL_ERROR; - - case SQL_USE_BOOKMARKS: - if (stmt) - stmt->options.use_bookmarks = vParam; - if (conn) - conn->stmtOptions.use_bookmarks = vParam; - break; - - case 1227: - case 1228: - if (stmt) - { - stmt->errornumber = STMT_OPTION_NOT_FOR_THE_DRIVER; - stmt->errormsg = "The option may be for MS SQL Server(Set)"; - } - else if (conn) - { - conn->errornumber = STMT_OPTION_NOT_FOR_THE_DRIVER; - conn->errormsg = "The option may be for MS SQL Server(Set)"; - } - return SQL_ERROR; - default: - { - char option[64]; - - if (stmt) - { - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Unknown statement option (Set)"; - sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); - SC_log_error(func, option, stmt); - } - if (conn) - { - conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - conn->errormsg = "Unknown statement option (Set)"; - sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); - CC_log_error(func, option, conn); - } - - return SQL_ERROR; - } - } - - if (changed) - { - if (stmt) - { - stmt->errormsg = "Requested value changed."; - stmt->errornumber = STMT_OPTION_VALUE_CHANGED; - } - if (conn) - { - conn->errormsg = "Requested value changed."; - conn->errornumber = STMT_OPTION_VALUE_CHANGED; - } - return SQL_SUCCESS_WITH_INFO; - } - else - return SQL_SUCCESS; -} - - -/* Implements only SQL_AUTOCOMMIT */ -RETCODE SQL_API -PGAPI_SetConnectOption( - HDBC hdbc, - UWORD fOption, - UDWORD vParam) -{ - static char *func = "PGAPI_SetConnectOption"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - char changed = FALSE; - RETCODE retval; - int i; - - mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam); - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - switch (fOption) - { - /* - * Statement Options (apply to all stmts on the connection and - * become defaults for new stmts) - */ - case SQL_ASYNC_ENABLE: - case SQL_BIND_TYPE: - case SQL_CONCURRENCY: - case SQL_CURSOR_TYPE: - case SQL_KEYSET_SIZE: - case SQL_MAX_LENGTH: - case SQL_MAX_ROWS: - case SQL_NOSCAN: - case SQL_QUERY_TIMEOUT: - case SQL_RETRIEVE_DATA: - case SQL_ROWSET_SIZE: - case SQL_SIMULATE_CURSOR: - case SQL_USE_BOOKMARKS: - - /* Affect all current Statements */ - for (i = 0; i < conn->num_stmts; i++) - { - if (conn->stmts[i]) - set_statement_option(NULL, conn->stmts[i], fOption, vParam); - } - - /* - * Become the default for all future statements on this - * connection - */ - retval = set_statement_option(conn, NULL, fOption, vParam); - - if (retval == SQL_SUCCESS_WITH_INFO) - changed = TRUE; - else if (retval == SQL_ERROR) - return SQL_ERROR; - - break; - - /* - * Connection Options - */ - - case SQL_ACCESS_MODE: /* ignored */ - break; - - case SQL_AUTOCOMMIT: - if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn)) - break; - else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn)) - break; - if (CC_is_in_trans(conn)) - CC_commit(conn); - - mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam); - - switch (vParam) - { - case SQL_AUTOCOMMIT_OFF: - CC_set_autocommit_off(conn); - break; - - case SQL_AUTOCOMMIT_ON: - CC_set_autocommit_on(conn); - break; - - default: - conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT"; - conn->errornumber = CONN_INVALID_ARGUMENT_NO; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - break; - - case SQL_CURRENT_QUALIFIER: /* ignored */ - break; - - case SQL_LOGIN_TIMEOUT: /* ignored */ - break; - - case SQL_PACKET_SIZE: /* ignored */ - break; - - case SQL_QUIET_MODE: /* ignored */ - break; - - case SQL_TXN_ISOLATION: /* ignored */ - retval = SQL_SUCCESS; - if (CC_is_in_trans(conn)) - { - conn->errormsg = "Cannot switch isolation level while a transaction is in progress"; - conn->errornumber = CONN_TRANSACT_IN_PROGRES; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - if (conn->isolation == vParam) - break; - switch (vParam) - { - case SQL_TXN_SERIALIZABLE: - if (PG_VERSION_GE(conn, 6.5) && - PG_VERSION_LE(conn, 7.0)) - retval = SQL_ERROR; - break; - case SQL_TXN_READ_COMMITTED: - if (PG_VERSION_LT(conn, 6.5)) - retval = SQL_ERROR; - break; - default: - retval = SQL_ERROR; - } - if (SQL_ERROR == retval) - { - conn->errornumber = CONN_INVALID_ARGUMENT_NO; - conn->errormsg = "Illegal parameter value for SQL_TXN_ISOLATION"; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - else - { - char *query; - QResultClass *res; - - if (vParam == SQL_TXN_SERIALIZABLE) - query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE"; - else - query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED"; - res = CC_send_query(conn, query, NULL, 0); - if (!res || !QR_command_maybe_successful(res)) - retval = SQL_ERROR; - else - conn->isolation = vParam; - if (res) - QR_Destructor(res); - if (SQL_ERROR == retval) - { - conn->errornumber = STMT_EXEC_ERROR; - conn->errormsg = "ISOLATION change request to the server error"; - return SQL_ERROR; - } - } - break; - - /* These options should be handled by driver manager */ - case SQL_ODBC_CURSORS: - case SQL_OPT_TRACE: - case SQL_OPT_TRACEFILE: - case SQL_TRANSLATE_DLL: - case SQL_TRANSLATE_OPTION: - CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn); - break; - - default: - { - char option[64]; - - conn->errormsg = "Unknown connect option (Set)"; - conn->errornumber = CONN_UNSUPPORTED_OPTION; - sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); - if (fOption == 30002 && vParam) - { - int cmp; -#ifdef UNICODE_SUPPORT - char *asPara; - if (conn->unicode) - { - asPara = ucs2_to_utf8((SQLWCHAR *) vParam, -1, NULL); - cmp = strcmp(asPara, "Microsoft Jet"); - free(asPara); - } - else -#endif /* UNICODE_SUPPORT */ - cmp = strncmp((char *) vParam, "Microsoft Jet", 13); - if (0 == cmp) - { - mylog("Microsoft Jet !!!!\n"); - conn->errornumber = 0; - conn->ms_jet = 1; - return SQL_SUCCESS; - } - } - CC_log_error(func, option, conn); - return SQL_ERROR; - } - } - - if (changed) - { - conn->errornumber = CONN_OPTION_VALUE_CHANGED; - conn->errormsg = "Requested value changed."; - return SQL_SUCCESS_WITH_INFO; - } - else - return SQL_SUCCESS; -} - - -/* This function just can tell you whether you are in Autcommit mode or not */ -RETCODE SQL_API -PGAPI_GetConnectOption( - HDBC hdbc, - UWORD fOption, - PTR pvParam) -{ - static char *func = "PGAPI_GetConnectOption"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - ConnInfo *ci = &(conn->connInfo); - - mylog("%s: entering...\n", func); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - switch (fOption) - { - case SQL_ACCESS_MODE: /* NOT SUPPORTED */ - *((UDWORD *) pvParam) = SQL_MODE_READ_WRITE; - break; - - case SQL_AUTOCOMMIT: - *((UDWORD *) pvParam) = (UDWORD) (CC_is_in_autocommit(conn) ? - SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF); - break; - - case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */ - if (pvParam) - ((char *) pvParam)[0] = ((char *) pvParam)[1] = '\0'; - - break; - - case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */ - *((UDWORD *) pvParam) = 0; - break; - - case SQL_PACKET_SIZE: /* NOT SUPPORTED */ - *((UDWORD *) pvParam) = ci->drivers.socket_buffersize; - break; - - case SQL_QUIET_MODE: /* NOT SUPPORTED */ - *((UDWORD *) pvParam) = (UDWORD) NULL; - break; - - case SQL_TXN_ISOLATION: - *((UDWORD *) pvParam) = conn->isolation; - break; - - /* These options should be handled by driver manager */ - case SQL_ODBC_CURSORS: - case SQL_OPT_TRACE: - case SQL_OPT_TRACEFILE: - case SQL_TRANSLATE_DLL: - case SQL_TRANSLATE_OPTION: - CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn); - break; - - default: - { - char option[64]; - - conn->errormsg = "Unknown connect option (Get)"; - conn->errornumber = CONN_UNSUPPORTED_OPTION; - sprintf(option, "fOption=%d", fOption); - CC_log_error(func, option, conn); - return SQL_ERROR; - break; - } - } - - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_SetStmtOption( - HSTMT hstmt, - UWORD fOption, - UDWORD vParam) -{ - static char *func = "PGAPI_SetStmtOption"; - StatementClass *stmt = (StatementClass *) hstmt; - - mylog("%s: entering...\n", func); - - /* - * Though we could fake Access out by just returning SQL_SUCCESS all - * the time, but it tries to set a huge value for SQL_MAX_LENGTH and - * expects the driver to reduce it to the real value. - */ - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - return set_statement_option(NULL, stmt, fOption, vParam); -} - - -RETCODE SQL_API -PGAPI_GetStmtOption( - HSTMT hstmt, - UWORD fOption, - PTR pvParam) -{ - static char *func = "PGAPI_GetStmtOption"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - ConnInfo *ci = &(SC_get_conn(stmt)->connInfo); - - mylog("%s: entering...\n", func); - - /* - * thought we could fake Access out by just returning SQL_SUCCESS all - * the time, but it tries to set a huge value for SQL_MAX_LENGTH and - * expects the driver to reduce it to the real value - */ - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - switch (fOption) - { - case SQL_GET_BOOKMARK: - case SQL_ROW_NUMBER: - - res = SC_get_Curres(stmt); - - if (stmt->manual_result || !ci->drivers.use_declarefetch) - { - /* make sure we're positioned on a valid row */ - if ((stmt->currTuple < 0) || - (stmt->currTuple >= QR_get_num_backend_tuples(res))) - { - stmt->errormsg = "Not positioned on a valid row."; - stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - else - { - if (stmt->currTuple == -1 || !res || !res->tupleField) - { - stmt->errormsg = "Not positioned on a valid row."; - stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - - if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF) - { - stmt->errormsg = "Operation invalid because use bookmarks not enabled."; - stmt->errornumber = STMT_OPERATION_INVALID; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - *((UDWORD *) pvParam) = SC_get_bookmark(stmt); - - break; - - case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */ - *((SDWORD *) pvParam) = SQL_ASYNC_ENABLE_OFF; - break; - - case SQL_BIND_TYPE: - *((SDWORD *) pvParam) = SC_get_ARD(stmt)->bind_size; - break; - - case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */ - mylog("GetStmtOption(): SQL_CONCURRENCY %d\n", stmt->options.scroll_concurrency); - *((SDWORD *) pvParam) = stmt->options.scroll_concurrency; - break; - - case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */ - mylog("GetStmtOption(): SQL_CURSOR_TYPE %d\n", stmt->options.cursor_type); - *((SDWORD *) pvParam) = stmt->options.cursor_type; - break; - - case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */ - mylog("GetStmtOption(): SQL_KEYSET_SIZE\n"); - *((SDWORD *) pvParam) = stmt->options.keyset_size; - break; - - case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */ - *((SDWORD *) pvParam) = stmt->options.maxLength; - break; - - case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */ - *((SDWORD *) pvParam) = stmt->options.maxRows; - mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows); - break; - - case SQL_NOSCAN: /* NOT SUPPORTED */ - *((SDWORD *) pvParam) = SQL_NOSCAN_ON; - break; - - case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */ - *((SDWORD *) pvParam) = 0; - break; - - case SQL_RETRIEVE_DATA: - *((SDWORD *) pvParam) = stmt->options.retrieve_data; - break; - - case SQL_ROWSET_SIZE: - *((SDWORD *) pvParam) = SC_get_ARD(stmt)->rowset_size; - break; - - case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */ - *((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE; - break; - - case SQL_USE_BOOKMARKS: - *((SDWORD *) pvParam) = stmt->options.use_bookmarks; - break; - - default: - { - char option[64]; - - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Unknown statement option (Get)"; - sprintf(option, "fOption=%d", fOption); - SC_log_error(func, option, stmt); - return SQL_ERROR; - } - } - - return SQL_SUCCESS; -} diff --git a/src/interfaces/odbc/parse.c b/src/interfaces/odbc/parse.c deleted file mode 100644 index a61b75e90c..0000000000 --- a/src/interfaces/odbc/parse.c +++ /dev/null @@ -1,1229 +0,0 @@ -/*-------- - * Module: parse.c - * - * Description: This module contains routines related to parsing SQL - * statements. This can be useful for two reasons: - * - * 1. So the query does not actually have to be executed - * to return data about it - * - * 2. To be able to return information about precision, - * nullability, aliases, etc. in the functions - * SQLDescribeCol and SQLColAttributes. Currently, - * Postgres doesn't return any information about - * these things in a query. - * - * Classes: none - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ -/* Multibyte support Eiji Tokuya 2001-03-15 */ - -#include "psqlodbc.h" - -#include -#include -#include - -#include "statement.h" -#include "connection.h" -#include "qresult.h" -#include "pgtypes.h" -#include "pgapifunc.h" - -#ifdef MULTIBYTE -#include "multibyte.h" -#endif - -#define FLD_INCR 32 -#define TAB_INCR 8 -#define COL_INCR 16 - -#ifdef MULTIBYTE -char *getNextToken(int ccsc, char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric); -#else -char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric); -#endif /* MULTIBYTE */ -void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k); -char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi); - -Int4 FI_precision(const FIELD_INFO *fi) -{ - if (!fi) return -1; - switch (fi->type) - { - case PG_TYPE_NUMERIC: - return fi->column_size; - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - return fi->decimal_digits; - } - return 0; -} -Int4 FI_scale(const FIELD_INFO *fi) -{ - if (!fi) return -1; - switch (fi->type) - { - case PG_TYPE_NUMERIC: - return fi->decimal_digits; - } - return 0; -} - -char * -getNextToken( -#ifdef MULTIBYTE - int ccsc, /* client encoding */ -#endif /* MULTIBYTE */ - char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric) -{ - int i = 0; - int out = 0; - char qc, - in_escape = FALSE; -#ifdef MULTIBYTE - encoded_str encstr; -#endif - - if (smax <= 1) - return NULL; - - smax--; - - /* skip leading delimiters */ - while (isspace((unsigned char) s[i]) || s[i] == ',') - { - /* mylog("skipping '%c'\n", s[i]); */ - i++; - } - - if (s[i] == '\0') - { - token[0] = '\0'; - return NULL; - } - - if (quote) - *quote = FALSE; - if (dquote) - *dquote = FALSE; - if (numeric) - *numeric = FALSE; - -#ifdef MULTIBYTE - encoded_str_constr(&encstr, ccsc, &s[i]); -#endif - /* get the next token */ - while (s[i] != '\0' && out < smax) - { -#ifdef MULTIBYTE - encoded_nextchar(&encstr); - if (ENCODE_STATUS(encstr) != 0) - { - token[out++] = s[i++]; - continue; - } -#endif - if (isspace((unsigned char) s[i]) || s[i] == ',') - break; - /* Handle quoted stuff */ - if (out == 0 && (s[i] == '\"' || s[i] == '\'')) - { - qc = s[i]; - if (qc == '\"') - { - if (dquote) - *dquote = TRUE; - } - if (qc == '\'') - { - if (quote) - *quote = TRUE; - } - - i++; /* dont return the quote */ - while (s[i] != '\0' && out != smax) - { -#ifdef MULTIBYTE - encoded_nextchar(&encstr); - if (ENCODE_STATUS(encstr) != 0) - { - token[out++] = s[i++]; - continue; - } -#endif - if (s[i] == qc && !in_escape) - break; - if (s[i] == '\\' && !in_escape) - in_escape = TRUE; - else - { - in_escape = FALSE; - token[out++] = s[i]; - } - i++; - } - if (s[i] == qc) - i++; - break; - } - - /* Check for numeric literals */ - if (out == 0 && isdigit((unsigned char) s[i])) - { - if (numeric) - *numeric = TRUE; - token[out++] = s[i++]; - while (isalnum((unsigned char) s[i]) || s[i] == '.') - token[out++] = s[i++]; - - break; - } - - if (ispunct((unsigned char) s[i]) && s[i] != '_') - { - mylog("got ispunct: s[%d] = '%c'\n", i, s[i]); - - if (out == 0) - { - token[out++] = s[i++]; - break; - } - else - break; - } - - if (out != smax) - token[out++] = s[i]; - - i++; - } - - /* mylog("done -- s[%d] = '%c'\n", i, s[i]); */ - - token[out] = '\0'; - - /* find the delimiter */ - while (isspace((unsigned char) s[i])) - i++; - - /* return the most priority delimiter */ - if (s[i] == ',') - { - if (delim) - *delim = s[i]; - } - else if (s[i] == '\0') - { - if (delim) - *delim = '\0'; - } - else - { - if (delim) - *delim = ' '; - } - - /* skip trailing blanks */ - while (isspace((unsigned char) s[i])) - i++; - - return &s[i]; -} - - -#if 0 -QR_set_num_fields(SC_get_Curres(stmt), 14); -QR_set_field_info(SC_get_Curres(stmt), 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); -QR_set_field_info(SC_get_Curres(stmt), 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); -QR_set_field_info(SC_get_Curres(stmt), 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); -QR_set_field_info(SC_get_Curres(stmt), 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); -QR_set_field_info(SC_get_Curres(stmt), 4, "DATA_TYPE", PG_TYPE_INT2, 2); -QR_set_field_info(SC_get_Curres(stmt), 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); -QR_set_field_info(SC_get_Curres(stmt), 6, "PRECISION", PG_TYPE_INT4, 4); -QR_set_field_info(SC_get_Curres(stmt), 7, "LENGTH", PG_TYPE_INT4, 4); -QR_set_field_info(SC_get_Curres(stmt), 8, "SCALE", PG_TYPE_INT2, 2); -QR_set_field_info(SC_get_Curres(stmt), 9, "RADIX", PG_TYPE_INT2, 2); -QR_set_field_info(SC_get_Curres(stmt), 10, "NULLABLE", PG_TYPE_INT2, 2); -QR_set_field_info(SC_get_Curres(stmt), 11, "REMARKS", PG_TYPE_TEXT, 254); -/* User defined fields */ -QR_set_field_info(SC_get_Curres(stmt), 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4); -QR_set_field_info(SC_get_Curres(stmt), 13, "FIELD_TYPE", PG_TYPE_INT4, 4); -#endif - -void -getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k) -{ - char *str; - Int2 reserved_cols; - -#if (ODBCVER >= 0x0300) - reserved_cols = 18; -#else - reserved_cols = 12; -#endif /* ODBCVER */ - if (fi->name[0] == '\0') - strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3)); - - fi->type = atoi(QR_get_value_manual(col_info->result, k, (Int2)(reserved_cols + 1))); - fi->column_size = atoi(QR_get_value_manual(col_info->result, k, 6)); - fi->length = atoi(QR_get_value_manual(col_info->result, k, 7)); - if (str = QR_get_value_manual(col_info->result, k, 8), str) - fi->decimal_digits = atoi(str); - else - fi->decimal_digits = -1; - fi->nullable = atoi(QR_get_value_manual(col_info->result, k, 10)); - fi->display_size = atoi(QR_get_value_manual(col_info->result, k, reserved_cols)); -} - - -char -searchColInfo(COL_INFO *col_info, FIELD_INFO *fi) -{ - int k, - cmp; - char *col; - - for (k = 0; k < QR_get_num_backend_tuples(col_info->result); k++) - { - col = QR_get_value_manual(col_info->result, k, 3); - if (fi->dquote) - cmp = strcmp(col, fi->name); - else - cmp = stricmp(col, fi->name); - if (!cmp) - { - if (!fi->dquote) - strcpy(fi->name, col); - getColInfo(col_info, fi, k); - - mylog("PARSE: searchColInfo: \n"); - return TRUE; - } - } - - return FALSE; -} - - -char -parse_statement(StatementClass *stmt) -{ - static char *func = "parse_statement"; - char token[256], stoken[256]; - char delim, - quote, - dquote, - numeric, - unquoted; - char *ptr, - *pptr = NULL; - char in_select = FALSE, - in_distinct = FALSE, - in_on = FALSE, - in_from = FALSE, - in_where = FALSE, - in_table = FALSE, - out_table = TRUE; - char in_field = FALSE, - in_expr = FALSE, - in_func = FALSE, - in_dot = FALSE, - in_as = FALSE; - int j, - i, - k = 0, - n, - blevel = 0, old_blevel, subqlevel = 0; - FIELD_INFO **fi; - TABLE_INFO **ti; - char parse; - ConnectionClass *conn = stmt->hdbc; - HSTMT hcol_stmt; - StatementClass *col_stmt; - IRDFields *irdflds = SC_get_IRD(stmt); - RETCODE result; - BOOL updatable = TRUE; - - mylog("%s: entering...\n", func); - - ptr = stmt->statement; - fi = irdflds->fi; - ti = stmt->ti; - - irdflds->nfields = 0; - stmt->ntab = 0; - stmt->from_pos = -1; - stmt->where_pos = -1; - -#ifdef MULTIBYTE - while (pptr = ptr, (ptr = getNextToken(conn->ccsc, pptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL) -#else - while (pptr = ptr, (ptr = getNextToken(pptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL) -#endif - { - unquoted = !(quote || dquote); - - mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr); - - old_blevel = blevel; - if (unquoted && blevel == 0) - { - if (in_select) - { - if (!stricmp(token, "distinct")) - { - in_distinct = TRUE; - updatable = FALSE; - - mylog("DISTINCT\n"); - continue; - } - else if (!stricmp(token, "into")) - { - in_select = FALSE; - mylog("INTO\n"); - stmt->statement_type = STMT_TYPE_CREATE; - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - else if (!stricmp(token, "from")) - { - in_select = FALSE; - in_from = TRUE; - if (stmt->from_pos < 0 && - (!strnicmp(pptr, "from", 4))) - { - mylog("First "); - stmt->from_pos = pptr - stmt->statement; - } - - mylog("FROM\n"); - continue; - } - } /* in_select && unquoted && blevel == 0 */ - else if ((!stricmp(token, "where") || - !stricmp(token, "union") || - !stricmp(token, "intersect") || - !stricmp(token, "except") || - !stricmp(token, "order") || - !stricmp(token, "group") || - !stricmp(token, "having"))) - { - in_from = FALSE; - in_where = TRUE; - - if (stmt->where_pos < 0) - stmt->where_pos = pptr - stmt->statement; - mylog("%s...\n", token); - if (stricmp(token, "where") && - stricmp(token, "order")) - { - updatable = FALSE; - break; - } - continue; - } - } /* unquoted && blevel == 0 */ - /* check the change of blevel etc */ - if (unquoted) - { - if (!stricmp(token, "select")) - { - stoken[0] = '\0'; - if (0 == blevel) - { - in_select = TRUE; - mylog("SELECT\n"); - continue; - } - else - { - mylog("SUBSELECT\n"); - if (0 == subqlevel) - subqlevel = blevel; - } - } - else if (token[0] == '(') - { - blevel++; - mylog("blevel++ = %d\n", blevel); - /* aggregate function ? */ - if (stoken[0] && updatable && 0 == subqlevel) - { - if (stricmp(stoken, "count") == 0 || - stricmp(stoken, "sum") == 0 || - stricmp(stoken, "avg") == 0 || - stricmp(stoken, "max") == 0 || - stricmp(stoken, "min") == 0 || - stricmp(stoken, "variance") == 0 || - stricmp(stoken, "stddev") == 0) - updatable = FALSE; - } - } - else if (token[0] == ')') - { - blevel--; - mylog("blevel-- = %d\n", blevel); - if (blevel < subqlevel) - subqlevel = 0; - } - if (blevel >= old_blevel && ',' != delim) - strcpy(stoken, token); - else - stoken[0] = '\0'; - } - if (in_select) - { - if (in_expr || in_func) - { - /* just eat the expression */ - mylog("in_expr=%d or func=%d\n", in_expr, in_func); - - if (blevel == 0) - { - if (delim == ',') - { - mylog("**** Got comma in_expr/func\n"); - in_func = FALSE; - in_expr = FALSE; - in_field = FALSE; - } - else if (unquoted && !stricmp(token, "as")) - { - mylog("got AS in_expr\n"); - in_func = FALSE; - in_expr = FALSE; - in_as = TRUE; - in_field = TRUE; - } - } - continue; - } /* (in_expr || in_func) && in_select */ - - if (in_distinct) - { - mylog("in distinct\n"); - - if (unquoted && !stricmp(token, "on")) - { - in_on = TRUE; - mylog("got on\n"); - continue; - } - if (in_on) - { - in_distinct = FALSE; - in_on = FALSE; - continue; /* just skip the unique on field */ - } - mylog("done distinct\n"); - in_distinct = FALSE; - } /* in_distinct */ - - if (!in_field) - { - if (!token[0]) - continue; - - if (!(irdflds->nfields % FLD_INCR)) - { - mylog("reallocing at nfld=%d\n", irdflds->nfields); - fi = (FIELD_INFO **) realloc(fi, (irdflds->nfields + FLD_INCR) * sizeof(FIELD_INFO *)); - if (!fi) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - irdflds->fi = fi; - } - - fi[irdflds->nfields] = (FIELD_INFO *) malloc(sizeof(FIELD_INFO)); - if (fi[irdflds->nfields] == NULL) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - - /* Initialize the field info */ - memset(fi[irdflds->nfields], 0, sizeof(FIELD_INFO)); - - /* double quotes are for qualifiers */ - if (dquote) - fi[irdflds->nfields]->dquote = TRUE; - - if (quote) - { - fi[irdflds->nfields]->quote = TRUE; - fi[irdflds->nfields]->column_size = strlen(token); - } - else if (numeric) - { - mylog("**** got numeric: nfld = %d\n", irdflds->nfields); - fi[irdflds->nfields]->numeric = TRUE; - } - else if (0 == old_blevel && blevel > 0) - { /* expression */ - mylog("got EXPRESSION\n"); - fi[irdflds->nfields++]->expr = TRUE; - in_expr = TRUE; - continue; - } - else - { - strcpy(fi[irdflds->nfields]->name, token); - fi[irdflds->nfields]->dot[0] = '\0'; - } - mylog("got field='%s', dot='%s'\n", fi[irdflds->nfields]->name, fi[irdflds->nfields]->dot); - - if (delim == ',') - mylog("comma (1)\n"); - else - in_field = TRUE; - irdflds->nfields++; - continue; - } /* !in_field */ - - /* - * We are in a field now - */ - if (in_dot) - { - int ifld = irdflds->nfields - 1; - - if (fi[ifld]->dot[0]) - { - fi[ifld]->schema = strdup(fi[ifld]->dot); - } - strcpy(fi[ifld]->dot, fi[ifld]->name); - strcpy(fi[ifld]->name, token); - - if (delim == ',') - { - mylog("in_dot: got comma\n"); - in_field = FALSE; - } - in_dot = FALSE; - continue; - } - - if (in_as) - { - irdflds->nfields--; - strcpy(fi[irdflds->nfields]->alias, token); - mylog("alias for field '%s' is '%s'\n", fi[irdflds->nfields]->name, fi[irdflds->nfields]->alias); - in_as = FALSE; - in_field = FALSE; - - irdflds->nfields++; - - if (delim == ',') - mylog("comma(2)\n"); - continue; - } - - /* Function */ - if (0 == old_blevel && blevel > 0) - { - in_dot = FALSE; - in_func = TRUE; - fi[irdflds->nfields - 1]->func = TRUE; - - /* - * name will have the function name -- maybe useful some - * day - */ - mylog("**** got function = '%s'\n", fi[irdflds->nfields - 1]->name); - continue; - } - - if (token[0] == '.') - { - in_dot = TRUE; - mylog("got dot\n"); - continue; - } - - in_dot = FALSE; - if (!stricmp(token, "as")) - { - in_as = TRUE; - mylog("got AS\n"); - continue; - } - - /* otherwise, it's probably an expression */ - in_expr = TRUE; - fi[irdflds->nfields - 1]->expr = TRUE; - fi[irdflds->nfields - 1]->name[0] = '\0'; - fi[irdflds->nfields - 1]->column_size = 0; - mylog("*** setting expression\n"); - } /* in_select end */ - - if (in_from) - { - if (token[0] == ';') - { - in_from = FALSE; - break; - } - switch (token[0]) - { - case '\0': - continue; - case ',': - out_table = TRUE; - continue; - } - if (out_table && !in_table) /* new table */ - { - - if (!(stmt->ntab % TAB_INCR)) - { - ti = (TABLE_INFO **) realloc(ti, (stmt->ntab + TAB_INCR) * sizeof(TABLE_INFO *)); - if (!ti) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - stmt->ti = ti; - } - ti[stmt->ntab] = (TABLE_INFO *) malloc(sizeof(TABLE_INFO)); - if (ti[stmt->ntab] == NULL) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - - ti[stmt->ntab]->schema[0] = '\0'; - ti[stmt->ntab]->alias[0] = '\0'; - ti[stmt->ntab]->updatable = 1; - - strcpy(ti[stmt->ntab]->name, token); - if (!dquote) - { - char *ptr; -#ifdef MULTIBYTE - encoded_str encstr; - make_encoded_str(&encstr, conn, ti[stmt->ntab]->name); -#endif /* MULTIBYTE */ - - /* lower case table name */ - for (ptr = ti[stmt->ntab]->name; *ptr; ptr++) - { -#ifdef MULTIBYTE - encoded_nextchar(&encstr); - if (ENCODE_STATUS(encstr) != 0) - ptr++; - else -#endif /* MULTIBYTE */ - *ptr = tolower((unsigned char) *ptr); - } - } - mylog("got table = '%s'\n", ti[stmt->ntab]->name); - - if (delim == ',') - { - out_table = TRUE; - mylog("more than 1 tables\n"); - } - else - { - out_table = FALSE; - in_table = TRUE; - } - stmt->ntab++; - in_dot = FALSE; - continue; - } - - if (!dquote && stricmp(token, "JOIN") == 0) - { - in_table = FALSE; - out_table = TRUE; - continue; - } - if (in_table) - { - if (in_dot) - { - strcpy(ti[stmt->ntab - 1]->schema, ti[stmt->ntab - 1]->name); - strcpy(ti[stmt->ntab - 1]->name, token); - in_dot = FALSE; - continue; - } - if (strcmp(token, ".") == 0) - { - in_dot = TRUE; - continue; - } - if (!dquote && stricmp(token, "as")) - { - if (stricmp(token, "LEFT") == 0 || - stricmp(token, "RIGHT") == 0 || - stricmp(token, "OUTER") == 0 || - stricmp(token, "FULL") == 0 || - stricmp(token, "ON") == 0) - { - in_table = FALSE; - continue; - } - strcpy(ti[stmt->ntab - 1]->alias, token); - mylog("alias for table '%s' is '%s'\n", ti[stmt->ntab - 1]->name, ti[stmt->ntab - 1]->alias); - in_table = FALSE; - if (delim == ',') - { - out_table = TRUE; - mylog("more than 1 tables\n"); - } - } - } - } /* in_from */ - } - - /* - * Resolve any possible field names with tables - */ - - parse = TRUE; - - /* Resolve field names with tables */ - for (i = 0; i < (int) irdflds->nfields; i++) - { - if (fi[i]->func || fi[i]->expr || fi[i]->numeric) - { - fi[i]->ti = NULL; - fi[i]->type = -1; - parse = FALSE; - continue; - } - else if (fi[i]->quote) - { /* handle as text */ - fi[i]->ti = NULL; - - /* - * fi[i]->type = PG_TYPE_TEXT; fi[i]->column_size = 0; the - * following may be better - */ - fi[i]->type = PG_TYPE_UNKNOWN; - if (fi[i]->column_size == 0) - { - fi[i]->type = PG_TYPE_VARCHAR; - fi[i]->column_size = 254; - } - fi[i]->length = fi[i]->column_size; - continue; - } - /* field name contains the schema name */ - else if (fi[i]->schema) - { - int matchidx = -1; - - for (k = 0; k < stmt->ntab; k++) - { - if (!stricmp(ti[k]->name, fi[i]->dot)) - { - if (!stricmp(ti[k]->schema, fi[i]->schema)) - { - fi[i]->ti = ti[k]; - break; - } - else if (!ti[k]->schema[0]) - { - if (matchidx < 0) - matchidx = k; - else - { - stmt->parse_status = STMT_PARSE_FATAL; - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "duplicated Table name"; - stmt->updatable = FALSE; - return FALSE; - } - } - } - } - if (matchidx >= 0) - fi[i]->ti = ti[matchidx]; - } - /* it's a dot, resolve to table or alias */ - else if (fi[i]->dot[0]) - { - for (k = 0; k < stmt->ntab; k++) - { - if (!stricmp(ti[k]->alias, fi[i]->dot)) - { - fi[i]->ti = ti[k]; - break; - } - else if (!stricmp(ti[k]->name, fi[i]->dot)) - { - fi[i]->ti = ti[k]; - break; - } - } - } - else if (stmt->ntab == 1) - fi[i]->ti = ti[0]; - } - - mylog("--------------------------------------------\n"); - mylog("nfld=%d, ntab=%d\n", irdflds->nfields, stmt->ntab); - if (0 == stmt->ntab) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - - for (i = 0; i < (int) irdflds->nfields; i++) - { - mylog("Field %d: expr=%d, func=%d, quote=%d, dquote=%d, numeric=%d, name='%s', alias='%s', dot='%s'\n", i, fi[i]->expr, fi[i]->func, fi[i]->quote, fi[i]->dquote, fi[i]->numeric, fi[i]->name, fi[i]->alias, fi[i]->dot); - if (fi[i]->ti) - mylog(" ----> table_name='%s', table_alias='%s'\n", fi[i]->ti->name, fi[i]->ti->alias); - } - - for (i = 0; i < stmt->ntab; i++) - mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias); - - - /* - * Now save the SQLColumns Info for the parse tables - */ - - /* Call SQLColumns for each table and store the result */ - if (stmt->ntab > 1) - updatable = FALSE; - else if (stmt->from_pos < 0) - updatable = FALSE; - for (i = 0; i < stmt->ntab; i++) - { - /* See if already got it */ - char found = FALSE; - - if (conn->schema_support) - { - if (!ti[i]->schema[0]) - { - const char *curschema = CC_get_current_schema(conn); - /* - * Though current_schema() doesn't have - * much sense in PostgreSQL, we first - * check the current_schema() when no - * explicit schema name was specified. - */ - for (k = 0; k < conn->ntables; k++) - { - if (!stricmp(conn->col_info[k]->name, ti[i]->name) && - !stricmp(conn->col_info[k]->schema, curschema)) - { - mylog("FOUND col_info table='%s' current schema='%s'\n", ti[i]->name, curschema); - found = TRUE; - strcpy(ti[i]->schema, curschema); - break; - } - } - if (!found) - { - QResultClass *res; - BOOL tblFound = FALSE; - - /* - * We also have to check as follows. - */ - sprintf(token, "select nspname from pg_namespace n, pg_class c" - " where c.relnamespace=n.oid and c.oid='%s'::regclass", ti[i]->name); - res = CC_send_query(conn, token, NULL, CLEAR_RESULT_ON_ABORT); - if (res) - { - if (QR_get_num_total_tuples(res) == 1) - { - tblFound = TRUE; - strcpy(ti[i]->schema, QR_get_value_backend_row(res, 0, 0)); - } - QR_Destructor(res); - } - else - CC_abort(conn); - if (!tblFound) - { - stmt->parse_status = STMT_PARSE_FATAL; - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Table not found"; - stmt->updatable = FALSE; - return FALSE; - } - } - } - if (!found && ti[i]->schema[0]) - { - for (k = 0; k < conn->ntables; k++) - { - if (!stricmp(conn->col_info[k]->name, ti[i]->name) && - !stricmp(conn->col_info[k]->schema, ti[i]->schema)) - { - mylog("FOUND col_info table='%s' schema='%s'\n", ti[i]->name, ti[i]->schema); - found = TRUE; - break; - } - } - } - } - else - { - for (k = 0; k < conn->ntables; k++) - { - if (!stricmp(conn->col_info[k]->name, ti[i]->name)) - { - mylog("FOUND col_info table='%s'\n", ti[i]->name); - found = TRUE; - break; - } - } - } - - if (!found) - { - mylog("PARSE: Getting PG_Columns for table[%d]='%s'\n", i, ti[i]->name); - - result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) - { - stmt->errormsg = "PGAPI_AllocStmt failed in parse_statement for columns."; - stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - - col_stmt = (StatementClass *) hcol_stmt; - col_stmt->internal = TRUE; - - result = PGAPI_Columns(hcol_stmt, "", 0, ti[i]->schema, - SQL_NTS, ti[i]->name, SQL_NTS, "", 0, PODBC_NOT_SEARCH_PATTERN); - - mylog(" Past PG_Columns\n"); - if (result == SQL_SUCCESS) - { - mylog(" Success\n"); - if (!(conn->ntables % COL_INCR)) - { - mylog("PARSE: Allocing col_info at ntables=%d\n", conn->ntables); - - conn->col_info = (COL_INFO **) realloc(conn->col_info, (conn->ntables + COL_INCR) * sizeof(COL_INFO *)); - if (!conn->col_info) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - } - - mylog("PARSE: malloc at conn->col_info[%d]\n", conn->ntables); - conn->col_info[conn->ntables] = (COL_INFO *) malloc(sizeof(COL_INFO)); - if (!conn->col_info[conn->ntables]) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - - /* - * Store the table name and the SQLColumns result - * structure - */ - if (ti[i]->schema[0]) - conn->col_info[conn->ntables]->schema = strdup(ti[i]->schema); - else - conn->col_info[conn->ntables]->schema = NULL; - strcpy(conn->col_info[conn->ntables]->name, ti[i]->name); - conn->col_info[conn->ntables]->result = SC_get_Curres(col_stmt); - - /* - * The connection will now free the result structures, so - * make sure that the statement doesn't free it - */ - SC_set_Result(col_stmt, NULL); - - conn->ntables++; - - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables); - } - else - { - PGAPI_FreeStmt(hcol_stmt, SQL_DROP); - break; - } - } - - /* Associate a table from the statement with a SQLColumn info */ - ti[i]->col_info = conn->col_info[k]; - mylog("associate col_info: i=%d, k=%d\n", i, k); - } - - mylog("Done PG_Columns\n"); - - /* - * Now resolve the fields to point to column info - */ - if (updatable && 1 == stmt->ntab) - updatable = stmt->ti[0]->updatable; - for (i = 0; i < (int) irdflds->nfields;) - { - fi[i]->updatable = updatable; - /* Dont worry about functions or quotes */ - if (fi[i]->func || fi[i]->quote || fi[i]->numeric) - { - fi[i]->updatable = FALSE; - i++; - continue; - } - - /* Stars get expanded to all fields in the table */ - else if (fi[i]->name[0] == '*') - { - char do_all_tables; - int total_cols, - old_alloc, - new_size, - cols; - int increased_cols; - - mylog("expanding field %d\n", i); - - total_cols = 0; - - if (fi[i]->ti) /* The star represents only the qualified - * table */ - total_cols = QR_get_num_backend_tuples(fi[i]->ti->col_info->result); - - else - { /* The star represents all tables */ - - /* Calculate the total number of columns after expansion */ - for (k = 0; k < stmt->ntab; k++) - total_cols += QR_get_num_backend_tuples(ti[k]->col_info->result); - } - increased_cols = total_cols - 1; - - /* Allocate some more field pointers if necessary */ - old_alloc = ((irdflds->nfields - 1) / FLD_INCR + 1) * FLD_INCR; - new_size = irdflds->nfields + increased_cols; - - mylog("k=%d, increased_cols=%d, old_alloc=%d, new_size=%d\n", k, increased_cols, old_alloc, new_size); - - if (new_size > old_alloc) - { - int new_alloc = ((new_size / FLD_INCR) + 1) * FLD_INCR; - - mylog("need more cols: new_alloc = %d\n", new_alloc); - fi = (FIELD_INFO **) realloc(fi, new_alloc * sizeof(FIELD_INFO *)); - if (!fi) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - irdflds->fi = fi; - } - - /* - * copy any other fields (if there are any) up past the - * expansion - */ - for (j = irdflds->nfields - 1; j > i; j--) - { - mylog("copying field %d to %d\n", j, increased_cols + j); - fi[increased_cols + j] = fi[j]; - } - mylog("done copying fields\n"); - - /* Set the new number of fields */ - irdflds->nfields += increased_cols; - mylog("irdflds->nfields now at %d\n", irdflds->nfields); - - - /* copy the new field info */ - do_all_tables = (fi[i]->ti ? FALSE : TRUE); - - for (k = 0; k < (do_all_tables ? stmt->ntab : 1); k++) - { - TABLE_INFO *the_ti = do_all_tables ? ti[k] : fi[i]->ti; - - cols = QR_get_num_backend_tuples(the_ti->col_info->result); - - for (n = 0; n < cols; n++) - { - mylog("creating field info: n=%d\n", n); - /* skip malloc (already did it for the Star) */ - if (k > 0 || n > 0) - { - mylog("allocating field info at %d\n", n + i); - fi[n + i] = (FIELD_INFO *) malloc(sizeof(FIELD_INFO)); - if (fi[n + i] == NULL) - { - stmt->parse_status = STMT_PARSE_FATAL; - return FALSE; - } - } - /* Initialize the new space (or the * field) */ - memset(fi[n + i], 0, sizeof(FIELD_INFO)); - fi[n + i]->ti = the_ti; - - mylog("about to copy at %d\n", n + i); - - getColInfo(the_ti->col_info, fi[n + i], n); - fi[n + i]->updatable = updatable; - - mylog("done copying\n"); - } - - i += cols; - mylog("i now at %d\n", i); - } - } - - /* - * We either know which table the field was in because it was - * qualified with a table name or alias -OR- there was only 1 - * table. - */ - else if (fi[i]->ti) - { - if (!searchColInfo(fi[i]->ti->col_info, fi[i])) - { - parse = FALSE; - fi[i]->updatable = FALSE; - } - i++; - } - - /* Don't know the table -- search all tables in "from" list */ - else - { - for (k = 0; k < stmt->ntab; k++) - { - if (searchColInfo(ti[k]->col_info, fi[i])) - { - fi[i]->ti = ti[k]; /* now know the table */ - break; - } - } - if (k >= stmt->ntab) - { - parse = FALSE; - fi[i]->updatable = FALSE; - } - i++; - } - } - - if (!parse) - stmt->parse_status = STMT_PARSE_INCOMPLETE; - else - stmt->parse_status = STMT_PARSE_COMPLETE; - - stmt->updatable = updatable; - mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status); - return parse; -} diff --git a/src/interfaces/odbc/pgapi30.c b/src/interfaces/odbc/pgapi30.c deleted file mode 100644 index 7fd6c9ac1c..0000000000 --- a/src/interfaces/odbc/pgapi30.c +++ /dev/null @@ -1,1656 +0,0 @@ -/*------- - * Module: pgapi30.c - * - * Description: This module contains routines related to ODBC 3.0 - * most of their implementations are temporary - * and must be rewritten properly. - * 2001/07/23 inoue - * - * Classes: n/a - * - * API functions: PGAPI_ColAttribute, PGAPI_GetDiagRec, - PGAPI_GetConnectAttr, PGAPI_GetStmtAttr, - PGAPI_SetConnectAttr, PGAPI_SetStmtAttr - *------- - */ - -#ifndef ODBCVER -#define ODBCVER 0x0300 -#endif -#include "psqlodbc.h" -#include -#include - -#include "environ.h" -#include "connection.h" -#include "statement.h" -#include "descriptor.h" -#include "qresult.h" -#include "pgapifunc.h" - -static HSTMT statementHandleFromDescHandle(SQLHDESC, SQLINTEGER *descType); -/* SQLError -> SQLDiagRec */ -RETCODE SQL_API -PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, - SQLINTEGER *NativeError, SQLCHAR *MessageText, - SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) -{ - RETCODE ret; - static const char *func = "PGAPI_GetDiagRec"; - - mylog("%s entering rec=%d", func, RecNumber); - switch (HandleType) - { - case SQL_HANDLE_ENV: - ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate, - NativeError, MessageText, - BufferLength, TextLength, 0); - break; - case SQL_HANDLE_DBC: - ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate, - NativeError, MessageText, BufferLength, - TextLength, 0); - break; - case SQL_HANDLE_STMT: - ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate, - NativeError, MessageText, BufferLength, - TextLength, 0); - break; - case SQL_HANDLE_DESC: - ret = PGAPI_StmtError(statementHandleFromDescHandle(Handle, NULL), - RecNumber, Sqlstate, NativeError, - MessageText, BufferLength, - TextLength, 0); - break; - default: - ret = SQL_ERROR; - } - mylog("%s exiting %d\n", func, ret); - return ret; -} - -/* - * Minimal implementation. - * - */ -RETCODE SQL_API -PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, - PTR DiagInfoPtr, SQLSMALLINT BufferLength, - SQLSMALLINT *StringLengthPtr) -{ - RETCODE ret = SQL_ERROR, rtn; - ConnectionClass *conn; - SQLHANDLE stmtHandle; - StatementClass *stmt; - SDWORD rc; - SWORD pcbErrm; - static const char *func = "PGAPI_GetDiagField"; - - mylog("%s entering rec=%d", func, RecNumber); - switch (HandleType) - { - case SQL_HANDLE_ENV: - switch (DiagIdentifier) - { - case SQL_DIAG_CLASS_ORIGIN: - case SQL_DIAG_SUBCLASS_ORIGIN: - case SQL_DIAG_CONNECTION_NAME: - case SQL_DIAG_SERVER_NAME: - strcpy((char *) DiagInfoPtr, ""); - if (StringLengthPtr) - *StringLengthPtr = 0; - ret = SQL_SUCCESS; - break; - case SQL_DIAG_MESSAGE_TEXT: - ret = PGAPI_EnvError(Handle, RecNumber, - NULL, NULL, DiagInfoPtr, - BufferLength, StringLengthPtr, 0); - break; - case SQL_DIAG_NATIVE: - ret = PGAPI_EnvError(Handle, RecNumber, - NULL, DiagInfoPtr, NULL, - 0, NULL, 0); - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - if (SQL_SUCCESS_WITH_INFO == ret) - ret = SQL_SUCCESS; - break; - case SQL_DIAG_NUMBER: - ret = PGAPI_EnvError(Handle, RecNumber, - NULL, NULL, NULL, - 0, NULL, 0); - if (SQL_SUCCESS == ret || - SQL_SUCCESS_WITH_INFO == ret) - { - *((SQLINTEGER *) DiagInfoPtr) = 1; - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - ret = SQL_SUCCESS; - } - break; - case SQL_DIAG_SQLSTATE: - ret = PGAPI_EnvError(Handle, RecNumber, - DiagInfoPtr, NULL, NULL, - 0, NULL, 0); - if (StringLengthPtr) - *StringLengthPtr = 5; - if (SQL_SUCCESS_WITH_INFO == ret) - ret = SQL_SUCCESS; - break; - case SQL_DIAG_RETURNCODE: /* driver manager returns */ - break; - case SQL_DIAG_CURSOR_ROW_COUNT: - case SQL_DIAG_ROW_COUNT: - case SQL_DIAG_DYNAMIC_FUNCTION: - case SQL_DIAG_DYNAMIC_FUNCTION_CODE: - /* options for statement type only */ - break; - } - break; - case SQL_HANDLE_DBC: - conn = (ConnectionClass *) Handle; - switch (DiagIdentifier) - { - case SQL_DIAG_CLASS_ORIGIN: - case SQL_DIAG_SUBCLASS_ORIGIN: - case SQL_DIAG_CONNECTION_NAME: - strcpy((char *) DiagInfoPtr, ""); - if (StringLengthPtr) - *StringLengthPtr = 0; - ret = SQL_SUCCESS; - break; - case SQL_DIAG_SERVER_NAME: - strcpy((SQLCHAR *) DiagInfoPtr, CC_get_DSN(conn)); - if (StringLengthPtr) - *StringLengthPtr = strlen(CC_get_DSN(conn)); - ret = SQL_SUCCESS; - break; - case SQL_DIAG_MESSAGE_TEXT: - ret = PGAPI_ConnectError(Handle, RecNumber, - NULL, NULL, DiagInfoPtr, - BufferLength, StringLengthPtr, 0); - break; - case SQL_DIAG_NATIVE: - ret = PGAPI_ConnectError(Handle, RecNumber, - NULL, DiagInfoPtr, NULL, - 0, NULL, 0); - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - if (SQL_SUCCESS_WITH_INFO == ret) - ret = SQL_SUCCESS; - break; - case SQL_DIAG_NUMBER: - ret = PGAPI_ConnectError(Handle, RecNumber, - NULL, NULL, NULL, - 0, NULL, 0); - if (SQL_SUCCESS == ret || - SQL_SUCCESS_WITH_INFO == ret) - { - *((SQLINTEGER *) DiagInfoPtr) = 1; - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - ret = SQL_SUCCESS; - } - break; - case SQL_DIAG_SQLSTATE: - ret = PGAPI_ConnectError(Handle, RecNumber, - DiagInfoPtr, NULL, NULL, - 0, NULL, 0); - if (StringLengthPtr) - *StringLengthPtr = 5; - if (SQL_SUCCESS_WITH_INFO == ret) - ret = SQL_SUCCESS; - break; - case SQL_DIAG_RETURNCODE: /* driver manager returns */ - break; - case SQL_DIAG_CURSOR_ROW_COUNT: - case SQL_DIAG_ROW_COUNT: - case SQL_DIAG_DYNAMIC_FUNCTION: - case SQL_DIAG_DYNAMIC_FUNCTION_CODE: - /* options for statement type only */ - break; - } - break; - case SQL_HANDLE_STMT: - conn = (ConnectionClass *) SC_get_conn(((StatementClass *) Handle)); - switch (DiagIdentifier) - { - case SQL_DIAG_CLASS_ORIGIN: - case SQL_DIAG_SUBCLASS_ORIGIN: - case SQL_DIAG_CONNECTION_NAME: - strcpy((char *) DiagInfoPtr, ""); - if (StringLengthPtr) - *StringLengthPtr = 0; - ret = SQL_SUCCESS; - break; - case SQL_DIAG_SERVER_NAME: - strcpy((SQLCHAR *) DiagInfoPtr, CC_get_DSN(conn)); - if (StringLengthPtr) - *StringLengthPtr = strlen(CC_get_DSN(conn)); - ret = SQL_SUCCESS; - break; - case SQL_DIAG_MESSAGE_TEXT: - ret = PGAPI_StmtError(Handle, RecNumber, - NULL, NULL, DiagInfoPtr, - BufferLength, StringLengthPtr, 0); - break; - case SQL_DIAG_NATIVE: - ret = PGAPI_StmtError(Handle, RecNumber, - NULL, DiagInfoPtr, NULL, - 0, NULL, 0); - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - if (SQL_SUCCESS_WITH_INFO == ret) - ret = SQL_SUCCESS; - break; - case SQL_DIAG_NUMBER: - *((SQLINTEGER *) DiagInfoPtr) = 0; - ret = SQL_NO_DATA_FOUND; - stmt = (StatementClass *) Handle; - do - { - rtn = PGAPI_StmtError(Handle, RecNumber, - NULL, NULL, NULL, - 0, &pcbErrm, 0); - if (SQL_SUCCESS == rtn || - SQL_SUCCESS_WITH_INFO == rtn) - { - *((SQLINTEGER *) DiagInfoPtr)++; - ret = SQL_SUCCESS; - } - } while (pcbErrm >= stmt->error_recsize); - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - break; - case SQL_DIAG_SQLSTATE: - ret = PGAPI_StmtError(Handle, RecNumber, - DiagInfoPtr, NULL, NULL, - 0, NULL, 0); - if (StringLengthPtr) - *StringLengthPtr = 5; - if (SQL_SUCCESS_WITH_INFO == ret) - ret = SQL_SUCCESS; - break; - case SQL_DIAG_CURSOR_ROW_COUNT: - stmt = (StatementClass *) Handle; - rc = -1; - if (stmt->status == STMT_FINISHED) - { - QResultClass *res = SC_get_Curres(stmt); - - if (res && QR_NumResultCols(res) > 0 && !SC_is_fetchcursor(stmt)) - rc = QR_get_num_total_tuples(res) - res->dl_count; - } - *((SQLINTEGER *) DiagInfoPtr) = rc; - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - ret = SQL_SUCCESS; - break; - case SQL_DIAG_ROW_COUNT: - stmt = (StatementClass *) Handle; - *((SQLINTEGER *) DiagInfoPtr) = stmt->diag_row_count; - if (StringLengthPtr) - *StringLengthPtr = sizeof(SQLINTEGER); - ret = SQL_SUCCESS; - break; - case SQL_DIAG_RETURNCODE: /* driver manager returns */ - break; - } - break; - case SQL_HANDLE_DESC: - stmtHandle = statementHandleFromDescHandle(Handle, NULL); - conn = (ConnectionClass *) SC_get_conn(((StatementClass *) stmtHandle)); - switch (DiagIdentifier) - { - case SQL_DIAG_CLASS_ORIGIN: - case SQL_DIAG_SUBCLASS_ORIGIN: - case SQL_DIAG_CONNECTION_NAME: - strcpy((char *) DiagInfoPtr, ""); - if (StringLengthPtr) - *StringLengthPtr = 0; - ret = SQL_SUCCESS; - break; - case SQL_DIAG_SERVER_NAME: - strcpy((SQLCHAR *) DiagInfoPtr, CC_get_DSN(conn)); - if (StringLengthPtr) - *StringLengthPtr = strlen(CC_get_DSN(conn)); - ret = SQL_SUCCESS; - break; - case SQL_DIAG_MESSAGE_TEXT: - case SQL_DIAG_NATIVE: - case SQL_DIAG_NUMBER: - case SQL_DIAG_SQLSTATE: - ret = PGAPI_GetDiagField(SQL_HANDLE_STMT, - stmtHandle, RecNumber, - DiagIdentifier, DiagInfoPtr, - BufferLength, StringLengthPtr); - break; - case SQL_DIAG_RETURNCODE: /* driver manager returns */ - break; - case SQL_DIAG_CURSOR_ROW_COUNT: - case SQL_DIAG_ROW_COUNT: - case SQL_DIAG_DYNAMIC_FUNCTION: - case SQL_DIAG_DYNAMIC_FUNCTION_CODE: - /* options for statement type only */ - break; - } - break; - default: - ret = SQL_ERROR; - } - mylog("%s exiting %d\n", func, ret); - return ret; -} - -/* SQLGetConnectOption -> SQLGetconnectAttr */ -RETCODE SQL_API -PGAPI_GetConnectAttr(HDBC ConnectionHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength) -{ - static const char *func = "PGAPI_GetConnectAttr"; - ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; - RETCODE ret = SQL_SUCCESS; - SQLINTEGER len = 4; - - mylog("PGAPI_GetConnectAttr %d\n", Attribute); - switch (Attribute) - { - case SQL_ATTR_ASYNC_ENABLE: - *((SQLUINTEGER *) Value) = SQL_ASYNC_ENABLE_OFF; - break; - case SQL_ATTR_AUTO_IPD: - *((SQLUINTEGER *) Value) = SQL_FALSE; - break; - case SQL_ATTR_CONNECTION_DEAD: - *((SQLUINTEGER *) Value) = (conn->status == CONN_NOT_CONNECTED || conn->status == CONN_DOWN); - break; - case SQL_ATTR_CONNECTION_TIMEOUT: - *((SQLUINTEGER *) Value) = 0; - break; - case SQL_ATTR_METADATA_ID: - conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER; - conn->errormsg = "Unsupported connect attribute (Get)"; - CC_log_error(func, "", conn); - return SQL_ERROR; - default: - ret = PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value); - } - if (StringLength) - *StringLength = len; - return ret; -} - -static SQLHDESC -descHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType) -{ - switch (descType) - { - case SQL_ATTR_APP_ROW_DESC: /* 10010 */ - return StatementHandle; /* this is bogus */ - case SQL_ATTR_APP_PARAM_DESC: /* 10011 */ - return (HSTMT) ((SQLUINTEGER) StatementHandle + 1) ; /* this is bogus */ - case SQL_ATTR_IMP_ROW_DESC: /* 10012 */ - return (HSTMT) ((SQLUINTEGER) StatementHandle + 2); /* this is bogus */ - case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */ - return (HSTMT) ((SQLUINTEGER) StatementHandle + 3); /* this is bogus */ - } - return (HSTMT) 0; -} -static HSTMT -statementHandleFromDescHandle(SQLHDESC DescHandle, SQLINTEGER *descType) -{ - SQLUINTEGER res = (SQLUINTEGER) DescHandle % 4; - if (descType) - { - switch (res) - { - case 0: *descType = SQL_ATTR_APP_ROW_DESC; /* 10010 */ - break; - case 1: *descType = SQL_ATTR_APP_PARAM_DESC; /* 10011 */ - break; - case 2: *descType = SQL_ATTR_IMP_ROW_DESC; /* 10012 */ - break; - case 3: *descType = SQL_ATTR_IMP_PARAM_DESC; /* 10013 */ - break; - } - } - return (HSTMT) ((SQLUINTEGER) DescHandle - res); -} - -void Desc_set_error(SQLHDESC hdesc, int errornumber, const char *errormsg) -{ - SQLINTEGER descType; - HSTMT hstmt = statementHandleFromDescHandle(hdesc, &descType); - StatementClass *stmt; - - if (!hstmt) - return; - stmt = (StatementClass *) hstmt; - stmt->errornumber = errornumber; - stmt->errormsg = errormsg; /* should be static */ -} - -static void column_bindings_set(ARDFields *opts, int cols, BOOL maxset) -{ - int i; - - if (cols == opts->allocated) - return; - if (cols > opts->allocated) - { - extend_column_bindings(opts, cols); - return; - } - if (maxset) return; - - for (i = opts->allocated; i > cols; i--) - reset_a_column_binding(opts, i); - opts->allocated = cols; - if (0 == cols) - { - free(opts->bindings); - opts->bindings = NULL; - } -} - -static RETCODE SQL_API -ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength) -{ - RETCODE ret = SQL_SUCCESS; - PTR tptr; - ARDFields *opts = SC_get_ARD(stmt); - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_SIZE: - opts->rowset_size = (SQLUINTEGER) Value; - break; - case SQL_DESC_ARRAY_STATUS_PTR: - opts->row_operation_ptr = Value; - break; - case SQL_DESC_BIND_OFFSET_PTR: - opts->row_offset_ptr = Value; - break; - case SQL_DESC_BIND_TYPE: - opts->bind_size = (SQLUINTEGER) Value; - break; - - case SQL_DESC_TYPE: - column_bindings_set(opts, RecNumber, TRUE); - reset_a_column_binding(opts, RecNumber); - opts->bindings[RecNumber - 1].returntype = (Int4) Value; - break; - case SQL_DESC_DATETIME_INTERVAL_CODE: - column_bindings_set(opts, RecNumber, TRUE); - switch (opts->bindings[RecNumber - 1].returntype) - { - case SQL_DATETIME: - case SQL_C_TYPE_DATE: - case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: - switch ((Int4) Value) - { - case SQL_CODE_DATE: - opts->bindings[RecNumber - 1].returntype = SQL_C_TYPE_DATE; - break; - case SQL_CODE_TIME: - opts->bindings[RecNumber - 1].returntype = SQL_C_TYPE_TIME; - break; - case SQL_CODE_TIMESTAMP: - opts->bindings[RecNumber - 1].returntype = SQL_C_TYPE_TIMESTAMP; - break; - } - break; - } - break; - case SQL_DESC_CONCISE_TYPE: - column_bindings_set(opts, RecNumber, TRUE); - opts->bindings[RecNumber - 1].returntype = (Int4) Value; - break; - case SQL_DESC_DATA_PTR: - if (!RecNumber) - opts->bookmark->buffer = Value; - else - { - column_bindings_set(opts, RecNumber, TRUE); - opts->bindings[RecNumber - 1].buffer = Value; - } - break; - case SQL_DESC_INDICATOR_PTR: - if (!RecNumber) - tptr = opts->bookmark->used; - else - { - column_bindings_set(opts, RecNumber, TRUE); - tptr = opts->bindings[RecNumber - 1].used; - } - if (Value != tptr) - { - ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR"; - } - break; - case SQL_DESC_OCTET_LENGTH_PTR: - if (!RecNumber) - opts->bookmark->used = Value; - else - { - column_bindings_set(opts, RecNumber, TRUE); - opts->bindings[RecNumber - 1].used = Value; - } - break; - case SQL_DESC_COUNT: - column_bindings_set(opts, (SQLUINTEGER) Value, FALSE); - break; - case SQL_DESC_OCTET_LENGTH: - if (RecNumber) - { - column_bindings_set(opts, RecNumber, TRUE); - opts->bindings[RecNumber - 1].buflen = (Int4) Value; - } - break; - case SQL_DESC_PRECISION: - if (RecNumber) - { - column_bindings_set(opts, RecNumber, TRUE); - opts->bindings[RecNumber - 1].precision = (Int2) Value; - } - break; - case SQL_DESC_SCALE: - if (RecNumber) - { - column_bindings_set(opts, RecNumber, TRUE); - opts->bindings[RecNumber - 1].scale = (Int4) Value; - } - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_PRECISION: - case SQL_DESC_LENGTH: - case SQL_DESC_NUM_PREC_RADIX: - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - return ret; -} - -static void parameter_bindings_set(APDFields *opts, int params, BOOL maxset) -{ - int i; - - if (params == opts->allocated) - return; - if (params > opts->allocated) - { - extend_parameter_bindings(opts, params); - return; - } - if (maxset) return; - - for (i = opts->allocated; i > params; i--) - reset_a_parameter_binding(opts, i); - opts->allocated = params; - if (0 == params) - { - free(opts->parameters); - opts->parameters = NULL; - } -} - -static RETCODE SQL_API -APDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength) -{ - RETCODE ret = SQL_SUCCESS; - APDFields *opts = SC_get_APD(stmt); - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_SIZE: - opts->paramset_size = (SQLUINTEGER) Value; - break; - case SQL_DESC_ARRAY_STATUS_PTR: - opts->param_operation_ptr = Value; - break; - case SQL_DESC_BIND_OFFSET_PTR: - opts->param_offset_ptr = Value; - break; - case SQL_DESC_BIND_TYPE: - opts->param_bind_type = (SQLUINTEGER) Value; - break; - - case SQL_DESC_TYPE: - parameter_bindings_set(opts, RecNumber, TRUE); - reset_a_parameter_binding(opts, RecNumber); - opts->parameters[RecNumber - 1].CType = (Int4) Value; - break; - case SQL_DESC_DATETIME_INTERVAL_CODE: - parameter_bindings_set(opts, RecNumber, TRUE); - switch (opts->parameters[RecNumber - 1].CType) - { - case SQL_DATETIME: - case SQL_C_TYPE_DATE: - case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: - switch ((Int4) Value) - { - case SQL_CODE_DATE: - opts->parameters[RecNumber - 1].CType = SQL_C_TYPE_DATE; - break; - case SQL_CODE_TIME: - opts->parameters[RecNumber - 1].CType = SQL_C_TYPE_TIME; - break; - case SQL_CODE_TIMESTAMP: - opts->parameters[RecNumber - 1].CType = SQL_C_TYPE_TIMESTAMP; - break; - } - break; - } - break; - case SQL_DESC_CONCISE_TYPE: - parameter_bindings_set(opts, RecNumber, TRUE); - opts->parameters[RecNumber - 1].CType = (Int4) Value; - break; - case SQL_DESC_DATA_PTR: - parameter_bindings_set(opts, RecNumber, TRUE); - opts->parameters[RecNumber - 1].buffer = Value; - break; - case SQL_DESC_INDICATOR_PTR: - if (opts->allocated < RecNumber || - Value != opts->parameters[RecNumber - 1].used) - { - ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR"; - } - break; - case SQL_DESC_OCTET_LENGTH: - parameter_bindings_set(opts, RecNumber, TRUE); - opts->parameters[RecNumber - 1].buflen = (Int4) Value; - break; - case SQL_DESC_OCTET_LENGTH_PTR: - parameter_bindings_set(opts, RecNumber, TRUE); - opts->parameters[RecNumber - 1].used = Value; - break; - case SQL_DESC_COUNT: - parameter_bindings_set(opts, (SQLUINTEGER) Value, FALSE); - break; - case SQL_DESC_PRECISION: - parameter_bindings_set(opts, RecNumber, TRUE); - opts->parameters[RecNumber - 1].precision = (Int2) Value; - break; - case SQL_DESC_SCALE: - parameter_bindings_set(opts, RecNumber, TRUE); - opts->parameters[RecNumber - 1].scale = (Int2) Value; - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_PRECISION: - case SQL_DESC_LENGTH: - case SQL_DESC_NUM_PREC_RADIX: - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - return ret; -} - -static RETCODE SQL_API -IRDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength) -{ - RETCODE ret = SQL_SUCCESS; - IRDFields *opts = SC_get_IRD(stmt); - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_STATUS_PTR: - opts->rowStatusArray = (SQLUSMALLINT *) Value; - break; - case SQL_DESC_ROWS_PROCESSED_PTR: - opts->rowsFetched = (SQLUINTEGER *) Value; - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - case SQL_DESC_COUNT: /* read-only */ - case SQL_DESC_AUTO_UNIQUE_VALUE: /* read-only */ - case SQL_DESC_BASE_COLUMN_NAME: /* read-only */ - case SQL_DESC_BASE_TABLE_NAME: /* read-only */ - case SQL_DESC_CASE_SENSITIVE: /* read-only */ - case SQL_DESC_CATALOG_NAME: /* read-only */ - case SQL_DESC_CONCISE_TYPE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_CODE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* read-only */ - case SQL_DESC_DISPLAY_SIZE: /* read-only */ - case SQL_DESC_FIXED_PREC_SCALE: /* read-only */ - case SQL_DESC_LABEL: /* read-only */ - case SQL_DESC_LENGTH: /* read-only */ - case SQL_DESC_LITERAL_PREFIX: /* read-only */ - case SQL_DESC_LITERAL_SUFFIX: /* read-only */ - case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */ - case SQL_DESC_NAME: /* read-only */ - case SQL_DESC_NULLABLE: /* read-only */ - case SQL_DESC_NUM_PREC_RADIX: /* read-only */ - case SQL_DESC_OCTET_LENGTH: /* read-only */ - case SQL_DESC_PRECISION: /* read-only */ -#if (ODBCVER >= 0x0350) - case SQL_DESC_ROWVER: /* read-only */ -#endif /* ODBCVER */ - case SQL_DESC_SCALE: /* read-only */ - case SQL_DESC_SCHEMA_NAME: /* read-only */ - case SQL_DESC_SEARCHABLE: /* read-only */ - case SQL_DESC_TABLE_NAME: /* read-only */ - case SQL_DESC_TYPE: /* read-only */ - case SQL_DESC_TYPE_NAME: /* read-only */ - case SQL_DESC_UNNAMED: /* read-only */ - case SQL_DESC_UNSIGNED: /* read-only */ - case SQL_DESC_UPDATABLE: /* read-only */ - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - return ret; -} - -static RETCODE SQL_API -IPDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength) -{ - RETCODE ret = SQL_SUCCESS; - IPDFields *ipdopts = SC_get_IPD(stmt); - APDFields *apdopts = SC_get_APD(stmt); - - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_STATUS_PTR: - ipdopts->param_status_ptr = (SQLUSMALLINT *) Value; - break; - case SQL_DESC_ROWS_PROCESSED_PTR: - ipdopts->param_processed_ptr = (SQLUINTEGER *) Value; - break; - case SQL_DESC_UNNAMED: /* only SQL_UNNAMED is allowed */ - if (SQL_UNNAMED != (SQLUINTEGER) Value) - { - ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - break; - case SQL_DESC_TYPE: - parameter_bindings_set(apdopts, RecNumber, TRUE); - apdopts->parameters[RecNumber - 1].SQLType = (Int4) Value; - break; - case SQL_DESC_DATETIME_INTERVAL_CODE: - parameter_bindings_set(apdopts, RecNumber, TRUE); - switch (apdopts->parameters[RecNumber - 1].SQLType) - { - case SQL_DATETIME: - case SQL_TYPE_DATE: - case SQL_TYPE_TIME: - case SQL_TYPE_TIMESTAMP: - switch ((Int4) Value) - { - case SQL_CODE_DATE: - apdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_DATE; - break; - case SQL_CODE_TIME: - apdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_TIME; - break; - case SQL_CODE_TIMESTAMP: - apdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_TIMESTAMP; - break; - } - break; - } - break; - case SQL_DESC_CONCISE_TYPE: - parameter_bindings_set(apdopts, RecNumber, TRUE); - apdopts->parameters[RecNumber - 1].SQLType = (Int4) Value; - break; - case SQL_DESC_COUNT: - parameter_bindings_set(apdopts, (SQLUINTEGER) Value, FALSE); - break; - case SQL_DESC_PARAMETER_TYPE: - apdopts->parameters[RecNumber - 1].paramType = (Int2) Value; - break; - case SQL_DESC_SCALE: - apdopts->parameters[RecNumber - 1].decimal_digits = (Int2) Value; - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - case SQL_DESC_CASE_SENSITIVE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_PRECISION: - case SQL_DESC_FIXED_PREC_SCALE: /* read-only */ - case SQL_DESC_LENGTH: - case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */ - case SQL_DESC_NAME: - case SQL_DESC_NULLABLE: /* read-only */ - case SQL_DESC_NUM_PREC_RADIX: - case SQL_DESC_OCTET_LENGTH: - case SQL_DESC_PRECISION: -#if (ODBCVER >= 0x0350) - case SQL_DESC_ROWVER: /* read-only */ -#endif /* ODBCVER */ - case SQL_DESC_TYPE_NAME: /* read-only */ - case SQL_DESC_UNSIGNED: /* read-only */ - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - return ret; -} - - -static RETCODE SQL_API -ARDGetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength, - SQLINTEGER *StringLength) -{ - RETCODE ret = SQL_SUCCESS; - SQLINTEGER len, ival, rettype = 0; - PTR ptr = NULL; - const ARDFields *opts = SC_get_ARD(stmt); - - len = 4; - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_SIZE: - ival = opts->rowset_size; - break; - case SQL_DESC_ARRAY_STATUS_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->row_operation_ptr; - break; - case SQL_DESC_BIND_OFFSET_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->row_offset_ptr; - break; - case SQL_DESC_BIND_TYPE: - ival = opts->bind_size; - break; - case SQL_DESC_TYPE: - switch (opts->bindings[RecNumber - 1].returntype) - { - case SQL_C_TYPE_DATE: - case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: - ival = SQL_DATETIME; - break; - default: - ival = opts->bindings[RecNumber - 1].returntype; - } - break; - case SQL_DESC_DATETIME_INTERVAL_CODE: - switch (opts->bindings[RecNumber - 1].returntype) - { - case SQL_C_TYPE_DATE: - ival = SQL_CODE_DATE; - break; - case SQL_C_TYPE_TIME: - ival = SQL_CODE_TIME; - break; - case SQL_C_TYPE_TIMESTAMP: - ival = SQL_CODE_TIMESTAMP; - break; - default: - ival = 0; - break; - } - break; - case SQL_DESC_CONCISE_TYPE: - ival = opts->bindings[RecNumber - 1].returntype; - break; - case SQL_DESC_DATA_PTR: - rettype = SQL_IS_POINTER; - if (!RecNumber) - ptr = opts->bookmark->buffer; - else - { - ptr = opts->bindings[RecNumber - 1].buffer; - } - break; - case SQL_DESC_INDICATOR_PTR: - rettype = SQL_IS_POINTER; - if (!RecNumber) - ptr = opts->bookmark->used; - else - { - ptr = opts->bindings[RecNumber - 1].used; - } - break; - case SQL_DESC_OCTET_LENGTH_PTR: - rettype = SQL_IS_POINTER; - if (!RecNumber) - ptr = opts->bookmark->used; - else - { - ptr = opts->bindings[RecNumber - 1].used; - } - break; - case SQL_DESC_COUNT: - ival = opts->allocated; - break; - case SQL_DESC_OCTET_LENGTH: - if (RecNumber) - { - ival = opts->bindings[RecNumber - 1].buflen; - } - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - ival = SQL_DESC_ALLOC_AUTO; - break; - case SQL_DESC_PRECISION: - if (RecNumber) - { - ival = opts->bindings[RecNumber - 1].precision; - } - break; - case SQL_DESC_SCALE: - if (RecNumber) - { - ival = opts->bindings[RecNumber - 1].scale; - } - break; - case SQL_DESC_NUM_PREC_RADIX: - ival = 10; - break; - case SQL_DESC_DATETIME_INTERVAL_PRECISION: - case SQL_DESC_LENGTH: - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - switch (rettype) - { - case 0: - case SQL_IS_INTEGER: - len = 4; - *((SQLINTEGER *) Value) = ival; - break; - case SQL_IS_POINTER: - len = 4; - *((void **) Value) = ptr; - break; - } - - if (StringLength) - *StringLength = len; - return ret; -} - -static RETCODE SQL_API -APDGetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength, - SQLINTEGER *StringLength) -{ - RETCODE ret = SQL_SUCCESS; - SQLINTEGER ival = 0, len, rettype = 0; - PTR ptr = NULL; - const APDFields *opts = SC_get_APD(stmt); - - len = 4; - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_SIZE: - rettype = SQL_IS_POINTER; - ival = opts->paramset_size; - break; - case SQL_DESC_ARRAY_STATUS_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->param_operation_ptr; - break; - case SQL_DESC_BIND_OFFSET_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->param_offset_ptr; - break; - case SQL_DESC_BIND_TYPE: - ival = opts->param_bind_type; - break; - - case SQL_DESC_TYPE: - switch (opts->parameters[RecNumber - 1].CType) - { - case SQL_C_TYPE_DATE: - case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: - ival = SQL_DATETIME; - break; - default: - ival = opts->parameters[RecNumber - 1].CType; - } - break; - case SQL_DESC_DATETIME_INTERVAL_CODE: - switch (opts->parameters[RecNumber - 1].CType) - { - case SQL_C_TYPE_DATE: - ival = SQL_CODE_DATE; - break; - case SQL_C_TYPE_TIME: - ival = SQL_CODE_TIME; - break; - case SQL_C_TYPE_TIMESTAMP: - ival = SQL_CODE_TIMESTAMP; - break; - default: - ival = 0; - break; - } - break; - case SQL_DESC_CONCISE_TYPE: - ival = opts->parameters[RecNumber - 1].CType; - break; - case SQL_DESC_DATA_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->parameters[RecNumber - 1].buffer; - break; - case SQL_DESC_INDICATOR_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->parameters[RecNumber - 1].used; - break; - case SQL_DESC_OCTET_LENGTH: - ival = opts->parameters[RecNumber - 1].buflen; - break; - case SQL_DESC_OCTET_LENGTH_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->parameters[RecNumber - 1].used; - break; - case SQL_DESC_COUNT: - ival = opts->allocated; - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - ival = SQL_DESC_ALLOC_AUTO; - break; - case SQL_DESC_NUM_PREC_RADIX: - ival = 10; - break; - case SQL_DESC_PRECISION: - ival = opts->parameters[RecNumber - 1].precision; - break; - case SQL_DESC_SCALE: - ival = opts->parameters[RecNumber - 1].scale; - break; - case SQL_DESC_DATETIME_INTERVAL_PRECISION: - case SQL_DESC_LENGTH: - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - switch (rettype) - { - case 0: - case SQL_IS_INTEGER: - len = 4; - *((Int4 *) Value) = ival; - break; - case SQL_IS_POINTER: - len = 4; - *((void **) Value) = ptr; - break; - } - - if (StringLength) - *StringLength = len; - return ret; -} - -static RETCODE SQL_API -IRDGetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength, - SQLINTEGER *StringLength) -{ - RETCODE ret = SQL_SUCCESS; - SQLINTEGER ival = 0, len, rettype = 0; - PTR ptr = NULL; - BOOL bCallColAtt = FALSE; - const IRDFields *opts = SC_get_IRD(stmt); - - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_STATUS_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->rowStatusArray; - break; - case SQL_DESC_ROWS_PROCESSED_PTR: - rettype = SQL_IS_POINTER; - ptr = opts->rowsFetched; - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - ival = SQL_DESC_ALLOC_AUTO; - break; - case SQL_DESC_COUNT: /* read-only */ - case SQL_DESC_AUTO_UNIQUE_VALUE: /* read-only */ - case SQL_DESC_CASE_SENSITIVE: /* read-only */ - case SQL_DESC_CONCISE_TYPE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_CODE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* read-only */ - case SQL_DESC_DISPLAY_SIZE: /* read-only */ - case SQL_DESC_FIXED_PREC_SCALE: /* read-only */ - case SQL_DESC_LENGTH: /* read-only */ - case SQL_DESC_NULLABLE: /* read-only */ - case SQL_DESC_NUM_PREC_RADIX: /* read-only */ - case SQL_DESC_OCTET_LENGTH: /* read-only */ - case SQL_DESC_PRECISION: /* read-only */ -#if (ODBCVER >= 0x0350) - case SQL_DESC_ROWVER: /* read-only */ -#endif /* ODBCVER */ - case SQL_DESC_SCALE: /* read-only */ - case SQL_DESC_SEARCHABLE: /* read-only */ - case SQL_DESC_TYPE: /* read-only */ - case SQL_DESC_UNNAMED: /* read-only */ - case SQL_DESC_UNSIGNED: /* read-only */ - case SQL_DESC_UPDATABLE: /* read-only */ - bCallColAtt = TRUE; - break; - case SQL_DESC_BASE_COLUMN_NAME: /* read-only */ - case SQL_DESC_BASE_TABLE_NAME: /* read-only */ - case SQL_DESC_CATALOG_NAME: /* read-only */ - case SQL_DESC_LABEL: /* read-only */ - case SQL_DESC_LITERAL_PREFIX: /* read-only */ - case SQL_DESC_LITERAL_SUFFIX: /* read-only */ - case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */ - case SQL_DESC_NAME: /* read-only */ - case SQL_DESC_SCHEMA_NAME: /* read-only */ - case SQL_DESC_TABLE_NAME: /* read-only */ - case SQL_DESC_TYPE_NAME: /* read-only */ - rettype = SQL_NTS; - bCallColAtt = TRUE; - break; - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - if (bCallColAtt) - { - SQLSMALLINT pcbL; - - ret = PGAPI_ColAttributes(stmt, RecNumber, - FieldIdentifier, Value, (SQLSMALLINT) BufferLength, - &pcbL, &ival); - len = pcbL; - } - switch (rettype) - { - case 0: - case SQL_IS_INTEGER: - len = 4; - *((Int4 *) Value) = ival; - break; - case SQL_IS_UINTEGER: - len = 4; - *((UInt4 *) Value) = ival; - break; - case SQL_IS_POINTER: - len = 4; - *((void **) Value) = ptr; - break; - } - - if (StringLength) - *StringLength = len; - return ret; -} - -static RETCODE SQL_API -IPDGetField(StatementClass *stmt, SQLSMALLINT RecNumber, - SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength, - SQLINTEGER *StringLength) -{ - RETCODE ret = SQL_SUCCESS; - SQLINTEGER ival = 0, len, rettype = 0; - PTR ptr = NULL; - const IPDFields *ipdopts = SC_get_IPD(stmt); - const APDFields *apdopts = SC_get_APD(stmt); - - switch (FieldIdentifier) - { - case SQL_DESC_ARRAY_STATUS_PTR: - rettype = SQL_IS_POINTER; - ptr = ipdopts->param_status_ptr; - break; - case SQL_DESC_ROWS_PROCESSED_PTR: - rettype = SQL_IS_POINTER; - ptr = ipdopts->param_processed_ptr; - break; - case SQL_DESC_UNNAMED: /* only SQL_UNNAMED is allowed */ - ival = SQL_UNNAMED; - break; - case SQL_DESC_TYPE: - switch (apdopts->parameters[RecNumber - 1].SQLType) - { - case SQL_TYPE_DATE: - case SQL_TYPE_TIME: - case SQL_TYPE_TIMESTAMP: - ival = SQL_DATETIME; - break; - default: - ival = apdopts->parameters[RecNumber - 1].SQLType; - } - break; - case SQL_DESC_DATETIME_INTERVAL_CODE: - switch (apdopts->parameters[RecNumber - 1].SQLType) - { - case SQL_TYPE_DATE: - ival = SQL_CODE_DATE; - case SQL_TYPE_TIME: - ival = SQL_CODE_TIME; - break; - case SQL_TYPE_TIMESTAMP: - ival = SQL_CODE_TIMESTAMP; - break; - default: - ival = 0; - } - break; - case SQL_DESC_CONCISE_TYPE: - ival = apdopts->parameters[RecNumber - 1].SQLType; - break; - case SQL_DESC_COUNT: - ival = apdopts->allocated; - break; - case SQL_DESC_PARAMETER_TYPE: - ival = apdopts->parameters[RecNumber - 1].paramType; - break; - case SQL_DESC_PRECISION: - switch (apdopts->parameters[RecNumber - 1].CType) - { - case SQL_C_TYPE_DATE: - case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: - case SQL_DATETIME: - ival = apdopts->parameters[RecNumber - 1].decimal_digits; - break; - } - break; - case SQL_DESC_SCALE: - switch (apdopts->parameters[RecNumber - 1].CType) - { - case SQL_C_NUMERIC: - ival = apdopts->parameters[RecNumber - 1].decimal_digits; - break; - } - break; - case SQL_DESC_ALLOC_TYPE: /* read-only */ - ival = SQL_DESC_ALLOC_AUTO; - break; - case SQL_DESC_CASE_SENSITIVE: /* read-only */ - case SQL_DESC_DATETIME_INTERVAL_PRECISION: - case SQL_DESC_FIXED_PREC_SCALE: /* read-only */ - case SQL_DESC_LENGTH: - case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */ - case SQL_DESC_NAME: - case SQL_DESC_NULLABLE: /* read-only */ - case SQL_DESC_NUM_PREC_RADIX: - case SQL_DESC_OCTET_LENGTH: -#if (ODBCVER >= 0x0350) - case SQL_DESC_ROWVER: /* read-only */ -#endif /* ODBCVER */ - case SQL_DESC_TYPE_NAME: /* read-only */ - case SQL_DESC_UNSIGNED: /* read-only */ - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INVALID_DESCRIPTOR_IDENTIFIER; - } - switch (rettype) - { - case 0: - case SQL_IS_INTEGER: - len = 4; - *((Int4 *) Value) = ival; - break; - case SQL_IS_POINTER: - len = 4; - *((void **)Value) = ptr; - break; - } - - if (StringLength) - *StringLength = len; - return ret; -} - -/* SQLGetStmtOption -> SQLGetStmtAttr */ -RETCODE SQL_API -PGAPI_GetStmtAttr(HSTMT StatementHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength) -{ - static char *func = "PGAPI_GetStmtAttr"; - StatementClass *stmt = (StatementClass *) StatementHandle; - RETCODE ret = SQL_SUCCESS; - int len = 0; - - mylog("%s Handle=%u %d\n", func, StatementHandle, Attribute); - switch (Attribute) - { - case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */ - *((void **) Value) = stmt->options.bookmark_ptr; - len = 4; - break; - case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */ - *((SQLUINTEGER **) Value) = SC_get_APD(stmt)->param_offset_ptr; - len = 4; - break; - case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */ - *((SQLUINTEGER *) Value) = SC_get_APD(stmt)->param_bind_type; - len = 4; - break; - case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */ - *((SQLUSMALLINT **) Value) = SC_get_APD(stmt)->param_operation_ptr; - len = 4; - break; - case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */ - *((SQLUSMALLINT **) Value) = SC_get_IPD(stmt)->param_status_ptr; - len = 4; - break; - case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */ - *((SQLUINTEGER **) Value) = SC_get_IPD(stmt)->param_processed_ptr; - len = 4; - break; - case SQL_ATTR_PARAMSET_SIZE: /* 22 */ - *((SQLUINTEGER *) Value) = SC_get_APD(stmt)->paramset_size; - len = 4; - break; - case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */ - *((SQLUINTEGER **) Value) = SC_get_ARD(stmt)->row_offset_ptr; - len = 4; - break; - case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */ - *((SQLUSMALLINT **) Value) = SC_get_ARD(stmt)->row_operation_ptr; - len = 4; - break; - case SQL_ATTR_ROW_STATUS_PTR: /* 25 */ - *((SQLUSMALLINT **) Value) = SC_get_IRD(stmt)->rowStatusArray; - len = 4; - break; - case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */ - *((SQLUINTEGER **) Value) = SC_get_IRD(stmt)->rowsFetched; - len = 4; - break; - case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */ - *((SQLUINTEGER *) Value) = SC_get_ARD(stmt)->rowset_size; - len = 4; - break; - case SQL_ATTR_APP_ROW_DESC: /* 10010 */ - case SQL_ATTR_APP_PARAM_DESC: /* 10011 */ - case SQL_ATTR_IMP_ROW_DESC: /* 10012 */ - case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */ - len = 4; - *((HSTMT *) Value) = descHandleFromStatementHandle(StatementHandle, Attribute); - break; - case SQL_ATTR_AUTO_IPD: /* 10001 */ - /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */ - - case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */ - case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */ - case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */ - case SQL_ATTR_METADATA_ID: /* 10014 */ - - /* - * case SQL_ATTR_PREDICATE_PTR: case - * SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: - */ - stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; - stmt->errormsg = "Unsupported statement option (Get)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - default: - len = 4; - ret = PGAPI_GetStmtOption(StatementHandle, (UWORD) Attribute, Value); - } - if (ret == SQL_SUCCESS && StringLength) - *StringLength = len; - return ret; -} - -/* SQLSetConnectOption -> SQLSetConnectAttr */ -RETCODE SQL_API -PGAPI_SetConnectAttr(HDBC ConnectionHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength) -{ - ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; - RETCODE ret = SQL_SUCCESS; - - mylog("PGAPI_SetConnectAttr %d\n", Attribute); - switch (Attribute) - { - case SQL_ATTR_ASYNC_ENABLE: - case SQL_ATTR_AUTO_IPD: - case SQL_ATTR_CONNECTION_DEAD: - case SQL_ATTR_CONNECTION_TIMEOUT: - case SQL_ATTR_METADATA_ID: - conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER; - conn->errormsg = "Unsupported connect attribute (Set)"; - return SQL_ERROR; - default: - ret = PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value); - } - return ret; -} - -/* new function */ -RETCODE SQL_API -PGAPI_GetDescField(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, - PTR Value, SQLINTEGER BufferLength, - SQLINTEGER *StringLength) -{ - RETCODE ret = SQL_SUCCESS; - HSTMT hstmt; - SQLUINTEGER descType; - StatementClass *stmt; - static const char *func = "PGAPI_GetDescField"; - - mylog("%s h=%u rec=%d field=%d blen=%d\n", func, DescriptorHandle, RecNumber, FieldIdentifier, BufferLength); - hstmt = statementHandleFromDescHandle(DescriptorHandle, &descType); - mylog("stmt=%x type=%d\n", hstmt, descType); - stmt = (StatementClass *) hstmt; - switch (descType) - { - case SQL_ATTR_APP_ROW_DESC: - ret = ARDGetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength, StringLength); - break; - case SQL_ATTR_APP_PARAM_DESC: - ret = APDGetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength, StringLength); - break; - case SQL_ATTR_IMP_ROW_DESC: - ret = IRDGetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength, StringLength); - break; - case SQL_ATTR_IMP_PARAM_DESC: - ret = IPDGetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength, StringLength); - break; - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INTERNAL_ERROR; - stmt->errormsg = "Error not implemented"; - } - if (ret == SQL_ERROR) - { - if (!stmt->errormsg && stmt->errornumber == STMT_INVALID_DESCRIPTOR_IDENTIFIER) - stmt->errormsg = "can't SQLGetDescField for this descriptor identifier"; - SC_log_error(func, "", stmt); - } - return ret; -} - -/* new function */ -RETCODE SQL_API -PGAPI_SetDescField(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, - PTR Value, SQLINTEGER BufferLength) -{ - RETCODE ret = SQL_SUCCESS; - HSTMT hstmt; - SQLUINTEGER descType; - StatementClass *stmt; - static const char *func = "PGAPI_SetDescField"; - - mylog("%s h=%u rec=%d field=%d val=%x,%d\n", func, DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength); - hstmt = statementHandleFromDescHandle(DescriptorHandle, &descType); - mylog("stmt=%x type=%d\n", hstmt, descType); - stmt = (StatementClass *) hstmt; - switch (descType) - { - case SQL_ATTR_APP_ROW_DESC: - ret = ARDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength); - break; - case SQL_ATTR_APP_PARAM_DESC: - ret = APDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength); - break; - case SQL_ATTR_IMP_ROW_DESC: - ret = IRDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength); - break; - case SQL_ATTR_IMP_PARAM_DESC: - ret = IPDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength); - break; - default:ret = SQL_ERROR; - stmt->errornumber = STMT_INTERNAL_ERROR; - stmt->errormsg = "Error not implemented"; - } - if (ret == SQL_ERROR) - { - if (!stmt->errormsg && stmt->errornumber == STMT_INVALID_DESCRIPTOR_IDENTIFIER) - stmt->errormsg = "can't SQLSetDescField for this descriptor identifier"; - SC_log_error(func, "", stmt); - } - return ret; -} - -/* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */ -RETCODE SQL_API -PGAPI_SetStmtAttr(HSTMT StatementHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength) -{ - static char *func = "PGAPI_SetStmtAttr"; - StatementClass *stmt = (StatementClass *) StatementHandle; - - mylog("%s Handle=%u %d,%u\n", func, StatementHandle, Attribute, Value); - switch (Attribute) - { - case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */ - case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */ - - case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */ - - case SQL_ATTR_APP_ROW_DESC: /* 10010 */ - case SQL_ATTR_APP_PARAM_DESC: /* 10011 */ - case SQL_ATTR_AUTO_IPD: /* 10001 */ - /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */ - case SQL_ATTR_IMP_ROW_DESC: /* 10012 (read-only) */ - case SQL_ATTR_IMP_PARAM_DESC: /* 10013 (read-only) */ - case SQL_ATTR_METADATA_ID: /* 10014 */ - - /* - * case SQL_ATTR_PREDICATE_PTR: case - * SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: - */ - stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; - stmt->errormsg = "Unsupported statement option (Set)"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - - case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */ - stmt->options.bookmark_ptr = Value; - break; - case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */ - SC_get_APD(stmt)->param_offset_ptr = (SQLUINTEGER *) Value; - break; - case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */ - SC_get_APD(stmt)->param_bind_type = (SQLUINTEGER) Value; - break; - case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */ - SC_get_APD(stmt)->param_operation_ptr = Value; - break; - case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */ - SC_get_IPD(stmt)->param_status_ptr = (SQLUSMALLINT *) Value; - break; - case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */ - SC_get_IPD(stmt)->param_processed_ptr = (SQLUINTEGER *) Value; - break; - case SQL_ATTR_PARAMSET_SIZE: /* 22 */ - SC_get_APD(stmt)->paramset_size = (SQLUINTEGER) Value; - break; - case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */ - SC_get_ARD(stmt)->row_offset_ptr = (SQLUINTEGER *) Value; - break; - case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */ - SC_get_ARD(stmt)->row_operation_ptr = Value; - break; - case SQL_ATTR_ROW_STATUS_PTR: /* 25 */ - SC_get_IRD(stmt)->rowStatusArray = (SQLUSMALLINT *) Value; - break; - case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */ - SC_get_IRD(stmt)->rowsFetched = (SQLUINTEGER *) Value; - break; - case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */ - SC_get_ARD(stmt)->rowset_size = (SQLUINTEGER) Value; - break; - default: - return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value); - } - return SQL_SUCCESS; -} - -#ifdef DRIVER_CURSOR_IMPLEMENT -RETCODE SQL_API -PGAPI_BulkOperations(HSTMT hstmt, SQLSMALLINT operation) -{ - static char *func = "PGAPI_BulkOperations"; - StatementClass *stmt = (StatementClass *) hstmt; - ARDFields *opts = SC_get_ARD(stmt); - RETCODE ret; - UInt4 offset, bind_size = opts->bind_size, *bmark = NULL; - int i, processed; - ConnectionClass *conn; - BOOL auto_commit_needed = FALSE; - QResultClass *res; - - mylog("%s operation = %d\n", func, operation); - SC_clear_error(stmt); - offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0; - - if (SQL_FETCH_BY_BOOKMARK != operation) - { - conn = SC_get_conn(stmt); - if (auto_commit_needed = CC_is_in_autocommit(conn), auto_commit_needed) - PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); - } - if (SQL_ADD != operation) - { - if (bmark = (UInt4 *) opts->bookmark->buffer, !bmark) - { - stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; - stmt->errormsg = "bookmark isn't specified"; - return SQL_ERROR; - } - bmark += (offset >> 4); - } - for (i = 0, processed = 0; i < opts->rowset_size; i++) - { - /* Note opts->row_operation_ptr is ignored */ - switch (operation) - { - case SQL_ADD: - ret = SC_pos_add(stmt, (UWORD) i); - break; - case SQL_UPDATE_BY_BOOKMARK: - ret = SC_pos_update(stmt, (UWORD) i, *bmark); - break; - case SQL_DELETE_BY_BOOKMARK: - ret = SC_pos_delete(stmt, (UWORD) i, *bmark); - break; - case SQL_FETCH_BY_BOOKMARK: - ret = SC_pos_refresh(stmt, (UWORD) i, *bmark); - break; - } - processed++; - if (SQL_ERROR == ret) - break; - if (SQL_ADD != operation) - { - if (bind_size > 0) - bmark += (bind_size >> 2); - else - bmark++; - } - } - if (auto_commit_needed) - PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON); - if (SC_get_IRD(stmt)->rowsFetched) - *(SC_get_IRD(stmt)->rowsFetched) = processed; - - if (res = SC_get_Curres(stmt), res) - res->recent_processed_row_count = stmt->diag_row_count = processed; - return ret; -} -#endif /* DRIVER_CURSOR_IMPLEMENT */ diff --git a/src/interfaces/odbc/pgapifunc.h b/src/interfaces/odbc/pgapifunc.h deleted file mode 100644 index 756a49d945..0000000000 --- a/src/interfaces/odbc/pgapifunc.h +++ /dev/null @@ -1,294 +0,0 @@ -/*------- - * Module: pgapifunc.h - * - *------- - */ -#ifndef _PG_API_FUNC_H__ -#define _PG_API_FUNC_H__ - -#include "psqlodbc.h" -#include -#include - -#define PODBC_NOT_SEARCH_PATTERN 1L -#define PODBC_ALLOW_PARTIAL_EXTRACT 1L -#define PODBC_ERROR_CLEAR (1L << 1) - -RETCODE SQL_API PGAPI_AllocConnect(HENV EnvironmentHandle, - HDBC FAR * ConnectionHandle); -RETCODE SQL_API PGAPI_AllocEnv(HENV FAR * EnvironmentHandle); -RETCODE SQL_API PGAPI_AllocStmt(HDBC ConnectionHandle, - HSTMT *StatementHandle); -RETCODE SQL_API PGAPI_BindCol(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, - PTR TargetValue, SQLINTEGER BufferLength, - SQLINTEGER *StrLen_or_Ind); -RETCODE SQL_API PGAPI_Cancel(HSTMT StatementHandle); -RETCODE SQL_API PGAPI_Columns(HSTMT StatementHandle, - SQLCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLCHAR *TableName, SQLSMALLINT NameLength3, - SQLCHAR *ColumnName, SQLSMALLINT NameLength4, - UWORD flag); -RETCODE SQL_API PGAPI_Connect(HDBC ConnectionHandle, - SQLCHAR *ServerName, SQLSMALLINT NameLength1, - SQLCHAR *UserName, SQLSMALLINT NameLength2, - SQLCHAR *Authentication, SQLSMALLINT NameLength3); -RETCODE SQL_API PGAPI_DriverConnect(HDBC hdbc, HWND hwnd, - UCHAR FAR * szConnStrIn, SWORD cbConnStrIn, - UCHAR FAR * szConnStrOut, SWORD cbConnStrOutMax, - SWORD FAR * pcbConnStrOut, UWORD fDriverCompletion); -RETCODE SQL_API PGAPI_BrowseConnect(HDBC hdbc, - SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, - SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, - SQLSMALLINT *pcbConnStrOut); -RETCODE SQL_API PGAPI_DataSources(HENV EnvironmentHandle, - SQLUSMALLINT Direction, SQLCHAR *ServerName, - SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, - SQLCHAR *Description, SQLSMALLINT BufferLength2, - SQLSMALLINT *NameLength2); -RETCODE SQL_API PGAPI_DescribeCol(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, - SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, - SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize, - SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable); -RETCODE SQL_API PGAPI_Disconnect(HDBC ConnectionHandle); -RETCODE SQL_API PGAPI_Error(HENV EnvironmentHandle, - HDBC ConnectionHandle, HSTMT StatementHandle, - SQLCHAR *Sqlstate, SQLINTEGER *NativeError, - SQLCHAR *MessageText, SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength); -/* Helper functions for Error handling */ -RETCODE SQL_API PGAPI_EnvError(HENV EnvironmentHandle, SWORD RecNumber, - SQLCHAR *Sqlstate, SQLINTEGER *NativeError, - SQLCHAR *MessageText, SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength, UWORD flag); -RETCODE SQL_API PGAPI_ConnectError(HDBC ConnectionHandle, SWORD RecNumber, - SQLCHAR *Sqlstate, SQLINTEGER *NativeError, - SQLCHAR *MessageText, SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength, UWORD flag); -RETCODE SQL_API PGAPI_StmtError(HSTMT StatementHandle, SWORD RecNumber, - SQLCHAR *Sqlstate, SQLINTEGER *NativeError, - SQLCHAR *MessageText, SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength, UWORD flag); - -RETCODE SQL_API PGAPI_ExecDirect(HSTMT StatementHandle, - SQLCHAR *StatementText, SQLINTEGER TextLength); -RETCODE SQL_API PGAPI_Execute(HSTMT StatementHandle); -RETCODE SQL_API PGAPI_Fetch(HSTMT StatementHandle); -RETCODE SQL_API PGAPI_FreeConnect(HDBC ConnectionHandle); -RETCODE SQL_API PGAPI_FreeEnv(HENV EnvironmentHandle); -RETCODE SQL_API PGAPI_FreeStmt(HSTMT StatementHandle, - SQLUSMALLINT Option); -RETCODE SQL_API PGAPI_GetConnectOption(HDBC ConnectionHandle, - SQLUSMALLINT Option, PTR Value); -RETCODE SQL_API PGAPI_GetCursorName(HSTMT StatementHandle, - SQLCHAR *CursorName, SQLSMALLINT BufferLength, - SQLSMALLINT *NameLength); -RETCODE SQL_API PGAPI_GetData(HSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, - PTR TargetValue, SQLINTEGER BufferLength, - SQLINTEGER *StrLen_or_Ind); -RETCODE SQL_API PGAPI_GetFunctions(HDBC ConnectionHandle, - SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported); -RETCODE SQL_API PGAPI_GetFunctions30(HDBC ConnectionHandle, - SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported); -RETCODE SQL_API PGAPI_GetInfo(HDBC ConnectionHandle, - SQLUSMALLINT InfoType, PTR InfoValue, - SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); -RETCODE SQL_API PGAPI_GetInfo30(HDBC ConnectionHandle, - SQLUSMALLINT InfoType, PTR InfoValue, - SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); -RETCODE SQL_API PGAPI_GetStmtOption(HSTMT StatementHandle, - SQLUSMALLINT Option, PTR Value); -RETCODE SQL_API PGAPI_GetTypeInfo(HSTMT StatementHandle, - SQLSMALLINT DataType); -RETCODE SQL_API PGAPI_NumResultCols(HSTMT StatementHandle, - SQLSMALLINT *ColumnCount); -RETCODE SQL_API PGAPI_ParamData(HSTMT StatementHandle, - PTR *Value); -RETCODE SQL_API PGAPI_Prepare(HSTMT StatementHandle, - SQLCHAR *StatementText, SQLINTEGER TextLength); -RETCODE SQL_API PGAPI_PutData(HSTMT StatementHandle, - PTR Data, SQLINTEGER StrLen_or_Ind); -RETCODE SQL_API PGAPI_RowCount(HSTMT StatementHandle, - SQLINTEGER *RowCount); -RETCODE SQL_API PGAPI_SetConnectOption(HDBC ConnectionHandle, - SQLUSMALLINT Option, SQLUINTEGER Value); -RETCODE SQL_API PGAPI_SetCursorName(HSTMT StatementHandle, - SQLCHAR *CursorName, SQLSMALLINT NameLength); -RETCODE SQL_API PGAPI_SetParam(HSTMT StatementHandle, - SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, - SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision, - SQLSMALLINT ParameterScale, PTR ParameterValue, - SQLINTEGER *StrLen_or_Ind); -RETCODE SQL_API PGAPI_SetStmtOption(HSTMT StatementHandle, - SQLUSMALLINT Option, SQLUINTEGER Value); -RETCODE SQL_API PGAPI_SpecialColumns(HSTMT StatementHandle, - SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName, - SQLSMALLINT NameLength1, SQLCHAR *SchemaName, - SQLSMALLINT NameLength2, SQLCHAR *TableName, - SQLSMALLINT NameLength3, SQLUSMALLINT Scope, - SQLUSMALLINT Nullable); -RETCODE SQL_API PGAPI_Statistics(HSTMT StatementHandle, - SQLCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLCHAR *TableName, SQLSMALLINT NameLength3, - SQLUSMALLINT Unique, SQLUSMALLINT Reserved); -RETCODE SQL_API PGAPI_Tables(HSTMT StatementHandle, - SQLCHAR *CatalogName, SQLSMALLINT NameLength1, - SQLCHAR *SchemaName, SQLSMALLINT NameLength2, - SQLCHAR *TableName, SQLSMALLINT NameLength3, - SQLCHAR *TableType, SQLSMALLINT NameLength4); -RETCODE SQL_API PGAPI_Transact(HENV EnvironmentHandle, - HDBC ConnectionHandle, SQLUSMALLINT CompletionType); -RETCODE SQL_API PGAPI_ColAttributes( - HSTMT hstmt, - SQLUSMALLINT icol, - SQLUSMALLINT fDescType, - PTR rgbDesc, - SQLSMALLINT cbDescMax, - SQLSMALLINT *pcbDesc, - SQLINTEGER *pfDesc); -RETCODE SQL_API PGAPI_ColumnPrivileges( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szTableName, - SQLSMALLINT cbTableName, - SQLCHAR *szColumnName, - SQLSMALLINT cbColumnName); -RETCODE SQL_API PGAPI_DescribeParam( - HSTMT hstmt, - SQLUSMALLINT ipar, - SQLSMALLINT *pfSqlType, - SQLUINTEGER *pcbParamDef, - SQLSMALLINT *pibScale, - SQLSMALLINT *pfNullable); -RETCODE SQL_API PGAPI_ExtendedFetch( - HSTMT hstmt, - SQLUSMALLINT fFetchType, - SQLINTEGER irow, - SQLUINTEGER *pcrow, - SQLUSMALLINT *rgfRowStatus, - SQLINTEGER FetchOffset); -RETCODE SQL_API PGAPI_ForeignKeys( - HSTMT hstmt, - SQLCHAR *szPkCatalogName, - SQLSMALLINT cbPkCatalogName, - SQLCHAR *szPkSchemaName, - SQLSMALLINT cbPkSchemaName, - SQLCHAR *szPkTableName, - SQLSMALLINT cbPkTableName, - SQLCHAR *szFkCatalogName, - SQLSMALLINT cbFkCatalogName, - SQLCHAR *szFkSchemaName, - SQLSMALLINT cbFkSchemaName, - SQLCHAR *szFkTableName, - SQLSMALLINT cbFkTableName); -RETCODE SQL_API PGAPI_MoreResults( - HSTMT hstmt); -RETCODE SQL_API PGAPI_NativeSql( - HDBC hdbc, - SQLCHAR *szSqlStrIn, - SQLINTEGER cbSqlStrIn, - SQLCHAR *szSqlStr, - SQLINTEGER cbSqlStrMax, - SQLINTEGER *pcbSqlStr); -RETCODE SQL_API PGAPI_NumParams( - HSTMT hstmt, - SQLSMALLINT *pcpar); -RETCODE SQL_API PGAPI_ParamOptions( - HSTMT hstmt, - SQLUINTEGER crow, - SQLUINTEGER *pirow); -RETCODE SQL_API PGAPI_PrimaryKeys( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szTableName, - SQLSMALLINT cbTableName); -RETCODE SQL_API PGAPI_ProcedureColumns( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szProcName, - SQLSMALLINT cbProcName, - SQLCHAR *szColumnName, - SQLSMALLINT cbColumnName); -RETCODE SQL_API PGAPI_Procedures( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szProcName, - SQLSMALLINT cbProcName); -RETCODE SQL_API PGAPI_SetPos( - HSTMT hstmt, - SQLUSMALLINT irow, - SQLUSMALLINT fOption, - SQLUSMALLINT fLock); -RETCODE SQL_API PGAPI_TablePrivileges( - HSTMT hstmt, - SQLCHAR *szCatalogName, - SQLSMALLINT cbCatalogName, - SQLCHAR *szSchemaName, - SQLSMALLINT cbSchemaName, - SQLCHAR *szTableName, - SQLSMALLINT cbTableName, - UWORD flag); -RETCODE SQL_API PGAPI_BindParameter( - HSTMT hstmt, - SQLUSMALLINT ipar, - SQLSMALLINT fParamType, - SQLSMALLINT fCType, - SQLSMALLINT fSqlType, - SQLUINTEGER cbColDef, - SQLSMALLINT ibScale, - PTR rgbValue, - SQLINTEGER cbValueMax, - SQLINTEGER *pcbValue); -RETCODE SQL_API PGAPI_SetScrollOptions( - HSTMT hstmt, - UWORD fConcurrency, - SDWORD crowKeyset, - UWORD crowRowset); - -#if (ODBCVER >= 0x0300) -RETCODE SQL_API PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, - SQLINTEGER *NativeError, SQLCHAR *MessageText, - SQLSMALLINT BufferLength, SQLSMALLINT *TextLength); -RETCODE SQL_API PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, - SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, - PTR DiagInfoPtr, SQLSMALLINT BufferLength, - SQLSMALLINT *StringLengthPtr); -RETCODE SQL_API PGAPI_GetConnectAttr(HDBC ConnectionHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength); -RETCODE SQL_API PGAPI_GetStmtAttr(HSTMT StatementHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER BufferLength, SQLINTEGER *StringLength); -RETCODE SQL_API PGAPI_SetConnectAttr(HDBC ConnectionHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength); -RETCODE SQL_API PGAPI_SetStmtAttr(HSTMT StatementHandle, - SQLINTEGER Attribute, PTR Value, - SQLINTEGER StringLength); -RETCODE SQL_API PGAPI_BulkOperations(HSTMT StatementHandle, - SQLSMALLINT operation); -RETCODE SQL_API PGAPI_SetDescField(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, - PTR Value, SQLINTEGER BufferLength); -RETCODE SQL_API PGAPI_GetDescField(SQLHDESC DescriptorHandle, - SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, - PTR Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); -#endif /* ODBCVER */ -#endif /* define_PG_API_FUNC_H__ */ diff --git a/src/interfaces/odbc/pgtypes.c b/src/interfaces/odbc/pgtypes.c deleted file mode 100644 index 6f3d1df3a9..0000000000 --- a/src/interfaces/odbc/pgtypes.c +++ /dev/null @@ -1,1475 +0,0 @@ -/*-------- - * Module: pgtypes.c - * - * Description: This module contains routines for getting information - * about the supported Postgres data types. Only the - * function pgtype_to_sqltype() returns an unknown condition. - * All other functions return a suitable default so that - * even data types that are not directly supported can be - * used (it is handled as char data). - * - * Classes: n/a - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ - -#include "pgtypes.h" - -#include "dlg_specific.h" -#include "statement.h" -#include "connection.h" -#include "environ.h" -#include "qresult.h" - - - -Int4 getCharColumnSize(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); - -/* - * these are the types we support. all of the pgtype_ functions should - * return values for each one of these. - * Even types not directly supported are handled as character types - * so all types should work (points, etc.) - */ - -/* - * ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all - * the SQL TYPES are reported and mapped to a corresponding Postgres Type - */ - -/* -Int4 pgtypes_defined[] = { - PG_TYPE_CHAR, - PG_TYPE_CHAR2, - PG_TYPE_CHAR4, - PG_TYPE_CHAR8, - PG_TYPE_CHAR16, - PG_TYPE_NAME, - PG_TYPE_VARCHAR, - PG_TYPE_BPCHAR, - PG_TYPE_DATE, - PG_TYPE_TIME, - PG_TYPE_TIME_WITH_TMZONE, - PG_TYPE_DATETIME, - PG_TYPE_ABSTIME, - PG_TYPE_TIMESTAMP_NO_TMZONE, - PG_TYPE_TIMESTAMP, - PG_TYPE_TEXT, - PG_TYPE_INT2, - PG_TYPE_INT4, - PG_TYPE_FLOAT4, - PG_TYPE_FLOAT8, - PG_TYPE_OID, - PG_TYPE_MONEY, - PG_TYPE_BOOL, - PG_TYPE_BYTEA, - PG_TYPE_LO, - 0 }; -*/ - - -/* These are NOW the SQL Types reported in SQLGetTypeInfo. */ -Int2 sqlTypes[] = { - SQL_BIGINT, - /* SQL_BINARY, -- Commented out because VarBinary is more correct. */ - SQL_BIT, - SQL_CHAR, - SQL_DATE, - SQL_DECIMAL, - SQL_DOUBLE, - SQL_FLOAT, - SQL_INTEGER, - SQL_LONGVARBINARY, - SQL_LONGVARCHAR, - SQL_NUMERIC, - SQL_REAL, - SQL_SMALLINT, - SQL_TIME, - SQL_TIMESTAMP, - SQL_TINYINT, - SQL_VARBINARY, - SQL_VARCHAR, -#ifdef UNICODE_SUPPORT - SQL_WCHAR, - SQL_WVARCHAR, - SQL_WLONGVARCHAR, -#endif /* UNICODE_SUPPORT */ - 0 -}; - -#if (ODBCVER >= 0x0300) && defined(OBDCINT64) -/* #define ALLOWED_C_BIGINT SQL_C_SBIGINT */ -#define ALLOWED_C_BIGINT SQL_C_CHAR /* Delphi should be either ? */ -#else -#define ALLOWED_C_BIGINT SQL_C_CHAR -#endif - -Int4 -sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType) -{ - Int4 pgType; - ConnectionClass *conn = SC_get_conn(stmt); - ConnInfo *ci = &(conn->connInfo); - - switch (fSqlType) - { - case SQL_BINARY: - pgType = PG_TYPE_BYTEA; - break; - - case SQL_CHAR: - pgType = PG_TYPE_BPCHAR; - break; - -#ifdef UNICODE_SUPPORT - case SQL_WCHAR: - pgType = PG_TYPE_BPCHAR; - break; -#endif /* UNICODE_SUPPORT */ - - case SQL_BIT: - pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL; - break; - - case SQL_DATE: -#if (ODBCVER >= 0x0300) - case SQL_TYPE_DATE: -#endif /* ODBCVER */ - pgType = PG_TYPE_DATE; - break; - - case SQL_DOUBLE: - case SQL_FLOAT: - pgType = PG_TYPE_FLOAT8; - break; - - case SQL_DECIMAL: - case SQL_NUMERIC: - pgType = PG_TYPE_NUMERIC; - break; - - case SQL_BIGINT: - pgType = PG_TYPE_INT8; - break; - - case SQL_INTEGER: - pgType = PG_TYPE_INT4; - break; - - case SQL_LONGVARBINARY: - pgType = PG_TYPE_LO; - break; - - case SQL_LONGVARCHAR: - pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR; - break; - -#ifdef UNICODE_SUPPORT - case SQL_WLONGVARCHAR: - pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR; - break; -#endif /* UNICODE_SUPPORT */ - - case SQL_REAL: - pgType = PG_TYPE_FLOAT4; - break; - - case SQL_SMALLINT: - case SQL_TINYINT: - pgType = PG_TYPE_INT2; - break; - - case SQL_TIME: -#if (ODBCVER >= 0x0300) - case SQL_TYPE_TIME: -#endif /* ODBCVER */ - pgType = PG_TYPE_TIME; - break; - - case SQL_TIMESTAMP: -#if (ODBCVER >= 0x0300) - case SQL_TYPE_TIMESTAMP: -#endif /* ODBCVER */ - pgType = PG_TYPE_DATETIME; - break; - - case SQL_VARBINARY: - pgType = PG_TYPE_BYTEA; - break; - - case SQL_VARCHAR: - pgType = PG_TYPE_VARCHAR; - break; - -#if UNICODE_SUPPORT - case SQL_WVARCHAR: - pgType = PG_TYPE_VARCHAR; - break; -#endif /* UNICODE_SUPPORT */ - - default: - pgType = 0; /* ??? */ - break; - } - - return pgType; -} - - -/* - * There are two ways of calling this function: - * - * 1. When going through the supported PG types (SQLGetTypeInfo) - * - * 2. When taking any type id (SQLColumns, SQLGetData) - * - * The first type will always work because all the types defined are returned here. - * The second type will return a default based on global parameter when it does not - * know. This allows for supporting - * types that are unknown. All other pg routines in here return a suitable default. - */ -Int2 -pgtype_to_concise_type(StatementClass *stmt, Int4 type) -{ - ConnectionClass *conn = SC_get_conn(stmt); - ConnInfo *ci = &(conn->connInfo); -#if (ODBCVER >= 0x0300) - EnvironmentClass *env = (EnvironmentClass *) (conn->henv); -#endif /* ODBCVER */ - - switch (type) - { - case PG_TYPE_CHAR: - case PG_TYPE_CHAR2: - case PG_TYPE_CHAR4: - case PG_TYPE_CHAR8: - case PG_TYPE_NAME: - return SQL_CHAR; - -#ifdef UNICODE_SUPPORT - case PG_TYPE_BPCHAR: - return conn->unicode ? SQL_WCHAR : SQL_CHAR; - - case PG_TYPE_VARCHAR: - return conn->unicode ? SQL_WVARCHAR : SQL_VARCHAR; - - case PG_TYPE_TEXT: - return ci->drivers.text_as_longvarchar ? - (conn->unicode ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR) : - (conn->unicode ? SQL_WVARCHAR : SQL_VARCHAR); - -#else - case PG_TYPE_BPCHAR: - return SQL_CHAR; - - case PG_TYPE_VARCHAR: - return SQL_VARCHAR; - - case PG_TYPE_TEXT: - return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; -#endif /* UNICODE_SUPPORT */ - - case PG_TYPE_BYTEA: - return SQL_VARBINARY; - case PG_TYPE_LO: - return SQL_LONGVARBINARY; - - case PG_TYPE_INT2: - return SQL_SMALLINT; - - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - return SQL_INTEGER; - - /* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */ - case PG_TYPE_INT8: - if (ci->int8_as != 0) - return ci->int8_as; - if (conn->ms_jet) - return SQL_NUMERIC; /* maybe a little better than SQL_VARCHAR */ -#if (ODBCVER >= 0x0300) - return SQL_BIGINT; -#else - return SQL_VARCHAR; -#endif /* ODBCVER */ - - case PG_TYPE_NUMERIC: - return SQL_NUMERIC; - - case PG_TYPE_FLOAT4: - return SQL_REAL; - case PG_TYPE_FLOAT8: - return SQL_FLOAT; - case PG_TYPE_DATE: -#if (ODBCVER >= 0x0300) - if (EN_is_odbc3(env)) - return SQL_TYPE_DATE; -#endif /* ODBCVER */ - return SQL_DATE; - case PG_TYPE_TIME: -#if (ODBCVER >= 0x0300) - if (EN_is_odbc3(env)) - return SQL_TYPE_TIME; -#endif /* ODBCVER */ - return SQL_TIME; - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIMESTAMP: -#if (ODBCVER >= 0x0300) - if (EN_is_odbc3(env)) - return SQL_TYPE_TIMESTAMP; -#endif /* ODBCVER */ - return SQL_TIMESTAMP; - case PG_TYPE_MONEY: - return SQL_FLOAT; - case PG_TYPE_BOOL: - return ci->drivers.bools_as_char ? SQL_CHAR : SQL_BIT; - - default: - - /* - * first, check to see if 'type' is in list. If not, look up - * with query. Add oid, name to list. If it's already in - * list, just return. - */ - /* hack until permanent type is available */ - if (type == stmt->hdbc->lobj_type) - return SQL_LONGVARBINARY; - - return ci->drivers.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; - } -} - -Int2 -pgtype_to_sqldesctype(StatementClass *stmt, Int4 type) -{ - Int2 rettype; - - switch (rettype = pgtype_to_concise_type(stmt, type)) - { -#if (ODBCVER >= 0x0300) - case SQL_TYPE_DATE: - case SQL_TYPE_TIME: - case SQL_TYPE_TIMESTAMP: - return SQL_DATETIME; -#endif /* ODBCVER */ - } - return rettype; -} - -Int2 -pgtype_to_datetime_sub(StatementClass *stmt, Int4 type) -{ - switch (pgtype_to_concise_type(stmt, type)) - { -#if (ODBCVER >= 0x0300) - case SQL_TYPE_DATE: - return SQL_CODE_DATE; - case SQL_TYPE_TIME: - return SQL_CODE_TIME; - case SQL_TYPE_TIMESTAMP: - return SQL_CODE_TIMESTAMP; -#endif /* ODBCVER */ - } - return -1; -} - - -Int2 -pgtype_to_ctype(StatementClass *stmt, Int4 type) -{ - ConnectionClass *conn = SC_get_conn(stmt); - ConnInfo *ci = &(conn->connInfo); -#if (ODBCVER >= 0x0300) - EnvironmentClass *env = (EnvironmentClass *) (conn->henv); -#endif /* ODBCVER */ - - switch (type) - { - case PG_TYPE_INT8: -#if (ODBCVER >= 0x0300) - if (!conn->ms_jet) - return ALLOWED_C_BIGINT; -#endif /* ODBCVER */ - return SQL_C_CHAR; - case PG_TYPE_NUMERIC: - return SQL_C_CHAR; - case PG_TYPE_INT2: - return SQL_C_SSHORT; - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - return SQL_C_SLONG; - case PG_TYPE_FLOAT4: - return SQL_C_FLOAT; - case PG_TYPE_FLOAT8: - return SQL_C_DOUBLE; - case PG_TYPE_DATE: -#if (ODBCVER >= 0x0300) - if (EN_is_odbc3(env)) - return SQL_C_TYPE_DATE; -#endif /* ODBCVER */ - return SQL_C_DATE; - case PG_TYPE_TIME: -#if (ODBCVER >= 0x0300) - if (EN_is_odbc3(env)) - return SQL_C_TYPE_TIME; -#endif /* ODBCVER */ - return SQL_C_TIME; - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIMESTAMP: -#if (ODBCVER >= 0x0300) - if (EN_is_odbc3(env)) - return SQL_C_TYPE_TIMESTAMP; -#endif /* ODBCVER */ - return SQL_C_TIMESTAMP; - case PG_TYPE_MONEY: - return SQL_C_FLOAT; - case PG_TYPE_BOOL: - return ci->drivers.bools_as_char ? SQL_C_CHAR : SQL_C_BIT; - - case PG_TYPE_BYTEA: - return SQL_C_BINARY; - case PG_TYPE_LO: - return SQL_C_BINARY; -#ifdef UNICODE_SUPPORT - case PG_TYPE_BPCHAR: - case PG_TYPE_VARCHAR: - case PG_TYPE_TEXT: - return conn->unicode ? SQL_C_WCHAR : SQL_C_CHAR; -#endif /* UNICODE_SUPPORT */ - - default: - /* hack until permanent type is available */ - if (type == stmt->hdbc->lobj_type) - return SQL_C_BINARY; - - return SQL_C_CHAR; - } -} - - -char * -pgtype_to_name(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_CHAR: - return "char"; - case PG_TYPE_CHAR2: - return "char2"; - case PG_TYPE_CHAR4: - return "char4"; - case PG_TYPE_CHAR8: - return "char8"; - case PG_TYPE_INT8: - return "int8"; - case PG_TYPE_NUMERIC: - return "numeric"; - case PG_TYPE_VARCHAR: - return "varchar"; - case PG_TYPE_BPCHAR: - return "char"; - case PG_TYPE_TEXT: - return "text"; - case PG_TYPE_NAME: - return "name"; - case PG_TYPE_INT2: - return "int2"; - case PG_TYPE_OID: - return "oid"; - case PG_TYPE_INT4: - return "int4"; - case PG_TYPE_FLOAT4: - return "float4"; - case PG_TYPE_FLOAT8: - return "float8"; - case PG_TYPE_DATE: - return "date"; - case PG_TYPE_TIME: - return "time"; - case PG_TYPE_ABSTIME: - return "abstime"; - case PG_TYPE_DATETIME: - return "datetime"; - case PG_TYPE_TIMESTAMP_NO_TMZONE: - return "timestamp_nozone"; - case PG_TYPE_TIMESTAMP: - return "timestamp"; - case PG_TYPE_MONEY: - return "money"; - case PG_TYPE_BOOL: - return "bool"; - case PG_TYPE_BYTEA: - return "bytea"; - - case PG_TYPE_LO: - return PG_TYPE_LO_NAME; - - default: - /* hack until permanent type is available */ - if (type == stmt->hdbc->lobj_type) - return PG_TYPE_LO_NAME; - - /* - * "unknown" can actually be used in alter table because it is - * a real PG type! - */ - return "unknown"; - } -} - - -static Int2 -getNumericDecimalDigits(StatementClass *stmt, Int4 type, int col) -{ - Int4 atttypmod = -1, default_decimal_digits = 6; - QResultClass *result; - ColumnInfoClass *flds; - - mylog("getNumericDecimalDigits: type=%d, col=%d\n", type, col); - - if (col < 0) - return PG_NUMERIC_MAX_SCALE; - - result = SC_get_Curres(stmt); - - /* - * Manual Result Sets -- use assigned column width (i.e., from - * set_tuplefield_string) - */ - if (stmt->manual_result) - { - flds = result->fields; - if (flds) - { - atttypmod = flds->atttypmod[col]; - if (atttypmod < 0 && flds->adtsize[col] > 0) - return flds->adtsize[col]; - } - if (atttypmod < 0) - return default_decimal_digits; - } - else - atttypmod = QR_get_atttypmod(result, col); - if (atttypmod > -1) - return (atttypmod & 0xffff); - else - { - Int4 dsp_size = QR_get_display_size(result, col); - if (dsp_size <= 0) - return default_decimal_digits; - if (dsp_size < 5) - dsp_size = 5; - return dsp_size; - } -} - - -static Int4 -getNumericColumnSize(StatementClass *stmt, Int4 type, int col) -{ - Int4 atttypmod = -1, max_column_size = PG_NUMERIC_MAX_PRECISION + PG_NUMERIC_MAX_SCALE, default_column_size = 28; - QResultClass *result; - ColumnInfoClass *flds; - - mylog("getNumericColumnSize: type=%d, col=%d\n", type, col); - - if (col < 0) - return max_column_size; - - result = SC_get_Curres(stmt); - - /* - * Manual Result Sets -- use assigned column width (i.e., from - * set_tuplefield_string) - */ - if (stmt->manual_result) - { - flds = result->fields; - if (flds) - { - atttypmod = flds->atttypmod[col]; - if (atttypmod < 0 && flds->adtsize[col] > 0) - return 2 * flds->adtsize[col]; - } - if (atttypmod < 0) - return default_column_size; - } - else - atttypmod = QR_get_atttypmod(result, col); - if (atttypmod > -1) - return (atttypmod >> 16) & 0xffff; - else - { - Int4 dsp_size = QR_get_display_size(result, col); - if (dsp_size <= 0) - return default_column_size; - dsp_size *= 2; - if (dsp_size < 10) - dsp_size = 10; - return dsp_size; - } -} - - -Int4 -getCharColumnSize(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - int p = -1, attlen = -1, - maxsize; - QResultClass *result; - ColumnInfoClass *flds; - ConnectionClass *conn = SC_get_conn(stmt); - ConnInfo *ci = &(conn->connInfo); - - mylog("getCharColumnSize: type=%d, col=%d, unknown = %d\n", type, col, handle_unknown_size_as); - - /* Assign Maximum size based on parameters */ - switch (type) - { - case PG_TYPE_TEXT: - if (ci->drivers.text_as_longvarchar) - maxsize = ci->drivers.max_longvarchar_size; - else - maxsize = ci->drivers.max_varchar_size; - break; - - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - maxsize = ci->drivers.max_varchar_size; - break; - - default: - if (ci->drivers.unknowns_as_longvarchar) - maxsize = ci->drivers.max_longvarchar_size; - else - maxsize = ci->drivers.max_varchar_size; - break; - } - - if (maxsize == TEXT_FIELD_SIZE + 1) /* magic length for testing */ - { - if (PG_VERSION_GE(SC_get_conn(stmt), 7.1)) - maxsize = 0; - else - maxsize = TEXT_FIELD_SIZE; - } - /* - * Static ColumnSize (i.e., the Maximum ColumnSize of the datatype) This - * has nothing to do with a result set. - */ - if (col < 0) - return maxsize; - - result = SC_get_Curres(stmt); - - /* - * Manual Result Sets -- use assigned column width (i.e., from - * set_tuplefield_string) - */ - if (stmt->manual_result) - { - flds = result->fields; - if (flds) - return flds->adtsize[col]; - else - return maxsize; - } - - p = QR_get_display_size(result, col); /* longest */ - attlen = QR_get_atttypmod(result, col); - /* Size is unknown -- handle according to parameter */ - if (attlen > 0) /* maybe the length is known */ - { - if (attlen >= p) - return attlen; - switch (type) - { - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - if (conn->unicode || conn->ms_jet) - return attlen; -#if (ODBCVER >= 0x0300) -#ifdef MULTIBYTE - return attlen; -#endif /* MULTIBYTE */ -#endif /* ODBCVER */ - return p; - } - } - - /* The type is really unknown */ - if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST) - { - mylog("getCharColumnSize: LONGEST: p = %d\n", p); - if (p >= 0) - return p; - } - - if (p > maxsize) - maxsize = p; - if (handle_unknown_size_as == UNKNOWNS_AS_MAX) - return maxsize; - else /* handle_unknown_size_as == DONT_KNOW */ - return -1; -} - -static Int2 -getTimestampDecimalDigits(StatementClass *stmt, Int4 type, int col) -{ - ConnectionClass *conn = SC_get_conn(stmt); - Int4 atttypmod; - QResultClass *result; - ColumnInfoClass *flds; - - mylog("getTimestampDecimalDigits: type=%d, col=%d\n", type, col); - - if (col < 0) - return 0; - if (PG_VERSION_LT(conn, 7.2)) - return 0; - - result = SC_get_Curres(stmt); - - /* - * Manual Result Sets -- use assigned column width (i.e., from - * set_tuplefield_string) - */ - atttypmod = 0; - if (stmt->manual_result) - { - flds = result->fields; - if (flds) - atttypmod = flds->atttypmod[col]; - mylog("atttypmod1=%d\n", atttypmod); - } - else - atttypmod = QR_get_atttypmod(result, col); - mylog("atttypmod2=%d\n", atttypmod); - return (atttypmod > -1 ? atttypmod : 0); -} - - -static Int4 -getTimestampColumnSize(StatementClass *stmt, Int4 type, int col) -{ - Int4 fixed, - scale; - - mylog("getTimestampColumnSize: type=%d, col=%d\n", type, col); - - switch (type) - { - case PG_TYPE_TIME: - fixed = 8; - break; - case PG_TYPE_TIME_WITH_TMZONE: - fixed = 11; - break; - case PG_TYPE_TIMESTAMP_NO_TMZONE: - fixed = 19; - break; - default: - if (USE_ZONE) - fixed = 22; - else - fixed = 19; - break; - } - scale = getTimestampDecimalDigits(stmt, type, col); - return (scale > 0) ? fixed + 1 + scale : fixed; -} - -/* - * This corresponds to "precision" in ODBC 2.x. - * - * For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will - * override this length with the atttypmod length from pg_attribute . - * - * If col >= 0, then will attempt to get the info from the result set. - * This is used for functions SQLDescribeCol and SQLColAttributes. - */ -Int4 -pgtype_column_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - switch (type) - { - case PG_TYPE_CHAR: - return 1; - case PG_TYPE_CHAR2: - return 2; - case PG_TYPE_CHAR4: - return 4; - case PG_TYPE_CHAR8: - return 8; - - case PG_TYPE_NAME: - return NAME_FIELD_SIZE; - - case PG_TYPE_INT2: - return 5; - - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - return 10; - - case PG_TYPE_INT8: - return 19; /* signed */ - - case PG_TYPE_NUMERIC: - return getNumericColumnSize(stmt, type, col); - - case PG_TYPE_FLOAT4: - case PG_TYPE_MONEY: - return 7; - - case PG_TYPE_FLOAT8: - return 15; - - case PG_TYPE_DATE: - return 10; - case PG_TYPE_TIME: - return 8; - - case PG_TYPE_ABSTIME: - case PG_TYPE_TIMESTAMP: - return 22; - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - /* return 22; */ - return getTimestampColumnSize(stmt, type, col); - - case PG_TYPE_BOOL: - { - BOOL true_is_minus1 = FALSE; - return true_is_minus1 ? 2 : 1; - } - - case PG_TYPE_LO: - return SQL_NO_TOTAL; - - default: - - if (type == stmt->hdbc->lobj_type) /* hack until permanent - * type is available */ - return SQL_NO_TOTAL; - - /* Handle Character types and unknown types */ - return getCharColumnSize(stmt, type, col, handle_unknown_size_as); - } -} - -/* - * "precision in ODBC 3.x. - */ -Int4 -pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - switch (type) - { - case PG_TYPE_NUMERIC: - return getNumericColumnSize(stmt, type, col); - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - return getTimestampDecimalDigits(stmt, type, col); - } - return -1; -} - - -Int4 -pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - int dsize; - - switch (type) - { - case PG_TYPE_INT2: - return 6; - - case PG_TYPE_OID: - case PG_TYPE_XID: - return 10; - - case PG_TYPE_INT4: - return 11; - - case PG_TYPE_INT8: - return 20; /* signed: 19 digits + sign */ - - case PG_TYPE_NUMERIC: - dsize = getNumericColumnSize(stmt, type, col); - return dsize < 0 ? dsize : dsize + 2; - - case PG_TYPE_MONEY: - return 15; /* ($9,999,999.99) */ - - case PG_TYPE_FLOAT4: - return 13; - - case PG_TYPE_FLOAT8: - return 22; - - /* Character types use regular precision */ - default: - return pgtype_column_size(stmt, type, col, handle_unknown_size_as); - } -} - - -/* - * The length in bytes of data transferred on an SQLGetData, SQLFetch, - * or SQLFetchScroll operation if SQL_C_DEFAULT is specified. - */ -Int4 -pgtype_buffer_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - ConnectionClass *conn = SC_get_conn(stmt); - - switch (type) - { - case PG_TYPE_INT2: - return 2; /* sizeof(SQLSMALLINT) */ - - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - return 4; /* sizeof(SQLINTEGER) */ - - case PG_TYPE_INT8: - if (SQL_C_CHAR == pgtype_to_ctype(stmt, type)) - return 20; /* signed: 19 digits + sign */ - return 8; /* sizeof(SQLSBININT) */ - - case PG_TYPE_NUMERIC: - return getNumericColumnSize(stmt, type, col) + 2; - - case PG_TYPE_FLOAT4: - case PG_TYPE_MONEY: - return 4; /* sizeof(SQLREAL) */ - - case PG_TYPE_FLOAT8: - return 8; /* sizeof(SQLFLOAT) */ - - case PG_TYPE_DATE: - case PG_TYPE_TIME: - return 6; /* sizeof(DATE(TIME)_STRUCT) */ - - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - return 16; /* sizeof(TIMESTAMP_STRUCT) */ - - /* Character types use the default precision */ - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - { - int coef = 1; - Int4 prec = pgtype_column_size(stmt, type, col, handle_unknown_size_as), maxvarc; - if (conn->unicode) - return prec * 2; -#ifdef MULTIBYTE - /* after 7.2 */ - if (PG_VERSION_GE(conn, 7.2)) - coef = 3; - else -#endif /* MULTIBYTE */ - if ((conn->connInfo).lf_conversion) - /* CR -> CR/LF */ - coef = 2; - if (coef == 1) - return prec; - maxvarc = conn->connInfo.drivers.max_varchar_size; - if (prec <= maxvarc && prec * coef > maxvarc) - return maxvarc; - return coef * prec; - } - default: - return pgtype_column_size(stmt, type, col, handle_unknown_size_as); - } -} - -/* - */ -Int4 -pgtype_desclength(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - switch (type) - { - case PG_TYPE_INT2: - return 2; - - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - return 4; - - case PG_TYPE_INT8: - return 20; /* signed: 19 digits + sign */ - - case PG_TYPE_NUMERIC: - return getNumericColumnSize(stmt, type, col) + 2; - - case PG_TYPE_FLOAT4: - case PG_TYPE_MONEY: - return 4; - - case PG_TYPE_FLOAT8: - return 8; - - case PG_TYPE_DATE: - case PG_TYPE_TIME: - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIMESTAMP: - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - return pgtype_column_size(stmt, type, col, handle_unknown_size_as); - default: - return pgtype_column_size(stmt, type, col, handle_unknown_size_as); - } -} - -/* - * Transfer octet length. - */ -Int4 -pgtype_transfer_octet_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) -{ - ConnectionClass *conn = SC_get_conn(stmt); - - int coef = 1; - Int4 prec = pgtype_column_size(stmt, type, col, handle_unknown_size_as), maxvarc; - switch (type) - { - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - if (conn->unicode) - return prec * 2; -#ifdef MULTIBYTE - /* after 7.2 */ - if (PG_VERSION_GE(conn, 7.2)) - coef = 3; - else -#endif /* MULTIBYTE */ - if ((conn->connInfo).lf_conversion) - /* CR -> CR/LF */ - coef = 2; - if (coef == 1) - return prec; - maxvarc = conn->connInfo.drivers.max_varchar_size; - if (prec <= maxvarc && prec * coef > maxvarc) - return maxvarc; - return coef * prec; - case PG_TYPE_BYTEA: - return prec; - } - return -1; -} - -/* - * corrsponds to "scale" in ODBC 2.x. - */ -Int2 -pgtype_decimal_digits(StatementClass *stmt, Int4 type, int col) -{ - switch (type) - { - case PG_TYPE_INT2: - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - case PG_TYPE_INT8: - case PG_TYPE_FLOAT4: - case PG_TYPE_FLOAT8: - case PG_TYPE_MONEY: - case PG_TYPE_BOOL: - - /* - * Number of digits to the right of the decimal point in - * "yyyy-mm=dd hh:mm:ss[.f...]" - */ - case PG_TYPE_ABSTIME: - case PG_TYPE_TIMESTAMP: - return 0; - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - /* return 0; */ - return getTimestampDecimalDigits(stmt, type, col); - - case PG_TYPE_NUMERIC: - return getNumericDecimalDigits(stmt, type, col); - - default: - return -1; - } -} - -/* - * "scale" in ODBC 3.x. - */ -Int2 -pgtype_scale(StatementClass *stmt, Int4 type, int col) -{ - switch (type) - { - case PG_TYPE_NUMERIC: - return getNumericDecimalDigits(stmt, type, col); - } - return -1; -} - - -Int2 -pgtype_radix(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_INT2: - case PG_TYPE_OID: - case PG_TYPE_INT4: - case PG_TYPE_INT8: - case PG_TYPE_NUMERIC: - case PG_TYPE_FLOAT4: - case PG_TYPE_MONEY: - case PG_TYPE_FLOAT8: - return 10; - default: - return -1; - } -} - - -Int2 -pgtype_nullable(StatementClass *stmt, Int4 type) -{ - return SQL_NULLABLE; /* everything should be nullable */ -} - - -Int2 -pgtype_auto_increment(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_INT2: - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - case PG_TYPE_FLOAT4: - case PG_TYPE_MONEY: - case PG_TYPE_BOOL: - case PG_TYPE_FLOAT8: - case PG_TYPE_INT8: - case PG_TYPE_NUMERIC: - - case PG_TYPE_DATE: - case PG_TYPE_TIME_WITH_TMZONE: - case PG_TYPE_TIME: - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP_NO_TMZONE: - case PG_TYPE_TIMESTAMP: - return FALSE; - - default: - return -1; - } -} - - -Int2 -pgtype_case_sensitive(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_CHAR: - - case PG_TYPE_CHAR2: - case PG_TYPE_CHAR4: - case PG_TYPE_CHAR8: - - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - case PG_TYPE_TEXT: - case PG_TYPE_NAME: - return TRUE; - - default: - return FALSE; - } -} - - -Int2 -pgtype_money(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_MONEY: - return TRUE; - default: - return FALSE; - } -} - - -Int2 -pgtype_searchable(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_CHAR: - case PG_TYPE_CHAR2: - case PG_TYPE_CHAR4: - case PG_TYPE_CHAR8: - - case PG_TYPE_VARCHAR: - case PG_TYPE_BPCHAR: - case PG_TYPE_TEXT: - case PG_TYPE_NAME: - return SQL_SEARCHABLE; - - default: - return SQL_ALL_EXCEPT_LIKE; - } -} - - -Int2 -pgtype_unsigned(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_OID: - case PG_TYPE_XID: - return TRUE; - - case PG_TYPE_INT2: - case PG_TYPE_INT4: - case PG_TYPE_INT8: - case PG_TYPE_NUMERIC: - case PG_TYPE_FLOAT4: - case PG_TYPE_FLOAT8: - case PG_TYPE_MONEY: - return FALSE; - - default: - return -1; - } -} - - -char * -pgtype_literal_prefix(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_INT2: - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - case PG_TYPE_INT8: - case PG_TYPE_NUMERIC: - case PG_TYPE_FLOAT4: - case PG_TYPE_FLOAT8: - case PG_TYPE_MONEY: - return NULL; - - default: - return "'"; - } -} - - -char * -pgtype_literal_suffix(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_INT2: - case PG_TYPE_OID: - case PG_TYPE_XID: - case PG_TYPE_INT4: - case PG_TYPE_INT8: - case PG_TYPE_NUMERIC: - case PG_TYPE_FLOAT4: - case PG_TYPE_FLOAT8: - case PG_TYPE_MONEY: - return NULL; - - default: - return "'"; - } -} - - -char * -pgtype_create_params(StatementClass *stmt, Int4 type) -{ - switch (type) - { - case PG_TYPE_BPCHAR: - case PG_TYPE_VARCHAR: - return "max. length"; - default: - return NULL; - } -} - - -Int2 -sqltype_to_default_ctype(Int2 sqltype) -{ - /* - * from the table on page 623 of ODBC 2.0 Programmer's Reference - * (Appendix D) - */ - switch (sqltype) - { - case SQL_CHAR: - case SQL_VARCHAR: - case SQL_LONGVARCHAR: - case SQL_DECIMAL: - case SQL_NUMERIC: -#if (ODBCVER < 0x0300) - case SQL_BIGINT: - return SQL_C_CHAR; -#else - return SQL_C_CHAR; - case SQL_BIGINT: - return ALLOWED_C_BIGINT; -#endif - -#ifdef UNICODE_SUPPORT - case SQL_WCHAR: - case SQL_WVARCHAR: - case SQL_WLONGVARCHAR: - return SQL_C_WCHAR; -#endif /* UNICODE_SUPPORT */ - - case SQL_BIT: - return SQL_C_BIT; - - case SQL_TINYINT: - return SQL_C_STINYINT; - - case SQL_SMALLINT: - return SQL_C_SSHORT; - - case SQL_INTEGER: - return SQL_C_SLONG; - - case SQL_REAL: - return SQL_C_FLOAT; - - case SQL_FLOAT: - case SQL_DOUBLE: - return SQL_C_DOUBLE; - - case SQL_BINARY: - case SQL_VARBINARY: - case SQL_LONGVARBINARY: - return SQL_C_BINARY; - - case SQL_DATE: - return SQL_C_DATE; - - case SQL_TIME: - return SQL_C_TIME; - - case SQL_TIMESTAMP: - return SQL_C_TIMESTAMP; - -#if (ODBCVER >= 0x0300) - case SQL_TYPE_DATE: - return SQL_C_TYPE_DATE; - - case SQL_TYPE_TIME: - return SQL_C_TYPE_TIME; - - case SQL_TYPE_TIMESTAMP: - return SQL_C_TYPE_TIMESTAMP; -#endif /* ODBCVER */ - - default: - /* should never happen */ - return SQL_C_CHAR; - } -} - -Int4 -ctype_length(Int2 ctype) -{ - switch (ctype) - { - case SQL_C_SSHORT: - case SQL_C_SHORT: - return sizeof(SWORD); - - case SQL_C_USHORT: - return sizeof(UWORD); - - case SQL_C_SLONG: - case SQL_C_LONG: - return sizeof(SDWORD); - - case SQL_C_ULONG: - return sizeof(UDWORD); - - case SQL_C_FLOAT: - return sizeof(SFLOAT); - - case SQL_C_DOUBLE: - return sizeof(SDOUBLE); - - case SQL_C_BIT: - return sizeof(UCHAR); - - case SQL_C_STINYINT: - case SQL_C_TINYINT: - return sizeof(SCHAR); - - case SQL_C_UTINYINT: - return sizeof(UCHAR); - - case SQL_C_DATE: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_DATE: -#endif /* ODBCVER */ - return sizeof(DATE_STRUCT); - - case SQL_C_TIME: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_TIME: -#endif /* ODBCVER */ - return sizeof(TIME_STRUCT); - - case SQL_C_TIMESTAMP: -#if (ODBCVER >= 0x0300) - case SQL_C_TYPE_TIMESTAMP: -#endif /* ODBCVER */ - return sizeof(TIMESTAMP_STRUCT); - - case SQL_C_BINARY: - case SQL_C_CHAR: -#ifdef UNICODE_SUPPORT - case SQL_C_WCHAR: -#endif /* UNICODE_SUPPORT */ - return 0; - - default: /* should never happen */ - return 0; - } -} diff --git a/src/interfaces/odbc/pgtypes.h b/src/interfaces/odbc/pgtypes.h deleted file mode 100644 index cef2362ddf..0000000000 --- a/src/interfaces/odbc/pgtypes.h +++ /dev/null @@ -1,106 +0,0 @@ -/* File: pgtypes.h - * - * Description: See "pgtypes.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __PGTYPES_H__ -#define __PGTYPES_H__ - -#include "psqlodbc.h" - -/* the type numbers are defined by the OID's of the types' rows */ -/* in table pg_type */ - - -#if 0 -#define PG_TYPE_LO ???? /* waiting for permanent type */ -#endif - -#define PG_TYPE_BOOL 16 -#define PG_TYPE_BYTEA 17 -#define PG_TYPE_CHAR 18 -#define PG_TYPE_NAME 19 -#define PG_TYPE_INT8 20 -#define PG_TYPE_INT2 21 -#define PG_TYPE_INT2VECTOR 22 -#define PG_TYPE_INT4 23 -#define PG_TYPE_REGPROC 24 -#define PG_TYPE_TEXT 25 -#define PG_TYPE_OID 26 -#define PG_TYPE_TID 27 -#define PG_TYPE_XID 28 -#define PG_TYPE_CID 29 -#define PG_TYPE_OIDVECTOR 30 -#define PG_TYPE_SET 32 -#define PG_TYPE_CHAR2 409 -#define PG_TYPE_CHAR4 410 -#define PG_TYPE_CHAR8 411 -#define PG_TYPE_POINT 600 -#define PG_TYPE_LSEG 601 -#define PG_TYPE_PATH 602 -#define PG_TYPE_BOX 603 -#define PG_TYPE_POLYGON 604 -#define PG_TYPE_FILENAME 605 -#define PG_TYPE_FLOAT4 700 -#define PG_TYPE_FLOAT8 701 -#define PG_TYPE_ABSTIME 702 -#define PG_TYPE_RELTIME 703 -#define PG_TYPE_TINTERVAL 704 -#define PG_TYPE_UNKNOWN 705 -#define PG_TYPE_MONEY 790 -#define PG_TYPE_OIDINT2 810 -#define PG_TYPE_OIDINT4 910 -#define PG_TYPE_OIDNAME 911 -#define PG_TYPE_BPCHAR 1042 -#define PG_TYPE_VARCHAR 1043 -#define PG_TYPE_DATE 1082 -#define PG_TYPE_TIME 1083 -#define PG_TYPE_TIMESTAMP_NO_TMZONE 1114 /* since 7.2 */ -#define PG_TYPE_DATETIME 1184 -#define PG_TYPE_TIME_WITH_TMZONE 1266 /* since 7.1 */ -#define PG_TYPE_TIMESTAMP 1296 /* deprecated since 7.0 */ -#define PG_TYPE_NUMERIC 1700 - -/* extern Int4 pgtypes_defined[]; */ -extern Int2 sqlTypes[]; - -/* Defines for pgtype_precision */ -#define PG_STATIC (-1) - -Int4 sqltype_to_pgtype(StatementClass *stmt, Int2 fSqlType); - -Int2 pgtype_to_concise_type(StatementClass *stmt, Int4 type); -Int2 pgtype_to_sqldesctype(StatementClass *stmt, Int4 type); -Int2 pgtype_to_datetime_sub(StatementClass *stmt, Int4 type); -Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type); -char *pgtype_to_name(StatementClass *stmt, Int4 type); - -/* These functions can use static numbers or result sets(col parameter) */ -Int4 pgtype_column_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); /* corresponds to "precision" in ODBC 2.x */ -Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); /* "precsion in ODBC 3.x */ -Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); -Int4 pgtype_buffer_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); -Int4 pgtype_desclength(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); -Int4 pgtype_transfer_octet_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); - -Int2 pgtype_decimal_digits(StatementClass *stmt, Int4 type, int col); /* corresponds to "scale" in ODBC 2.x */ -Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col); /* ODBC 3.x " */ -Int2 pgtype_radix(StatementClass *stmt, Int4 type); -Int2 pgtype_nullable(StatementClass *stmt, Int4 type); -Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type); -Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type); -Int2 pgtype_money(StatementClass *stmt, Int4 type); -Int2 pgtype_searchable(StatementClass *stmt, Int4 type); -Int2 pgtype_unsigned(StatementClass *stmt, Int4 type); -char *pgtype_literal_prefix(StatementClass *stmt, Int4 type); -char *pgtype_literal_suffix(StatementClass *stmt, Int4 type); -char *pgtype_create_params(StatementClass *stmt, Int4 type); - -Int2 sqltype_to_default_ctype(Int2 sqltype); -Int4 ctype_length(Int2 ctype); - -#define USE_ZONE FALSE -#endif diff --git a/src/interfaces/odbc/psqlodbc.c b/src/interfaces/odbc/psqlodbc.c deleted file mode 100644 index cc8d8b7bfb..0000000000 --- a/src/interfaces/odbc/psqlodbc.c +++ /dev/null @@ -1,132 +0,0 @@ -/*-------- - * Module: psqlodbc.c - * - * Description: This module contains the main entry point (DllMain) - * for the library. It also contains functions to get - * and set global variables for the driver in the registry. - * - * Classes: n/a - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ - -#include "psqlodbc.h" -#include "dlg_specific.h" - -#ifdef WIN32 -#include -#endif - -GLOBAL_VALUES globals; - -RETCODE SQL_API SQLDummyOrdinal(void); - -#ifdef WIN32 -HINSTANCE NEAR s_hModule; /* Saved module handle. */ - -/* This is where the Driver Manager attaches to this Driver */ -BOOL WINAPI -DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) -{ - WORD wVersionRequested; - WSADATA wsaData; - - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - s_hModule = hInst; /* Save for dialog boxes */ - - /* Load the WinSock Library */ - wVersionRequested = MAKEWORD(1, 1); - - if (WSAStartup(wVersionRequested, &wsaData)) - return FALSE; - - /* Verify that this is the minimum version of WinSock */ - if (LOBYTE(wsaData.wVersion) != 1 || - HIBYTE(wsaData.wVersion) != 1) - { - WSACleanup(); - return FALSE; - } - - getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL); - break; - - case DLL_THREAD_ATTACH: - break; - - case DLL_PROCESS_DETACH: - WSACleanup(); - return TRUE; - - case DLL_THREAD_DETACH: - break; - - default: - break; - } - - return TRUE; - - UNREFERENCED_PARAMETER(lpReserved); -} - -#else /* not WIN32 */ - -#ifndef TRUE -#define TRUE (BOOL)1 -#endif -#ifndef FALSE -#define FALSE (BOOL)0 -#endif - -#ifdef __GNUC__ - -/* This function is called at library initialization time. */ - -static BOOL -__attribute__((constructor)) -init(void) -{ - getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL); - return TRUE; -} - -#else /* not __GNUC__ */ - -/* - * These two functions do shared library initialziation on UNIX, well at least - * on Linux. I don't know about other systems. - */ -BOOL -_init(void) -{ - getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL); - return TRUE; -} - -BOOL -_fini(void) -{ - return TRUE; -} -#endif /* not __GNUC__ */ -#endif /* not WIN32 */ - - -/* - * This function is used to cause the Driver Manager to - * call functions by number rather than name, which is faster. - * The ordinal value of this function must be 199 to have the - * Driver Manager do this. Also, the ordinal values of the - * functions must match the value of fFunction in SQLGetFunctions() - */ -RETCODE SQL_API -SQLDummyOrdinal(void) -{ - return SQL_SUCCESS; -} diff --git a/src/interfaces/odbc/psqlodbc.h b/src/interfaces/odbc/psqlodbc.h deleted file mode 100644 index fae864bd4d..0000000000 --- a/src/interfaces/odbc/psqlodbc.h +++ /dev/null @@ -1,279 +0,0 @@ -/* File: psqlodbc.h - * - * Description: This file contains defines and declarations that are related to - * the entire driver. - * - * Comments: See "notice.txt" for copyright and license information. - * - * $Id: psqlodbc.h,v 1.69 2002/07/11 01:52:46 inoue Exp $ - * - */ - -#ifndef __PSQLODBC_H__ -#define __PSQLODBC_H__ - -#ifndef WIN32 -#include "pg_config.h" -#else -#include -#endif - -#include /* for FILE* pointers: see GLOBAL_VALUES */ - -#include "version.h" - -/* Must come before sql.h */ -#ifndef ODBCVER -#define ODBCVER 0x0250 -#endif /* ODBCVER_REP */ - -#ifndef NAMEDATALEN -#define NAMEDATALEN 32 -#endif /* NAMEDATALEN */ - - -#if defined(WIN32) || defined(WITH_UNIXODBC) || defined(WITH_IODBC) -#include -#include -#else -#include "iodbc.h" -#include "isql.h" -#include "isqlext.h" -#endif - -#if defined(WIN32) -#include -#elif defined(WITH_UNIXODBC) -#include -#elif defined(WITH_IODBC) -#include -#else -#include "gpps.h" -#endif - -#ifndef WIN32 -#define Int4 long int -#define UInt4 unsigned int -#define Int2 short -#define UInt2 unsigned short - -#if !defined(WITH_UNIXODBC) && !defined(WITH_IODBC) -typedef float SFLOAT; -typedef double SDOUBLE; -#endif - -#ifndef CALLBACK -#define CALLBACK -#endif - -#else -#define Int4 int -#define UInt4 unsigned int -#define Int2 short -#define UInt2 unsigned short -#endif - -typedef UInt4 Oid; - -#ifndef WIN32 -#define stricmp strcasecmp -#define strnicmp strncasecmp -#else -#define snprintf _snprintf -#endif - -/* Driver stuff */ - -#define DRIVERNAME "PostgreSQL ODBC" -#if (ODBCVER >= 0x0300) -#define DRIVER_ODBC_VER "03.00" -#define DBMS_NAME "PostgreSQL30" -#else -#define DRIVER_ODBC_VER "02.50" -#define DBMS_NAME "PostgreSQL" -#endif /* ODBCVER */ - -#ifdef WIN32 -#if (ODBCVER >= 0x0300) -#ifdef UNICODE_SUPPORT -#define DRIVER_FILE_NAME "PSQLODBC30W.DLL" -#else -#define DRIVER_FILE_NAME "PSQLODBC30.DLL" -#endif /* UNICODE_SUPPORT */ -#else -#define DRIVER_FILE_NAME "PSQLODBC.DLL" -#endif /* ODBCVER */ -#else -#define DRIVER_FILE_NAME "libpsqlodbc.so" -#endif /* WIN32 */ - -/* Limits */ -#ifdef WIN32 -#define BLCKSZ 4096 -#endif - -#define MAX_MESSAGE_LEN 65536 /* This puts a limit on - * query size but I don't */ - /* see an easy way round this - DJP 24-1-2001 */ -#define MAX_CONNECT_STRING 4096 -#define ERROR_MSG_LENGTH 4096 -#define FETCH_MAX 100 /* default number of rows to cache - * for declare/fetch */ -#define TUPLE_MALLOC_INC 100 -#define SOCK_BUFFER_SIZE 4096 /* default socket buffer - * size */ -#define MAX_CONNECTIONS 128 /* conns per environment - * (arbitrary) */ -#define MAX_FIELDS 512 -#define BYTELEN 8 -#define VARHDRSZ sizeof(Int4) - -#define MAX_SCHEMA_LEN NAMEDATALEN -#define MAX_TABLE_LEN NAMEDATALEN -#define MAX_COLUMN_LEN NAMEDATALEN -#define MAX_CURSOR_LEN 32 - -/* Registry length limits */ -#define LARGE_REGISTRY_LEN 4096 /* used for special cases */ -#define MEDIUM_REGISTRY_LEN 256 /* normal size for - * user,database,etc. */ -#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */ - - -/* These prefixes denote system tables */ -#define POSTGRES_SYS_PREFIX "pg_" -#define KEYS_TABLE "dd_fkey" - -/* Info limits */ -#define MAX_INFO_STRING 128 -#define MAX_KEYPARTS 20 -#define MAX_KEYLEN 512 /* max key of the form - * "date+outlet+invoice" */ -#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the - * Tuple Toaster */ -#define MAX_STATEMENT_LEN 0 /* Unlimited statement size with - * 7.0 */ - -/* Previously, numerous query strings were defined of length MAX_STATEMENT_LEN */ -/* Now that's 0, lets use this instead. DJP 24-1-2001 */ -#define STD_STATEMENT_LEN MAX_MESSAGE_LEN - -#define PG62 "6.2" /* "Protocol" key setting - * to force Postgres 6.2 */ -#define PG63 "6.3" /* "Protocol" key setting - * to force postgres 6.3 */ -#define PG64 "6.4" - -typedef struct ConnectionClass_ ConnectionClass; -typedef struct StatementClass_ StatementClass; -typedef struct QResultClass_ QResultClass; -typedef struct SocketClass_ SocketClass; -typedef struct BindInfoClass_ BindInfoClass; -typedef struct ParameterInfoClass_ ParameterInfoClass; -typedef struct ColumnInfoClass_ ColumnInfoClass; -typedef struct TupleListClass_ TupleListClass; -typedef struct EnvironmentClass_ EnvironmentClass; -typedef struct TupleNode_ TupleNode; -typedef struct TupleField_ TupleField; -typedef struct KeySet_ KeySet; -typedef struct Rollback_ Rollback; -typedef struct ARDFields_ ARDFields; -typedef struct APDFields_ APDFields; -typedef struct IRDFields_ IRDFields; -typedef struct IPDFields_ IPDFields; - -typedef struct col_info COL_INFO; -typedef struct lo_arg LO_ARG; - -typedef struct GlobalValues_ -{ - int fetch_max; - int socket_buffersize; - int unknown_sizes; - int max_varchar_size; - int max_longvarchar_size; - char debug; - char commlog; - char disable_optimizer; - char ksqo; - char unique_index; - char onlyread; /* readonly is reserved on Digital C++ - * compiler */ - char use_declarefetch; - char text_as_longvarchar; - char unknowns_as_longvarchar; - char bools_as_char; - char lie; - char parse; - char cancel_as_freestmt; - char extra_systable_prefixes[MEDIUM_REGISTRY_LEN]; - char conn_settings[LARGE_REGISTRY_LEN]; - char protocol[SMALL_REGISTRY_LEN]; -} GLOBAL_VALUES; - -typedef struct StatementOptions_ -{ - int maxRows; - int maxLength; - int keyset_size; - int cursor_type; - int scroll_concurrency; - int retrieve_data; - int use_bookmarks; - void *bookmark_ptr; -} StatementOptions; - -/* Used to pass extra query info to send_query */ -typedef struct QueryInfo_ -{ - int row_size; - QResultClass *result_in; - char *cursor; -} QueryInfo; - -void logs_on_off(int cnopen, int, int); - -#define PG_TYPE_LO (-999) /* hack until permanent - * type available */ -#define PG_TYPE_LO_NAME "lo" -#define OID_ATTNUM (-2) /* the attnum in pg_index - * of the oid */ - -/* sizes */ -#define TEXT_FIELD_SIZE 8190 /* size of text fields - * (not including null - * term) */ -#define NAME_FIELD_SIZE NAMEDATALEN /* size of name fields */ -#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not - * including null term) */ - -#define PG_NUMERIC_MAX_PRECISION 1000 -#define PG_NUMERIC_MAX_SCALE 1000 - -#define INFO_INQUIRY_LEN 8192 /* this seems sufficiently big for - * queries used in info.c inoue - * 2001/05/17 */ - -#include "misc.h" - -#ifdef UNICODE_SUPPORT -UInt4 ucs2strlen(const SQLWCHAR *ucs2str); -char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen); -UInt4 utf8_to_ucs2_lf(const char * utf8str, Int4 ilen, BOOL lfconv, SQLWCHAR *ucs2str, UInt4 buflen); -#define utf8_to_ucs2(utf8str, ilen, ucs2str, buflen) utf8_to_ucs2_lf(utf8str, ilen, FALSE, ucs2str, buflen) -#endif /* UNICODE_SUPPORT */ -/*#define _MEMORY_DEBUG_ */ -#ifdef _MEMORY_DEBUG_ -void *debug_alloc(size_t); -void *debug_realloc(void *, size_t); -char *debug_strdup(const char *); -void debug_free(void *); -void debug_memory_check(void); - -#define malloc debug_alloc -#define realloc debug_realloc -#define strdup debug_strdup -#define free debug_free -#endif /* _MEMORY_DEBUG_ */ - -#endif diff --git a/src/interfaces/odbc/psqlodbc.rc b/src/interfaces/odbc/psqlodbc.rc deleted file mode 100644 index 11f63fe9db..0000000000 --- a/src/interfaces/odbc/psqlodbc.rc +++ /dev/null @@ -1,321 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" -#include "version.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// ‰pŒê (±Òض) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "#include ""version.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -DLG_CONFIG DIALOG DISCARDABLE 65, 43, 292, 116 -STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -CAPTION "PostgreSQL ODBC Driver (psqlODBC) Setup" -FONT 10, "Terminal" -BEGIN - RTEXT "&Data Source",IDC_DSNAMETEXT,5,11,50,12,NOT WS_GROUP - EDITTEXT IDC_DSNAME,57,10,72,12,ES_AUTOHSCROLL | WS_GROUP - RTEXT "Des&cription",IDC_DESCTEXT,129,10,45,12,NOT WS_GROUP - EDITTEXT IDC_DESC,176,10,107,12,ES_AUTOHSCROLL - RTEXT "Data&base",IDC_STATIC,16,26,38,12,NOT WS_GROUP - EDITTEXT IDC_DATABASE,57,25,72,12,ES_AUTOHSCROLL - RTEXT "&Server",IDC_STATIC,26,41,29,12,NOT WS_GROUP - EDITTEXT IDC_SERVER,57,40,72,12,ES_AUTOHSCROLL - RTEXT "&Port",IDC_STATIC,151,41,22,12 - EDITTEXT IDC_PORT,175,40,37,12,ES_AUTOHSCROLL - RTEXT "&User Name",IDC_STATIC,16,56,39,12 - EDITTEXT IDC_USER,57,55,72,12,ES_AUTOHSCROLL - RTEXT "Pass&word",IDC_STATIC,139,57,34,9 - EDITTEXT IDC_PASSWORD,175,55,72,12,ES_PASSWORD | ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,25,87,40,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,80,87,40,14 - GROUPBOX "Options",IDC_OPTIONS,140,74,140,35,BS_LEFT - PUSHBUTTON "Datasource",IDC_DATASOURCE,159,87,50,14 - PUSHBUTTON "Global",IDC_DRIVER,220,87,50,14 - CTEXT "Please supply any missing information required to connect.", - DRV_MSG_LABEL,36,2,220,10 -END - -DLG_OPTIONS_DRV DIALOG DISCARDABLE 0, 0, 287, 231 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced Options (DataSource)" -FONT 10, "Terminal" -BEGIN - PUSHBUTTON "Page 1",IDPREVPAGE,5,5,40,15 - PUSHBUTTON "Page 2",IDNEXTPAGE,49,5,40,15 - CONTROL "Disable Genetic &Optimizer",DRV_OPTIMIZER,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,26,116,10 - CONTROL "Comm&Log (C:\\psqlodbc_xxxx.log)",DRV_COMMLOG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,149,26,131,10 - CONTROL "&KSQO(Keyset Query Optimization)",DRV_KSQO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,41,132,10 - CONTROL "Recognize Unique &Indexes",DRV_UNIQUEINDEX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,56,110,10 - CONTROL "P&arse Statements",DRV_PARSE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,149,41,80,10 - CONTROL "&Use Declare/Fetch",DRV_USEDECLAREFETCH,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,71,83,10 - CONTROL "Cancel as FreeStmt (Exp)",DRV_CANCELASFREESTMT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,149,56,114,10 - CONTROL "MyLog (C:\\mylog_xxxx.log)",DRV_DEBUG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,149,71,112,10 - GROUPBOX "Unknown Sizes",IDC_STATIC,5,85,277,25 - CONTROL "Maximum",DRV_UNKNOWN_MAX,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,15,96,45,10 - CONTROL "Don't Know",DRV_UNKNOWN_DONTKNOW,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,105,96,53,10 - CONTROL "Longest",DRV_UNKNOWN_LONGEST,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,215,95,50,10 - GROUPBOX "Data Type Options",IDC_STATIC,5,115,277,25 - CONTROL "Text as LongVarChar",DRV_TEXT_LONGVARCHAR,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,125,90,10 - CONTROL "Unknowns as LongVarChar",DRV_UNKNOWNS_LONGVARCHAR, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,125,105,10 - CONTROL "Bools as Char",DRV_BOOLS_CHAR,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,215,125,67,10 - LTEXT "&Cache Size:",IDC_STATIC,14,183,52,8 - EDITTEXT DRV_CACHE_SIZE,69,181,35,12,ES_AUTOHSCROLL - LTEXT "Max &Varchar:",IDC_STATIC,13,161,54,8 - EDITTEXT DRV_VARCHAR_SIZE,70,160,35,12,ES_AUTOHSCROLL - LTEXT "Max Lon&gVarChar:",IDC_STATIC,125,161,67,8 - EDITTEXT DRV_LONGVARCHAR_SIZE,199,160,35,12,ES_AUTOHSCROLL - LTEXT "SysTable &Prefixes:",IDC_STATIC,125,183,61,18 - EDITTEXT DRV_EXTRASYSTABLEPREFIXES,199,181,71,12,ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,5,212,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,81,211,50,15 - PUSHBUTTON "Apply",IDAPPLY,156,212,50,14 - PUSHBUTTON "Defaults",IDDEFAULTS,232,211,50,15 - GROUPBOX "Miscellanous",IDC_STATIC,5,145,277,58 -END - -DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 287, 231 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Advanced Options (DataSource)" -FONT 10, "Terminal" -BEGIN - PUSHBUTTON "Page 2",IDNEXTPAGE,49,5,40,15 - PUSHBUTTON "Page 1",IDPREVPAGE,5,5,40,15 - CONTROL "&Read Only",DS_READONLY,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,15,26,102,10 - CONTROL "Row &Versioning",DS_ROWVERSIONING,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,149,26,85,10 - CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,41,100,10 - CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,149,41,85,10 - CONTROL "LF <-> CR/LF conversion",DS_LFCONVERSION,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,56,106,10 - CONTROL "True is -1",DS_TRUEISMINUS1,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,149,56,86,10 - CONTROL "Updatable Cursors",DS_UPDATABLECURSORS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,71,87,10 - GROUPBOX "Int8 As",IDC_STATIC,5,85,277,25 - CONTROL "default",DS_INT8_AS_DEFAULT,"Button",BS_AUTORADIOBUTTON | - WS_GROUP,12,95,40,10 - CONTROL "bigint",DS_INT8_AS_BIGINT,"Button",BS_AUTORADIOBUTTON | - WS_TABSTOP,55,95,35,10 - CONTROL "numeric",DS_INT8_AS_NUMERIC,"Button",BS_AUTORADIOBUTTON | - WS_TABSTOP,98,95,40,10 - CONTROL "varchar",DS_INT8_AS_VARCHAR,"Button",BS_AUTORADIOBUTTON | - WS_TABSTOP,141,95,40,10 - CONTROL "double",DS_INT8_AS_DOUBLE,"Button",BS_AUTORADIOBUTTON | - WS_TABSTOP,184,95,40,10 - CONTROL "int4",DS_INT8_AS_INT4,"Button",BS_AUTORADIOBUTTON | - WS_TABSTOP,227,95,29,10 - GROUPBOX "Protocol",IDC_STATIC,5,115,277,25 - CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | - WS_GROUP,44,126,49,10 - CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, - 117,126,26,10 - CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, - 191,126,26,10 - GROUPBOX "OID Options",IDC_STATIC,5,145,277,25 - CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,53,157,59,10 - CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,155,156,51,10 - LTEXT "Connect &Settings:",IDC_STATIC,5,182,62,17 - EDITTEXT DS_CONNSETTINGS,71,178,211,27,ES_MULTILINE | - ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN - DEFPUSHBUTTON "OK",IDOK,5,212,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,81,212,50,14 - PUSHBUTTON "Apply",IDAPPLY,156,212,50,14 -END - -DLG_OPTIONS_GLOBAL DIALOG DISCARDABLE 0, 0, 306, 87 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Global settings" -FONT 10, "Terminal" -BEGIN - CONTROL "Comm&Log (C:\\psqlodbc_xxxx.log - Communications log)", - DRV_COMMLOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,24, - 263,10 - CONTROL "Mylog (C:\\mylog_xxxx.log - Detailed debug output)", - DRV_DEBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,42, - 264,10 - DEFPUSHBUTTON "OK",IDOK,82,68,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,172,67,50,15 - GROUPBOX "Pre-connection/default logging options",IDC_STATIC,5,5, - 296,58 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - DLG_CONFIG, DIALOG - BEGIN - BOTTOMMARGIN, 115 - END - - DLG_OPTIONS_DRV, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 282 - TOPMARGIN, 5 - BOTTOMMARGIN, 226 - END - - DLG_OPTIONS_DS, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 282 - TOPMARGIN, 5 - BOTTOMMARGIN, 226 - END - - DLG_OPTIONS_GLOBAL, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 301 - TOPMARGIN, 5 - BOTTOMMARGIN, 82 - END -END -#endif // APSTUDIO_INVOKED - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION PG_DRVFILE_VERSION - PRODUCTVERSION PG_DRVFILE_VERSION - FILEFLAGSMASK 0x3L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "Comments", "PostgreSQL ODBC driver\0" - VALUE "CompanyName", "Insight Distribution Systems\0" - VALUE "FileDescription", "PostgreSQL Driver\0" - VALUE "FileVersion", POSTGRES_RESOURCE_VERSION - VALUE "InternalName", "psqlodbc\0" - VALUE "LegalCopyright", "\0" - VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0" - VALUE "OriginalFilename", "psqlodbc.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Microsoft Open Database Connectivity\0" - VALUE "ProductVersion", POSTGRES_RESOURCE_VERSION - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - IDS_BADDSN "Invalid DSN entry, please recheck." - IDS_MSGTITLE "Invalid DSN" -END - -#endif // ‰pŒê (±Òض) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/interfaces/odbc/psqlodbc.reg b/src/interfaces/odbc/psqlodbc.reg deleted file mode 100644 index 71155f50a1..0000000000 --- a/src/interfaces/odbc/psqlodbc.reg +++ /dev/null @@ -1,16 +0,0 @@ -REGEDIT4 - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI] - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] -"PostgreSQL"="Installed" - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL] -"APILevel"="1" -"ConnectFunctions"="YYN" -"Driver"="PSQLODBC.DLL" -"DriverODBCVer"="02.50" -"FileUsage"="0" -"Setup"="PSQLODBC.DLL" -"SQLLevel"="1" -"UsageCount"=dword:00000001 diff --git a/src/interfaces/odbc/psqlodbc30.reg b/src/interfaces/odbc/psqlodbc30.reg deleted file mode 100644 index 79a63effff..0000000000 --- a/src/interfaces/odbc/psqlodbc30.reg +++ /dev/null @@ -1,16 +0,0 @@ -REGEDIT4 - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI] - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] -"PostgreSQL+ (Beta)"="Installed" - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL+ (Beta)] -"APILevel"="1" -"ConnectFunctions"="YYN" -"Driver"="PSQLODBC30.DLL" -"DriverODBCVer"="03.00" -"FileUsage"="0" -"Setup"="PSQLODBC30.DLL" -"SQLLevel"="1" -"UsageCount"=dword:00000001 diff --git a/src/interfaces/odbc/psqlodbc30w.reg b/src/interfaces/odbc/psqlodbc30w.reg deleted file mode 100644 index ffeac51418..0000000000 --- a/src/interfaces/odbc/psqlodbc30w.reg +++ /dev/null @@ -1,16 +0,0 @@ -REGEDIT4 - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI] - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] -"PostgreSQL+ Unicode (Beta)"="Installed" - -[HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL+ Unicode (Beta)] -"APILevel"="1" -"ConnectFunctions"="YYN" -"Driver"="PSQLODBC30W.DLL" -"DriverODBCVer"="03.00" -"FileUsage"="0" -"Setup"="PSQLODBC30W.DLL" -"SQLLevel"="1" -"UsageCount"=dword:00000001 diff --git a/src/interfaces/odbc/psqlodbc_api30.def b/src/interfaces/odbc/psqlodbc_api30.def deleted file mode 100755 index ddc78062e6..0000000000 --- a/src/interfaces/odbc/psqlodbc_api30.def +++ /dev/null @@ -1,82 +0,0 @@ -LIBRARY psqlodbc30 -EXPORTS -SQLAllocConnect @1 -SQLAllocEnv @2 -SQLAllocStmt @3 -SQLBindCol @4 -SQLCancel @5 -; SQLColAttributes @6 */ -SQLConnect @7 -SQLDescribeCol @8 -SQLDisconnect @9 -SQLError @10 -SQLExecDirect @11 -SQLExecute @12 -SQLFetch @13 -SQLFreeConnect @14 -SQLFreeEnv @15 -SQLFreeStmt @16 -SQLGetCursorName @17 -SQLNumResultCols @18 -SQLPrepare @19 -SQLRowCount @20 -SQLSetCursorName @21 -SQLTransact @23 -SQLColumns @40 -SQLDriverConnect @41 -SQLGetConnectOption @42 -SQLGetData @43 -SQLGetFunctions @44 -SQLGetInfo @45 -SQLGetStmtOption @46 -SQLGetTypeInfo @47 -SQLParamData @48 -SQLPutData @49 -SQLSetConnectOption @50 -SQLSetStmtOption @51 -SQLSpecialColumns @52 -SQLStatistics @53 -SQLTables @54 -SQLBrowseConnect @55 -SQLColumnPrivileges @56 -SQLDescribeParam @58 -SQLExtendedFetch @59 -SQLForeignKeys @60 -SQLMoreResults @61 -SQLNativeSql @62 -SQLNumParams @63 -SQLParamOptions @64 -SQLPrimaryKeys @65 -SQLProcedureColumns @66 -SQLProcedures @67 -SQLSetPos @68 -SQLSetScrollOptions @69 -SQLTablePrivileges @70 -SQLBindParameter @72 - -SQLAllocHandle @80 -SQLBindParam @81 -SQLCloseCursor @82 -SQLColAttribute @83 -SQLCopyDesc @84 -SQLEndTran @85 -SQLFetchScroll @86 -SQLFreeHandle @87 -SQLGetDescField @88 -SQLGetDescRec @89 -SQLGetDiagField @90 -SQLGetDiagRec @91 -SQLGetEnvAttr @92 -SQLGetConnectAttr @93 -SQLGetStmtAttr @94 -SQLSetConnectAttr @95 -SQLSetDescField @96 -SQLSetDescRec @97 -SQLSetEnvAttr @98 -SQLSetStmtAttr @99 -SQLBulkOperations @100 - -SQLDummyOrdinal @199 -dconn_FDriverConnectProc @200 -DllMain @201 -ConfigDSN @202 diff --git a/src/interfaces/odbc/psqlodbc_api30w.def b/src/interfaces/odbc/psqlodbc_api30w.def deleted file mode 100644 index 86dedae64c..0000000000 --- a/src/interfaces/odbc/psqlodbc_api30w.def +++ /dev/null @@ -1,107 +0,0 @@ -LIBRARY psqlodbc30w -EXPORTS -SQLAllocConnect @1 -SQLAllocEnv @2 -SQLAllocStmt @3 -SQLBindCol @4 -SQLCancel @5 -; SQLColAttributes @6 -SQLConnect @7 -SQLDescribeCol @8 -SQLDisconnect @9 -SQLError @10 -SQLExecDirect @11 -SQLExecute @12 -SQLFetch @13 -SQLFreeConnect @14 -SQLFreeEnv @15 -SQLFreeStmt @16 -SQLGetCursorName @17 -SQLNumResultCols @18 -SQLPrepare @19 -SQLRowCount @20 -SQLSetCursorName @21 -SQLTransact @23 -SQLColumns @40 -SQLDriverConnect @41 -SQLGetData @43 -SQLGetFunctions @44 -SQLGetInfo @45 -SQLGetStmtOption @46 -SQLGetTypeInfo @47 -SQLParamData @48 -SQLPutData @49 -SQLSpecialColumns @52 -SQLStatistics @53 -SQLTables @54 -SQLBrowseConnect @55 -SQLColumnPrivileges @56 -SQLDescribeParam @58 -SQLExtendedFetch @59 -SQLForeignKeys @60 -SQLMoreResults @61 -SQLNativeSql @62 -SQLNumParams @63 -SQLParamOptions @64 -SQLPrimaryKeys @65 -SQLProcedureColumns @66 -SQLProcedures @67 -SQLSetPos @68 -SQLSetScrollOptions @69 -SQLTablePrivileges @70 -SQLBindParameter @72 - -SQLAllocHandle @80 -SQLBindParam @81 -SQLCloseCursor @82 -SQLColAttribute @83 -SQLCopyDesc @84 -SQLEndTran @85 -SQLFetchScroll @86 -SQLFreeHandle @87 -SQLGetDescField @88 -SQLGetDescRec @89 -SQLGetDiagField @90 -SQLGetDiagRec @91 -SQLGetEnvAttr @92 -SQLGetConnectAttr @93 -SQLGetStmtAttr @94 -SQLSetConnectAttr @95 -SQLSetDescField @96 -SQLSetDescRec @97 -SQLSetEnvAttr @98 -SQLSetStmtAttr @99 -SQLBulkOperations @100 - -SQLDummyOrdinal @199 -dconn_FDriverConnectProc @200 -DllMain @201 -ConfigDSN @202 - -SQLColAttributeW @101 -SQLColumnPrivilegesW @102 -SQLColumnsW @103 -SQLConnectW @104 -SQLDescribeColW @106 -SQLExecDirectW @107 -SQLForeignKeysW @108 -SQLGetConnectAttrW @109 -SQLGetCursorNameW @110 -SQLGetInfoW @111 -SQLNativeSqlW @112 -SQLPrepareW @113 -SQLPrimaryKeysW @114 -SQLProcedureColumnsW @115 -SQLProceduresW @116 -SQLSetConnectAttrW @117 -SQLSetCursorNameW @118 -SQLSpecialColumnsW @119 -SQLStatisticsW @120 -SQLTablesW @121 -SQLTablePrivilegesW @122 -SQLDriverConnectW @123 -SQLGetDiagRecW @124 -SQLGetStmtAttrW @125 -SQLSetStmtAttrW @126 -SQLSetDescFieldW @127 -SQLGetTypeInfoW @128 diff --git a/src/interfaces/odbc/psqlodbc_apiw.def b/src/interfaces/odbc/psqlodbc_apiw.def deleted file mode 100644 index c719a20e3b..0000000000 --- a/src/interfaces/odbc/psqlodbc_apiw.def +++ /dev/null @@ -1,84 +0,0 @@ -LIBRARY psqlodbc -EXPORTS -SQLAllocConnect @1 -SQLAllocEnv @2 -SQLAllocStmt @3 -SQLBindCol @4 -SQLCancel @5 -SQLColAttributes @6 -SQLConnect @7 -SQLDescribeCol @8 -SQLDisconnect @9 -SQLError @10 -SQLExecDirect @11 -SQLExecute @12 -SQLFetch @13 -SQLFreeConnect @14 -SQLFreeEnv @15 -SQLFreeStmt @16 -SQLGetCursorName @17 -SQLNumResultCols @18 -SQLPrepare @19 -SQLRowCount @20 -SQLSetCursorName @21 -SQLTransact @23 -SQLColumns @40 -SQLDriverConnect @41 -SQLGetConnectOption @42 -SQLGetData @43 -SQLGetFunctions @44 -SQLGetInfo @45 -SQLGetStmtOption @46 -SQLGetTypeInfo @47 -SQLParamData @48 -SQLPutData @49 -SQLSetConnectOption @50 -SQLSetStmtOption @51 -SQLSpecialColumns @52 -SQLStatistics @53 -SQLTables @54 -SQLBrowseConnect @55 -SQLColumnPrivileges @56 -SQLDescribeParam @58 -SQLExtendedFetch @59 -SQLForeignKeys @60 -SQLMoreResults @61 -SQLNativeSql @62 -SQLNumParams @63 -SQLParamOptions @64 -SQLPrimaryKeys @65 -SQLProcedureColumns @66 -SQLProcedures @67 -SQLSetPos @68 -SQLSetScrollOptions @69 -SQLTablePrivileges @70 -SQLBindParameter @72 - -SQLColAttributesW @101 -SQLColumnPrivilegesW @102 -SQLColumnsW @103 -SQLConnectW @104 -SQLDescribeColW @106 -SQLExecDirectW @107 -SQLForeignKeysW @108 -SQLGetConnectOptionW @109 -SQLGetCursorNameW @110 -SQLGetInfoW @111 -SQLNativeSqlW @112 -SQLPrepareW @113 -SQLPrimaryKeysW @114 -SQLProcedureColumnsW @115 -SQLProceduresW @116 -SQLSetConnectOptionW @117 -SQLSetCursorNameW @118 -SQLSpecialColumnsW @119 -SQLStatisticsW @120 -SQLTablesW @121 -SQLTablePrivilegesW @122 -SQLDriverConnectW @123 -SQLErrorW @124 -SQLGetTypeInfoW @128 - -dconn_FDriverConnectProc @200 -DllMain @201 -ConfigDSN @202 diff --git a/src/interfaces/odbc/psqlodbc_win32.def b/src/interfaces/odbc/psqlodbc_win32.def deleted file mode 100644 index 23a5a82b39..0000000000 --- a/src/interfaces/odbc/psqlodbc_win32.def +++ /dev/null @@ -1,60 +0,0 @@ -LIBRARY psqlodbc -EXPORTS -SQLAllocConnect @1 -SQLAllocEnv @2 -SQLAllocStmt @3 -SQLBindCol @4 -SQLCancel @5 -SQLColAttributes @6 -SQLConnect @7 -SQLDescribeCol @8 -SQLDisconnect @9 -SQLError @10 -SQLExecDirect @11 -SQLExecute @12 -SQLFetch @13 -SQLFreeConnect @14 -SQLFreeEnv @15 -SQLFreeStmt @16 -SQLGetCursorName @17 -SQLNumResultCols @18 -SQLPrepare @19 -SQLRowCount @20 -SQLSetCursorName @21 -SQLTransact @23 -SQLColumns @40 -SQLDriverConnect @41 -SQLGetConnectOption @42 -SQLGetData @43 -SQLGetFunctions @44 -SQLGetInfo @45 -SQLGetStmtOption @46 -SQLGetTypeInfo @47 -SQLParamData @48 -SQLPutData @49 -SQLSetConnectOption @50 -SQLSetStmtOption @51 -SQLSpecialColumns @52 -SQLStatistics @53 -SQLTables @54 -SQLBrowseConnect @55 -SQLColumnPrivileges @56 -SQLDescribeParam @58 -SQLExtendedFetch @59 -SQLForeignKeys @60 -SQLMoreResults @61 -SQLNativeSql @62 -SQLNumParams @63 -SQLParamOptions @64 -SQLPrimaryKeys @65 -SQLProcedureColumns @66 -SQLProcedures @67 -SQLSetPos @68 -SQLSetScrollOptions @69 -SQLTablePrivileges @70 -SQLBindParameter @72 -SQLDummyOrdinal @199 -dconn_FDriverConnectProc @200 -DllMain @201 -ConfigDSN @202 - diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c deleted file mode 100644 index 8c978b6414..0000000000 --- a/src/interfaces/odbc/qresult.c +++ /dev/null @@ -1,846 +0,0 @@ -/*--------- - * Module: qresult.c - * - * Description: This module contains functions related to - * managing result information (i.e, fetching rows - * from the backend, managing the tuple cache, etc.) - * and retrieving it. Depending on the situation, a - * QResultClass will hold either data from the backend - * or a manually built result (see "qresult.h" to - * see which functions/macros are for manual or backend - * results. For manually built results, the - * QResultClass simply points to TupleList and - * ColumnInfo structures, which actually hold the data. - * - * Classes: QResultClass (Functions prefix: "QR_") - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *--------- - */ - -#include "qresult.h" - -#include "misc.h" -#include -#include - -#ifndef TRUE -#define TRUE (BOOL)1 -#endif -#ifndef FALSE -#define FALSE (BOOL)0 -#endif - - -/* - * Used for building a Manual Result only - * All info functions call this function to create the manual result set. - */ -void -QR_set_num_fields(QResultClass *self, int new_num_fields) -{ - mylog("in QR_set_num_fields\n"); - - CI_set_num_fields(self->fields, new_num_fields); - if (self->manual_tuples) - TL_Destructor(self->manual_tuples); - - self->manual_tuples = TL_Constructor(new_num_fields); - - mylog("exit QR_set_num_fields\n"); -} - - -void -QR_set_position(QResultClass *self, int pos) -{ - self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields); -} - - -void -QR_set_cache_size(QResultClass *self, int cache_size) -{ - self->cache_size = cache_size; -} - - -void -QR_set_rowset_size(QResultClass *self, int rowset_size) -{ - self->rowset_size = rowset_size; -} - - -void -QR_inc_base(QResultClass *self, int base_inc) -{ - self->base += base_inc; -} - - -/* - * CLASS QResult - */ -QResultClass * -QR_Constructor() -{ - QResultClass *rv; - - mylog("in QR_Constructor\n"); - rv = (QResultClass *) malloc(sizeof(QResultClass)); - - if (rv != NULL) - { - rv->status = PGRES_EMPTY_QUERY; - - /* construct the column info */ - if (!(rv->fields = CI_Constructor())) - { - free(rv); - return NULL; - } - rv->manual_tuples = NULL; - rv->backend_tuples = NULL; - rv->message = NULL; - rv->command = NULL; - rv->notice = NULL; - rv->conn = NULL; - rv->next = NULL; - rv->inTuples = FALSE; - rv->count_backend_allocated = 0; - rv->count_keyset_allocated = 0; - rv->num_total_rows = 0; - rv->num_backend_rows = 0; - rv->fetch_count = 0; - rv->base = 0; - rv->recent_processed_row_count = -1; - rv->currTuple = -1; - rv->num_fields = 0; - rv->tupleField = NULL; - rv->cursor = NULL; - rv->aborted = FALSE; - - rv->cache_size = 0; - rv->rowset_size = 1; - rv->haskeyset = 0; - rv->keyset = NULL; - rv->rb_alloc = 0; - rv->rb_count = 0; - rv->rollback = NULL; - rv->dl_alloc = 0; - rv->dl_count = 0; - rv->deleted = NULL; - } - - mylog("exit QR_Constructor\n"); - return rv; -} - - -void -QR_Destructor(QResultClass *self) -{ - mylog("QResult: in DESTRUCTOR\n"); - - /* manual result set tuples */ - if (self->manual_tuples) - TL_Destructor(self->manual_tuples); - - /* - * If conn is defined, then we may have used "backend_tuples", so in - * case we need to, free it up. Also, close the cursor. - */ - if (self->conn && self->conn->sock && CC_is_in_trans(self->conn)) - QR_close(self); /* close the cursor if there is one */ - - QR_free_memory(self); /* safe to call anyway */ - - /* Should have been freed in the close() but just in case... */ - if (self->cursor) - free(self->cursor); - - /* Free up column info */ - if (self->fields) - CI_Destructor(self->fields); - - /* Free command info (this is from strdup()) */ - if (self->command) - free(self->command); - - /* Free notice info (this is from strdup()) */ - if (self->notice) - free(self->notice); - /* Destruct the result object in the chain */ - if (self->next) - QR_Destructor(self->next); - - free(self); - - mylog("QResult: exit DESTRUCTOR\n"); -} - - -void -QR_set_command(QResultClass *self, char *msg) -{ - if (self->command) - free(self->command); - - self->command = msg ? strdup(msg) : NULL; -} - - -void -QR_set_notice(QResultClass *self, char *msg) -{ - if (self->notice) - free(self->notice); - - self->notice = msg ? strdup(msg) : NULL; -} - - -void -QR_free_memory(QResultClass *self) -{ - register int lf, - row; - register TupleField *tuple = self->backend_tuples; - int num_backend_rows = self->num_backend_rows; - int num_fields = self->num_fields; - - mylog("QResult: free memory in, fcount=%d\n", num_backend_rows); - - if (self->backend_tuples) - { - for (row = 0; row < num_backend_rows; row++) - { - mylog("row = %d, num_fields = %d\n", row, num_fields); - for (lf = 0; lf < num_fields; lf++) - { - if (tuple[lf].value != NULL) - { - mylog("free [lf=%d] %u\n", lf, tuple[lf].value); - free(tuple[lf].value); - } - } - tuple += num_fields; /* next row */ - } - - free(self->backend_tuples); - self->count_backend_allocated = 0; - self->backend_tuples = NULL; - } - if (self->keyset) - { - free(self->keyset); - self->keyset = NULL; - self->count_keyset_allocated = 0; - } - if (self->rollback) - { - free(self->rollback); - self->rb_alloc = 0; - self->rb_count = 0; - self->rollback = NULL; - } - if (self->deleted) - { - free(self->deleted); - self->dl_alloc = 0; - self->dl_count = 0; - self->deleted = NULL; - } - - self->num_total_rows = 0; - self->num_backend_rows = 0; - - mylog("QResult: free memory out\n"); -} - - -/* This function is called by send_query() */ -char -QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) -{ - int tuple_size; - - /* - * If called from send_query the first time (conn != NULL), then set - * the inTuples state, and read the tuples. If conn is NULL, it - * implies that we are being called from next_tuple(), like to get - * more rows so don't call next_tuple again! - */ - if (conn != NULL) - { - ConnInfo *ci = &(conn->connInfo); - BOOL fetch_cursor = (ci->drivers.use_declarefetch && cursor && cursor[0]); - - self->conn = conn; - - mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor == NULL) ? "" : cursor, self->cursor); - - if (self->cursor) - free(self->cursor); - self->cursor = NULL; - - if (fetch_cursor) - { - if (!cursor || cursor[0] == '\0') - { - self->status = PGRES_INTERNAL_ERROR; - QR_set_message(self, "Internal Error -- no cursor for fetch"); - return FALSE; - } - self->cursor = strdup(cursor); - } - - /* - * Read the field attributes. - * - * $$$$ Should do some error control HERE! $$$$ - */ - if (CI_read_fields(self->fields, self->conn)) - { - self->status = PGRES_FIELDS_OK; - self->num_fields = CI_get_num_fields(self->fields); - if (self->haskeyset) - self->num_fields -= 2; - } - else - { - self->status = PGRES_BAD_RESPONSE; - QR_set_message(self, "Error reading field information"); - return FALSE; - } - - mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields); - - if (fetch_cursor) - { - if (self->cache_size <= 0) - self->cache_size = ci->drivers.fetch_max; - tuple_size = self->cache_size; - } - else - tuple_size = TUPLE_MALLOC_INC; - - /* allocate memory for the tuple cache */ - mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size); - self->count_backend_allocated = self->count_keyset_allocated = 0; - if (self->num_fields > 0) - { - self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size); - if (!self->backend_tuples) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Could not get memory for tuple cache."); - return FALSE; - } - self->count_backend_allocated = tuple_size; - } - if (self->haskeyset) - { - if (self->keyset = (KeySet *) calloc(sizeof(KeySet), tuple_size), !self->keyset) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Could not get memory for tuple cache."); - return FALSE; - } - self->count_keyset_allocated = tuple_size; - } - - self->inTuples = TRUE; - - /* Force a read to occur in next_tuple */ - self->num_total_rows = 0; - self->num_backend_rows = tuple_size + 1; - self->fetch_count = tuple_size + 1; - self->base = 0; - - return QR_next_tuple(self); - } - else - { - /* - * Always have to read the field attributes. But we dont have to - * reallocate memory for them! - */ - - if (!CI_read_fields(NULL, self->conn)) - { - self->status = PGRES_BAD_RESPONSE; - QR_set_message(self, "Error reading field information"); - return FALSE; - } - return TRUE; - } -} - - -/* - * Close the cursor and end the transaction (if no cursors left) - * We only close cursor/end the transaction if a cursor was used. - */ -int -QR_close(QResultClass *self) -{ - QResultClass *res; - - if (self->conn && self->cursor && self->conn->connInfo.drivers.use_declarefetch) - { - char buf[64]; - - sprintf(buf, "close %s", self->cursor); - mylog("QResult: closing cursor: '%s'\n", buf); - - res = CC_send_query(self->conn, buf, NULL, CLEAR_RESULT_ON_ABORT); - - self->inTuples = FALSE; - self->currTuple = -1; - - free(self->cursor); - self->cursor = NULL; - - if (res == NULL) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Error closing cursor."); - return FALSE; - } - QR_Destructor(res); - - /* End the transaction if there are no cursors left on this conn */ - if (CC_is_in_autocommit(self->conn) && CC_cursor_count(self->conn) == 0) - { - mylog("QResult: END transaction on conn=%u\n", self->conn); - - if (!CC_commit(self->conn)) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Error ending transaction."); - return FALSE; - } - } - } - - return TRUE; -} - - -/* This function is called by fetch_tuples() AND SQLFetch() */ -int -QR_next_tuple(QResultClass *self) -{ - int id; - QResultClass *res; - SocketClass *sock; - - /* Speed up access */ - int fetch_count = self->fetch_count; - int num_backend_rows = self->num_backend_rows; - int fetch_size, - offset = 0; - int end_tuple = self->rowset_size + self->base; - char corrected = FALSE; - TupleField *the_tuples = self->backend_tuples; - - /* ERROR_MSG_LENGTH is sufficient */ - static char msgbuffer[ERROR_MSG_LENGTH + 1]; - - /* QR_set_command() dups this string so doesn't need static */ - char cmdbuffer[ERROR_MSG_LENGTH + 1]; - char fetch[128]; - QueryInfo qi; - ConnInfo *ci = NULL; - BOOL msg_truncated; - UDWORD abort_opt; - - if (fetch_count < num_backend_rows) - { - /* return a row from cache */ - mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, num_backend_rows); - self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */ - self->fetch_count++; - return TRUE; - } - else if (self->num_backend_rows < self->cache_size) - { - /* last row from cache */ - /* We are done because we didn't even get CACHE_SIZE tuples */ - mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", num_backend_rows, fetch_count); - self->tupleField = NULL; - self->status = PGRES_END_TUPLES; - /* end of tuples */ - return -1; - } - else - { - /* - * See if we need to fetch another group of rows. We may be being - * called from send_query(), and if so, don't send another fetch, - * just fall through and read the tuples. - */ - self->tupleField = NULL; - - if (!self->inTuples) - { - ci = &(self->conn->connInfo); - if (!self->cursor || !ci->drivers.use_declarefetch) - { - mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", self->num_total_rows, fetch_count); - self->tupleField = NULL; - self->status = PGRES_END_TUPLES; - return -1; /* end of tuples */ - } - - if (self->base == num_backend_rows) - { - int row, lf; - TupleField *tuple = self->backend_tuples; - - /* not a correction */ - /* Determine the optimum cache size. */ - if (ci->drivers.fetch_max % self->rowset_size == 0) - fetch_size = ci->drivers.fetch_max; - else if (self->rowset_size < ci->drivers.fetch_max) - fetch_size = (ci->drivers.fetch_max / self->rowset_size) * self->rowset_size; - else - fetch_size = self->rowset_size; - - self->cache_size = fetch_size; - /* clear obsolete tuples */ -inolog("clear obsolete %d tuples\n", num_backend_rows); - for (row = 0; row < num_backend_rows; row++) - { - for (lf = 0; lf < self->num_fields; lf++) - { - if (tuple[lf].value != NULL) - { - free(tuple[lf].value); - tuple[lf].value = NULL; - } - } - tuple += self->num_fields; - } - self->fetch_count = 1; - } - else - { - /* need to correct */ - corrected = TRUE; - - fetch_size = end_tuple - num_backend_rows; - - self->cache_size += fetch_size; - - offset = self->fetch_count; - self->fetch_count++; - } - - if (!self->backend_tuples || self->cache_size > self->count_backend_allocated) - { - self->count_backend_allocated = 0; - if (self->num_fields > 0) - { - self->backend_tuples = (TupleField *) realloc(self->backend_tuples, - self->num_fields * sizeof(TupleField) * self->cache_size); - if (!self->backend_tuples) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Out of memory while reading tuples."); - return FALSE; - } - self->count_backend_allocated = self->cache_size; - } - } - if (self->haskeyset && (!self->keyset || self->cache_size > self->count_keyset_allocated)) - { - self->count_keyset_allocated = 0; - self->keyset = (KeySet *) realloc(self->keyset, sizeof(KeySet) * self->cache_size); - self->count_keyset_allocated = self->cache_size; - } - sprintf(fetch, "fetch %d in %s", fetch_size, self->cursor); - - mylog("next_tuple: sending actual fetch (%d) query '%s'\n", fetch_size, fetch); - - /* don't read ahead for the next tuple (self) ! */ - qi.row_size = self->cache_size; - qi.result_in = self; - qi.cursor = NULL; - res = CC_send_query(self->conn, fetch, &qi, CLEAR_RESULT_ON_ABORT); - if (res == NULL) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Error fetching next group."); - return FALSE; - } - self->inTuples = TRUE; - } - else - { - mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->num_backend_rows, self->fetch_count); - - /* - * This is a pre-fetch (fetching rows right after query but - * before any real SQLFetch() calls. This is done so the - * field attributes are available. - */ - self->fetch_count = 0; - } - } - - if (!corrected) - { - self->base = 0; - self->num_backend_rows = 0; - } - - sock = CC_get_socket(self->conn); - self->tupleField = NULL; - ci = &(self->conn->connInfo); - - for (;;) - { - id = SOCK_get_char(sock); - - switch (id) - { - - case 'T': /* Tuples within tuples cannot be handled */ - self->status = PGRES_BAD_RESPONSE; - QR_set_message(self, "Tuples within tuples cannot be handled"); - return FALSE; - case 'B': /* Tuples in binary format */ - case 'D': /* Tuples in ASCII format */ - - if (!self->cursor || !ci->drivers.use_declarefetch) - { - if (self->num_fields > 0 && - self->num_total_rows >= self->count_backend_allocated) - { - int tuple_size = self->count_backend_allocated; - - mylog("REALLOC: old_count = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size); - tuple_size *= 2; - self->backend_tuples = (TupleField *) realloc(self->backend_tuples, - tuple_size * self->num_fields * sizeof(TupleField)); - if (!self->backend_tuples) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Out of memory while reading tuples."); - return FALSE; - } - self->count_backend_allocated = tuple_size; - } - if (self->haskeyset && - self->num_total_rows >= self->count_keyset_allocated) - { - int tuple_size = self->count_keyset_allocated; - tuple_size *= 2; - self->keyset = (KeySet *) realloc(self->keyset, sizeof(KeySet) * tuple_size); - self->count_keyset_allocated = tuple_size; - } - } - - if (!QR_read_tuple(self, (char) (id == 0))) - { - self->status = PGRES_BAD_RESPONSE; - QR_set_message(self, "Error reading the tuple"); - return FALSE; - } - self->num_total_rows++; - if (self->num_fields > 0) - self->num_backend_rows++; - break; /* continue reading */ - - case 'C': /* End of tuple list */ - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - QR_set_command(self, cmdbuffer); - - mylog("end of tuple list -- setting inUse to false: this = %u\n", self); - - self->inTuples = FALSE; - if (self->num_total_rows > 0) - { - qlog(" [ fetched %d rows ]\n", self->num_total_rows); - mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->num_total_rows); - - /* set to first row */ - self->tupleField = self->backend_tuples + (offset * self->num_fields); - return TRUE; - } - else - { - /* We are surely done here (we read 0 tuples) */ - qlog(" [ fetched 0 rows ]\n"); - mylog("_next_tuple: 'C': DONE (fcount == 0)\n"); - return -1; /* end of tuples */ - } - - case 'E': /* Error */ - msg_truncated = SOCK_get_string(sock, msgbuffer, - ERROR_MSG_LENGTH); - - /* Remove a newline */ - if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n') - msgbuffer[strlen(msgbuffer) - 1] = '\0'; - - abort_opt = 0; - if (!strncmp(msgbuffer, "FATAL", 5)) - abort_opt = NO_TRANS | CONN_DEAD; - CC_on_abort(self->conn, abort_opt); - QR_set_status(self, PGRES_FATAL_ERROR); - QR_set_message(self, msgbuffer); - QR_set_aborted(self, TRUE); - - mylog("ERROR from backend in next_tuple: '%s'\n", msgbuffer); - qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer); - while (msg_truncated) - msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - - return FALSE; - - case 'N': /* Notice */ - msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - QR_set_notice(self, cmdbuffer); - if (QR_command_successful(self)) - QR_set_status(self, PGRES_NONFATAL_ERROR); - qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer); - while (msg_truncated) - msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - continue; - - default: /* this should only happen if the backend - * dumped core */ - mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id); - qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id); - QR_set_message(self, "Unexpected result from backend. It probably crashed"); - self->status = PGRES_FATAL_ERROR; - CC_on_abort(self->conn, NO_TRANS | CONN_DEAD); - return FALSE; - } - } - return TRUE; -} - - -char -QR_read_tuple(QResultClass *self, char binary) -{ - Int2 field_lf; - TupleField *this_tuplefield; - KeySet *this_keyset = NULL; - char bmp, - bitmap[MAX_FIELDS]; /* Max. len of the bitmap */ - Int2 bitmaplen; /* len of the bitmap in bytes */ - Int2 bitmap_pos; - Int2 bitcnt; - Int4 len; - char *buffer; - int ci_num_fields = QR_NumResultCols(self); /* speed up access */ - int num_fields = self->num_fields; /* speed up access */ - SocketClass *sock = CC_get_socket(self->conn); - ColumnInfoClass *flds; - int effective_cols; - char tidoidbuf[32]; - - /* set the current row to read the fields into */ - effective_cols = ci_num_fields; - this_tuplefield = self->backend_tuples + (self->num_backend_rows * num_fields); - if (self->haskeyset) - { - this_keyset = self->keyset + self->num_total_rows; - this_keyset->status = 0; - effective_cols -= 2; - } - - bitmaplen = (Int2) ci_num_fields / BYTELEN; - if ((ci_num_fields % BYTELEN) > 0) - bitmaplen++; - - /* - * At first the server sends a bitmap that indicates which database - * fields are null - */ - SOCK_get_n_char(sock, bitmap, bitmaplen); - - bitmap_pos = 0; - bitcnt = 0; - bmp = bitmap[bitmap_pos]; - flds = self->fields; - - for (field_lf = 0; field_lf < ci_num_fields; field_lf++) - { - /* Check if the current field is NULL */ - if (!(bmp & 0200)) - { - /* YES, it is NULL ! */ - this_tuplefield[field_lf].len = 0; - this_tuplefield[field_lf].value = 0; - } - else - { - /* - * NO, the field is not null. so get at first the length of - * the field (four bytes) - */ - len = SOCK_get_int(sock, VARHDRSZ); - if (!binary) - len -= VARHDRSZ; - - if (field_lf >= effective_cols) - buffer = tidoidbuf; - else - buffer = (char *) malloc(len + 1); - SOCK_get_n_char(sock, buffer, len); - buffer[len] = '\0'; - - mylog("qresult: len=%d, buffer='%s'\n", len, buffer); - - if (field_lf >= effective_cols) - { - if (field_lf == effective_cols) - sscanf(buffer, "(%lu,%hu)", - &this_keyset->blocknum, &this_keyset->offset); - else - this_keyset->oid = strtoul(buffer, NULL, 10); - } - else - { - this_tuplefield[field_lf].len = len; - this_tuplefield[field_lf].value = buffer; - - /* - * This can be used to set the longest length of the column - * for any row in the tuple cache. It would not be accurate - * for varchar and text fields to use this since a tuple cache - * is only 100 rows. Bpchar can be handled since the strlen of - * all rows is fixed, assuming there are not 100 nulls in a - * row! - */ - - if (flds && flds->display_size && flds->display_size[field_lf] < len) - flds->display_size[field_lf] = len; - } - } - - /* - * Now adjust for the next bit to be scanned in the next loop. - */ - bitcnt++; - if (BYTELEN == bitcnt) - { - bitmap_pos++; - bmp = bitmap[bitmap_pos]; - bitcnt = 0; - } - else - bmp <<= 1; - } - self->currTuple++; - return TRUE; -} diff --git a/src/interfaces/odbc/qresult.h b/src/interfaces/odbc/qresult.h deleted file mode 100644 index 03c4ed35fb..0000000000 --- a/src/interfaces/odbc/qresult.h +++ /dev/null @@ -1,146 +0,0 @@ -/* File: qresult.h - * - * Description: See "qresult.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __QRESULT_H__ -#define __QRESULT_H__ - -#include "psqlodbc.h" - -#include "connection.h" -#include "socket.h" -#include "columninfo.h" -#include "tuplelist.h" -#include "tuple.h" - -enum QueryResultCode_ -{ - PGRES_EMPTY_QUERY = 0, - PGRES_COMMAND_OK, /* a query command that doesn't return */ - /* anything was executed properly by the backend */ - PGRES_TUPLES_OK, /* a query command that returns tuples */ - /* was executed properly by the backend, PGresult */ - /* contains the resulttuples */ - PGRES_COPY_OUT, - PGRES_COPY_IN, - PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from - * the backend */ - PGRES_NONFATAL_ERROR, - PGRES_FATAL_ERROR, - PGRES_FIELDS_OK, /* field information from a query was - * successful */ - PGRES_END_TUPLES, - PGRES_INTERNAL_ERROR -}; -typedef enum QueryResultCode_ QueryResultCode; - - -struct QResultClass_ -{ - ColumnInfoClass *fields; /* the Column information */ - TupleListClass *manual_tuples; /* manual result tuple list */ - ConnectionClass *conn; /* the connection this result is using - * (backend) */ - QResultClass *next; /* the following result class */ - - /* Stuff for declare/fetch tuples */ - int num_total_rows; /* total count of rows read in */ - int count_backend_allocated;/* m(re)alloced count */ - int count_keyset_allocated; /* m(re)alloced count */ - int num_backend_rows; /* count of tuples kept in backend_tuples member */ - int fetch_count; /* logical rows read so far */ - int currTuple; - int base; - - int num_fields; /* number of fields in the result */ - int cache_size; - int rowset_size; - Int4 recent_processed_row_count; - - QueryResultCode status; - - char *message; - char *cursor; /* The name of the cursor for select - * statements */ - char *command; - char *notice; - - TupleField *backend_tuples; /* data from the backend (the tuple cache) */ - TupleField *tupleField; /* current backend tuple being retrieved */ - - char inTuples; /* is a fetch of rows from the backend in - * progress? */ - char aborted; /* was aborted? */ - char haskeyset; /* this result contains keyset ? */ - KeySet *keyset; - UInt2 rb_alloc; /* count of allocated rollback info */ - UInt2 rb_count; /* count of rollback info */ - Rollback *rollback; - UInt2 dl_alloc; /* count of allocated deleted info */ - UInt2 dl_count; /* count of deleted info */ - UInt4 *deleted; -}; - -#define QR_get_fields(self) (self->fields) - - -/* These functions are for retrieving data from the qresult */ -#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno)) -#define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value) -#define QR_get_value_backend_row(self, tupleno, fieldno) ((self->backend_tuples + (tupleno * self->num_fields))[fieldno].value) - -/* These functions are used by both manual and backend results */ -#define QR_NumResultCols(self) (CI_get_num_fields(self->fields)) -#define QR_get_fieldname(self, fieldno_) (CI_get_fieldname(self->fields, fieldno_)) -#define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_)) -#define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_)) -#define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_)) -#define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_)) - -/* These functions are used only for manual result sets */ -#define QR_get_num_total_tuples(self) (self->manual_tuples ? TL_get_num_tuples(self->manual_tuples) : self->num_total_rows) -#define QR_get_num_backend_tuples(self) (self->manual_tuples ? TL_get_num_tuples(self->manual_tuples) : self->num_backend_rows) -#define QR_add_tuple(self, new_tuple) (TL_add_tuple(self->manual_tuples, new_tuple)) -#define QR_set_field_info(self, field_num, name, adtid, adtsize) (CI_set_field_info(self->fields, field_num, name, adtid, adtsize, -1)) - -/* status macros */ -#define QR_command_successful(self) ( !(self->status == PGRES_BAD_RESPONSE || self->status == PGRES_NONFATAL_ERROR || self->status == PGRES_FATAL_ERROR)) -#define QR_command_maybe_successful(self) ( !(self->status == PGRES_BAD_RESPONSE || self->status == PGRES_FATAL_ERROR)) -#define QR_command_nonfatal(self) ( self->status == PGRES_NONFATAL_ERROR) -#define QR_end_tuples(self) ( self->status == PGRES_END_TUPLES) -#define QR_set_status(self, condition) ( self->status = condition ) -#define QR_set_message(self, message_) ( self->message = message_) -#define QR_set_aborted(self, aborted_) ( self->aborted = aborted_) -#define QR_set_haskeyset(self) (self->haskeyset = TRUE) - -#define QR_get_message(self) (self->message) -#define QR_get_command(self) (self->command) -#define QR_get_notice(self) (self->notice) -#define QR_get_status(self) (self->status) -#define QR_get_aborted(self) (self->aborted) - -#define QR_aborted(self) (!self || self->aborted) - -/* Core Functions */ -QResultClass *QR_Constructor(void); -void QR_Destructor(QResultClass *self); -char QR_read_tuple(QResultClass *self, char binary); -int QR_next_tuple(QResultClass *self); -int QR_close(QResultClass *self); -char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor); -void QR_free_memory(QResultClass *self); -void QR_set_command(QResultClass *self, char *msg); -void QR_set_notice(QResultClass *self, char *msg); - -void QR_set_num_fields(QResultClass *self, int new_num_fields); /* manual result only */ - -void QR_inc_base(QResultClass *self, int base_inc); -void QR_set_cache_size(QResultClass *self, int cache_size); -void QR_set_rowset_size(QResultClass *self, int rowset_size); -void QR_set_position(QResultClass *self, int pos); - -#endif diff --git a/src/interfaces/odbc/readme.txt b/src/interfaces/odbc/readme.txt deleted file mode 100644 index 045b87bd8d..0000000000 --- a/src/interfaces/odbc/readme.txt +++ /dev/null @@ -1,84 +0,0 @@ - -Readme for psqlodbc.dll 04/04/2001 ------------------------------------------------------------------------------------ -Precompiled binaries for Win32 are available from ftp://ftp.postgresql.org/pub/odbc - - -I. Building the Driver from the source code - -This section describes how to build the PostgreSQL ODBC Driver (psqlodbc.dll). -Microsoft Visual C++ version 4.0 or higher is required. Other compilers may work -but have not been formally tested. The psqlodbc.dll may be built either in the -VC++ IDE or from the command line: - -IDE Method ----------- - -1. Create a new project workspace with the type DLL. For the name, type in the - name "psqlodbc". - -2. The above step creates the directory "psqlodbc" under the - "\\projects" path to hold the source files. - (example, \msdev\projects\psqlodbc). Now, either unzip the source code release - into this directory or just copy all the files into this directory. - -3. Insert all of the source files (*.c, *.h, *.rc, *.def) into the Visual project - using the "Insert files into project" command. You may have to do 2 inserts -- - the first to get the 'c' and header files, and the second to get the def file. - Don't forget the .def file since it is an important part of the release. - You can even insert ".txt" files into the projects -- they will do nothing. - -4. Add the "wsock32.lib" library to the end of the list of libraries for linking - using the Build settings menu. - -5. Select the type of build on the toolbar (i.e., Release or Debug). This is - one of the useful features of the visual c++ environment in that you can - browse the entire project if you build the "Debug" release. For release - purposes however, select "Release" build. - -6. Build the dll by selecting Build from the build menu. - -7. When complete, the "psqlodbc.dll" file is under the "Release" subdirectory. - (i.e., "\msdev\projects\psqlodbc\release\psqlodbc.dll") - -Command Line Method -------------------- - -1. From a command prompt, CD to the directory containing the source code. - -2. Use NMAKE to build the dll eg: - - C:\psqlodbc\> nmake /f win32.mak CFG=Release ALL - - Possible configurations are Release, Debug, MultiByteRelease or MultiByteDebug - Possible build types are ALL or CLEAN - - -II. Using Large Objects for handling LongVarBinary (OLE Objects in Access) - -Large objects are mapped to LONGVARBINARY in the driver to allow storing things like -OLE objects in Microsoft Access. Multiple SQLPutData and SQLGetData calls are usually -used to send and retrieve these objects. The driver creates a new large object and simply -inserts its 'identifier' into the respective table. However, since Postgres uses an 'Oid' -to identify a Large Object, it is necessary to create a new Postgres type to be able -to discriminate between an ordinary Oid and a Large Object Oid. Until this new type -becomes an official part of Postgres, it must be added into the desired database and -looked up for each connection. The type used in the driver is simply called "lo" and -here is the command used to create it: - -create type lo (internallength=4,externallength=10,input=int4in,output=int4out, - default='',passedbyvalue); - -Once this is done, simply use the new 'lo' type to define columns in that database. Note -that this must be done for each database you want to use large objects in with the driver. -When the driver sees an 'lo' type, it will handle it as LONGVARBINARY. - -Another important note is that this new type is lacking in functionality. It will not -cleanup after itself on updates and deletes, thus leaving orphans around and using up -extra disk space. And currently, Postgres does not support the vacuuming of large -objects. Hopefully in the future, a real large object data type will be available. - -But for now, it sure is fun to stick a Word document, Visio document, or avi of a dancing -baby into a database column, even if you will fill up your server's hard disk after a while! - - diff --git a/src/interfaces/odbc/resource.h b/src/interfaces/odbc/resource.h deleted file mode 100644 index bcd6384029..0000000000 --- a/src/interfaces/odbc/resource.h +++ /dev/null @@ -1,79 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by psqlodbc.rc -// -#define IDS_BADDSN 1 -#define IDS_MSGTITLE 2 -#define DLG_OPTIONS_DRV 102 -#define DLG_OPTIONS_DS 103 -#define DLG_OPTIONS_GLOBAL 104 -#define IDC_DSNAME 400 -#define IDC_DSNAMETEXT 401 -#define IDC_DESC 404 -#define IDC_SERVER 407 -#define IDC_DATABASE 408 -#define DLG_CONFIG 1001 -#define IDC_PORT 1002 -#define IDC_USER 1006 -#define IDC_PASSWORD 1009 -#define DS_READONLY 1011 -#define DS_SHOWOIDCOLUMN 1012 -#define DS_FAKEOIDINDEX 1013 -#define DRV_COMMLOG 1014 -#define DS_PG62 1016 -#define IDC_DATASOURCE 1018 -#define DRV_OPTIMIZER 1019 -#define DS_CONNSETTINGS 1020 -#define IDC_DRIVER 1021 -#define DRV_CONNSETTINGS 1031 -#define DRV_UNIQUEINDEX 1032 -#define DRV_UNKNOWN_MAX 1035 -#define DRV_UNKNOWN_DONTKNOW 1036 -#define DRV_READONLY 1037 -#define IDC_DESCTEXT 1039 -#define DRV_MSG_LABEL 1040 -#define DRV_UNKNOWN_LONGEST 1041 -#define DRV_TEXT_LONGVARCHAR 1043 -#define DRV_UNKNOWNS_LONGVARCHAR 1044 -#define DRV_CACHE_SIZE 1045 -#define DRV_VARCHAR_SIZE 1046 -#define DRV_LONGVARCHAR_SIZE 1047 -#define IDDEFAULTS 1048 -#define DRV_USEDECLAREFETCH 1049 -#define DRV_BOOLS_CHAR 1050 -#define DS_SHOWSYSTEMTABLES 1051 -#define DRV_EXTRASYSTABLEPREFIXES 1051 -#define DS_ROWVERSIONING 1052 -#define DRV_PARSE 1052 -#define DRV_CANCELASFREESTMT 1053 -#define IDC_OPTIONS 1054 -#define DRV_KSQO 1055 -#define DS_PG64 1057 -#define DS_PG63 1058 -#define DRV_OR_DSN 1059 -#define DRV_DEBUG 1060 -#define DS_DISALLOWPREMATURE 1061 -#define DS_LFCONVERSION 1062 -#define DS_TRUEISMINUS1 1063 -#define DS_UPDATABLECURSORS 1064 -#define IDNEXTPAGE 1065 -#define IDPREVPAGE 1066 -#define DS_INT8_AS_DEFAULT 1067 -#define DS_INT8_AS_BIGINT 1068 -#define DS_INT8_AS_NUMERIC 1069 -#define DS_INT8_AS_VARCHAR 1070 -#define DS_INT8_AS_DOUBLE 1071 -#define DS_INT8_AS_INT4 1072 -#define DRV_MSG_LABEL2 1073 -#define IDAPPLY 1074 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1075 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c deleted file mode 100644 index 28af870746..0000000000 --- a/src/interfaces/odbc/results.c +++ /dev/null @@ -1,2999 +0,0 @@ -/*------- - * Module: results.c - * - * Description: This module contains functions related to - * retrieving result information through the ODBC API. - * - * Classes: n/a - * - * API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol, - * SQLColAttributes, SQLGetData, SQLFetch, SQLExtendedFetch, - * SQLMoreResults, SQLSetPos, SQLSetScrollOptions(NI), - * SQLSetCursorName, SQLGetCursorName - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "psqlodbc.h" - -#include -#include "dlg_specific.h" -#include "environ.h" -#include "connection.h" -#include "statement.h" -#include "bind.h" -#include "qresult.h" -#include "convert.h" -#include "pgtypes.h" - -#include - -#include "pgapifunc.h" - - - -RETCODE SQL_API -PGAPI_RowCount( - HSTMT hstmt, - SDWORD FAR * pcrow) -{ - static char *func = "PGAPI_RowCount"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - ConnInfo *ci; - - mylog("%s: entering...\n", func); - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - ci = &(SC_get_conn(stmt)->connInfo); - if (stmt->manual_result) - { - if (pcrow) - *pcrow = -1; - return SQL_SUCCESS; - } - - res = SC_get_Curres(stmt); - if (res && pcrow) - { - if (stmt->status != STMT_FINISHED) - { - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "Can't get row count while statement is still executing."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - if (res->recent_processed_row_count >= 0) - { - *pcrow = res->recent_processed_row_count; - mylog("**** PGAPI_RowCount(): THE ROWS: *pcrow = %d\n", *pcrow); - - return SQL_SUCCESS; - } - else if (QR_NumResultCols(res) > 0) - { - *pcrow = SC_is_fetchcursor(stmt) ? -1 : QR_get_num_total_tuples(res) - res->dl_count; - mylog("RowCount=%d\n", *pcrow); - return SQL_SUCCESS; - } - } - - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "Bad return value", stmt); - return SQL_ERROR; -} - - -/* - * This returns the number of columns associated with the database - * attached to "hstmt". - */ -RETCODE SQL_API -PGAPI_NumResultCols( - HSTMT hstmt, - SWORD FAR * pccol) -{ - static char *func = "PGAPI_NumResultCols"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *result; - char parse_ok; - ConnInfo *ci; - - mylog("%s: entering...\n", func); - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - ci = &(SC_get_conn(stmt)->connInfo); - - SC_clear_error(stmt); - - parse_ok = FALSE; - if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT) - { - if (stmt->parse_status == STMT_PARSE_NONE) - { - mylog("PGAPI_NumResultCols: calling parse_statement on stmt=%u\n", stmt); - parse_statement(stmt); - } - - if (stmt->parse_status != STMT_PARSE_FATAL) - { - parse_ok = TRUE; - *pccol = SC_get_IRD(stmt)->nfields; - mylog("PARSE: PGAPI_NumResultCols: *pccol = %d\n", *pccol); - } - } - - if (!parse_ok) - { - SC_pre_execute(stmt); - result = SC_get_Curres(stmt); - - mylog("PGAPI_NumResultCols: result = %u, status = %d, numcols = %d\n", result, stmt->status, result != NULL ? QR_NumResultCols(result) : -1); - if ((!result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) - { - /* no query has been executed on this statement */ - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "No query has been executed with that handle"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - *pccol = QR_NumResultCols(result); - /* updatable cursors */ - if (result->keyset) - *pccol -= 2; - } - - return SQL_SUCCESS; -} - - -/* - * Return information about the database column the user wants - * information about. - */ -RETCODE SQL_API -PGAPI_DescribeCol( - HSTMT hstmt, - UWORD icol, - UCHAR FAR * szColName, - SWORD cbColNameMax, - SWORD FAR * pcbColName, - SWORD FAR * pfSqlType, - UDWORD FAR * pcbColDef, - SWORD FAR * pibScale, - SWORD FAR * pfNullable) -{ - static char *func = "PGAPI_DescribeCol"; - - /* gets all the information about a specific column */ - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn; - IRDFields *irdflds; - QResultClass *res; - char *col_name = NULL; - Int4 fieldtype = 0; - int column_size = 0, - decimal_digits = 0; - ConnInfo *ci; - char parse_ok; - char buf[255]; - int len = 0; - RETCODE result; - - mylog("%s: entering.%d..\n", func, icol); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - SC_clear_error(stmt); - - irdflds = SC_get_IRD(stmt); -#if (ODBCVER >= 0x0300) - if (0 == icol) /* bookmark column */ - { - SQLSMALLINT fType = stmt->options.use_bookmarks == SQL_UB_VARIABLE ? SQL_BINARY : SQL_INTEGER; - - if (szColName && cbColNameMax > 0) - *szColName = '\0'; - if (pcbColName) - *pcbColName = 0; - if (pfSqlType) - *pfSqlType = fType; - if (pcbColDef) - *pcbColDef = 10; - if (pibScale) - *pibScale = 0; - if (pfNullable) - *pfNullable = SQL_NO_NULLS; - return SQL_SUCCESS; - } -#endif /* ODBCVER */ - /* - * Dont check for bookmark column. This is the responsibility of the - * driver manager. - */ - - icol--; /* use zero based column numbers */ - - parse_ok = FALSE; - if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT) - { - if (stmt->parse_status == STMT_PARSE_NONE) - { - mylog("PGAPI_DescribeCol: calling parse_statement on stmt=%u\n", stmt); - parse_statement(stmt); - } - - mylog("PARSE: DescribeCol: icol=%d, stmt=%u, stmt->nfld=%d, stmt->fi=%u\n", icol, stmt, irdflds->nfields, irdflds->fi); - - if (stmt->parse_status != STMT_PARSE_FATAL && irdflds->fi && irdflds->fi[icol]) - { - if (icol >= irdflds->nfields) - { - stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR; - stmt->errormsg = "Invalid column number in DescribeCol."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - mylog("DescribeCol: getting info for icol=%d\n", icol); - - fieldtype = irdflds->fi[icol]->type; - if (irdflds->fi[icol]->alias[0]) - col_name = irdflds->fi[icol]->alias; - else - col_name = irdflds->fi[icol]->name; - column_size = irdflds->fi[icol]->column_size; - decimal_digits = irdflds->fi[icol]->decimal_digits; - - mylog("PARSE: fieldtype=%d, col_name='%s', column_size=%d\n", fieldtype, col_name, column_size); - if (fieldtype > 0) - parse_ok = TRUE; - } - } - - /* - * If couldn't parse it OR the field being described was not parsed - * (i.e., because it was a function or expression, etc, then do it the - * old fashioned way. - */ - if (!parse_ok) - { - SC_pre_execute(stmt); - - res = SC_get_Curres(stmt); - - mylog("**** PGAPI_DescribeCol: res = %u, stmt->status = %d, !finished=%d, !premature=%d\n", res, stmt->status, stmt->status != STMT_FINISHED, stmt->status != STMT_PREMATURE); - if ((NULL == res) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) - { - /* no query has been executed on this statement */ - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "No query has been assigned to this statement."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (icol >= QR_NumResultCols(res)) - { - stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR; - stmt->errormsg = "Invalid column number in DescribeCol."; - sprintf(buf, "Col#=%d, #Cols=%d", icol, QR_NumResultCols(res)); - SC_log_error(func, buf, stmt); - return SQL_ERROR; - } - - col_name = QR_get_fieldname(res, icol); - fieldtype = QR_get_field_type(res, icol); - - /* atoi(ci->unknown_sizes) */ - column_size = pgtype_column_size(stmt, fieldtype, icol, ci->drivers.unknown_sizes); - decimal_digits = pgtype_decimal_digits(stmt, fieldtype, icol); - } - - mylog("describeCol: col %d fieldname = '%s'\n", icol, col_name); - mylog("describeCol: col %d fieldtype = %d\n", icol, fieldtype); - mylog("describeCol: col %d column_size = %d\n", icol, column_size); - - result = SQL_SUCCESS; - - /* - * COLUMN NAME - */ - len = strlen(col_name); - - if (pcbColName) - *pcbColName = len; - - if (szColName && cbColNameMax > 0) - { - strncpy_null(szColName, col_name, cbColNameMax); - - if (len >= cbColNameMax) - { - result = SQL_SUCCESS_WITH_INFO; - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "The buffer was too small for the colName."; - } - } - - /* - * CONCISE(SQL) TYPE - */ - if (pfSqlType) - { - *pfSqlType = pgtype_to_concise_type(stmt, fieldtype); - - mylog("describeCol: col %d *pfSqlType = %d\n", icol, *pfSqlType); - } - - /* - * COLUMN SIZE(PRECISION in 2.x) - */ - if (pcbColDef) - { - if (column_size < 0) - column_size = 0; /* "I dont know" */ - - *pcbColDef = column_size; - - mylog("describeCol: col %d *pcbColDef = %d\n", icol, *pcbColDef); - } - - /* - * DECIMAL DIGITS(SCALE in 2.x) - */ - if (pibScale) - { - if (decimal_digits < 0) - decimal_digits = 0; - - *pibScale = decimal_digits; - mylog("describeCol: col %d *pibScale = %d\n", icol, *pibScale); - } - - /* - * NULLABILITY - */ - if (pfNullable) - { - *pfNullable = (parse_ok) ? irdflds->fi[icol]->nullable : pgtype_nullable(stmt, fieldtype); - - mylog("describeCol: col %d *pfNullable = %d\n", icol, *pfNullable); - } - - return result; -} - - -/* Returns result column descriptor information for a result set. */ -RETCODE SQL_API -PGAPI_ColAttributes( - HSTMT hstmt, - UWORD icol, - UWORD fDescType, - PTR rgbDesc, - SWORD cbDescMax, - SWORD FAR * pcbDesc, - SDWORD FAR * pfDesc) -{ - static char *func = "PGAPI_ColAttributes"; - StatementClass *stmt = (StatementClass *) hstmt; - IRDFields *irdflds; - Int4 col_idx, field_type = 0; - ConnectionClass *conn; - ConnInfo *ci; - int unknown_sizes; - int cols = 0; - char parse_ok; - RETCODE result; - const char *p = NULL; - int len = 0, - value = 0; - const FIELD_INFO *fi = NULL; - - mylog("%s: entering..col=%d %d len=%d.\n", func, icol, fDescType, - cbDescMax); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - if (pcbDesc) - *pcbDesc = 0; - irdflds = SC_get_IRD(stmt); - conn = SC_get_conn(stmt); - ci = &(conn->connInfo); - - /* - * Dont check for bookmark column. This is the responsibility of the - * driver manager. For certain types of arguments, the column number - * is ignored anyway, so it may be 0. - */ - -#if (ODBCVER >= 0x0300) - if (0 == icol && SQL_DESC_COUNT != fDescType) /* bookmark column */ - { - switch (fDescType) - { - case SQL_DESC_OCTET_LENGTH: - if (pfDesc) - *pfDesc = 4; - break; - case SQL_DESC_TYPE: - if (pfDesc) - *pfDesc = stmt->options.use_bookmarks == SQL_UB_VARIABLE ? SQL_BINARY : SQL_INTEGER; - break; - } - return SQL_SUCCESS; - } -#endif /* ODBCVER */ - col_idx = icol - 1; - - /* atoi(ci->unknown_sizes); */ - unknown_sizes = ci->drivers.unknown_sizes; - - /* not appropriate for SQLColAttributes() */ - if (unknown_sizes == UNKNOWNS_AS_DONTKNOW) - unknown_sizes = UNKNOWNS_AS_MAX; - - parse_ok = FALSE; - if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT) - { - if (stmt->parse_status == STMT_PARSE_NONE) - { - mylog("PGAPI_ColAttributes: calling parse_statement\n"); - parse_statement(stmt); - } - - cols = irdflds->nfields; - - /* - * Column Count is a special case. The Column number is ignored - * in this case. - */ -#if (ODBCVER >= 0x0300) - if (fDescType == SQL_DESC_COUNT) -#else - if (fDescType == SQL_COLUMN_COUNT) -#endif /* ODBCVER */ - { - if (pfDesc) - *pfDesc = cols; - - return SQL_SUCCESS; - } - - if (stmt->parse_status != STMT_PARSE_FATAL && irdflds->fi) - { - if (col_idx >= cols) - { - stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR; - stmt->errormsg = "Invalid column number in ColAttributes."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - if (irdflds->fi[col_idx]) - { - field_type = irdflds->fi[col_idx]->type; - if (field_type > 0) - parse_ok = TRUE; - } - } - } - - if (parse_ok) - fi = irdflds->fi[col_idx]; - else - { - SC_pre_execute(stmt); - - mylog("**** PGAPI_ColAtt: result = %u, status = %d, numcols = %d\n", SC_get_Curres(stmt), stmt->status, SC_get_Curres(stmt) != NULL ? QR_NumResultCols(SC_get_Curres(stmt)) : -1); - - if ((NULL == SC_get_Curres(stmt)) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) - { - stmt->errormsg = "Can't get column attributes: no result found."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - cols = QR_NumResultCols(SC_get_Curres(stmt)); - - /* - * Column Count is a special case. The Column number is ignored - * in this case. - */ -#if (ODBCVER >= 0x0300) - if (fDescType == SQL_DESC_COUNT) -#else - if (fDescType == SQL_COLUMN_COUNT) -#endif /* ODBCVER */ - { - if (pfDesc) - *pfDesc = cols; - - return SQL_SUCCESS; - } - - if (col_idx >= cols) - { - stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR; - stmt->errormsg = "Invalid column number in ColAttributes."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - field_type = QR_get_field_type(SC_get_Curres(stmt), col_idx); - if (stmt->parse_status != STMT_PARSE_FATAL && irdflds->fi && irdflds->fi[col_idx]) - fi = irdflds->fi[col_idx]; - } - - mylog("colAttr: col %d field_type = %d\n", col_idx, field_type); - - switch (fDescType) - { - case SQL_COLUMN_AUTO_INCREMENT: /* == SQL_DESC_AUTO_UNIQUE_VALUE */ - value = pgtype_auto_increment(stmt, field_type); - if (value == -1) /* non-numeric becomes FALSE (ODBC Doc) */ - value = FALSE; -inolog("AUTO_INCREMENT=%d\n", value); - - break; - - case SQL_COLUMN_CASE_SENSITIVE: /* == SQL_DESC_CASE_SENSITIVE */ - value = pgtype_case_sensitive(stmt, field_type); - break; - - /* - * This special case is handled above. - * - * case SQL_COLUMN_COUNT: - */ - case SQL_COLUMN_DISPLAY_SIZE: /* == SQL_DESC_DISPLAY_SIZE */ - value = fi ? fi->display_size : pgtype_display_size(stmt, field_type, col_idx, unknown_sizes); - - mylog("PGAPI_ColAttributes: col %d, display_size= %d\n", col_idx, value); - - break; - - case SQL_COLUMN_LABEL: /* == SQL_DESC_LABEL */ - if (fi && fi->alias[0] != '\0') - { - p = fi->alias; - - mylog("PGAPI_ColAttr: COLUMN_LABEL = '%s'\n", p); - break; - - } - /* otherwise same as column name -- FALL THROUGH!!! */ - -#if (ODBCVER >= 0x0300) - case SQL_DESC_NAME: -#else - case SQL_COLUMN_NAME: -#endif /* ODBCVER */ - p = fi ? (fi->alias[0] ? fi->alias : fi->name) : QR_get_fieldname(SC_get_Curres(stmt), col_idx); - - mylog("PGAPI_ColAttr: COLUMN_NAME = '%s'\n", p); - break; - - case SQL_COLUMN_LENGTH: - value = (fi && fi->length > 0) ? fi->length : pgtype_buffer_length(stmt, field_type, col_idx, unknown_sizes); - if (value < 0) - value = 0; - - mylog("PGAPI_ColAttributes: col %d, length = %d\n", col_idx, value); - break; - - case SQL_COLUMN_MONEY: /* == SQL_DESC_FIXED_PREC_SCALE */ - value = pgtype_money(stmt, field_type); -inolog("COLUMN_MONEY=%d\n", value); - break; - -#if (ODBCVER >= 0x0300) - case SQL_DESC_NULLABLE: -#else - case SQL_COLUMN_NULLABLE: -#endif /* ODBCVER */ - value = fi ? fi->nullable : pgtype_nullable(stmt, field_type); -inolog("COLUMN_NULLABLE=%d\n", value); - break; - - case SQL_COLUMN_OWNER_NAME: /* == SQL_DESC_SCHEMA_NAME */ - p = fi && (fi->ti) ? fi->ti->schema : ""; - break; - - case SQL_COLUMN_PRECISION: /* in 2.x */ - value = (fi && fi->column_size > 0) ? fi->column_size : pgtype_column_size(stmt, field_type, col_idx, unknown_sizes); - if (value < 0) - value = 0; - - mylog("PGAPI_ColAttributes: col %d, column_size = %d\n", col_idx, value); - break; - - case SQL_COLUMN_QUALIFIER_NAME: /* == SQL_DESC_CATALOG_NAME */ - p = ""; - break; - - case SQL_COLUMN_SCALE: /* in 2.x */ - value = pgtype_decimal_digits(stmt, field_type, col_idx); -inolog("COLUMN_SCALE=%d\n", value); - if (value < 0) - value = 0; - break; - - case SQL_COLUMN_SEARCHABLE: /* SQL_DESC_SEARCHABLE */ - value = pgtype_searchable(stmt, field_type); - break; - - case SQL_COLUMN_TABLE_NAME: /* == SQL_DESC_TABLE_NAME */ - p = fi && (fi->ti) ? fi->ti->name : ""; - - mylog("PGAPI_ColAttr: TABLE_NAME = '%s'\n", p); - break; - - case SQL_COLUMN_TYPE: /* == SQL_DESC_CONCISE_TYPE */ - value = pgtype_to_concise_type(stmt, field_type); -inolog("COLUMN_TYPE=%d\n", value); - break; - - case SQL_COLUMN_TYPE_NAME: /* == SQL_DESC_TYPE_NAME */ - p = pgtype_to_name(stmt, field_type); - break; - - case SQL_COLUMN_UNSIGNED: /* == SQL_DESC_UNSINGED */ - value = pgtype_unsigned(stmt, field_type); - if (value == -1) /* non-numeric becomes TRUE (ODBC Doc) */ - value = TRUE; - - break; - - case SQL_COLUMN_UPDATABLE: /* == SQL_DESC_UPDATABLE */ - - /* - * Neither Access or Borland care about this. - * - * if (field_type == PG_TYPE_OID) pfDesc = SQL_ATTR_READONLY; - * else - */ - value = fi ? (fi->updatable ? SQL_ATTR_WRITE : SQL_ATTR_READONLY) : SQL_ATTR_READWRITE_UNKNOWN; - if (SQL_ATTR_READONLY != value) - { - const char *name = fi ? fi->name : QR_get_fieldname(SC_get_Curres(stmt), col_idx); - if (stricmp(name, "oid") == 0 || - stricmp(name, "ctid") == 0 || - stricmp(name, "xmin") == 0) - value = SQL_ATTR_READONLY; - } - - mylog("PGAPI_ColAttr: UPDATEABLE = %d\n", value); - break; -#if (ODBCVER >= 0x0300) - case SQL_DESC_BASE_COLUMN_NAME: - - p = fi ? fi->name : QR_get_fieldname(SC_get_Curres(stmt), col_idx); - - mylog("PGAPI_ColAttr: BASE_COLUMN_NAME = '%s'\n", p); - break; - case SQL_DESC_BASE_TABLE_NAME: /* the same as TABLE_NAME ok ? */ - p = (fi && (fi->ti)) ? fi->ti->name : ""; - - mylog("PGAPI_ColAttr: BASE_TABLE_NAME = '%s'\n", p); - break; - case SQL_DESC_LENGTH: /* different from SQL_COLUMN_LENGTH */ - value = (fi && fi->length > 0) ? fi->length : pgtype_desclength(stmt, field_type, col_idx, unknown_sizes); - if (value < 0) - value = 0; - - mylog("PGAPI_ColAttributes: col %d, length = %d\n", col_idx, value); - break; - case SQL_DESC_OCTET_LENGTH: - value = (fi && fi->length > 0) ? fi->length : pgtype_transfer_octet_length(stmt, field_type, col_idx, unknown_sizes); - if (value < 0) - value = 0; - mylog("PGAPI_ColAttributes: col %d, octet_length = %d\n", col_idx, value); - break; - case SQL_DESC_PRECISION: /* different from SQL_COLUMN_PRECISION */ - if (value = FI_precision(fi), value <= 0) - value = pgtype_precision(stmt, field_type, col_idx, unknown_sizes); - if (value < 0) - value = 0; - - mylog("PGAPI_ColAttributes: col %d, desc_precision = %d\n", col_idx, value); - break; - case SQL_DESC_SCALE: /* different from SQL_COLUMN_SCALE */ - value = pgtype_scale(stmt, field_type, col_idx); - if (value < 0) - value = 0; - break; - case SQL_DESC_LOCAL_TYPE_NAME: - p = pgtype_to_name(stmt, field_type); - break; - case SQL_DESC_TYPE: - value = pgtype_to_sqldesctype(stmt, field_type); - break; - case SQL_DESC_NUM_PREC_RADIX: - value = pgtype_radix(stmt, field_type); - break; - case SQL_DESC_LITERAL_PREFIX: - p = pgtype_literal_prefix(stmt, field_type); - break; - case SQL_DESC_LITERAL_SUFFIX: - p = pgtype_literal_suffix(stmt, field_type); - break; - case SQL_DESC_UNNAMED: - value = (fi && !fi->name[0] && !fi->alias[0]) ? SQL_UNNAMED : SQL_NAMED; - break; -#endif /* ODBCVER */ - case 1212: - stmt->errornumber = STMT_OPTION_NOT_FOR_THE_DRIVER; - stmt->errormsg = "this request may be for MS SQL Server"; - return SQL_ERROR; - default: - stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; - stmt->errormsg = "ColAttribute for this type not implemented yet"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - result = SQL_SUCCESS; - - if (p) - { /* char/binary data */ - len = strlen(p); - - if (rgbDesc) - { - strncpy_null((char *) rgbDesc, p, (size_t) cbDescMax); - - if (len >= cbDescMax) - { - result = SQL_SUCCESS_WITH_INFO; - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "The buffer was too small for the rgbDesc."; - } - } - - if (pcbDesc) - *pcbDesc = len; - } - else - { - /* numeric data */ - if (pfDesc) - *pfDesc = value; - } - - return result; -} - - -/* Returns result data for a single column in the current row. */ -RETCODE SQL_API -PGAPI_GetData( - HSTMT hstmt, - UWORD icol, - SWORD fCType, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR * pcbValue) -{ - static char *func = "PGAPI_GetData"; - QResultClass *res; - StatementClass *stmt = (StatementClass *) hstmt; - int num_cols, - num_rows; - Int4 field_type; - void *value = NULL; - int result; - char get_bookmark = FALSE; - ConnInfo *ci; - - mylog("PGAPI_GetData: enter, stmt=%u\n", stmt); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - ci = &(SC_get_conn(stmt)->connInfo); - res = SC_get_Curres(stmt); - - if (STMT_EXECUTING == stmt->status) - { - stmt->errormsg = "Can't get data while statement is still executing."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (stmt->status != STMT_FINISHED) - { - stmt->errornumber = STMT_STATUS_ERROR; - stmt->errormsg = "GetData can only be called after the successful execution on a SQL statement"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (icol == 0) - { - if (stmt->options.use_bookmarks == SQL_UB_OFF) - { - stmt->errornumber = STMT_COLNUM_ERROR; - stmt->errormsg = "Attempt to retrieve bookmark with bookmark usage disabled"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - /* Make sure it is the bookmark data type */ - switch (fCType) - { - case SQL_C_BOOKMARK: -#if (ODBCVER >= 0x0300) - case SQL_C_VARBOOKMARK: -#endif /* ODBCVER */ - break; - default: - stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK"; - inolog("Column 0 is type %d not of type SQL_C_BOOKMARK", fCType); - stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - get_bookmark = TRUE; - } - else - { - /* use zero-based column numbers */ - icol--; - - /* make sure the column number is valid */ - num_cols = QR_NumResultCols(res); - if (icol >= num_cols) - { - stmt->errormsg = "Invalid column number."; - stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - - if (stmt->manual_result || !SC_is_fetchcursor(stmt)) - { - /* make sure we're positioned on a valid row */ - num_rows = QR_get_num_total_tuples(res); - if ((stmt->currTuple < 0) || - (stmt->currTuple >= num_rows)) - { - stmt->errormsg = "Not positioned on a valid row for GetData."; - stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - mylog(" num_rows = %d\n", num_rows); - - if (!get_bookmark) - { - if (stmt->manual_result) - value = QR_get_value_manual(res, stmt->currTuple, icol); - else - { - Int4 curt = res->base; - if (stmt->rowset_start >= 0) - curt += (stmt->currTuple - stmt->rowset_start); - value = QR_get_value_backend_row(res, curt, icol); - } - mylog(" value = '%s'\n", value); - } - } - else - { - /* it's a SOCKET result (backend data) */ - if (stmt->currTuple == -1 || !res || !res->tupleField) - { - stmt->errormsg = "Not positioned on a valid row for GetData."; - stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (!get_bookmark) - value = QR_get_value_backend(res, icol); - - mylog(" socket: value = '%s'\n", value); - } - - if (get_bookmark) - { - *((UDWORD *) rgbValue) = SC_get_bookmark(stmt); - - if (pcbValue) - *pcbValue = 4; - - return SQL_SUCCESS; - } - - field_type = QR_get_field_type(res, icol); - - mylog("**** PGAPI_GetData: icol = %d, fCType = %d, field_type = %d, value = '%s'\n", icol, fCType, field_type, value); - - stmt->current_col = icol; - - result = copy_and_convert_field(stmt, field_type, value, - fCType, rgbValue, cbValueMax, pcbValue); - - stmt->current_col = -1; - - switch (result) - { - case COPY_OK: - return SQL_SUCCESS; - - case COPY_UNSUPPORTED_TYPE: - stmt->errormsg = "Received an unsupported type from Postgres."; - stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - - case COPY_UNSUPPORTED_CONVERSION: - stmt->errormsg = "Couldn't handle the necessary data type conversion."; - stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - - case COPY_RESULT_TRUNCATED: - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "The buffer was too small for the GetData."; - return SQL_SUCCESS_WITH_INFO; - - case COPY_GENERAL_ERROR: /* error msg already filled in */ - SC_log_error(func, "", stmt); - return SQL_ERROR; - - case COPY_NO_DATA_FOUND: - /* SC_log_error(func, "no data found", stmt); */ - return SQL_NO_DATA_FOUND; - - default: - stmt->errormsg = "Unrecognized return value from copy_and_convert_field."; - stmt->errornumber = STMT_INTERNAL_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } -} - - -/* - * Returns data for bound columns in the current row ("hstmt->iCursor"), - * advances the cursor. - */ -RETCODE SQL_API -PGAPI_Fetch( - HSTMT hstmt) -{ - static char *func = "PGAPI_Fetch"; - StatementClass *stmt = (StatementClass *) hstmt; - ARDFields *opts; - QResultClass *res; - - mylog("PGAPI_Fetch: stmt = %u, stmt->result= %u\n", stmt, SC_get_Curres(stmt)); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - SC_clear_error(stmt); - - if (!(res = SC_get_Curres(stmt))) - { - stmt->errormsg = "Null statement result in PGAPI_Fetch."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - /* Not allowed to bind a bookmark column when using SQLFetch. */ - opts = SC_get_ARD(stmt); - if (opts->bookmark->buffer) - { - stmt->errornumber = STMT_COLNUM_ERROR; - stmt->errormsg = "Not allowed to bind a bookmark column when using PGAPI_Fetch"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (stmt->status == STMT_EXECUTING) - { - stmt->errormsg = "Can't fetch while statement is still executing."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (stmt->status != STMT_FINISHED) - { - stmt->errornumber = STMT_STATUS_ERROR; - stmt->errormsg = "Fetch can only be called after the successful execution on a SQL statement"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (opts->bindings == NULL) - { - /* just to avoid a crash if the user insists on calling this */ - /* function even if SQL_ExecDirect has reported an Error */ - stmt->errormsg = "Bindings were not allocated properly."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - QR_set_rowset_size(res, 1); - QR_inc_base(res, stmt->last_fetch_count_include_ommitted); - - return SC_fetch(stmt); -} - -#ifdef DRIVER_CURSOR_IMPLEMENT -static RETCODE SQL_API -SC_pos_reload_needed(StatementClass *stmt, UDWORD flag); -static Int4 -getNthValid(QResultClass *res, Int4 sta, UWORD orientation, UInt4 nth, Int4 *nearest) -{ - Int4 i, num_tuples = QR_get_num_total_tuples(res); - UInt4 count; - KeySet *keyset; - - if (0 == res->dl_count) - { - if (SQL_FETCH_PRIOR == orientation) - { - if (sta + 1 >= (Int4) nth) - { - *nearest = sta + 1 - nth; - return nth; - } - *nearest = -1; - return -(Int4)(sta + 1); - } - else - { - if ((*nearest = sta + nth - 1) < num_tuples) - return nth; - *nearest = num_tuples; - return -(Int4)(num_tuples - sta); - } - } - count = 0; - if (SQL_FETCH_PRIOR == orientation) - { - for (i = sta, keyset = res->keyset + sta; - i >= 0; i--, keyset--) - { - if (0 == (keyset->status & (CURS_SELF_DELETING | CURS_SELF_DELETING | CURS_OTHER_DELETED))) - { - *nearest = i; - if (++count == nth) - return count; - } - } - *nearest = -1; - } - else - { - for (i = sta, keyset = res->keyset + sta; - i < num_tuples; i++, keyset++) - { - if (0 == (keyset->status & (CURS_SELF_DELETING | CURS_SELF_DELETING | CURS_OTHER_DELETED))) - { - *nearest = i; - if (++count == nth) - return count; - } - } - *nearest = num_tuples; - } - return -(Int4)count; -} -#endif /* DRIVER_CURSOR_IMPLEMENT */ - -/* - * return NO_DATA_FOUND macros - * save_rowset_start or num_tuples must be defined - */ -#define EXTFETCH_RETURN_BOF(stmt, res) \ -{ \ - stmt->rowset_start = -1; \ - stmt->currTuple = -1; \ - res->base += (stmt->rowset_start - save_rowset_start); \ - return SQL_NO_DATA_FOUND; \ -} -#define EXTFETCH_RETURN_EOF(stmt, res) \ -{ \ - stmt->rowset_start = num_tuples; \ - stmt->currTuple = -1; \ - res->base += (stmt->rowset_start - save_rowset_start); \ - return SQL_NO_DATA_FOUND; \ -} - -/* This fetchs a block of data (rowset). */ -RETCODE SQL_API -PGAPI_ExtendedFetch( - HSTMT hstmt, - UWORD fFetchType, - SDWORD irow, - UDWORD FAR * pcrow, - UWORD FAR * rgfRowStatus, - SQLINTEGER bookmark_offset) -{ - static char *func = "PGAPI_ExtendedFetch"; - StatementClass *stmt = (StatementClass *) hstmt; - ARDFields *opts; - QResultClass *res; - int num_tuples, - i, - save_rowset_size, - save_rowset_start, - progress_size; - RETCODE result; - char truncated, - error; - ConnInfo *ci; - DWORD currp; -#ifdef DRIVER_CURSOR_IMPLEMENT - UWORD pstatus; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - mylog("PGAPI_ExtendedFetch: stmt=%u\n", stmt); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - ci = &(SC_get_conn(stmt)->connInfo); - - /* if (SC_is_fetchcursor(stmt) && !stmt->manual_result) */ - if (SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type && !stmt->manual_result) - { - if (fFetchType != SQL_FETCH_NEXT) - { - stmt->errornumber = STMT_FETCH_OUT_OF_RANGE; - stmt->errormsg = "The fetch type for PGAPI_ExtendedFetch isn't allowed with ForwardOnly cursor."; - return SQL_ERROR; - } - } - - SC_clear_error(stmt); - - if (!(res = SC_get_Curres(stmt))) - { - stmt->errormsg = "Null statement result in PGAPI_ExtendedFetch."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - opts = SC_get_ARD(stmt); - /* - * If a bookmark colunmn is bound but bookmark usage is off, then - * error - */ - if (opts->bookmark->buffer && stmt->options.use_bookmarks == SQL_UB_OFF) - { - stmt->errornumber = STMT_COLNUM_ERROR; - stmt->errormsg = "Attempt to retrieve bookmark with bookmark usage disabled"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (stmt->status == STMT_EXECUTING) - { - stmt->errormsg = "Can't fetch while statement is still executing."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (stmt->status != STMT_FINISHED) - { - stmt->errornumber = STMT_STATUS_ERROR; - stmt->errormsg = "ExtendedFetch can only be called after the successful execution on a SQL statement"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (opts->bindings == NULL) - { - /* just to avoid a crash if the user insists on calling this */ - /* function even if SQL_ExecDirect has reported an Error */ - stmt->errormsg = "Bindings were not allocated properly."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - /* Initialize to no rows fetched */ - if (rgfRowStatus) - for (i = 0; i < opts->rowset_size; i++) - *(rgfRowStatus + i) = SQL_ROW_NOROW; - - if (pcrow) - *pcrow = 0; - - num_tuples = QR_get_num_total_tuples(res); - - /* Save and discard the saved rowset size */ - save_rowset_start = stmt->rowset_start; - save_rowset_size = stmt->save_rowset_size; - stmt->save_rowset_size = -1; - - switch (fFetchType) - { - case SQL_FETCH_NEXT: - - /* - * From the odbc spec... If positioned before the start of the - * RESULT SET, then this should be equivalent to - * SQL_FETCH_FIRST. - */ - - progress_size = (save_rowset_size > 0 ? save_rowset_size : opts->rowset_size); - if (stmt->rowset_start < 0) - stmt->rowset_start = 0; - -#ifdef DRIVER_CURSOR_IMPLEMENT - else if (res->keyset) - { - if (stmt->last_fetch_count <= progress_size) - { - stmt->rowset_start += stmt->last_fetch_count_include_ommitted; - progress_size -= stmt->last_fetch_count; - } - if (progress_size > 0 && - getNthValid(res, stmt->rowset_start, - SQL_FETCH_NEXT, progress_size + 1, - &stmt->rowset_start) <= 0) - { - EXTFETCH_RETURN_EOF(stmt, res) - } - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - else - stmt->rowset_start += progress_size; - - mylog("SQL_FETCH_NEXT: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); - break; - - case SQL_FETCH_PRIOR: - mylog("SQL_FETCH_PRIOR: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); - - /* - * From the odbc spec... If positioned after the end of the - * RESULT SET, then this should be equivalent to - * SQL_FETCH_LAST. - */ - if (stmt->rowset_start <= 0) - { - EXTFETCH_RETURN_BOF(stmt, res) - } - if (stmt->rowset_start >= num_tuples) - { - if (opts->rowset_size > num_tuples) - { - stmt->errornumber = STMT_POS_BEFORE_RECORDSET; - stmt->errormsg = "fetch prior from eof and before the beggining"; - } - stmt->rowset_start = num_tuples <= 0 ? 0 : (num_tuples - opts->rowset_size); - - } - else - { -#ifdef DRIVER_CURSOR_IMPLEMENT - if (i = getNthValid(res, stmt->rowset_start - 1, SQL_FETCH_PRIOR, opts->rowset_size, &stmt->rowset_start), i < -1) - { - stmt->errormsg = "fetch prior and before the beggining"; - stmt->errornumber = STMT_POS_BEFORE_RECORDSET; - stmt->rowset_start = 0; - } - else if (i <= 0) - { - EXTFETCH_RETURN_BOF(stmt, res) - } -#else - if (stmt->rowset_start < opts->rowset_size) - { - stmt->errormsg = "fetch prior and before the beggining"; - stmt->errornumber = STMT_POS_BEFORE_RECORDSET; - stmt->rowset_start = 0; - } - else - stmt->rowset_start -= opts->rowset_size; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - } - break; - - case SQL_FETCH_FIRST: - mylog("SQL_FETCH_FIRST: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); - - stmt->rowset_start = 0; - break; - - case SQL_FETCH_LAST: - mylog("SQL_FETCH_LAST: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); - - stmt->rowset_start = num_tuples <= 0 ? 0 : (num_tuples - opts->rowset_size); - break; - - case SQL_FETCH_ABSOLUTE: - mylog("SQL_FETCH_ABSOLUTE: num_tuples=%d, currtuple=%d, irow=%d\n", num_tuples, stmt->currTuple, irow); - - /* Position before result set, but dont fetch anything */ - if (irow == 0) - { - EXTFETCH_RETURN_BOF(stmt, res) - } - /* Position before the desired row */ - else if (irow > 0) -#ifdef DRIVER_CURSOR_IMPLEMENT - { - if (getNthValid(res, 0, SQL_FETCH_NEXT, irow, &stmt->rowset_start) <= 0) - { - EXTFETCH_RETURN_EOF(stmt, res) - } - } -#else - stmt->rowset_start = irow - 1; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - /* Position with respect to the end of the result set */ - else -#ifdef DRIVER_CURSOR_IMPLEMENT - { - if (getNthValid(res, num_tuples - 1, SQL_FETCH_PRIOR, -irow, &stmt->rowset_start) <= 0) - { - EXTFETCH_RETURN_BOF(stmt, res) - } - } -#else - stmt->rowset_start = num_tuples + irow; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - break; - - case SQL_FETCH_RELATIVE: - - /* - * Refresh the current rowset -- not currently implemented, - * but lie anyway - */ - if (irow == 0) - break; - -#ifdef DRIVER_CURSOR_IMPLEMENT - if (irow > 0) - { - if (getNthValid(res, stmt->rowset_start + 1, SQL_FETCH_NEXT, irow, &stmt->rowset_start) <= 0) - { - EXTFETCH_RETURN_EOF(stmt, res) - } - } - else - { - if (getNthValid(res, stmt->rowset_start - 1, SQL_FETCH_PRIOR, -irow, &stmt->rowset_start) <= 0) - { - EXTFETCH_RETURN_BOF(stmt, res) - } - } -#else - stmt->rowset_start += irow; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - break; - - case SQL_FETCH_BOOKMARK: -#ifdef DRIVER_CURSOR_IMPLEMENT - if (bookmark_offset > 0) - { - if (getNthValid(res, irow - 1, SQL_FETCH_NEXT, bookmark_offset + 1, &stmt->rowset_start) <= 0) - { - EXTFETCH_RETURN_EOF(stmt, res) - } - } - else if (getNthValid(res, irow - 1, SQL_FETCH_PRIOR, 1 - bookmark_offset, &stmt->rowset_start) <= 0) - { - stmt->currTuple = -1; - EXTFETCH_RETURN_BOF(stmt, res) - } -#else - stmt->rowset_start = irow + bookmark_offset - 1; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - break; - - default: - SC_log_error(func, "Unsupported PGAPI_ExtendedFetch Direction", stmt); - return SQL_ERROR; - } - - /* - * CHECK FOR PROPER CURSOR STATE - */ - - /* - * Handle Declare Fetch style specially because the end is not really - * the end... - */ - if (SC_is_fetchcursor(stmt) && !stmt->manual_result) - { - if (QR_end_tuples(res)) - return SQL_NO_DATA_FOUND; - } - else - { - /* If *new* rowset is after the result_set, return no data found */ - if (stmt->rowset_start >= num_tuples) - { - EXTFETCH_RETURN_EOF(stmt, res) - } - } - - /* If *new* rowset is prior to result_set, return no data found */ - if (stmt->rowset_start < 0) - { - if (stmt->rowset_start + opts->rowset_size <= 0) - { - EXTFETCH_RETURN_BOF(stmt, res) - } - else - { /* overlap with beginning of result set, - * so get first rowset */ - stmt->rowset_start = 0; - } - } - - /* currTuple is always 1 row prior to the rowset */ - stmt->currTuple = stmt->rowset_start - 1; - - /* increment the base row in the tuple cache */ - QR_set_rowset_size(res, opts->rowset_size); - if (SC_is_fetchcursor(stmt)) - QR_inc_base(res, stmt->last_fetch_count_include_ommitted); - else - res->base = stmt->rowset_start; - -#ifdef DRIVER_CURSOR_IMPLEMENT - if (res->keyset) - SC_pos_reload_needed(stmt, SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - /* Physical Row advancement occurs for each row fetched below */ - - mylog("PGAPI_ExtendedFetch: new currTuple = %d\n", stmt->currTuple); - - truncated = error = FALSE; - for (i = 0, currp = stmt->rowset_start; i < opts->rowset_size; currp++) - { - stmt->bind_row = i; /* set the binding location */ - result = SC_fetch(stmt); -#ifdef DRIVER_CURSOR_IMPLEMENT - if (SQL_SUCCESS_WITH_INFO == result && 0 == stmt->last_fetch_count && res->keyset) - { - res->keyset[stmt->currTuple].status &= ~CURS_IN_ROWSET; - continue; - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - /* Determine Function status */ - if (result == SQL_NO_DATA_FOUND) - break; - else if (result == SQL_SUCCESS_WITH_INFO) - truncated = TRUE; - else if (result == SQL_ERROR) - error = TRUE; - - /* Determine Row Status */ - if (rgfRowStatus) - { - if (result == SQL_ERROR) - *(rgfRowStatus + i) = SQL_ROW_ERROR; -#ifdef DRIVER_CURSOR_IMPLEMENT - else if (res->keyset) - { - pstatus = (res->keyset[currp].status & KEYSET_INFO_PUBLIC); - if (pstatus != 0 && pstatus != SQL_ROW_ADDED) - { - rgfRowStatus[i] = pstatus; - } - else - rgfRowStatus[i] = SQL_ROW_SUCCESS; - res->keyset[currp].status |= CURS_IN_ROWSET; - /* refresh the status */ - /* if (SQL_ROW_DELETED != pstatus) */ - res->keyset[currp].status &= (~KEYSET_INFO_PUBLIC); - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - else - *(rgfRowStatus + i) = SQL_ROW_SUCCESS; - } - i++; - } - - /* Save the fetch count for SQLSetPos */ - stmt->last_fetch_count = i; - stmt->last_fetch_count_include_ommitted = currp - stmt->rowset_start; - - /* Reset next binding row */ - stmt->bind_row = 0; - - /* Move the cursor position to the first row in the result set. */ - stmt->currTuple = stmt->rowset_start; - - /* For declare/fetch, need to reset cursor to beginning of rowset */ - if (SC_is_fetchcursor(stmt) && !stmt->manual_result) - QR_set_position(res, 0); - - /* Set the number of rows retrieved */ - if (pcrow) - *pcrow = i; - - if (i == 0) - /* Only DeclareFetch should wind up here */ - return SQL_NO_DATA_FOUND; - else if (error) - return SQL_ERROR; - else if (truncated) - return SQL_SUCCESS_WITH_INFO; - else if (stmt->errornumber == STMT_POS_BEFORE_RECORDSET) - return SQL_SUCCESS_WITH_INFO; - else - return SQL_SUCCESS; -} - - -/* - * This determines whether there are more results sets available for - * the "hstmt". - */ -/* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */ -RETCODE SQL_API -PGAPI_MoreResults( - HSTMT hstmt) -{ - const char *func = "PGAPI_MoreResults"; - StatementClass *stmt = (StatementClass *) hstmt; - QResultClass *res; - - mylog("%s: entering...\n", func); - if (stmt && (res = SC_get_Curres(stmt))) - SC_set_Curres(stmt, res->next); - if (res = SC_get_Curres(stmt), res) - { - stmt->diag_row_count = res->recent_processed_row_count; - return SQL_SUCCESS; - } - return SQL_NO_DATA_FOUND; -} - - -#ifdef DRIVER_CURSOR_IMPLEMENT -/* - * Stuff for updatable cursors. - */ -static Int2 getNumResultCols(const QResultClass *res) -{ - Int2 res_cols = QR_NumResultCols(res); - return res->keyset ? res_cols - 2 : res_cols; -} -static UInt4 getOid(const QResultClass *res, int index) -{ - return res->keyset[index].oid; -} -static void getTid(const QResultClass *res, int index, UInt4 *blocknum, UInt2 *offset) -{ - *blocknum = res->keyset[index].blocknum; - *offset = res->keyset[index].offset; -} -static void KeySetSet(const TupleField *tuple, int num_fields, KeySet *keyset) -{ - sscanf(tuple[num_fields - 2].value, "(%u,%hu)", - &keyset->blocknum, &keyset->offset); - sscanf(tuple[num_fields - 1].value, "%u", &keyset->oid); -} - -static void DiscardDeleted(QResultClass *res, int index); -static void AddRollback(ConnectionClass *conn, QResultClass *res, int index, const KeySet *keyset) -{ - Rollback *rollback; - - if (!res->rollback) - { - res->rb_count = 0; - res->rb_alloc = 10; - rollback = res->rollback = malloc(sizeof(Rollback) * res->rb_alloc); - } - else - { - if (res->rb_count >= res->rb_alloc) - { - res->rb_alloc *= 2; - if (rollback = realloc(res->rollback, sizeof(Rollback) * res->rb_alloc), !rollback) - { - res->rb_alloc = res->rb_count = 0; - return; - } - res->rollback = rollback; - } - rollback = res->rollback + res->rb_count; - } - rollback->index = index; - if (keyset) - { - rollback->blocknum = keyset[index].blocknum; - rollback->offset = keyset[index].offset; - } - else - { - rollback->offset = 0; - rollback->blocknum = 0; - } - - conn->result_uncommitted = 1; - res->rb_count++; -} - -static void DiscardRollback(QResultClass *res) -{ - int i, index; - UWORD status; - Rollback *rollback; - KeySet *keyset; - - if (0 == res->rb_count || NULL == res->rollback) - return; - rollback = res->rollback; - keyset = res->keyset; - for (i = 0; i < res->rb_count; i++) - { - index = rollback[i].index; - status = keyset[index].status; - if (0 != (status & CURS_SELF_DELETING)) - DiscardDeleted(res, index); - keyset[index].status &= ~(CURS_SELF_DELETING | CURS_SELF_UPDATING | CURS_SELF_ADDING); - keyset[index].status |= ((status & (CURS_SELF_DELETING | CURS_SELF_UPDATING | CURS_SELF_ADDING)) << 3); - } - free(rollback); - res->rollback = NULL; - res->rb_count = res->rb_alloc = 0; -} - -static void UndoRollback(StatementClass *stmt, QResultClass *res) -{ - int i, index, ridx; - UWORD status; - Rollback *rollback; - KeySet *keyset; - - if (0 == res->rb_count || NULL == res->rollback) - return; - rollback = res->rollback; - keyset = res->keyset; - for (i = res->rb_count - 1; i >= 0; i--) - { - index = rollback[i].index; - status = keyset[index].status; - if (0 != (status & CURS_SELF_ADDING)) - { - ridx = index - stmt->rowset_start + res->base; - if (ridx >=0 && ridx < res->num_backend_rows) - { - TupleField *tuple = res->backend_tuples + res->num_fields * ridx; - int j; - - for (j = 0; j < res->num_fields; j++, tuple++) - { - if (tuple->len > 0 && tuple->value) - { - free(tuple->value); - tuple->value = NULL; - } - tuple->len = 0; - } - } - if (index < res->num_total_rows) - res->num_total_rows = index; - } - else - { - if (0 != (status & CURS_SELF_DELETING)) - DiscardDeleted(res, index); - keyset[index].blocknum = rollback[i].blocknum; - keyset[index].offset = rollback[i].offset; - if (0 != (keyset[index].status & CURS_SELF_UPDATING)) - keyset[index].status |= CURS_NEEDS_REREAD; - keyset[index].status &= ~(CURS_SELF_DELETING | CURS_SELF_UPDATING | CURS_SELF_ADDING | KEYSET_INFO_PUBLIC); - } - } - free(rollback); - res->rollback = NULL; - res->rb_count = res->rb_alloc = 0; -} - -void ProcessRollback(ConnectionClass *conn, BOOL undo) -{ - int i; - StatementClass *stmt; - QResultClass *res; - - for (i = 0; i < conn->num_stmts; i++) - { - if (stmt = conn->stmts[i], !stmt) - continue; - for (res = SC_get_Result(stmt); res; res = res->next) - { - if (undo) - UndoRollback(stmt, res); - else - DiscardRollback(res); - } - } -} - - -static void AddDeleted(QResultClass *res, int index) -{ - int i; - UInt4 *deleted; - - if (!res->deleted) - { - res->dl_count = 0; - res->dl_alloc = 10; - deleted = res->deleted = malloc(sizeof(UInt4) * res->dl_alloc); - } - else - { - if (res->dl_count >= res->dl_alloc) - { - res->dl_alloc *= 2; - if (deleted = realloc(res->deleted, sizeof(UInt4) * res->dl_alloc), !deleted) - { - res->dl_alloc = res->dl_count = 0; - return; - } - res->deleted = deleted; - } - for (i = 0, deleted = res->deleted; i < res->dl_count; i++, deleted++) - { - if (index < (int) *deleted) - break; - } - memmove(deleted + 1, deleted, sizeof(UInt4) * (res->dl_count - i)); - } - *deleted = index; - res->dl_count++; -} -static void DiscardDeleted(QResultClass *res, int index) -{ - int i; - UInt4 *deleted; - - if (!res->deleted) - return; - - for (i = 0, deleted = res->deleted; i < res->dl_count; i++, deleted++) - { - if (index == (int) *deleted) - break; - } - if (i >= res->dl_count) - return; - memmove(deleted, deleted + 1, sizeof(UInt4) * (res->dl_count - i - 1)); - res->dl_count--; -} - -#define LATEST_TUPLE_LOAD 1L -#define USE_INSERTED_TID (1L << 1) -static QResultClass * -positioned_load(StatementClass *stmt, UInt4 flag, UInt4 oid, const char *tidval) -{ - QResultClass *qres; - char *selstr; - BOOL latest = ((flag & LATEST_TUPLE_LOAD) != 0); - UInt4 len; - - len = strlen(stmt->load_statement); - if (tidval) - { - len += 100; - selstr = malloc(len); - if (latest) - { - if (stmt->ti[0]->schema[0]) - sprintf(selstr, "%s where ctid = currtid2('\"%s\".\"%s\"', '%s') and oid = %u", - stmt->load_statement, stmt->ti[0]->schema, - stmt->ti[0]->name, tidval, oid); - else - sprintf(selstr, "%s where ctid = currtid2('%s', '%s') and oid = %u", stmt->load_statement, stmt->ti[0]->name, tidval, oid); - } - else - sprintf(selstr, "%s where ctid = '%s' and oid = %u", stmt->load_statement, tidval, oid); - } - else if ((flag & USE_INSERTED_TID) != 0) - { - len += 50; - selstr = malloc(len); - sprintf(selstr, "%s where ctid = currtid(0, '(,)') and oid = %u", stmt->load_statement, oid); - } - else - { - len += 20; - selstr = malloc(len); - sprintf(selstr, "%s where oid = %u", stmt->load_statement, oid); - } - - mylog("selstr=%s\n", selstr); - qres = CC_send_query(SC_get_conn(stmt), selstr, NULL, CLEAR_RESULT_ON_ABORT); - free(selstr); - return qres; -} - -RETCODE SQL_API -SC_pos_reload(StatementClass *stmt, UDWORD global_ridx, UWORD *count, BOOL logChanges) -{ - int i, - res_cols; - UWORD rcnt, offset; - Int4 res_ridx; - UInt4 oid, blocknum; - QResultClass *res, - *qres; - IRDFields *irdflds = SC_get_IRD(stmt); - RETCODE ret = SQL_ERROR; - char tidval[32]; - - mylog("positioned load fi=%x ti=%x\n", irdflds->fi, stmt->ti); - rcnt = 0; - if (count) - *count = 0; - if (!(res = SC_get_Curres(stmt))) - return SQL_ERROR; - if (!stmt->ti) - parse_statement(stmt); /* not preferable */ - if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - res_ridx = global_ridx - stmt->rowset_start + res->base; - if (!(oid = getOid(res, global_ridx))) - return SQL_SUCCESS_WITH_INFO; - getTid(res, global_ridx, &blocknum, &offset); - sprintf(tidval, "(%u, %u)", blocknum, offset); - res_cols = getNumResultCols(res); - if (qres = positioned_load(stmt, LATEST_TUPLE_LOAD, oid, tidval), qres) - { - TupleField *tupleo, *tuplen; - ConnectionClass *conn = SC_get_conn(stmt); - - rcnt = QR_get_num_backend_tuples(qres); - tupleo = res->backend_tuples + res->num_fields * res_ridx; - if (logChanges && CC_is_in_trans(conn)) - AddRollback(conn, res, global_ridx, res->keyset); - if (rcnt == 1) - { - int effective_fields = res_cols; - - QR_set_position(qres, 0); - tuplen = qres->tupleField; - if (res->keyset) - { - if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type && - strcmp(tuplen[qres->num_fields - 2].value, tidval)) - res->keyset[global_ridx].status |= SQL_ROW_UPDATED; - KeySetSet(tuplen, qres->num_fields, res->keyset + global_ridx); - } - for (i = 0; i < effective_fields; i++) - { - if (tupleo[i].value) - free(tupleo[i].value); - tupleo[i].len = tuplen[i].len; - tuplen[i].len = 0; - tupleo[i].value = tuplen[i].value; - tuplen[i].value = NULL; - } - ret = SQL_SUCCESS; - } - else - { - stmt->errornumber = STMT_ROW_VERSION_CHANGED; - stmt->errormsg = "the content was deleted after last fetch"; - ret = SQL_SUCCESS_WITH_INFO; - if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) - { - res->keyset[global_ridx].status |= SQL_ROW_DELETED; - } - } - QR_Destructor(qres); - } - else if (stmt->errornumber == 0) - stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; - if (count) - *count = rcnt; - return ret; -} - -static RETCODE SQL_API -SC_pos_reload_needed(StatementClass *stmt, UDWORD flag) -{ - Int4 i, limitrow; - UWORD qcount; - QResultClass *res; - IRDFields *irdflds = SC_get_IRD(stmt); - RETCODE ret = SQL_ERROR; - ConnectionClass *conn = SC_get_conn(stmt); - UInt4 oid, blocknum, lodlen; - char *qval = NULL, *sval; - Int4 rowc; - UWORD offset; - BOOL create_from_scratch = (0 != flag); - - mylog("SC_pos_reload_needed\n"); - if (!(res = SC_get_Curres(stmt))) - return SQL_ERROR; - if (!stmt->ti) - parse_statement(stmt); /* not preferable */ - if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - limitrow = stmt->rowset_start + res->rowset_size; - if (limitrow > res->num_total_rows) - limitrow = res->num_total_rows; - if (create_from_scratch) - { - int flds_cnt = res->num_backend_rows * res->num_fields, - brows; - - for (i = 0; i < flds_cnt; i++) - { - if (res->backend_tuples[i].value) - free(res->backend_tuples[i].value); - } - brows = limitrow - stmt->rowset_start; - if (brows > res->count_backend_allocated) - { - res->backend_tuples = realloc(res->backend_tuples, sizeof(TupleField) * res->num_fields * brows); - res->count_backend_allocated = brows; - } - if (brows > 0) - memset(res->backend_tuples, 0, sizeof(TupleField) * res->num_fields * brows); - res->num_backend_rows = brows; - res->base = 0; - for (i = stmt->rowset_start; i < limitrow; i++) - { - if (0 == (res->keyset[i].status & (CURS_SELF_DELETING | CURS_SELF_DELETED | CURS_OTHER_DELETED))) - res->keyset[i].status |= CURS_NEEDS_REREAD; - } - } - - for (i = stmt->rowset_start, rowc = 0;; i++) - { - if (i >= limitrow) - { - if (!rowc) - break; - rowc = -1; /* end of loop */ - } - if (rowc < 0 || rowc >= 10) - { - QResultClass *qres; - - strcpy(sval, ")"); - qres = CC_send_query(conn, qval, NULL, CLEAR_RESULT_ON_ABORT | CREATE_KEYSET); - if (qres) - { - int j, k, l, m; - TupleField *tuple, *tuplew; - - for (j = 0; j < qres->num_total_rows; j++) - { - oid = getOid(qres, j); - getTid(qres, j, &blocknum, &offset); - for (k = stmt->rowset_start; k < limitrow; k++) - { - if (oid == getOid(res, k)) - { - l = k - stmt->rowset_start + res->base; - tuple = res->backend_tuples + res->num_fields * l; - tuplew = qres->backend_tuples + qres->num_fields * j; - for (m = 0; m < res->num_fields; m++, tuple++, tuplew++) - { - if (tuple->len > 0 && tuple->value) - free(tuple->value); - tuple->value = tuplew->value; - tuple->len = tuplew->len; - tuplew->value = NULL; - tuplew->len = 0; - } - res->keyset[k].status &= ~CURS_NEEDS_REREAD; - break; - } - } - } - QR_Destructor(qres); - } - if (rowc < 0) - break; - rowc = 0; - } - if (!rowc) - { - if (!qval) - { - UInt4 allen; - - lodlen = strlen(stmt->load_statement); - allen = lodlen + 20 + 23 * 10; - qval = malloc(allen); - } - memcpy(qval, stmt->load_statement, lodlen); - sval = qval + lodlen; - sval[0]= '\0'; - strcpy(sval, " where ctid in ("); - sval = strchr(sval, '\0'); - } - if (0 != (res->keyset[i].status & CURS_NEEDS_REREAD)) - { - getTid(res, i, &blocknum, &offset); - if (rowc) - sprintf(sval, ", '(%u, %u)'", blocknum, offset); - else - sprintf(sval, "'(%u, %u)'", blocknum, offset); - sval = strchr(sval, '\0'); - rowc++; - } - } - if (qval) - free(qval); - else - return SQL_SUCCESS; - - for (i = stmt->rowset_start; i < limitrow; i++) - { - if (0 != (res->keyset[i].status & CURS_NEEDS_REREAD)) - { - ret = SC_pos_reload(stmt, i, &qcount, FALSE); - if (SQL_ERROR == ret) - { - break; - } - if (SQL_ROW_DELETED == (res->keyset[i].status & KEYSET_INFO_PUBLIC)) - { - res->keyset[i].status |= CURS_OTHER_DELETED; - } - res->keyset[i].status &= ~CURS_NEEDS_REREAD; - } - } - return ret; -} - -RETCODE SQL_API -SC_pos_newload(StatementClass *stmt, UInt4 oid, BOOL tidRef) -{ - int i; - QResultClass *res, *qres; - RETCODE ret = SQL_ERROR; - - mylog("positioned new ti=%x\n", stmt->ti); - if (!(res = SC_get_Curres(stmt))) - return SQL_ERROR; - if (!stmt->ti) - parse_statement(stmt); /* not preferable */ - if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - if (qres = positioned_load(stmt, tidRef ? USE_INSERTED_TID : 0, oid, NULL), qres) - { - TupleField *tupleo, *tuplen; - int count = QR_get_num_backend_tuples(qres); - - QR_set_position(qres, 0); - if (count == 1) - { - int effective_fields = res->num_fields; - int tuple_size; - - tuplen = qres->tupleField; - if (res->haskeyset && - res->num_total_rows >= res->count_keyset_allocated) - { - - if (!res->count_keyset_allocated) - tuple_size = TUPLE_MALLOC_INC; - else - tuple_size = res->count_keyset_allocated * 2; - res->keyset = (KeySet *) realloc(res->keyset, sizeof(KeySet) * tuple_size); - res->count_keyset_allocated = tuple_size; - } - KeySetSet(tuplen, qres->num_fields, res->keyset + res->num_total_rows); - - if (res->num_total_rows == res->num_backend_rows - res->base + stmt->rowset_start) - { - if (res->num_backend_rows >= res->count_backend_allocated) - { - if (!res->count_backend_allocated) - tuple_size = TUPLE_MALLOC_INC; - else - tuple_size = res->count_backend_allocated * 2; - res->backend_tuples = (TupleField *) realloc( - res->backend_tuples, - res->num_fields * sizeof(TupleField) * tuple_size); - if (!res->backend_tuples) - { - stmt->errornumber = res->status = PGRES_FATAL_ERROR; - stmt->errormsg = "Out of memory while reading tuples."; - QR_Destructor(qres); - return SQL_ERROR; - } - res->count_backend_allocated = tuple_size; - } - tupleo = res->backend_tuples + res->num_fields * res->num_backend_rows; - for (i = 0; i < effective_fields; i++) - { - tupleo[i].len = tuplen[i].len; - tuplen[i].len = 0; - tupleo[i].value = tuplen[i].value; - tuplen[i].value = NULL; - } - for (; i < res->num_fields; i++) - { - tupleo[i].len = 0; - tupleo[i].value = NULL; - } - res->num_backend_rows++; - } - res->num_total_rows++; - ret = SQL_SUCCESS; - } - else if (0 == count) - ret = SQL_NO_DATA_FOUND; - else - { - stmt->errornumber = STMT_ROW_VERSION_CHANGED; - stmt->errormsg = "the driver cound't identify inserted rows"; - ret = SQL_ERROR; - } - QR_Destructor(qres); - /* stmt->currTuple = stmt->rowset_start + ridx; */ - } - return ret; -} - -static RETCODE SQL_API -irow_update(RETCODE ret, StatementClass *stmt, StatementClass *ustmt, UWORD irow, UDWORD global_ridx) -{ - if (ret != SQL_ERROR) - { - int updcnt; - const char *cmdstr = QR_get_command(SC_get_Curres(ustmt)); - - if (cmdstr && - sscanf(cmdstr, "UPDATE %d", &updcnt) == 1) - { - if (updcnt == 1) - ret = SC_pos_reload(stmt, global_ridx, (UWORD *) 0, TRUE); - else if (updcnt == 0) - { - stmt->errornumber = STMT_ROW_VERSION_CHANGED; - stmt->errormsg = "the content was changed before updation"; - ret = SQL_ERROR; - if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) - SC_pos_reload(stmt, global_ridx, (UWORD *) 0, FALSE); - } - else - ret = SQL_ERROR; - } - else - ret = SQL_ERROR; - if (ret == SQL_ERROR && stmt->errornumber == 0) - { - stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; - stmt->errormsg = "SetPos update return error"; - } - } - return ret; -} -RETCODE -SC_pos_update(StatementClass *stmt, - UWORD irow, UDWORD global_ridx) -{ - int i, - num_cols, - upd_cols; - QResultClass *res; - ConnectionClass *conn = SC_get_conn(stmt); - ARDFields *opts = SC_get_ARD(stmt); - IRDFields *irdflds = SC_get_IRD(stmt); - BindInfoClass *bindings = opts->bindings; - FIELD_INFO **fi = SC_get_IRD(stmt)->fi; - char updstr[4096]; - RETCODE ret; - UInt4 oid, offset, blocknum; - UInt2 pgoffset; - Int4 *used, bind_size = opts->bind_size; - - mylog("POS UPDATE %d+%d fi=%x ti=%x\n", irow, SC_get_Curres(stmt)->base,fi, stmt->ti); - if (!(res = SC_get_Curres(stmt))) - return SQL_ERROR; - if (!stmt->ti) - parse_statement(stmt); /* not preferable */ - if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - if (!(oid = getOid(res, global_ridx))) - { - stmt->errormsg = "The row is already deleted"; - return SQL_ERROR; - } - getTid(res, global_ridx, &blocknum, &pgoffset); - - if (stmt->ti[0]->schema[0]) - sprintf(updstr, "update \"%s\".\"%s\" set", stmt->ti[0]->schema, stmt->ti[0]->name); - else - sprintf(updstr, "update \"%s\" set", stmt->ti[0]->name); - num_cols = irdflds->nfields; - offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0; - for (i = upd_cols = 0; i < num_cols; i++) - { - if (used = bindings[i].used, used != NULL) - { - used += (offset >> 2); - if (bind_size > 0) - used += (bind_size * irow / 4); - else - used += irow; - mylog("%d used=%d,%x\n", i, *used, used); - if (*used != SQL_IGNORE && fi[i]->updatable) - { - if (upd_cols) - sprintf(updstr, "%s, \"%s\" = ?", updstr, fi[i]->name); - else - sprintf(updstr, "%s \"%s\" = ?", updstr, fi[i]->name); - upd_cols++; - } - } - else - mylog("%d null bind\n", i); - } - if (upd_cols > 0) - { - HSTMT hstmt; - int j; - int res_cols = QR_NumResultCols(res); - ConnInfo *ci = &(conn->connInfo); - StatementClass *qstmt; - APDFields *apdopts; - Int4 fieldtype = 0; - - /*sprintf(updstr, "%s where ctid = '%s' and oid = %s", updstr, - tidval, oidval);*/ - sprintf(updstr, "%s where ctid = '(%u, %u)' and oid = %u", updstr, - blocknum, pgoffset, oid); - mylog("updstr=%s\n", updstr); - if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS) - return SQL_ERROR; - qstmt = (StatementClass *) hstmt; - apdopts = SC_get_APD(qstmt); - apdopts->param_bind_type = opts->bind_size; - apdopts->param_offset_ptr = opts->row_offset_ptr; - for (i = j = 0; i < num_cols; i++) - { - if (used = bindings[i].used, used != NULL) - { - used += (offset >> 2); - if (bind_size > 0) - used += (bind_size * irow / 4); - else - used += irow; - mylog("%d used=%d\n", i, *used); - if (*used != SQL_IGNORE && fi[i]->updatable) - { - fieldtype = QR_get_field_type(res, i); - PGAPI_BindParameter(hstmt, (SQLUSMALLINT) ++j, - SQL_PARAM_INPUT, bindings[i].returntype, - pgtype_to_concise_type(stmt, fieldtype), - fi[i]->column_size > 0 ? fi[i]->column_size : pgtype_column_size(stmt, fieldtype, i, ci->drivers.unknown_sizes), - (SQLSMALLINT) fi[i]->decimal_digits, - bindings[i].buffer, - bindings[i].buflen, - bindings[i].used); - } - } - } - qstmt->exec_start_row = qstmt->exec_end_row = irow; - ret = PGAPI_ExecDirect(hstmt, updstr, strlen(updstr)); - if (ret == SQL_ERROR) - { - stmt->errornumber = qstmt->errornumber; - stmt->errormsg = qstmt->errormsg; - } - else if (ret == SQL_NEED_DATA) /* must be fixed */ - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; - stmt->errormsg = "SetPos with data_at_exec not yet supported"; - ret = SQL_ERROR; - } - ret = irow_update(ret, stmt, qstmt, irow, global_ridx); - PGAPI_FreeStmt(hstmt, SQL_DROP); - } - else - { - ret = SQL_SUCCESS_WITH_INFO; - stmt->errormsg = "update list null"; - } - if (SQL_SUCCESS == ret && res->keyset) - { - if (CC_is_in_trans(conn)) - { - res->keyset[global_ridx].status |= (SQL_ROW_UPDATED | CURS_SELF_UPDATING); - } - else - res->keyset[global_ridx].status |= (SQL_ROW_UPDATED | CURS_SELF_UPDATED); - } -#if (ODBCVER >= 0x0300) - if (irdflds->rowStatusArray) - { - switch (ret) - { - case SQL_SUCCESS: - irdflds->rowStatusArray[irow] = SQL_ROW_UPDATED; - break; - default: - irdflds->rowStatusArray[irow] = ret; - } - } -#endif /* ODBCVER */ - - return ret; -} -RETCODE -SC_pos_delete(StatementClass *stmt, - UWORD irow, UDWORD global_ridx) -{ - UWORD offset; - QResultClass *res, *qres; - ConnectionClass *conn = SC_get_conn(stmt); - ARDFields *opts = SC_get_ARD(stmt); - IRDFields *irdflds = SC_get_IRD(stmt); - BindInfoClass *bindings = opts->bindings; - char dltstr[4096]; - RETCODE ret; - UInt4 oid, blocknum, qflag; - - mylog("POS DELETE ti=%x\n", stmt->ti); - if (!(res = SC_get_Curres(stmt))) - return SQL_ERROR; - if (!stmt->ti) - parse_statement(stmt); /* not preferable */ - if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - if (!(oid = getOid(res, global_ridx))) - { - stmt->errormsg = "The row is already deleted"; - return SQL_ERROR; - } - getTid(res, global_ridx, &blocknum, &offset); - /*sprintf(dltstr, "delete from \"%s\" where ctid = '%s' and oid = %s",*/ - if (stmt->ti[0]->schema[0]) - sprintf(dltstr, "delete from \"%s\".\"%s\" where ctid = '(%u, %u)' and oid = %u", - stmt->ti[0]->schema, stmt->ti[0]->name, blocknum, offset, oid); - else - sprintf(dltstr, "delete from \"%s\" where ctid = '(%u, %u)' and oid = %u", - stmt->ti[0]->name, blocknum, offset, oid); - - mylog("dltstr=%s\n", dltstr); - qflag = CLEAR_RESULT_ON_ABORT; - if (!stmt->internal && !CC_is_in_trans(conn) && - (!CC_is_in_autocommit(conn))) - qflag |= GO_INTO_TRANSACTION; - qres = CC_send_query(conn, dltstr, NULL, qflag); - ret = SQL_SUCCESS; - if (qres && QR_command_maybe_successful(qres)) - { - int dltcnt; - const char *cmdstr = QR_get_command(qres); - - if (cmdstr && - sscanf(cmdstr, "DELETE %d", &dltcnt) == 1) - { - if (dltcnt == 1) - SC_pos_reload(stmt, global_ridx, (UWORD *) 0, TRUE); - else if (dltcnt == 0) - { - stmt->errornumber = STMT_ROW_VERSION_CHANGED; - stmt->errormsg = "the content was changed before deletion"; - ret = SQL_ERROR; - if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) - SC_pos_reload(stmt, global_ridx, (UWORD *) 0, FALSE); - } - else - ret = SQL_ERROR; - } - else - ret = SQL_ERROR; - } - else - ret = SQL_ERROR; - if (ret == SQL_ERROR && stmt->errornumber == 0) - { - stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; - stmt->errormsg = "SetPos delete return error"; - } - if (qres) - QR_Destructor(qres); - if (SQL_SUCCESS == ret && res->keyset) - { - AddDeleted(res, global_ridx); - if (CC_is_in_trans(conn)) - { - res->keyset[global_ridx].status |= (SQL_ROW_DELETED | CURS_SELF_DELETING); - } - else - res->keyset[global_ridx].status |= (SQL_ROW_DELETED | CURS_SELF_DELETED); - } -#if (ODBCVER >= 0x0300) - if (irdflds->rowStatusArray) - { - switch (ret) - { - case SQL_SUCCESS: - irdflds->rowStatusArray[irow] = SQL_ROW_DELETED; - break; - default: - irdflds->rowStatusArray[irow] = ret; - } - } -#endif /* ODBCVER */ - return ret; -} - -static RETCODE SQL_API -irow_insert(RETCODE ret, StatementClass *stmt, StatementClass *istmt, int addpos) -{ - if (ret != SQL_ERROR) - { - int addcnt; - UInt4 oid; - ARDFields *opts = SC_get_ARD(stmt); - QResultClass *ires = SC_get_Curres(istmt); - const char *cmdstr; - - cmdstr = QR_get_command((ires->next ? ires->next : ires)); - if (cmdstr && - sscanf(cmdstr, "INSERT %u %d", &oid, &addcnt) == 2 && - addcnt == 1) - { - ConnectionClass *conn = SC_get_conn(stmt); - RETCODE qret; - - qret = SQL_NO_DATA_FOUND; - if (PG_VERSION_GE(conn, 7.2)) - { - qret = SC_pos_newload(stmt, oid, TRUE); - if (SQL_ERROR == qret) - return qret; - } - if (SQL_NO_DATA_FOUND == qret) - { - qret = SC_pos_newload(stmt, oid, FALSE); - if (SQL_ERROR == qret) - return qret; - } - if (opts->bookmark->buffer) - { - char buf[32]; - UInt4 offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0; - - sprintf(buf, "%ld", addpos + 1); - copy_and_convert_field(stmt, 0, buf, - SQL_C_ULONG, opts->bookmark->buffer + offset, - 0, opts->bookmark->used ? opts->bookmark->used - + (offset >> 2) : NULL); - } - } - else - { - stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; - stmt->errormsg = "SetPos insert return error"; - } - } - return ret; -} -RETCODE -SC_pos_add(StatementClass *stmt, - UWORD irow) -{ - int num_cols, - add_cols, - i; - HSTMT hstmt; - StatementClass *qstmt; - ConnectionClass *conn; - ConnInfo *ci; - QResultClass *res; - ARDFields *opts = SC_get_ARD(stmt); - IRDFields *irdflds = SC_get_IRD(stmt); - APDFields *apdopts; - BindInfoClass *bindings = opts->bindings; - FIELD_INFO **fi = SC_get_IRD(stmt)->fi; - char addstr[4096]; - RETCODE ret; - UInt4 offset; - Int4 *used, bind_size = opts->bind_size; - Int4 fieldtype; - - mylog("POS ADD fi=%x ti=%x\n", fi, stmt->ti); - if (!(res = SC_get_Curres(stmt))) - return SQL_ERROR; - if (!stmt->ti) - parse_statement(stmt); /* not preferable */ - if (!stmt->updatable) - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - return SQL_ERROR; - } - num_cols = irdflds->nfields; - conn = SC_get_conn(stmt); - if (stmt->ti[0]->schema[0]) - sprintf(addstr, "insert into \"%s\".\"%s\" (", stmt->ti[0]->schema, stmt->ti[0]->name); - else - sprintf(addstr, "insert into \"%s\" (", stmt->ti[0]->name); - if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS) - return SQL_ERROR; - if (opts->row_offset_ptr) - offset = *opts->row_offset_ptr; - else - offset = 0; - qstmt = (StatementClass *) hstmt; - apdopts = SC_get_APD(qstmt); - apdopts->param_bind_type = opts->bind_size; - apdopts->param_offset_ptr = opts->row_offset_ptr; - ci = &(conn->connInfo); - for (i = add_cols = 0; i < num_cols; i++) - { - if (used = bindings[i].used, used != NULL) - { - used += (offset >> 2); - if (bind_size > 0) - used += (bind_size * irow / 4); - else - used += irow; - mylog("%d used=%d\n", i, *used); - if (*used != SQL_IGNORE && fi[i]->updatable) - { - fieldtype = QR_get_field_type(res, i); - if (add_cols) - sprintf(addstr, "%s, \"%s\"", addstr, fi[i]->name); - else - sprintf(addstr, "%s\"%s\"", addstr, fi[i]->name); - PGAPI_BindParameter(hstmt, (SQLUSMALLINT) ++add_cols, - SQL_PARAM_INPUT, bindings[i].returntype, - pgtype_to_concise_type(stmt, fieldtype), - fi[i]->column_size > 0 ? fi[i]->column_size : pgtype_column_size(stmt, fieldtype, i, ci->drivers.unknown_sizes), - (SQLSMALLINT) fi[i]->decimal_digits, - bindings[i].buffer, - bindings[i].buflen, - bindings[i].used); - } - } - else - mylog("%d null bind\n", i); - } - if (add_cols > 0) - { - int brow_save; - - sprintf(addstr, "%s) values (", addstr); - for (i = 0; i < add_cols; i++) - { - if (i) - strcat(addstr, ", ?"); - else - strcat(addstr, "?"); - } - strcat(addstr, ")"); - mylog("addstr=%s\n", addstr); - qstmt->exec_start_row = qstmt->exec_end_row = irow; - ret = PGAPI_ExecDirect(hstmt, addstr, strlen(addstr)); - if (ret == SQL_ERROR) - { - stmt->errornumber = qstmt->errornumber; - stmt->errormsg = qstmt->errormsg; - } - else if (ret == SQL_NEED_DATA) /* must be fixed */ - { - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; - stmt->errormsg = "SetPos with data_at_exec not yet supported"; - ret = SQL_ERROR; - } - brow_save = stmt->bind_row; - stmt->bind_row = irow; - ret = irow_insert(ret, stmt, qstmt, res->num_total_rows); - stmt->bind_row = brow_save; - } - else - { - ret = SQL_SUCCESS_WITH_INFO; - stmt->errormsg = "insert list null"; - } - PGAPI_FreeStmt(hstmt, SQL_DROP); - if (SQL_SUCCESS == ret && res->keyset) - { - int global_ridx = res->num_total_rows + stmt->rowset_start - res->base - 1; - if (CC_is_in_trans(conn)) - { - - AddRollback(conn, res, global_ridx, NULL); - res->keyset[global_ridx].status |= (SQL_ROW_ADDED | CURS_SELF_ADDING); - } - else - res->keyset[global_ridx].status |= (SQL_ROW_ADDED | CURS_SELF_ADDED); - } -#if (ODBCVER >= 0x0300) - if (irdflds->rowStatusArray) - { - switch (ret) - { - case SQL_SUCCESS: - irdflds->rowStatusArray[irow] = SQL_ROW_ADDED; - break; - default: - irdflds->rowStatusArray[irow] = ret; - } - } -#endif /* ODBCVER */ - - return ret; -} - -/* - * Stuff for updatable cursors end. - */ -#endif /* DRIVER_CURSOR_IMPLEMENT */ - -RETCODE -SC_pos_refresh(StatementClass *stmt, UWORD irow , UDWORD global_ridx) -{ - RETCODE ret; -#if (ODBCVER >= 0x0300) - IRDFields *irdflds = SC_get_IRD(stmt); -#endif /* ODBCVER */ - /* save the last_fetch_count */ - int last_fetch = stmt->last_fetch_count; - int last_fetch2 = stmt->last_fetch_count_include_ommitted; - int bind_save = stmt->bind_row; - -#ifdef DRIVER_CURSOR_IMPLEMENT - if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) - SC_pos_reload(stmt, global_ridx, (UWORD *) 0, FALSE); -#endif /* DRIVER_CURSOR_IMPLEMENT */ - stmt->bind_row = irow; - ret = SC_fetch(stmt); - /* restore the last_fetch_count */ - stmt->last_fetch_count = last_fetch; - stmt->last_fetch_count_include_ommitted = last_fetch2; - stmt->bind_row = bind_save; -#if (ODBCVER >= 0x0300) - if (irdflds->rowStatusArray) - { - switch (ret) - { - case SQL_ERROR: - irdflds->rowStatusArray[irow] = SQL_ROW_ERROR; - break; - case SQL_SUCCESS: - irdflds->rowStatusArray[irow] = SQL_ROW_SUCCESS; - break; - case SQL_SUCCESS_WITH_INFO: - default: - irdflds->rowStatusArray[irow] = ret; - break; - } - } -#endif /* ODBCVER */ - - return SQL_SUCCESS; -} - -/* - * This positions the cursor within a rowset, that was positioned using SQLExtendedFetch. - * This will be useful (so far) only when using SQLGetData after SQLExtendedFetch. - */ -RETCODE SQL_API -PGAPI_SetPos( - HSTMT hstmt, - UWORD irow, - UWORD fOption, - UWORD fLock) -{ - static char *func = "PGAPI_SetPos"; - RETCODE ret; - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn = SC_get_conn(stmt); - QResultClass *res; - int num_cols, i, start_row, end_row, processed, ridx; - UWORD nrow; - ARDFields *opts; - BindInfoClass *bindings; - UDWORD global_ridx; - BOOL auto_commit_needed = FALSE; - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - opts = SC_get_ARD(stmt); - bindings = opts->bindings; -#ifdef DRIVER_CURSOR_IMPLEMENT - mylog("%s fOption=%d irow=%d lock=%d currt=%d\n", func, fOption, irow, fLock, stmt->currTuple); - if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY) - ; - else -#endif /* DRIVER_CURSOR_IMPLEMENT */ - if (fOption != SQL_POSITION && fOption != SQL_REFRESH) - { - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Only SQL_POSITION/REFRESH is supported for PGAPI_SetPos"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (!(res = SC_get_Curres(stmt))) - { - stmt->errormsg = "Null statement result in PGAPI_SetPos."; - stmt->errornumber = STMT_SEQUENCE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - if (irow == 0) /* bulk operation */ - { - if (SQL_POSITION == fOption) - { - stmt->errornumber = STMT_INVALID_CURSOR_POSITION; - stmt->errormsg = "Bulk Position operations not allowed."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - start_row = 0; - end_row = opts->rowset_size - 1; - } - else - { - if (irow > stmt->last_fetch_count) - { - stmt->errornumber = STMT_ROW_OUT_OF_RANGE; - stmt->errormsg = "Row value out of range"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - start_row = end_row = irow - 1; - } - - num_cols = QR_NumResultCols(res); - /* Reset for SQLGetData */ - if (bindings) - for (i = 0; i < num_cols; i++) - bindings[i].data_left = -1; - ret = SQL_SUCCESS; -#ifdef DRIVER_CURSOR_IMPLEMENT - switch (fOption) - { - case SQL_UPDATE: - case SQL_DELETE: - case SQL_ADD: - if (auto_commit_needed = CC_is_in_autocommit(conn), auto_commit_needed) - PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); - break; - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - ridx = -1; - for (i = nrow = 0, processed = 0; nrow <= end_row; i++) - { - global_ridx = i + stmt->rowset_start; - if (SQL_ADD != fOption) - { - if ((int) global_ridx >= res->num_total_rows) - break; -#ifdef DRIVER_CURSOR_IMPLEMENT - if (res->keyset) /* the row may be deleted and not in the rowset */ - { - if (0 == (res->keyset[global_ridx].status & CURS_IN_ROWSET)) - continue; - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - } - if (nrow < start_row) - { - nrow++; - continue; - } - ridx = nrow; -#if (ODBCVER >= 0x0300) - if (0 != irow || !opts->row_operation_ptr || opts->row_operation_ptr[nrow] == SQL_ROW_PROCEED) - { -#endif /* ODBCVER */ - switch (fOption) - { -#ifdef DRIVER_CURSOR_IMPLEMENT - case SQL_UPDATE: - ret = SC_pos_update(stmt, nrow, global_ridx); - break; - case SQL_DELETE: - ret = SC_pos_delete(stmt, nrow, global_ridx); - break; - case SQL_ADD: - ret = SC_pos_add(stmt, nrow); - break; -#endif /* DRIVER_CURSOR_IMPLEMENT */ - case SQL_REFRESH: - ret = SC_pos_refresh(stmt, nrow, global_ridx); - break; - } - processed++; - if (SQL_ERROR == ret) - break; -#if (ODBCVER >= 0x0300) - } -#endif /* ODBCVER */ - nrow++; - } - if (SQL_ERROR == ret) - CC_abort(conn); - if (auto_commit_needed) - PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON); - if (irow > 0) - { - if (SQL_ADD != fOption && ridx >= 0) /* for SQLGetData */ - { - stmt->currTuple = stmt->rowset_start + ridx; - QR_set_position(res, ridx); - } - } - else if (SC_get_IRD(stmt)->rowsFetched) - *(SC_get_IRD(stmt)->rowsFetched) = processed; - res->recent_processed_row_count = stmt->diag_row_count = processed; -inolog("rowset=%d processed=%d ret=%d\n", opts->rowset_size, processed, ret); - return ret; -} - - -/* Sets options that control the behavior of cursors. */ -RETCODE SQL_API -PGAPI_SetScrollOptions( HSTMT hstmt, - UWORD fConcurrency, - SDWORD crowKeyset, - UWORD crowRowset) -{ - static char *func = "PGAPI_SetScrollOptions"; - StatementClass *stmt = (StatementClass *) hstmt; - - mylog("PGAPI_SetScrollOptions fConcurrency=%d crowKeyset=%d crowRowset=%d\n", - fConcurrency, crowKeyset, crowRowset); - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "SetScroll option not implemeted"; - - SC_log_error(func, "Function not implemented", hstmt); - return SQL_ERROR; -} - - -/* Set the cursor name on a statement handle */ -RETCODE SQL_API -PGAPI_SetCursorName( - HSTMT hstmt, - UCHAR FAR * szCursor, - SWORD cbCursor) -{ - static char *func = "PGAPI_SetCursorName"; - StatementClass *stmt = (StatementClass *) hstmt; - int len; - - mylog("PGAPI_SetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n", hstmt, szCursor, cbCursor); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - len = (cbCursor == SQL_NTS) ? strlen(szCursor) : cbCursor; - - if (len <= 0 || len > sizeof(stmt->cursor_name) - 1) - { - stmt->errornumber = STMT_INVALID_CURSOR_NAME; - stmt->errormsg = "Invalid Cursor Name"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - strncpy_null(stmt->cursor_name, szCursor, len + 1); - return SQL_SUCCESS; -} - - -/* Return the cursor name for a statement handle */ -RETCODE SQL_API -PGAPI_GetCursorName( - HSTMT hstmt, - UCHAR FAR * szCursor, - SWORD cbCursorMax, - SWORD FAR * pcbCursor) -{ - static char *func = "PGAPI_GetCursorName"; - StatementClass *stmt = (StatementClass *) hstmt; - int len = 0; - RETCODE result; - - mylog("PGAPI_GetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", hstmt, szCursor, cbCursorMax, pcbCursor); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - if (stmt->cursor_name[0] == '\0') - { - stmt->errornumber = STMT_NO_CURSOR_NAME; - stmt->errormsg = "No Cursor name available"; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - result = SQL_SUCCESS; - len = strlen(stmt->cursor_name); - - if (szCursor) - { - strncpy_null(szCursor, stmt->cursor_name, cbCursorMax); - - if (len >= cbCursorMax) - { - result = SQL_SUCCESS_WITH_INFO; - stmt->errornumber = STMT_TRUNCATED; - stmt->errormsg = "The buffer was too small for the GetCursorName."; - } - } - - if (pcbCursor) - *pcbCursor = len; - - return result; -} diff --git a/src/interfaces/odbc/setup.c b/src/interfaces/odbc/setup.c deleted file mode 100644 index 7320cbba58..0000000000 --- a/src/interfaces/odbc/setup.c +++ /dev/null @@ -1,409 +0,0 @@ -/*------- - * Module: setup.c - * - * Description: This module contains the setup functions for - * adding/modifying a Data Source in the ODBC.INI portion - * of the registry. - * - * Classes: n/a - * - * API functions: ConfigDSN - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "psqlodbc.h" - -#include "connection.h" -#include -#include -#include -#include "resource.h" -#include "dlg_specific.h" -#include "win_setup.h" - - -#define INTFUNC __stdcall - -extern HINSTANCE NEAR s_hModule; /* Saved module handle. */ -extern GLOBAL_VALUES globals; - -/* Constants */ -#define MIN(x,y) ((x) < (y) ? (x) : (y)) - -#ifdef WIN32 -#define MAXPGPATH (255+1) -#endif - -#define MAXKEYLEN (15+1) /* Max keyword length */ -#define MAXDESC (255+1) /* Max description length */ -#define MAXDSNAME (32+1) /* Max data source name length */ - - -/*-------- - * ConfigDSN - * - * Description: ODBC Setup entry point - * This entry point is called by the ODBC Installer - * (see file header for more details) - * Input : hwnd ----------- Parent window handle - * fRequest ------- Request type (i.e., add, config, or remove) - * lpszDriver ----- Driver name - * lpszAttributes - data source attribute string - * Output : TRUE success, FALSE otherwise - *-------- - */ -BOOL CALLBACK -ConfigDSN(HWND hwnd, - WORD fRequest, - LPCSTR lpszDriver, - LPCSTR lpszAttributes) -{ - BOOL fSuccess; /* Success/fail flag */ - GLOBALHANDLE hglbAttr; - LPSETUPDLG lpsetupdlg; - - - /* Allocate attribute array */ - hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG)); - if (!hglbAttr) - return FALSE; - lpsetupdlg = (LPSETUPDLG) GlobalLock(hglbAttr); - /* Parse attribute string */ - if (lpszAttributes) - ParseAttributes(lpszAttributes, lpsetupdlg); - - /* Save original data source name */ - if (lpsetupdlg->ci.dsn[0]) - lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn); - else - lpsetupdlg->szDSN[0] = '\0'; - - /* Remove data source */ - if (ODBC_REMOVE_DSN == fRequest) - { - /* Fail if no data source name was supplied */ - if (!lpsetupdlg->ci.dsn[0]) - fSuccess = FALSE; - - /* Otherwise remove data source from ODBC.INI */ - else - fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn); - } - /* Add or Configure data source */ - else - { - /* Save passed variables for global access (e.g., dialog access) */ - lpsetupdlg->hwndParent = hwnd; - lpsetupdlg->lpszDrvr = lpszDriver; - lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest); - lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN); - - /* - * Display the appropriate dialog (if parent window handle - * supplied) - */ - if (hwnd) - { - /* Display dialog(s) */ - fSuccess = (IDOK == DialogBoxParam(s_hModule, - MAKEINTRESOURCE(DLG_CONFIG), - hwnd, - ConfigDlgProc, - (LONG) (LPSTR) lpsetupdlg)); - } - else if (lpsetupdlg->ci.dsn[0]) - fSuccess = SetDSNAttributes(hwnd, lpsetupdlg); - else - fSuccess = FALSE; - } - - GlobalUnlock(hglbAttr); - GlobalFree(hglbAttr); - - return fSuccess; -} - - -/*------- - * CenterDialog - * - * Description: Center the dialog over the frame window - * Input : hdlg -- Dialog window handle - * Output : None - *------- - */ -void INTFUNC -CenterDialog(HWND hdlg) -{ - HWND hwndFrame; - RECT rcDlg, - rcScr, - rcFrame; - int cx, - cy; - - hwndFrame = GetParent(hdlg); - - GetWindowRect(hdlg, &rcDlg); - cx = rcDlg.right - rcDlg.left; - cy = rcDlg.bottom - rcDlg.top; - - GetClientRect(hwndFrame, &rcFrame); - ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.left)); - ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.right)); - rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1); - rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1); - rcDlg.bottom = rcDlg.top + cy; - rcDlg.right = rcDlg.left + cx; - - GetWindowRect(GetDesktopWindow(), &rcScr); - if (rcDlg.bottom > rcScr.bottom) - { - rcDlg.bottom = rcScr.bottom; - rcDlg.top = rcDlg.bottom - cy; - } - if (rcDlg.right > rcScr.right) - { - rcDlg.right = rcScr.right; - rcDlg.left = rcDlg.right - cx; - } - - if (rcDlg.left < 0) - rcDlg.left = 0; - if (rcDlg.top < 0) - rcDlg.top = 0; - - MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE); - return; -} - -/*------- - * ConfigDlgProc - * Description: Manage add data source name dialog - * Input : hdlg --- Dialog window handle - * wMsg --- Message - * wParam - Message parameter - * lParam - Message parameter - * Output : TRUE if message processed, FALSE otherwise - *------- - */ -int CALLBACK -ConfigDlgProc(HWND hdlg, - UINT wMsg, - WPARAM wParam, - LPARAM lParam) -{ - LPSETUPDLG lpsetupdlg; - ConnInfo *ci; - DWORD cmd; - - switch (wMsg) - { - /* Initialize the dialog */ - case WM_INITDIALOG: - lpsetupdlg = (LPSETUPDLG) lParam; - ci = &lpsetupdlg->ci; - - /* Hide the driver connect message */ - ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE); - SetWindowText(GetDlgItem(hdlg, IDOK), "Save"); - - SetWindowLong(hdlg, DWL_USER, lParam); - CenterDialog(hdlg); /* Center dialog */ - - /* - * NOTE: Values supplied in the attribute string will always - */ - /* override settings in ODBC.INI */ - - memcpy(&ci->drivers, &globals, sizeof(globals)); - /* Get the rest of the common attributes */ - getDSNinfo(ci, CONN_DONT_OVERWRITE); - - /* Fill in any defaults */ - getDSNdefaults(ci); - - /* Initialize dialog fields */ - SetDlgStuff(hdlg, ci); - - if (lpsetupdlg->fDefault) - { - EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE); - EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE); - } - else - SendDlgItemMessage(hdlg, IDC_DSNAME, - EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L); - - SendDlgItemMessage(hdlg, IDC_DESC, - EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L); - return TRUE; /* Focus was not set */ - - /* Process buttons */ - case WM_COMMAND: - switch (cmd = GET_WM_COMMAND_ID(wParam, lParam)) - { - /* - * Ensure the OK button is enabled only when a data - * source name - */ - /* is entered */ - case IDC_DSNAME: - if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE) - { - char szItem[MAXDSNAME]; /* Edit control text */ - - /* Enable/disable the OK button */ - EnableWindow(GetDlgItem(hdlg, IDOK), - GetDlgItemText(hdlg, IDC_DSNAME, - szItem, sizeof(szItem))); - return TRUE; - } - break; - - /* Accept results */ - case IDOK: - case IDAPPLY: - lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER); - /* Retrieve dialog values */ - if (!lpsetupdlg->fDefault) - GetDlgItemText(hdlg, IDC_DSNAME, - lpsetupdlg->ci.dsn, - sizeof(lpsetupdlg->ci.dsn)); - /* Get Dialog Values */ - GetDlgStuff(hdlg, &lpsetupdlg->ci); - - /* Update ODBC.INI */ - SetDSNAttributes(hdlg, lpsetupdlg); - if (IDAPPLY == cmd) - break; - /* Return to caller */ - case IDCANCEL: - EndDialog(hdlg, wParam); - return TRUE; - - case IDC_DATASOURCE: - lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER); - DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV), - hdlg, ds_options1Proc, (LPARAM) &lpsetupdlg->ci); - return TRUE; - - case IDC_DRIVER: - lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER); - DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_GLOBAL), - hdlg, global_optionsProc, (LPARAM) &lpsetupdlg->ci); - - return TRUE; - } - break; - } - - /* Message not processed */ - return FALSE; -} - - -/*------- - * ParseAttributes - * - * Description: Parse attribute string moving values into the aAttr array - * Input : lpszAttributes - Pointer to attribute string - * Output : None (global aAttr normally updated) - *------- - */ -void INTFUNC -ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg) -{ - LPCSTR lpsz; - LPCSTR lpszStart; - char aszKey[MAXKEYLEN]; - int cbKey; - char value[MAXPGPATH]; - - CC_conninfo_init(&(lpsetupdlg->ci)); - - for (lpsz = lpszAttributes; *lpsz; lpsz++) - { - /* - * Extract key name (e.g., DSN), it must be terminated by an - * equals - */ - lpszStart = lpsz; - for (;; lpsz++) - { - if (!*lpsz) - return; /* No key was found */ - else if (*lpsz == '=') - break; /* Valid key found */ - } - /* Determine the key's index in the key table (-1 if not found) */ - cbKey = lpsz - lpszStart; - if (cbKey < sizeof(aszKey)) - { - _fmemcpy(aszKey, lpszStart, cbKey); - aszKey[cbKey] = '\0'; - } - - /* Locate end of key value */ - lpszStart = ++lpsz; - for (; *lpsz; lpsz++) - ; - - /* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */ - _fmemcpy(value, lpszStart, MIN(lpsz - lpszStart + 1, MAXPGPATH)); - - mylog("aszKey='%s', value='%s'\n", aszKey, value); - - /* Copy the appropriate value to the conninfo */ - copyAttributes(&lpsetupdlg->ci, aszKey, value); - } - return; -} - - -/*-------- - * SetDSNAttributes - * - * Description: Write data source attributes to ODBC.INI - * Input : hwnd - Parent window handle (plus globals) - * Output : TRUE if successful, FALSE otherwise - *-------- - */ -BOOL INTFUNC -SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg) -{ - LPCSTR lpszDSN; /* Pointer to data source name */ - - lpszDSN = lpsetupdlg->ci.dsn; - - /* Validate arguments */ - if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn) - return FALSE; - - /* Write the data source name */ - if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr)) - { - if (hwndParent) - { - char szBuf[MAXPGPATH]; - char szMsg[MAXPGPATH]; - - LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf)); - wsprintf(szMsg, szBuf, lpszDSN); - LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf)); - MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK); - } - return FALSE; - } - - /* Update ODBC.INI */ - writeDriverCommoninfo(&lpsetupdlg->ci); - writeDSNinfo(&lpsetupdlg->ci); - - /* If the data source name has changed, remove the old name */ - if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn)) - SQLRemoveDSNFromIni(lpsetupdlg->szDSN); - return TRUE; -} diff --git a/src/interfaces/odbc/setup.rul b/src/interfaces/odbc/setup.rul deleted file mode 100644 index a4f52a03f7..0000000000 --- a/src/interfaces/odbc/setup.rul +++ /dev/null @@ -1,495 +0,0 @@ -/* -# Insight Distribution Systems - System V - Apr 1998 -#ident "@(#)setup.rul 1.13 :/sccs/sql/odbc/s.setup.rul 1/6/99 14:47:48" -*/ - -/*----------------------------------------------------------------------------*\ - * - * PostgreSQL ODBC Driver Installation Script for InstallShield - * -\*----------------------------------------------------------------------------*/ - - -#define APP_NAME "PostgreSQL ODBC Driver" -#define DRIVER_NAME "PostgreSQL" -#define DRIVER_FILE "PSQLODBC.DLL" -#define OLD_DRIVER_FILE "PODBC32.DLL" -#define OLD_DRIVER_FILE_RENAMED "podbc32_sav.dll" - -#define COMPANY_NAME "Insight" -#define PRODUCT_NAME "PostgreSQL ODBC Driver" -#define PRODUCT_VERSION "6.3" -#define PRODUCT_KEY "PSQLODBC.DLL" -#define UNINSTALL_KEY "PSQLODBCv6.3" - -#define ODBC_DM_KEY "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs" -#define ODBC_COMP_KEY "\\SOFTWARE\\ODBC\\ODBCINST.INI" -#define ODBC_CORE_KEY "\\SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Core" -#define ODBC_DRIVERS_KEY "\\SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers" - - -declare - // functions - prototype SetupScreen(); - prototype FileCompare(STRING, STRING, STRING, STRING); - - // variables - STRING svMainDirectory [_MAX_STRING], svGrp, svUninstLogFile, svPath; - STRING svValue, szName, szKey, szMessage; - STRING szMsg, szTmp, szTmp2, szFileSet, szProgram; - NUMBER nResult, pos, nvType, nvSize, nStartup, ComponentUsageCount; - - NUMBER nvDoNot, nvVersion, nvInstall, nCore, nDM; - STRING dm, core, szFileName, svFileName; - NUMBER options, nvInfo, nvResult; - LONG lResult; - STRING svCompVersion, svFileVersion, svCompDate, svCompTime, svFileDate, svFileTime; - -program - -StartHere: - Disable( BACKGROUND ); - - // Set up the installation screen. - SetupScreen(); - InstallationInfo(COMPANY_NAME, PRODUCT_NAME, PRODUCT_VERSION, PRODUCT_KEY); - RegDBSetAppInfo("Location", REGDB_STRING, WINSYSDIR ^ DRIVER_FILE, -1); - -// Create a Welcome dialog. -WelcomeDlg: - Disable( BACKBUTTON ); - Welcome( "Welcome to the PostgreSQL Odbc Driver Installation", 0 ); - Enable( BACKBUTTON ); - Enable( NEXTBUTTON ); - -GetTargetDirectory: - svMainDirectory = WINSYSDIR; - -OptionsDlg: - RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); - szKey = ODBC_DM_KEY; - nCore = RegDBKeyExist(szKey); - - szName = WINSYSDIR ^ "ODBC32.DLL"; - nDM = RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize); - - szMessage = "Select options for installing the ODBC Driver Manager.\n" + - "Analysis of your system suggests that the ODBC Driver Manager\n"; - - nvDoNot = FALSE; - nvInstall = FALSE; - nvVersion = FALSE; - if (nCore >= 0 && nDM >= 0) then - nvDoNot = TRUE; - szMessage = szMessage + "is already installed. Therefore, you may choose not to install it."; - else - nvInstall = TRUE; - szMessage = szMessage + "is not installed. Therefore, you should install it now."; - endif; - - Enable(FINISHBUTTON); - nResult = AskOptions(EXCLUSIVE, szMessage, - "Do not install Driver Manager", nvDoNot, - "Install Driver Manager ", nvInstall, - "Install Driver Manager (with version checking)", nvVersion); - - if (nResult = BACK) then - Disable(FINISHBUTTON); - goto WelcomeDlg; - endif; - -Version: - CompressInfo("driver.z", DRIVER_FILE, COMP_INFO_VERSIONMS|COMP_INFO_VERSIONLS, nvInfo, svCompVersion); - - szFileName = WINSYSDIR ^ DRIVER_FILE; - nResult = VerGetFileVersion(szFileName, svFileVersion); - - // MessageBox("System file PSQLODBC.dll version is " + svFileVersion, INFORMATION); - - lResult = VerCompare(svCompVersion, svFileVersion, VERSION); - - if (lResult = EQUALS) then - //date - CompressInfo("driver.z", DRIVER_FILE, COMP_INFO_DATE, nvInfo, svCompDate); - GetFileInfo(szFileName, FILE_DATE, nvResult, svFileDate); - - //time - CompressInfo("driver.z", DRIVER_FILE, COMP_INFO_TIME, nvInfo, svCompTime); - GetFileInfo(szFileName, FILE_TIME, nvResult, svFileTime); - - // If compressed file date/time is earlier than system file date/time - // then - nResult = FileCompare(svCompDate, svCompTime, svFileDate, svFileTime); - if (nResult < 0) then - lResult = LESS_THAN; - endif; - - NumToStr(szTmp, nResult); - // MessageBox("File Compare = " + szTmp, INFORMATION); - endif; - - if (lResult = LESS_THAN) then - MessageBeep(0); - nResult = AskYesNo("The " + PRODUCT_NAME + " is already installed on your system \nand is a newer version than the one that is about to be installed.\n\n" + - "Would you like to continue the installation anyway (not recommended)?", NO); - if (nResult = NO) then - MessageBeep(0); - MessageBox("Installation has been aborted.\nNo changes have been made to your system.", WARNING); - exit; - endif; - else - /* - nResult = AskYesNo("Ready to install " + PRODUCT_NAME + ".\n\nPress Yes to proceed with the installation.\nPress No to abort the installation.", YES); - if (nResult = NO) then - MessageBeep(0); - MessageBox("Installation has been aborted.\nNo changes have been made to your system.", WARNING); - exit; - endif; - */ - endif; - -CheckRegistry: - Enable(STATUSDLG); - - SetStatusWindow(5, "Checking registry entries..."); - Delay(1); - - RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); - szKey = ODBC_DM_KEY; - nResult = RegDBKeyExist(szKey); - if (nResult < 0 && nvDoNot = TRUE) then - MessageBeep(0); - MessageBox("ODBC Core Components are not installed!", SEVERE); - Disable(STATUSDLG); - MessageBeep(0); - MessageBox("Please install the ODBC Core Components\nand rerun this setup program.", INFORMATION); - exit; - endif; - - szName = WINSYSDIR ^ "ODBC32.DLL"; - nResult = RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize); - if (nResult < 0 && nvDoNot = TRUE) then - MessageBeep(0); - MessageBox("ODBC Driver Manager (ODBC32.DLL) is not installed!", SEVERE); - Disable(STATUSDLG); - MessageBeep(0); - MessageBox("Please install the ODBC Driver Manager\nand rerun this setup program.", INFORMATION); - exit; - endif; - - -FileSetup: - - SetStatusWindow( 10, "Copying program files..."); - StatusUpdate(ON, 90); - - DeinstallStart(svMainDirectory, svUninstLogFile, UNINSTALL_KEY, 0); - - // Show the uninstall under Add/Remove Programs in Control Panel - RegDBSetItem(REGDB_UNINSTALL_NAME, PRODUCT_NAME); - - szFileSet = "psqlodbc"; - - TARGETDIR = svMainDirectory; // winsys - - FileSetBeginDefine(szFileSet); - - - nResult = CompressGet("driver.z", "*.*", COMP_NORMAL); - if (nResult < 0) then - NumToStr(szTmp, nResult); - MessageBox("Compress Get Error on driver.z files.\n\nError # " + szTmp, SEVERE); - exit; - endif; - - TARGETDIR = svMainDirectory; // winsys - - // Driver Manager stuff - if (! nvDoNot) then - if (nvVersion) then - options = COMP_UPDATE_VERSION; - else - options = COMP_NORMAL; - endif; - - // The File usage count increments are handled by CompressGet - // with the SHAREDFILE option. - - nResult = CompressGet("redist.z", "*.*", options|SHAREDFILE); - if (nResult < 0) then - NumToStr(szTmp, nResult); - MessageBox("Compress Get Error on redist.z files.\n\nError # " + szTmp, SEVERE); - exit; - endif; - endif; - - - FileSetEndDefine(szFileSet); - -FileTransfer: - nResult = FileSetPerformEz(szFileSet, 0); - - switch(nResult) - case FS_DONE: - case FS_CREATEDIR: - MessageBeep(0); - MessageBox("Unable to create a required subdirectory under " + TARGETDIR + "." - + "\nPlease check write access to this directory.", SEVERE); - - abort; - default: - NumToStr(szTmp, nResult); - MessageBeep(0); - MessageBox("Error copying files to " + TARGETDIR + "." - + "\nPlease check this location and try again." - + "\n\nError Number:"+szTmp, SEVERE); - - abort; - - endswitch; - - -UpdateRegistry: - SetStatusWindow(95, "Creating registry entries..."); - Delay(2); - - RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); - - Disable(LOGGING); - - // Create ODBC Core Subkey (if it doesn't exist) - // (But don't create uninstall information for it) - szKey = ODBC_CORE_KEY; - nResult = RegDBCreateKeyEx(szKey, ""); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create ODBC Core subkey.", SEVERE); - exit; - endif; - - // Create Installed Driver Key (if it doesn't exist) - // (But don't create uninstall information for it) - szKey = ODBC_DRIVERS_KEY; - nResult = RegDBCreateKeyEx(szKey, ""); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create ODBC Drivers subkey.", SEVERE); - exit; - endif; - - - // Increment Driver Manager Component UsageCount - szKey = ODBC_CORE_KEY; - szName = "UsageCount"; - if (RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize) < 0) then - ComponentUsageCount = 0; - endif; - - // MessageBox("Current Driver Manager Component Usage Count = " + svValue, INFORMATION); - - StrToNum(ComponentUsageCount, svValue); - ComponentUsageCount = ComponentUsageCount + 1; - NumToStr(szTmp, ComponentUsageCount); - // MessageBox("New Driver Manager Component Usage Count = " + szTmp, INFORMATION); - - nResult = RegDBSetKeyValueEx(szKey, szName, REGDB_NUMBER, szTmp, -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to increment Driver Manager component usage count.", SEVERE); - exit; - endif; - - // Re-enable logging now - Enable(LOGGING); - - // set ODBC Drivers Subkey (installed) - szKey = ODBC_DRIVERS_KEY; - nResult = RegDBSetKeyValueEx(szKey, DRIVER_NAME, REGDB_STRING, "Installed", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'Installed' key value.", SEVERE); - exit; - endif; - - - // Driver Specification Subkey (PostgreSQL) - szKey = ODBC_COMP_KEY + "\\" + DRIVER_NAME; - nResult = RegDBCreateKeyEx(szKey, ""); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create ODBC Driver Key.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "APILevel", REGDB_STRING, "1", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'APILevel' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "ConnectFunctions", REGDB_STRING, "YYN", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'ConnectFunctions' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "Driver", REGDB_STRING, WINSYSDIR ^ DRIVER_FILE, -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'Driver' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "DriverODBCVer", REGDB_STRING, "02.00", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'DriverODBCVer' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "FileUsage", REGDB_STRING, "0", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'FileUsage' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "Setup", REGDB_STRING, WINSYSDIR ^ DRIVER_FILE, -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'Setup' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "SQLLevel", REGDB_STRING, "1", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'SQLLevel' key value.", SEVERE); - exit; - endif; - - nResult = RegDBSetKeyValueEx(szKey, "UsageCount", REGDB_NUMBER, "1", -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'UsageCount' key value.", SEVERE); - exit; - endif; - - pos = StrFind(CMDLINE, "UseDeclareFetch="); - if (pos >= 0) then - StrSub(svValue, CMDLINE, pos + 16, 1); - nResult = RegDBSetKeyValueEx(szKey, "UseDeclareFetch", REGDB_STRING, svValue, -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'UseDeclareFetch' key value.", SEVERE); - exit; - endif; - endif; - - pos = StrFind(CMDLINE, "Protocol="); - if (pos >= 0) then - StrSub(svValue, CMDLINE, pos + 9, 3); - nResult = RegDBSetKeyValueEx(szKey, "Protocol", REGDB_STRING, svValue, -1); - if (nResult < 0) then - MessageBeep(0); - MessageBox("Unable to create 'Protocol' key value.", SEVERE); - exit; - endif; - endif; - -RenameOld: - if (FindFile(WINSYSDIR, OLD_DRIVER_FILE, svFileName) = 0) then - szMessage = "Renaming old driver to " + OLD_DRIVER_FILE_RENAMED + " ..."; - SetStatusWindow(98, szMessage); - Delay(1); - - Disable(LOGGING); - - SRCDIR= WINSYSDIR; - TARGETDIR = WINSYSDIR; - - RenameFile(OLD_DRIVER_FILE, OLD_DRIVER_FILE_RENAMED); - - Enable(LOGGING); - endif; - -Done: - Delay(1); - SetStatusWindow(100, "Installation complete"); - - Delay(1); - Disable(STATUSDLG); - - if (BATCH_INSTALL = TRUE) then - szMsg = "Some files could not be updated because they are " + - "currently in use by other programs on the system. " + - "Files in use will be updated the next time you restart " + - "your system."; - RebootDialog("Restart Windows", szMsg, SYS_BOOTMACHINE); - CommitSharedFiles(0); - szMsg = "Driver setup complete.\n\nReboot your system to complete the installation."; - MessageBeep(0); - MessageBox(szMsg, INFORMATION); - else - - szMsg = "Driver installation completed successfully."; - MessageBeep(0); - MessageBox(szMsg, INFORMATION); - endif; - - exit; - -/*---------------------------------------------------------------------------*\ - * - * Function: SetupScreen - * - * Purpose: This function will set up the screen look. This includes - * colors, fonts, text to be displayed, etc. - * - * - * Input: - * - * Returns: - * - * Comments: -\*---------------------------------------------------------------------------*/ - -function SetupScreen() - begin - - Enable( INDVFILESTATUS ); - - SetTitle( APP_NAME + " Setup", 28, WHITE ); - - SetTitle( "Setup", 0, BACKGROUNDCAPTION ); // Caption bar text. - - Enable( BACKGROUND ); - - end; - -function FileCompare(szCompInfoDate, szCompInfoTime, szFileInfoDate, szFileInfoTime) - STRING year, month, day, file_date, file_time; - NUMBER nResult; - begin - StrSub(year, szFileInfoDate, 2, 2); - StrSub(month, szFileInfoDate, 5, 2); - StrSub(day, szFileInfoDate, 8, 2); - file_date = month + "-" + day + "-" + year; - - nResult = StrCompare(szCompInfoDate, file_date); - if (nResult != 0) then - return nResult; - endif; - - StrSub(file_time, szFileInfoTime, 0, 5); - - // MessageBox("Comp = " + szCompInfoDate + " " + szCompInfoTime + ", File = " + file_date + " " + file_time, INFORMATION); - nResult = StrCompare(szCompInfoTime, file_time); - - return nResult; - end; - - - diff --git a/src/interfaces/odbc/socket.c b/src/interfaces/odbc/socket.c deleted file mode 100644 index 7f56359274..0000000000 --- a/src/interfaces/odbc/socket.c +++ /dev/null @@ -1,354 +0,0 @@ -/*------- - * Module: socket.c - * - * Description: This module contains functions for low level socket - * operations (connecting/reading/writing to the backend) - * - * Classes: SocketClass (Functions prefix: "SOCK_") - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "socket.h" - -#include "connection.h" - -#ifndef WIN32 -#include -#include /* for memset */ -#endif - -extern GLOBAL_VALUES globals; - -#ifndef BOOL -#define BOOL int -#endif -#ifndef TRUE -#define TRUE (BOOL)1 -#endif -#ifndef FALSE -#define FALSE (BOOL)0 -#endif - - -void -SOCK_clear_error(SocketClass *self) -{ - self->errornumber = 0; - self->errormsg = NULL; -} - - -SocketClass * -SOCK_Constructor(const ConnectionClass *conn) -{ - SocketClass *rv; - - rv = (SocketClass *) malloc(sizeof(SocketClass)); - - if (rv != NULL) - { - rv->socket = (SOCKETFD) - 1; - rv->buffer_filled_in = 0; - rv->buffer_filled_out = 0; - rv->buffer_read_in = 0; - - if (rv) - rv->buffer_size = conn->connInfo.drivers.socket_buffersize; - else - rv->buffer_size = globals.socket_buffersize; - rv->buffer_in = (unsigned char *) malloc(rv->buffer_size); - if (!rv->buffer_in) - { - free(rv); - return NULL; - } - - rv->buffer_out = (unsigned char *) malloc(rv->buffer_size); - if (!rv->buffer_out) - { - free(rv->buffer_in); - free(rv); - return NULL; - } - rv->errormsg = NULL; - rv->errornumber = 0; - rv->reverse = FALSE; - } - return rv; -} - - -void -SOCK_Destructor(SocketClass *self) -{ - mylog("SOCK_Destructor\n"); - if (self->socket != -1) - { - SOCK_put_char(self, 'X'); - SOCK_flush_output(self); - closesocket(self->socket); - } - - if (self->buffer_in) - free(self->buffer_in); - - if (self->buffer_out) - free(self->buffer_out); - - free(self); -} - - -char -SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname) -{ - struct hostent *host; - unsigned long iaddr; - - if (self->socket != -1) - { - self->errornumber = SOCKET_ALREADY_CONNECTED; - self->errormsg = "Socket is already connected"; - return 0; - } - - memset((char *) &(self->sadr), 0, sizeof(self->sadr)); - - /* - * If it is a valid IP address, use it. Otherwise use hostname lookup. - */ - iaddr = inet_addr(hostname); - if (iaddr == INADDR_NONE) - { - host = gethostbyname(hostname); - if (host == NULL) - { - self->errornumber = SOCKET_HOST_NOT_FOUND; - self->errormsg = "Could not resolve hostname."; - return 0; - } - memcpy(&(self->sadr.sin_addr), host->h_addr, host->h_length); - } - else - memcpy(&(self->sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr)); - - self->sadr.sin_family = AF_INET; - self->sadr.sin_port = htons(port); - - self->socket = socket(AF_INET, SOCK_STREAM, 0); - if (self->socket == -1) - { - self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET; - self->errormsg = "Could not create Socket."; - return 0; - } - - if (connect(self->socket, (struct sockaddr *) & (self->sadr), - sizeof(self->sadr)) < 0) - { - self->errornumber = SOCKET_COULD_NOT_CONNECT; - self->errormsg = "Could not connect to remote socket."; - closesocket(self->socket); - self->socket = (SOCKETFD) - 1; - return 0; - } - return 1; -} - - -void -SOCK_get_n_char(SocketClass *self, char *buffer, int len) -{ - int lf; - - if (!buffer) - { - self->errornumber = SOCKET_NULLPOINTER_PARAMETER; - self->errormsg = "get_n_char was called with NULL-Pointer"; - return; - } - - for (lf = 0; lf < len; lf++) - buffer[lf] = SOCK_get_next_byte(self); -} - - -void -SOCK_put_n_char(SocketClass *self, char *buffer, int len) -{ - int lf; - - if (!buffer) - { - self->errornumber = SOCKET_NULLPOINTER_PARAMETER; - self->errormsg = "put_n_char was called with NULL-Pointer"; - return; - } - - for (lf = 0; lf < len; lf++) - SOCK_put_next_byte(self, (unsigned char) buffer[lf]); -} - - -/* - * bufsize must include room for the null terminator - * will read at most bufsize-1 characters + null. - * returns TRUE if truncation occurs. - */ -BOOL -SOCK_get_string(SocketClass *self, char *buffer, int bufsize) -{ - register int lf = 0; - - for (lf = 0; lf < bufsize - 1; lf++) - if (!(buffer[lf] = SOCK_get_next_byte(self))) - return FALSE; - - buffer[bufsize - 1] = '\0'; - return TRUE; -} - - -void -SOCK_put_string(SocketClass *self, char *string) -{ - register int lf; - int len; - - len = strlen(string) + 1; - - for (lf = 0; lf < len; lf++) - SOCK_put_next_byte(self, (unsigned char) string[lf]); -} - - -int -SOCK_get_int(SocketClass *self, short len) -{ - switch (len) - { - case 2: - { - unsigned short buf; - - SOCK_get_n_char(self, (char *) &buf, len); - if (self->reverse) - return buf; - else - return ntohs(buf); - } - - case 4: - { - unsigned int buf; - - SOCK_get_n_char(self, (char *) &buf, len); - if (self->reverse) - return buf; - else - return ntohl(buf); - } - - default: - self->errornumber = SOCKET_GET_INT_WRONG_LENGTH; - self->errormsg = "Cannot read ints of that length"; - return 0; - } -} - - -void -SOCK_put_int(SocketClass *self, int value, short len) -{ - unsigned int rv; - - switch (len) - { - case 2: - rv = self->reverse ? value : htons((unsigned short) value); - SOCK_put_n_char(self, (char *) &rv, 2); - return; - - case 4: - rv = self->reverse ? value : htonl((unsigned int) value); - SOCK_put_n_char(self, (char *) &rv, 4); - return; - - default: - self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH; - self->errormsg = "Cannot write ints of that length"; - return; - } -} - - -void -SOCK_flush_output(SocketClass *self) -{ - int written; - - written = send(self->socket, (char *) self->buffer_out, self->buffer_filled_out, 0); - if (written != self->buffer_filled_out) - { - self->errornumber = SOCKET_WRITE_ERROR; - self->errormsg = "Could not flush socket buffer."; - } - self->buffer_filled_out = 0; -} - - -unsigned char -SOCK_get_next_byte(SocketClass *self) -{ - if (self->buffer_read_in >= self->buffer_filled_in) - { - /* - * there are no more bytes left in the buffer so reload the buffer - */ - self->buffer_read_in = 0; - self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, self->buffer_size, 0); - - mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size); - - if (self->buffer_filled_in < 0) - { - self->errornumber = SOCKET_READ_ERROR; - self->errormsg = "Error while reading from the socket."; - self->buffer_filled_in = 0; - return 0; - } - if (self->buffer_filled_in == 0) - { - self->errornumber = SOCKET_CLOSED; - self->errormsg = "Socket has been closed."; - self->buffer_filled_in = 0; - return 0; - } - } - return self->buffer_in[self->buffer_read_in++]; -} - - -void -SOCK_put_next_byte(SocketClass *self, unsigned char next_byte) -{ - int bytes_sent; - - self->buffer_out[self->buffer_filled_out++] = next_byte; - - if (self->buffer_filled_out == self->buffer_size) - { - /* buffer is full, so write it out */ - bytes_sent = send(self->socket, (char *) self->buffer_out, self->buffer_size, 0); - if (bytes_sent != self->buffer_size) - { - self->errornumber = SOCKET_WRITE_ERROR; - self->errormsg = "Error while writing to the socket."; - } - self->buffer_filled_out = 0; - } -} diff --git a/src/interfaces/odbc/socket.h b/src/interfaces/odbc/socket.h deleted file mode 100644 index 2337eb9a08..0000000000 --- a/src/interfaces/odbc/socket.h +++ /dev/null @@ -1,95 +0,0 @@ -/* File: socket.h - * - * Description: See "socket.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __SOCKET_H__ -#define __SOCKET_H__ - -#include "psqlodbc.h" - -#ifndef WIN32 -#include -#include -#include -#include -#include -#include - -#define closesocket(xxx) close(xxx) -#define SOCKETFD int - -#ifndef INADDR_NONE -#ifndef _IN_ADDR_T -#define _IN_ADDR_T -typedef unsigned int in_addr_t; -#endif -#define INADDR_NONE ((in_addr_t)-1) -#endif - -#else -#include -#define SOCKETFD SOCKET -#endif - -#define SOCKET_ALREADY_CONNECTED 1 -#define SOCKET_HOST_NOT_FOUND 2 -#define SOCKET_COULD_NOT_CREATE_SOCKET 3 -#define SOCKET_COULD_NOT_CONNECT 4 -#define SOCKET_READ_ERROR 5 -#define SOCKET_WRITE_ERROR 6 -#define SOCKET_NULLPOINTER_PARAMETER 7 -#define SOCKET_PUT_INT_WRONG_LENGTH 8 -#define SOCKET_GET_INT_WRONG_LENGTH 9 -#define SOCKET_CLOSED 10 - - -struct SocketClass_ -{ - - int buffer_size; - int buffer_filled_in; - int buffer_filled_out; - int buffer_read_in; - unsigned char *buffer_in; - unsigned char *buffer_out; - - SOCKETFD socket; - - char *errormsg; - int errornumber; - struct sockaddr_in sadr; /* Used for handling connections for cancel */ - - char reverse; /* used to handle Postgres 6.2 protocol - * (reverse byte order) */ - -}; - -#define SOCK_get_char(self) (SOCK_get_next_byte(self)) -#define SOCK_put_char(self, c) (SOCK_put_next_byte(self, c)) - - -/* error functions */ -#define SOCK_get_errcode(self) (self->errornumber) -#define SOCK_get_errmsg(self) (self->errormsg) - - -/* Socket prototypes */ -SocketClass *SOCK_Constructor(const ConnectionClass *conn); -void SOCK_Destructor(SocketClass *self); -char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname); -void SOCK_get_n_char(SocketClass *self, char *buffer, int len); -void SOCK_put_n_char(SocketClass *self, char *buffer, int len); -BOOL SOCK_get_string(SocketClass *self, char *buffer, int bufsize); -void SOCK_put_string(SocketClass *self, char *string); -int SOCK_get_int(SocketClass *self, short len); -void SOCK_put_int(SocketClass *self, int value, short len); -void SOCK_flush_output(SocketClass *self); -unsigned char SOCK_get_next_byte(SocketClass *self); -void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte); -void SOCK_clear_error(SocketClass *self); - -#endif diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c deleted file mode 100644 index c8742a6cd3..0000000000 --- a/src/interfaces/odbc/statement.c +++ /dev/null @@ -1,1197 +0,0 @@ -/*------- - * Module: statement.c - * - * Description: This module contains functions related to creating - * and manipulating a statement. - * - * Classes: StatementClass (Functions prefix: "SC_") - * - * API functions: SQLAllocStmt, SQLFreeStmt - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "statement.h" - -#include "bind.h" -#include "connection.h" -#include "qresult.h" -#include "convert.h" -#include "environ.h" - -#include -#include -#include - -#include "pgapifunc.h" - - -#define PRN_NULLCHECK - - -/* Map sql commands to statement types */ -static struct -{ - int type; - char *s; -} Statement_Type[] = - -{ - { - STMT_TYPE_SELECT, "SELECT" - }, - { - STMT_TYPE_INSERT, "INSERT" - }, - { - STMT_TYPE_UPDATE, "UPDATE" - }, - { - STMT_TYPE_DELETE, "DELETE" - }, - { - STMT_TYPE_CREATE, "CREATE" - }, - { - STMT_TYPE_ALTER, "ALTER" - }, - { - STMT_TYPE_DROP, "DROP" - }, - { - STMT_TYPE_GRANT, "GRANT" - }, - { - STMT_TYPE_REVOKE, "REVOKE" - }, - { - STMT_TYPE_PROCCALL, "{" - }, - { - STMT_TYPE_LOCK, "LOCK" - }, - { - 0, NULL - } -}; - - -RETCODE SQL_API -PGAPI_AllocStmt(HDBC hdbc, - HSTMT FAR * phstmt) -{ - static char *func = "PGAPI_AllocStmt"; - ConnectionClass *conn = (ConnectionClass *) hdbc; - StatementClass *stmt; - - mylog("%s: entering...\n", func); - - if (!conn) - { - CC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - - stmt = SC_Constructor(); - - mylog("**** PGAPI_AllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt); - - if (!stmt) - { - conn->errornumber = CONN_STMT_ALLOC_ERROR; - conn->errormsg = "No more memory to allocate a further SQL-statement"; - *phstmt = SQL_NULL_HSTMT; - CC_log_error(func, "", conn); - return SQL_ERROR; - } - - if (!CC_add_statement(conn, stmt)) - { - conn->errormsg = "Maximum number of connections exceeded."; - conn->errornumber = CONN_STMT_ALLOC_ERROR; - CC_log_error(func, "", conn); - SC_Destructor(stmt); - *phstmt = SQL_NULL_HSTMT; - return SQL_ERROR; - } - - *phstmt = (HSTMT) stmt; - - /* Copy default statement options based from Connection options */ - stmt->options = conn->stmtOptions; - stmt->ardopts = conn->ardOptions; - stmt->ardopts.bookmark = (BindInfoClass *) malloc(sizeof(BindInfoClass)); - stmt->ardopts.bookmark->buffer = NULL; - stmt->ardopts.bookmark->used = NULL; - - stmt->stmt_size_limit = CC_get_max_query_len(conn); - /* Save the handle for later */ - stmt->phstmt = phstmt; - - return SQL_SUCCESS; -} - - -RETCODE SQL_API -PGAPI_FreeStmt(HSTMT hstmt, - UWORD fOption) -{ - static char *func = "PGAPI_FreeStmt"; - StatementClass *stmt = (StatementClass *) hstmt; - - mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption); - - if (!stmt) - { - SC_log_error(func, "", NULL); - return SQL_INVALID_HANDLE; - } - SC_clear_error(stmt); - - if (fOption == SQL_DROP) - { - ConnectionClass *conn = stmt->hdbc; - - /* Remove the statement from the connection's statement list */ - if (conn) - { - if (!CC_remove_statement(conn, stmt)) - { - stmt->errornumber = STMT_SEQUENCE_ERROR; - stmt->errormsg = "Statement is currently executing a transaction."; - SC_log_error(func, "", stmt); - return SQL_ERROR; /* stmt may be executing a - * transaction */ - } - - /* Free any cursors and discard any result info */ - if (SC_get_Result(stmt)) - { - QR_Destructor(SC_get_Result(stmt)); - SC_set_Result(stmt, NULL); - } - } - - /* Destroy the statement and free any results, cursors, etc. */ - SC_Destructor(stmt); - } - else if (fOption == SQL_UNBIND) - SC_unbind_cols(stmt); - else if (fOption == SQL_CLOSE) - { - /* - * this should discard all the results, but leave the statement - * itself in place (it can be executed again) - */ - if (!SC_recycle_statement(stmt)) - { - /* errormsg passed in above */ - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - } - else if (fOption == SQL_RESET_PARAMS) - SC_free_params(stmt, STMT_FREE_PARAMS_ALL); - else - { - stmt->errormsg = "Invalid option passed to PGAPI_FreeStmt."; - stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - - return SQL_SUCCESS; -} - - -/* - * StatementClass implementation - */ -void -InitializeStatementOptions(StatementOptions *opt) -{ - memset(opt, 0, sizeof(StatementOptions)); - opt->maxRows = 0; /* driver returns all rows */ - opt->maxLength = 0; /* driver returns all data for char/binary */ - opt->keyset_size = 0; /* fully keyset driven is the default */ - opt->scroll_concurrency = SQL_CONCUR_READ_ONLY; - opt->cursor_type = SQL_CURSOR_FORWARD_ONLY; - opt->retrieve_data = SQL_RD_ON; - opt->use_bookmarks = SQL_UB_OFF; -} - - -/* - * ARDFields initialize - */ -void -InitializeARDFields(ARDFields *opt) -{ - memset(opt, 0, sizeof(ARDFields)); - opt->rowset_size = 1; - opt->bind_size = 0; /* default is to bind by column */ -} -/* - * APDFields initialize - */ -void -InitializeAPDFields(APDFields *opt) -{ - memset(opt, 0, sizeof(APDFields)); - opt->paramset_size = 1; - opt->param_bind_type = 0; /* default is to bind by column */ -} - - -StatementClass * -SC_Constructor(void) -{ - StatementClass *rv; - - rv = (StatementClass *) malloc(sizeof(StatementClass)); - if (rv) - { - rv->hdbc = NULL; /* no connection associated yet */ - rv->phstmt = NULL; - rv->result = NULL; - rv->curres = NULL; - rv->manual_result = FALSE; - rv->prepare = FALSE; - rv->status = STMT_ALLOCATED; - rv->internal = FALSE; - - rv->errormsg = NULL; - rv->errornumber = 0; - rv->errormsg_created = FALSE; - - rv->statement = NULL; - rv->stmt_with_params = NULL; - rv->load_statement = NULL; - rv->stmt_size_limit = -1; - rv->statement_type = STMT_TYPE_UNKNOWN; - - rv->currTuple = -1; - rv->rowset_start = -1; - rv->current_col = -1; - rv->bind_row = 0; - rv->last_fetch_count = rv->last_fetch_count_include_ommitted = 0; - rv->save_rowset_size = -1; - - rv->data_at_exec = -1; - rv->current_exec_param = -1; - rv->exec_start_row = -1; - rv->exec_end_row = -1; - rv->exec_current_row = -1; - rv->put_data = FALSE; - - rv->lobj_fd = -1; - rv->cursor_name[0] = '\0'; - - /* Parse Stuff */ - rv->ti = NULL; - rv->ntab = 0; - rv->parse_status = STMT_PARSE_NONE; - - /* Clear Statement Options -- defaults will be set in AllocStmt */ - memset(&rv->options, 0, sizeof(StatementOptions)); - memset(&rv->ardopts, 0, sizeof(ARDFields)); - memset(&rv->apdopts, 0, sizeof(APDFields)); - memset(&rv->irdopts, 0, sizeof(IRDFields)); - memset(&rv->ipdopts, 0, sizeof(IPDFields)); - - rv->pre_executing = FALSE; - rv->inaccurate_result = FALSE; - rv->miscinfo = 0; - rv->updatable = FALSE; - rv->error_recsize = -1; - rv->diag_row_count = 0; - } - return rv; -} - - -void ARDFields_free(ARDFields * self) -{ - if (self->bookmark) - { - free(self->bookmark); - self->bookmark = NULL; - } - /* - * the memory pointed to by the bindings is not deallocated by the - * driver but by the application that uses that driver, so we don't - * have to care - */ - ARD_unbind_cols(self, TRUE); -} - -void APDFields_free(APDFields * self) -{ - /* param bindings */ - APD_free_params(self, STMT_FREE_PARAMS_ALL); -} - -void IRDFields_free(IRDFields * self) -{ - /* Free the parsed field information */ - if (self->fi) - { - int i; - - for (i = 0; i < (int) self->nfields; i++) - { - if (self->fi[i]) - { - if (self->fi[i]->schema) - free(self->fi[i]->schema); - free(self->fi[i]); - } - } - free(self->fi); - self->fi = NULL; - } -} - -void IPDFields_free(IPDFields * self) -{ -} - -char -SC_Destructor(StatementClass *self) -{ - QResultClass *res = SC_get_Result(self); - - mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, res, self->hdbc); - SC_clear_error(self); - if (STMT_EXECUTING == self->status) - { - self->errornumber = STMT_SEQUENCE_ERROR; - self->errormsg = "Statement is currently executing a transaction."; - return FALSE; - } - - if (res) - { - if (!self->hdbc) - res->conn = NULL; /* prevent any dbase activity */ - - QR_Destructor(res); - } - - if (self->statement) - free(self->statement); - if (self->stmt_with_params) - { - free(self->stmt_with_params); - self->stmt_with_params = NULL; - } - if (self->load_statement) - free(self->load_statement); - - /* Free the parsed table information */ - if (self->ti) - { - int i; - - for (i = 0; i < self->ntab; i++) - if (self->ti[i]); - free(self->ti[i]); - - free(self->ti); - self->ti = NULL; - } - - /* Free the parsed field information */ - ARDFields_free(&(self->ardopts)); - APDFields_free(&(self->apdopts)); - IRDFields_free(&(self->irdopts)); - IPDFields_free(&(self->ipdopts)); - - free(self); - - mylog("SC_Destructor: EXIT\n"); - - return TRUE; -} - - -/* - * Free parameters and free the memory from the - * data-at-execution parameters that was allocated in SQLPutData. - */ -void -SC_free_params(StatementClass *self, char option) -{ - APD_free_params(SC_get_APD(self), option); - self->data_at_exec = -1; - self->current_exec_param = -1; - self->put_data = FALSE; - if (option == STMT_FREE_PARAMS_ALL) - { - self->exec_start_row = -1; - self->exec_end_row = -1; - self->exec_current_row = -1; - } -} - - -int -statement_type(char *statement) -{ - int i; - - /* ignore leading whitespace in query string */ - while (*statement && (isspace((unsigned char) *statement) || *statement == '(')) - statement++; - - for (i = 0; Statement_Type[i].s; i++) - if (!strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s))) - return Statement_Type[i].type; - - return STMT_TYPE_OTHER; -} - - -/* - * Called from SQLPrepare if STMT_PREMATURE, or - * from SQLExecute if STMT_FINISHED, or - * from SQLFreeStmt(SQL_CLOSE) - */ -char -SC_recycle_statement(StatementClass *self) -{ - ConnectionClass *conn; - QResultClass *res; - - mylog("recycle statement: self= %u\n", self); - - SC_clear_error(self); - /* This would not happen */ - if (self->status == STMT_EXECUTING) - { - self->errornumber = STMT_SEQUENCE_ERROR; - self->errormsg = "Statement is currently executing a transaction."; - return FALSE; - } - - switch (self->status) - { - case STMT_ALLOCATED: - /* this statement does not need to be recycled */ - return TRUE; - - case STMT_READY: - break; - - case STMT_PREMATURE: - - /* - * Premature execution of the statement might have caused the - * start of a transaction. If so, we have to rollback that - * transaction. - */ - conn = SC_get_conn(self); - if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) - { - if (SC_is_pre_executable(self) && !conn->connInfo.disallow_premature) - CC_abort(conn); - } - break; - - case STMT_FINISHED: - break; - - default: - self->errormsg = "An internal error occured while recycling statements"; - self->errornumber = STMT_INTERNAL_ERROR; - return FALSE; - } - - /* Free the parsed table information */ - if (self->ti) - { - int i; - - for (i = 0; i < self->ntab; i++) - if (self->ti[i]) - free(self->ti[i]); - self->ti = NULL; - self->ntab = 0; - } - /* Free the parsed field information */ - IRDFields_free(SC_get_IRD(self)); - - self->parse_status = STMT_PARSE_NONE; - self->updatable = FALSE; - - /* Free any cursors */ - if (res = SC_get_Result(self), res) - { - QR_Destructor(res); - SC_set_Result(self, NULL); - } - self->inaccurate_result = FALSE; - - /* - * Reset only parameters that have anything to do with results - */ - self->status = STMT_READY; - self->manual_result = FALSE; /* very important */ - - self->currTuple = -1; - self->rowset_start = -1; - self->current_col = -1; - self->bind_row = 0; - self->last_fetch_count = self->last_fetch_count_include_ommitted = 0; - - self->errormsg = NULL; - self->errornumber = 0; - self->errormsg_created = FALSE; - - self->lobj_fd = -1; - - /* - * Free any data at exec params before the statement is executed - * again. If not, then there will be a memory leak when the next - * SQLParamData/SQLPutData is called. - */ - SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY); - if (self->stmt_with_params) - free(self->stmt_with_params); - self->stmt_with_params = NULL; - if (self->load_statement) - free(self->load_statement); - self->load_statement = NULL; - - return TRUE; -} - - -/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */ -void -SC_pre_execute(StatementClass *self) -{ - mylog("SC_pre_execute: status = %d\n", self->status); - - if (self->status == STMT_READY) - { - mylog(" preprocess: status = READY\n"); - - self->miscinfo = 0; - if (self->statement_type == STMT_TYPE_SELECT) - { - char old_pre_executing = self->pre_executing; - - self->pre_executing = TRUE; - self->inaccurate_result = FALSE; - - PGAPI_Execute(self); - - self->pre_executing = old_pre_executing; - - if (self->status == STMT_FINISHED) - { - mylog(" preprocess: after status = FINISHED, so set PREMATURE\n"); - self->status = STMT_PREMATURE; - } - } - if (!SC_is_pre_executable(self)) - { - SC_set_Result(self, QR_Constructor()); - QR_set_status(SC_get_Result(self), PGRES_TUPLES_OK); - self->inaccurate_result = TRUE; - self->status = STMT_PREMATURE; - } - } -} - - -/* This is only called from SQLFreeStmt(SQL_UNBIND) */ -char -SC_unbind_cols(StatementClass *self) -{ - ARDFields *opts = SC_get_ARD(self); - - ARD_unbind_cols(opts, FALSE); - opts->bookmark->buffer = NULL; - opts->bookmark->used = NULL; - - return 1; -} - - -void -SC_clear_error(StatementClass *self) -{ - self->errornumber = 0; - self->errormsg = NULL; - self->errormsg_created = FALSE; - self->errorpos = 0; - self->error_recsize = -1; - self->diag_row_count = 0; -} - - -/* - * This function creates an error msg which is the concatenation - * of the result, statement, connection, and socket messages. - */ -char * -SC_create_errormsg(StatementClass *self) -{ - QResultClass *res = SC_get_Curres(self); - ConnectionClass *conn = self->hdbc; - int pos; - BOOL detailmsg = FALSE; - static char msg[4096]; - - msg[0] = '\0'; - - if (res && res->message) - { - strcpy(msg, res->message); - detailmsg = TRUE; - } - else if (self->errormsg) - strcpy(msg, self->errormsg); - - if (!msg[0] && res && QR_get_notice(res)) - { - char *notice = QR_get_notice(res); - int len = strlen(notice); - if (len < sizeof(msg)) - { - memcpy(msg, notice, len); - msg[len] = '\0'; - } - else - return notice; - } - if (conn) - { - SocketClass *sock = conn->sock; - - if (!detailmsg && conn->errormsg && conn->errormsg[0] != '\0') - { - pos = strlen(msg); - sprintf(&msg[pos], ";\n%s", conn->errormsg); - } - - if (sock && sock->errormsg && sock->errormsg[0] != '\0') - { - pos = strlen(msg); - sprintf(&msg[pos], ";\n%s", sock->errormsg); - } - } - return msg; -} - - -char -SC_get_error(StatementClass *self, int *number, char **message) -{ - char rv; - - /* Create a very informative errormsg if it hasn't been done yet. */ - if (!self->errormsg_created) - { - self->errormsg = SC_create_errormsg(self); - self->errormsg_created = TRUE; - self->errorpos = 0; - self->error_recsize = -1; - } - - if (self->errornumber) - { - *number = self->errornumber; - *message = self->errormsg; - } - - rv = (self->errornumber != 0); - - return rv; -} - - -/* - * Currently, the driver offers very simple bookmark support -- it is - * just the current row number. But it could be more sophisticated - * someday, such as mapping a key to a 32 bit value - */ -unsigned long -SC_get_bookmark(StatementClass *self) -{ - return (self->currTuple + 1); -} - - -RETCODE -SC_fetch(StatementClass *self) -{ - static char *func = "SC_fetch"; - QResultClass *res = SC_get_Curres(self); - ARDFields *opts; - int retval, - result; - - Int2 num_cols, - lf; - Oid type; - char *value; - ColumnInfoClass *coli; - - /* TupleField *tupleField; */ - ConnInfo *ci = &(SC_get_conn(self)->connInfo); - - self->last_fetch_count = self->last_fetch_count_include_ommitted = 0; - coli = QR_get_fields(res); /* the column info */ - - mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch); - - if (self->manual_result || !SC_is_fetchcursor(self)) - { - if (self->currTuple >= QR_get_num_total_tuples(res) - 1 || - (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) - { - /* - * if at the end of the tuples, return "no data found" and set - * the cursor past the end of the result set - */ - self->currTuple = QR_get_num_total_tuples(res); - return SQL_NO_DATA_FOUND; - } - - mylog("**** SC_fetch: manual_result\n"); - (self->currTuple)++; - } - else - { - /* read from the cache or the physical next tuple */ - retval = QR_next_tuple(res); - if (retval < 0) - { - mylog("**** SC_fetch: end_tuples\n"); - return SQL_NO_DATA_FOUND; - } - else if (retval > 0) - (self->currTuple)++; /* all is well */ - else - { - mylog("SC_fetch: error\n"); - self->errornumber = STMT_EXEC_ERROR; - self->errormsg = "Error fetching next row"; - SC_log_error(func, "", self); - return SQL_ERROR; - } - } -#ifdef DRIVER_CURSOR_IMPLEMENT - if (res->haskeyset) - { - UWORD pstatus = res->keyset[self->currTuple].status; - if (0 != (pstatus & (CURS_SELF_DELETING | CURS_SELF_DELETED))) - return SQL_SUCCESS_WITH_INFO; - if (SQL_ROW_DELETED != (pstatus & KEYSET_INFO_PUBLIC) && - 0 != (pstatus & CURS_OTHER_DELETED)) - return SQL_SUCCESS_WITH_INFO; - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - - num_cols = QR_NumResultCols(res); - - result = SQL_SUCCESS; - self->last_fetch_count++; - self->last_fetch_count_include_ommitted++; - - opts = SC_get_ARD(self); - /* - * If the bookmark column was bound then return a bookmark. Since this - * is used with SQLExtendedFetch, and the rowset size may be greater - * than 1, and an application can use row or column wise binding, use - * the code in copy_and_convert_field() to handle that. - */ - if (opts->bookmark->buffer) - { - char buf[32]; - UInt4 offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0; - - sprintf(buf, "%ld", SC_get_bookmark(self)); - result = copy_and_convert_field(self, 0, buf, - SQL_C_ULONG, opts->bookmark->buffer + offset, 0, - opts->bookmark->used ? opts->bookmark->used + (offset >> 2) : NULL); - } - -#ifdef DRIVER_CURSOR_IMPLEMENT - if (res->haskeyset) - { - num_cols -= 2; - } -#endif /* DRIVER_CURSOR_IMPLEMENT */ - if (self->options.retrieve_data == SQL_RD_OFF) /* data isn't required */ - return SQL_SUCCESS; - for (lf = 0; lf < num_cols; lf++) - { - mylog("fetch: cols=%d, lf=%d, opts = %u, opts->bindings = %u, buffer[] = %u\n", num_cols, lf, opts, opts->bindings, opts->bindings[lf].buffer); - - /* reset for SQLGetData */ - opts->bindings[lf].data_left = -1; - - if (opts->bindings[lf].buffer != NULL) - { - /* this column has a binding */ - - /* type = QR_get_field_type(res, lf); */ - type = CI_get_oid(coli, lf); /* speed things up */ - - mylog("type = %d\n", type); - - if (self->manual_result) - { - value = QR_get_value_manual(res, self->currTuple, lf); - mylog("manual_result\n"); - } - else if (SC_is_fetchcursor(self)) - value = QR_get_value_backend(res, lf); - else - { - int curt = res->base; - if (self->rowset_start >= 0) - curt += (self->currTuple - self->rowset_start); - value = QR_get_value_backend_row(res, curt, lf); - } - - mylog("value = '%s'\n", (value == NULL) ? "" : value); - - retval = copy_and_convert_field_bindinfo(self, type, value, lf); - - mylog("copy_and_convert: retval = %d\n", retval); - - switch (retval) - { - case COPY_OK: - break; /* OK, do next bound column */ - - case COPY_UNSUPPORTED_TYPE: - self->errormsg = "Received an unsupported type from Postgres."; - self->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; - SC_log_error(func, "", self); - result = SQL_ERROR; - break; - - case COPY_UNSUPPORTED_CONVERSION: - self->errormsg = "Couldn't handle the necessary data type conversion."; - self->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; - SC_log_error(func, "", self); - result = SQL_ERROR; - break; - - case COPY_RESULT_TRUNCATED: - self->errornumber = STMT_TRUNCATED; - self->errormsg = "Fetched item was truncated."; - qlog("The %dth item was truncated\n", lf + 1); - qlog("The buffer size = %d", opts->bindings[lf].buflen); - qlog(" and the value is '%s'\n", value); - result = SQL_SUCCESS_WITH_INFO; - break; - - /* error msg already filled in */ - case COPY_GENERAL_ERROR: - SC_log_error(func, "", self); - result = SQL_ERROR; - break; - - /* This would not be meaningful in SQLFetch. */ - case COPY_NO_DATA_FOUND: - break; - - default: - self->errormsg = "Unrecognized return value from copy_and_convert_field."; - self->errornumber = STMT_INTERNAL_ERROR; - SC_log_error(func, "", self); - result = SQL_ERROR; - break; - } - } - } - - return result; -} - - -RETCODE -SC_execute(StatementClass *self) -{ - static char *func = "SC_execute"; - ConnectionClass *conn; - APDFields *apdopts; - char was_ok, was_nonfatal; - QResultClass *res = NULL; - Int2 oldstatus, - numcols; - QueryInfo qi; - ConnInfo *ci; - UDWORD qflag = 0; - - - conn = SC_get_conn(self); - ci = &(conn->connInfo); - - /* Begin a transaction if one is not already in progress */ - - /* - * Basically we don't have to begin a transaction in autocommit mode - * because Postgres backend runs in autocomit mode. We issue "BEGIN" - * in the following cases. 1) we use declare/fetch and the statement - * is SELECT (because declare/fetch must be called in a transaction). - * 2) we are in autocommit off state and the statement isn't of type - * OTHER. - */ - if (!self->internal && !CC_is_in_trans(conn) && - (SC_is_fetchcursor(self) || - (!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER))) - { - mylog(" about to begin a transaction on statement = %u\n", self); - if (PG_VERSION_GE(conn, 7.1)) - qflag |= GO_INTO_TRANSACTION; - else if (!CC_begin(conn)) - { - self->errormsg = "Could not begin a transaction"; - self->errornumber = STMT_EXEC_ERROR; - SC_log_error(func, "", self); - return SQL_ERROR; - } - } - - oldstatus = conn->status; - conn->status = CONN_EXECUTING; - self->status = STMT_EXECUTING; - - /* If it's a SELECT statement, use a cursor. */ - - /* - * Note that the declare cursor has already been prepended to the - * statement - */ - /* in copy_statement... */ - if (self->statement_type == STMT_TYPE_SELECT) - { - char fetch[128]; - qflag |= (SQL_CONCUR_READ_ONLY != self->options.scroll_concurrency ? CREATE_KEYSET : 0); - - mylog(" Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name); - - /* send the declare/select */ - res = CC_send_query(conn, self->stmt_with_params, NULL, qflag); - if (SC_is_fetchcursor(self) && res != NULL && - QR_command_maybe_successful(res)) - { - QR_Destructor(res); - qflag &= (~ GO_INTO_TRANSACTION); - - /* - * That worked, so now send the fetch to start getting data - * back - */ - qi.result_in = NULL; - qi.cursor = self->cursor_name; - qi.row_size = ci->drivers.fetch_max; - - /* - * Most likely the rowset size will not be set by the - * application until after the statement is executed, so might - * as well use the cache size. The qr_next_tuple() function - * will correct for any discrepancies in sizes and adjust the - * cache accordingly. - */ - sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name); - - res = CC_send_query(conn, fetch, &qi, qflag); - } - mylog(" done sending the query:\n"); - } - else - { - /* not a SELECT statement so don't use a cursor */ - mylog(" it's NOT a select statement: stmt=%u\n", self); - res = CC_send_query(conn, self->stmt_with_params, NULL, qflag); - - /* - * We shouldn't send COMMIT. Postgres backend does the autocommit - * if neccessary. (Zoltan, 04/26/2000) - */ - - /* - * Above seems wrong. Even in case of autocommit, started - * transactions must be committed. (Hiroshi, 02/11/2001) - */ - if (!self->internal && CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) - CC_commit(conn); - } - - conn->status = oldstatus; - self->status = STMT_FINISHED; - - /* Check the status of the result */ - if (res) - { - was_ok = QR_command_successful(res); - was_nonfatal = QR_command_nonfatal(res); - - if (was_ok) - self->errornumber = STMT_OK; - else - self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND; - - /* set cursor before the first tuple in the list */ - self->currTuple = -1; - self->current_col = -1; - self->rowset_start = -1; - - /* issue "ABORT" when query aborted */ - if (QR_get_aborted(res)) - { - if (!self->internal) - CC_abort(conn); - } - else - { - /* see if the query did return any result columns */ - numcols = QR_NumResultCols(res); - /* now allocate the array to hold the binding info */ - if (numcols > 0) - { - ARDFields *opts = SC_get_ARD(self); - extend_column_bindings(opts, numcols); - if (opts->bindings == NULL) - { - QR_Destructor(res); - self->errornumber = STMT_NO_MEMORY_ERROR; - self->errormsg = "Could not get enough free memory to store the binding information"; - SC_log_error(func, "", self); - return SQL_ERROR; - } - } - } - } - else - { - /* Bad Error -- The error message will be in the Connection */ - if (self->statement_type == STMT_TYPE_CREATE) - { - self->errornumber = STMT_CREATE_TABLE_ERROR; - self->errormsg = "Error creating the table"; - - /* - * This would allow the table to already exists, thus - * appending rows to it. BUT, if the table didn't have the - * same attributes, it would fail. return - * SQL_SUCCESS_WITH_INFO; - */ - } - else - { - self->errornumber = STMT_EXEC_ERROR; - self->errormsg = conn->errormsg; - } - - if (!self->internal) - CC_abort(conn); - } - if (!SC_get_Result(self)) - SC_set_Result(self, res); - else - { - QResultClass *last; - for (last = SC_get_Result(self); last->next; last = last->next) - ; - last->next = res; - } - - apdopts = SC_get_APD(self); - if (self->statement_type == STMT_TYPE_PROCCALL && - (self->errornumber == STMT_OK || - self->errornumber == STMT_INFO_ONLY) && - apdopts->parameters && - apdopts->parameters[0].buffer && - apdopts->parameters[0].paramType == SQL_PARAM_OUTPUT) - { /* get the return value of the procedure - * call */ - RETCODE ret; - HSTMT hstmt = (HSTMT) self; - - ret = SC_fetch(hstmt); - if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) - { - ret = PGAPI_GetData(hstmt, 1, apdopts->parameters[0].CType, apdopts->parameters[0].buffer, apdopts->parameters[0].buflen, apdopts->parameters[0].used); - if (ret != SQL_SUCCESS) - { - self->errornumber = STMT_EXEC_ERROR; - self->errormsg = "GetData to Procedure return failed."; - } - } - else - { - self->errornumber = STMT_EXEC_ERROR; - self->errormsg = "SC_fetch to get a Procedure return failed."; - } - } - if (self->errornumber == STMT_OK) - return SQL_SUCCESS; - else if (self->errornumber == STMT_INFO_ONLY) - return SQL_SUCCESS_WITH_INFO; - else - { - if (!self->errormsg || !self->errormsg[0]) - self->errormsg = "Error while executing the query"; - SC_log_error(func, "", self); - return SQL_ERROR; - } -} - - -void -SC_log_error(const char *func, const char *desc, const StatementClass *self) -{ -#ifdef PRN_NULLCHECK -#define nullcheck(a) (a ? a : "(NULL)") -#endif - if (self) - { - QResultClass *res = SC_get_Result(self); - const ARDFields *opts = SC_get_ARD(self); - const APDFields *apdopts = SC_get_APD(self); - - qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg)); - mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg)); - qlog(" ------------------------------------------------------------\n"); - qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, res); - qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal); - qlog(" bindings=%u, bindings_allocated=%d\n", opts->bindings, opts->allocated); - qlog(" parameters=%u, parameters_allocated=%d\n", apdopts->parameters, apdopts->allocated); - qlog(" statement_type=%d, statement='%s'\n", self->statement_type, nullcheck(self->statement)); - qlog(" stmt_with_params='%s'\n", nullcheck(self->stmt_with_params)); - qlog(" data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data); - qlog(" currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd); - qlog(" maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->options.maxRows, opts->rowset_size, self->options.keyset_size, self->options.cursor_type, self->options.scroll_concurrency); - qlog(" cursor_name='%s'\n", nullcheck(self->cursor_name)); - - qlog(" ----------------QResult Info -------------------------------\n"); - - if (res) - { - qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn); - qlog(" fetch_count=%d, num_total_rows=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->num_total_rows, res->num_fields, nullcheck(res->cursor)); - qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice)); - qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples); - } - - /* Log the connection error if there is one */ - CC_log_error(func, desc, self->hdbc); - } - else - { - qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc); - mylog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc); - } -#undef PRN_NULLCHECK -} diff --git a/src/interfaces/odbc/statement.h b/src/interfaces/odbc/statement.h deleted file mode 100644 index fd220671e5..0000000000 --- a/src/interfaces/odbc/statement.h +++ /dev/null @@ -1,248 +0,0 @@ -/* File: statement.h - * - * Description: See "statement.c" - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __STATEMENT_H__ -#define __STATEMENT_H__ - -#include "psqlodbc.h" - -#include "bind.h" -#include "descriptor.h" - - -#ifndef FALSE -#define FALSE (BOOL)0 -#endif -#ifndef TRUE -#define TRUE (BOOL)1 -#endif - -typedef enum -{ - STMT_ALLOCATED, /* The statement handle is allocated, but - * not used so far */ - STMT_READY, /* the statement is waiting to be executed */ - STMT_PREMATURE, /* ODBC states that it is legal to call - * e.g. SQLDescribeCol before a call to - * SQLExecute, but after SQLPrepare. To - * get all the necessary information in - * such a case, we simply execute the - * query _before_ the actual call to - * SQLExecute, so that statement is - * considered to be "premature". */ - STMT_FINISHED, /* statement execution has finished */ - STMT_EXECUTING /* statement execution is still going on */ -} STMT_Status; - -#define STMT_ROW_VERSION_CHANGED (-4) -#define STMT_POS_BEFORE_RECORDSET (-3) -#define STMT_TRUNCATED (-2) -#define STMT_INFO_ONLY (-1) /* not an error message, - * just a notification - * to be returned by - * SQLError */ -#define STMT_OK 0 /* will be interpreted - * as "no error pending" */ -#define STMT_EXEC_ERROR 1 -#define STMT_STATUS_ERROR 2 -#define STMT_SEQUENCE_ERROR 3 -#define STMT_NO_MEMORY_ERROR 4 -#define STMT_COLNUM_ERROR 5 -#define STMT_NO_STMTSTRING 6 -#define STMT_ERROR_TAKEN_FROM_BACKEND 7 -#define STMT_INTERNAL_ERROR 8 -#define STMT_STILL_EXECUTING 9 -#define STMT_NOT_IMPLEMENTED_ERROR 10 -#define STMT_BAD_PARAMETER_NUMBER_ERROR 11 -#define STMT_OPTION_OUT_OF_RANGE_ERROR 12 -#define STMT_INVALID_COLUMN_NUMBER_ERROR 13 -#define STMT_RESTRICTED_DATA_TYPE_ERROR 14 -#define STMT_INVALID_CURSOR_STATE_ERROR 15 -#define STMT_OPTION_VALUE_CHANGED 16 -#define STMT_CREATE_TABLE_ERROR 17 -#define STMT_NO_CURSOR_NAME 18 -#define STMT_INVALID_CURSOR_NAME 19 -#define STMT_INVALID_ARGUMENT_NO 20 -#define STMT_ROW_OUT_OF_RANGE 21 -#define STMT_OPERATION_CANCELLED 22 -#define STMT_INVALID_CURSOR_POSITION 23 -#define STMT_VALUE_OUT_OF_RANGE 24 -#define STMT_OPERATION_INVALID 25 -#define STMT_PROGRAM_TYPE_OUT_OF_RANGE 26 -#define STMT_BAD_ERROR 27 -#define STMT_INVALID_OPTION_IDENTIFIER 28 -#define STMT_RETURN_NULL_WITHOUT_INDICATOR 29 -#define STMT_ERROR_IN_ROW 30 -#define STMT_INVALID_DESCRIPTOR_IDENTIFIER 31 -#define STMT_OPTION_NOT_FOR_THE_DRIVER 32 -#define STMT_FETCH_OUT_OF_RANGE 33 - -/* statement types */ -enum -{ - STMT_TYPE_UNKNOWN = -2, - STMT_TYPE_OTHER = -1, - STMT_TYPE_SELECT = 0, - STMT_TYPE_INSERT, - STMT_TYPE_UPDATE, - STMT_TYPE_DELETE, - STMT_TYPE_CREATE, - STMT_TYPE_ALTER, - STMT_TYPE_DROP, - STMT_TYPE_GRANT, - STMT_TYPE_REVOKE, - STMT_TYPE_PROCCALL, - STMT_TYPE_LOCK -}; - -#define STMT_UPDATE(stmt) (stmt->statement_type > STMT_TYPE_SELECT) - - -/* Parsing status */ -enum -{ - STMT_PARSE_NONE = 0, - STMT_PARSE_COMPLETE, - STMT_PARSE_INCOMPLETE, - STMT_PARSE_FATAL, -}; - -/* Result style */ -enum -{ - STMT_FETCH_NONE = 0, - STMT_FETCH_NORMAL, - STMT_FETCH_EXTENDED, -}; - - -/******** Statement Handle ***********/ -struct StatementClass_ -{ - ConnectionClass *hdbc; /* pointer to ConnectionClass this - * statement belongs to */ - QResultClass *result; /* result of the current statement */ - QResultClass *curres; /* the current result in the chain */ - HSTMT FAR *phstmt; - StatementOptions options; - ARDFields ardopts; - IRDFields irdopts; - APDFields apdopts; - IPDFields ipdopts; - - STMT_Status status; - char *errormsg; - int errornumber; - - Int4 currTuple; /* current absolute row number (GetData, - * SetPos, SQLFetch) */ - int save_rowset_size; /* saved rowset size in case of - * change/FETCH_NEXT */ - int rowset_start; /* start of rowset (an absolute row - * number) */ - int bind_row; /* current offset for Multiple row/column - * binding */ - int last_fetch_count; /* number of rows retrieved in - * last fetch/extended fetch */ - int current_col; /* current column for GetData -- used to - * handle multiple calls */ - int lobj_fd; /* fd of the current large object */ - - char *statement; /* if non--null pointer to the SQL - * statement that has been executed */ - - TABLE_INFO **ti; - int ntab; - - int parse_status; - - int statement_type; /* According to the defines above */ - int data_at_exec; /* Number of params needing SQLPutData */ - int current_exec_param; /* The current parameter for - * SQLPutData */ - - char put_data; /* Has SQLPutData been called yet? */ - - char errormsg_created; /* has an informative error msg - * been created? */ - char manual_result; /* Is the statement result manually built? */ - char prepare; /* is this statement a prepared statement - * or direct */ - - char internal; /* Is this statement being called - * internally? */ - - char cursor_name[MAX_CURSOR_LEN + 1]; - - char *stmt_with_params; /* statement after parameter - * substitution */ - int stmt_size_limit; - int exec_start_row; - int exec_end_row; - int exec_current_row; - - char pre_executing; /* This statement is prematurely executing */ - char inaccurate_result; /* Current status is PREMATURE but - * result is inaccurate */ - char miscinfo; - char updatable; - SWORD errorpos; - SWORD error_recsize; - Int4 diag_row_count; - char *load_statement; /* to (re)load updatable individual rows */ - Int4 from_pos; - Int4 where_pos; - Int4 last_fetch_count_include_ommitted; -}; - -#define SC_get_conn(a) (a->hdbc) -#define SC_set_Result(a, b) (a->result = a->curres = b) -#define SC_get_Result(a) (a->result) -#define SC_set_Curres(a, b) (a->curres = b) -#define SC_get_Curres(a) (a->curres) -#define SC_get_ARD(a) (&(a->ardopts)) -#define SC_get_APD(a) (&(a->apdopts)) -#define SC_get_IRD(a) (&(a->irdopts)) -#define SC_get_IPD(a) (&(a->ipdopts)) - -/* options for SC_free_params() */ -#define STMT_FREE_PARAMS_ALL 0 -#define STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY 1 - -/* misc info */ -#define SC_set_pre_executable(a) (a->miscinfo |= 1L) -#define SC_no_pre_executable(a) (a->miscinfo &= ~1L) -#define SC_is_pre_executable(a) ((a->miscinfo & 1L) != 0) -#define SC_set_fetchcursor(a) (a->miscinfo |= 2L) -#define SC_no_fetchcursor(a) (a->miscinfo &= ~2L) -#define SC_is_fetchcursor(a) ((a->miscinfo & 2L) != 0) - -/* Statement prototypes */ -StatementClass *SC_Constructor(void); -void InitializeStatementOptions(StatementOptions *opt); -char SC_Destructor(StatementClass *self); -int statement_type(char *statement); -char parse_statement(StatementClass *stmt); -void SC_pre_execute(StatementClass *self); -char SC_unbind_cols(StatementClass *self); -char SC_recycle_statement(StatementClass *self); - -void SC_clear_error(StatementClass *self); -char SC_get_error(StatementClass *self, int *number, char **message); -char *SC_create_errormsg(StatementClass *self); -RETCODE SC_execute(StatementClass *self); -RETCODE SC_fetch(StatementClass *self); -void SC_free_params(StatementClass *self, char option); -void SC_log_error(const char *func, const char *desc, const StatementClass *self); -unsigned long SC_get_bookmark(StatementClass *self); -RETCODE SC_pos_update(StatementClass *self, UWORD irow, UDWORD index); -RETCODE SC_pos_delete(StatementClass *self, UWORD irow, UDWORD index); -RETCODE SC_pos_refresh(StatementClass *self, UWORD irow, UDWORD index); -RETCODE SC_pos_add(StatementClass *self, UWORD irow); - -#endif diff --git a/src/interfaces/odbc/tuple.c b/src/interfaces/odbc/tuple.c deleted file mode 100644 index 512f36d2b2..0000000000 --- a/src/interfaces/odbc/tuple.c +++ /dev/null @@ -1,66 +0,0 @@ -/*------- - * Module: tuple.c - * - * Description: This module contains functions for setting the data - * for individual fields (TupleField structure) of a - * manual result set. - * - * Important Note: These functions are ONLY used in building manual - * result sets for info functions (SQLTables, - * SQLColumns, etc.) - * - * Classes: n/a - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *------- - */ - -#include "tuple.h" - -#include -#include - - -void -set_tuplefield_null(TupleField *tuple_field) -{ - tuple_field->len = 0; - tuple_field->value = NULL; /* strdup(""); */ -} - - -void -set_tuplefield_string(TupleField *tuple_field, char *string) -{ - tuple_field->len = strlen(string); - tuple_field->value = malloc(strlen(string) + 1); - strcpy(tuple_field->value, string); -} - - -void -set_tuplefield_int2(TupleField *tuple_field, Int2 value) -{ - char buffer[10]; - - sprintf(buffer, "%d", value); - - tuple_field->len = strlen(buffer) + 1; - /* +1 ... is this correct (better be on the save side-...) */ - tuple_field->value = strdup(buffer); -} - - -void -set_tuplefield_int4(TupleField *tuple_field, Int4 value) -{ - char buffer[15]; - - sprintf(buffer, "%ld", value); - - tuple_field->len = strlen(buffer) + 1; - /* +1 ... is this correct (better be on the save side-...) */ - tuple_field->value = strdup(buffer); -} diff --git a/src/interfaces/odbc/tuple.h b/src/interfaces/odbc/tuple.h deleted file mode 100644 index c7fe46def4..0000000000 --- a/src/interfaces/odbc/tuple.h +++ /dev/null @@ -1,72 +0,0 @@ -/* File: tuple.h - * - * Description: See "tuple.c" - * - * Important NOTE: The TupleField structure is used both to hold backend data and - * manual result set data. The "set_" functions and the TupleNode - * structure are only used for manual result sets by info routines. - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __TUPLE_H__ -#define __TUPLE_H__ - -#include "psqlodbc.h" - -/* Used by backend data AND manual result sets */ -struct TupleField_ -{ - Int4 len; /* length of the current Tuple */ - void *value; /* an array representing the value */ -}; - -/* Used ONLY for manual result sets */ -struct TupleNode_ -{ - struct TupleNode_ *prev, - *next; - TupleField tuple[1]; -}; - -/* keyset(TID + OID) info */ -struct KeySet_ -{ - UWORD status; - UWORD offset; - UDWORD blocknum; - UDWORD oid; -}; -/* Rollback(index + original TID) info */ -struct Rollback_ -{ - UDWORD index; - UDWORD blocknum; - UWORD offset; -}; -#define KEYSET_INFO_PUBLIC 0x07 -#define CURS_SELF_ADDING (1L << 3) -#define CURS_SELF_DELETING (1L << 4) -#define CURS_SELF_UPDATING (1L << 5) -#define CURS_SELF_ADDED (1L << 6) -#define CURS_SELF_DELETED (1L << 7) -#define CURS_SELF_UPDATED (1L << 8) -#define CURS_NEEDS_REREAD (1L << 9) -#define CURS_IN_ROWSET (1L << 10) -#define CURS_OTHER_DELETED (1L << 11) - -/* These macros are wrappers for the corresponding set_tuplefield functions - but these handle automatic NULL determination and call set_tuplefield_null() - if appropriate for the datatype (used by SQLGetTypeInfo). -*/ -#define set_nullfield_string(FLD, VAL) ((VAL) ? set_tuplefield_string(FLD, (VAL)) : set_tuplefield_null(FLD)) -#define set_nullfield_int2(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int2(FLD, (VAL)) : set_tuplefield_null(FLD)) -#define set_nullfield_int4(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int4(FLD, (VAL)) : set_tuplefield_null(FLD)) - -void set_tuplefield_null(TupleField *tuple_field); -void set_tuplefield_string(TupleField *tuple_field, char *string); -void set_tuplefield_int2(TupleField *tuple_field, Int2 value); -void set_tuplefield_int4(TupleField *tuple_field, Int4 value); - -#endif diff --git a/src/interfaces/odbc/tuplelist.c b/src/interfaces/odbc/tuplelist.c deleted file mode 100644 index 0ae2130bff..0000000000 --- a/src/interfaces/odbc/tuplelist.c +++ /dev/null @@ -1,216 +0,0 @@ -/*-------- - * Module: tuplelist.c - * - * Description: This module contains functions for creating a manual - * result set (the TupleList) and retrieving data from - * it for a specific row/column. - * - * Classes: TupleListClass (Functions prefix: "TL_") - * - * API functions: none - * - * Comments: See "notice.txt" for copyright and license information. - *-------- - */ - -#include "tuplelist.h" - -#include -#include "tuple.h" - - -TupleListClass * -TL_Constructor(UInt4 fieldcnt) -{ - TupleListClass *rv; - - mylog("in TL_Constructor\n"); - - rv = (TupleListClass *) malloc(sizeof(TupleListClass)); - if (rv) - { - rv->num_fields = fieldcnt; - rv->num_tuples = 0; - rv->list_start = NULL; - rv->list_end = NULL; - rv->lastref = NULL; - rv->last_indexed = -1; - } - - mylog("exit TL_Constructor\n"); - - return rv; -} - - -void -TL_Destructor(TupleListClass *self) -{ - int lf; - TupleNode *node, - *tp; - - mylog("TupleList: in DESTRUCTOR\n"); - - node = self->list_start; - while (node != NULL) - { - for (lf = 0; lf < self->num_fields; lf++) - if (node->tuple[lf].value != NULL) - free(node->tuple[lf].value); - tp = node->next; - free(node); - node = tp; - } - - free(self); - - mylog("TupleList: exit DESTRUCTOR\n"); -} - - -void * -TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno) -{ - Int4 lf; - Int4 delta, - from_end; - char end_is_closer, - start_is_closer; - TupleNode *rv; - - if (self->last_indexed == -1) - /* we have an empty tuple list */ - return NULL; - - /* some more sanity checks */ - if ((tupleno >= self->num_tuples) || (tupleno < 0)) - /* illegal tuple number range */ - return NULL; - - if ((fieldno >= self->num_fields) || (fieldno < 0)) - /* illegel field number range */ - return NULL; - - /* - * check if we are accessing the same tuple that was used in the last - * fetch (e.g: for fetching all the fields one after another. Do this - * to speed things up - */ - if (tupleno == self->last_indexed) - return self->lastref->tuple[fieldno].value; - - /* now for the tricky part... */ - - /* - * Since random access is quite inefficient for linked lists we use - * the lastref pointer that points to the last element referenced by a - * get_fieldval() call in conjunction with the its index number that - * is stored in last_indexed. (So we use some locality of reference - * principle to speed things up) - */ - - delta = tupleno - self->last_indexed; - /* if delta is positive, we have to go forward */ - - /* - * now check if we are closer to the start or the end of the list than - * to our last_indexed pointer - */ - from_end = (self->num_tuples - 1) - tupleno; - - start_is_closer = labs(delta) > tupleno; - - /* - * true if we are closer to the start of the list than to the - * last_indexed pointer - */ - - end_is_closer = labs(delta) > from_end; - /* true if we are closer at the end of the list */ - - if (end_is_closer) - { - /* scanning from the end is the shortest way. so we do that... */ - rv = self->list_end; - for (lf = 0; lf < from_end; lf++) - rv = rv->prev; - } - else if (start_is_closer) - { - /* - * the shortest way is to start the search from the head of the - * list - */ - rv = self->list_start; - for (lf = 0; lf < tupleno; lf++) - rv = rv->next; - } - else - { - /* the closest way is starting from our lastref - pointer */ - rv = self->lastref; - - /* - * at first determine whether we have to search forward or - * backwards - */ - if (delta < 0) - { - /* we have to search backwards */ - for (lf = 0; lf < (-1) * delta; lf++) - rv = rv->prev; - } - else - { - /* ok, we have to search forward... */ - for (lf = 0; lf < delta; lf++) - rv = rv->next; - } - } - - /* - * now we have got our return pointer, so update the lastref and the - * last_indexed values - */ - self->lastref = rv; - self->last_indexed = tupleno; - - return rv->tuple[fieldno].value; -} - - -char -TL_add_tuple(TupleListClass *self, TupleNode *new_field) -{ - /* - * we append the tuple at the end of the doubly linked list of the - * tuples we have already read in - */ - - new_field->prev = NULL; - new_field->next = NULL; - - if (self->list_start == NULL) - { - /* the list is empty, we have to add the first tuple */ - self->list_start = new_field; - self->list_end = new_field; - self->lastref = new_field; - self->last_indexed = 0; - } - else - { - /* - * there is already an element in the list, so add the new one at - * the end of the list - */ - self->list_end->next = new_field; - new_field->prev = self->list_end; - self->list_end = new_field; - } - self->num_tuples++; - - /* this method of building a list cannot fail, so we return 1 */ - return 1; -} diff --git a/src/interfaces/odbc/tuplelist.h b/src/interfaces/odbc/tuplelist.h deleted file mode 100644 index 3dc98dd78f..0000000000 --- a/src/interfaces/odbc/tuplelist.h +++ /dev/null @@ -1,35 +0,0 @@ -/* File: tuplelist.h - * - * Description: See "tuplelist.c" - * - * Important Note: This structure and its functions are ONLY used in building manual result - * sets for info functions (SQLTables, SQLColumns, etc.) - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __TUPLELIST_H__ -#define __TUPLELIST_H__ - -#include "psqlodbc.h" - -struct TupleListClass_ -{ - Int4 num_fields; - Int4 num_tuples; - TupleNode *list_start, - *list_end, - *lastref; - Int4 last_indexed; -}; - -#define TL_get_num_tuples(x) (x->num_tuples) - -/* Create a TupleList. Each tuple consits of fieldcnt columns */ -TupleListClass *TL_Constructor(UInt4 fieldcnt); -void TL_Destructor(TupleListClass *self); -void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno); -char TL_add_tuple(TupleListClass *self, TupleNode *new_field); - -#endif diff --git a/src/interfaces/odbc/version.h b/src/interfaces/odbc/version.h deleted file mode 100644 index 88516a768f..0000000000 --- a/src/interfaces/odbc/version.h +++ /dev/null @@ -1,16 +0,0 @@ -/* File: version.h - * - * Description: This file defines the driver version. - * - * Comments: See "notice.txt" for copyright and license information. - * - */ - -#ifndef __VERSION_H__ -#define __VERSION_H__ - -#define POSTGRESDRIVERVERSION "07.02.0002" -#define POSTGRES_RESOURCE_VERSION "07.02.0002\0" -#define PG_DRVFILE_VERSION 7,2,0,02 - -#endif diff --git a/src/interfaces/odbc/win32.mak b/src/interfaces/odbc/win32.mak deleted file mode 100644 index af801a9544..0000000000 --- a/src/interfaces/odbc/win32.mak +++ /dev/null @@ -1,511 +0,0 @@ - -# -# File: win32.mak -# -# Description: psqlodbc Makefile for Win32. -# -# Configurations: Debug, Release, MultibyteDebug, MultibyteRelease -# Build Types: ALL, CLEAN -# Usage: NMAKE /f win32.mak CFG=[Release | Debug | MultibyteRelease | MultiByteDebug] [ALL | CLEAN] -# -# Comments: Created by Dave Page, 2001-02-12 -# - -!MESSAGE Building the PostgreSQL ODBC Driver for Win32... -!MESSAGE -!IF "$(CFG)" == "" -CFG=MultibyteRelease -!MESSAGE No configuration specified. Defaulting to Release. -!MESSAGE -!ENDIF - -!IF "$(CFG)" != "Release" && "$(CFG)" != "Debug" && "$(CFG)" != "MultibyteRelease" && "$(CFG)" != "MultibyteDebug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f win32.mak CFG=[Release | Debug | MultibyteRelease | MultiByteDebug] [ALL | CLEAN] -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Release" (Win32 Release DLL) -!MESSAGE "Debug" (Win32 Debug DLL) -!MESSAGE "MultibyteRelease" (Win32 Release DLL with Multibyte support) -!MESSAGE "MultibyteDebug" (Win32 Debug DLL with Multibyte support) -!MESSAGE -!ERROR An invalid configuration was specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Release" || "$(CFG)" == "MultibyteRelease" - -!IF "$(CFG)" == "MultibyteRelease" -OUTDIR=.\MultibyteRelease -OUTDIRBIN=.\MultibyteRelease -INTDIR=.\MultibyteRelease -!ELSE -OUTDIR=.\Release -OUTDIRBIN=.\Release -INTDIR=.\Release -!ENDIF - -ALL : "$(OUTDIRBIN)\psqlodbc.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\dlg_wingui.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" -!IF "$(CFG)" == "MultibyteRelease" - -@erase "$(INTDIR)\multibyte.obj" -!ENDIF - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\psqlodbc.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pch" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -!IF "$(CFG)" == "MultibyteRelease" -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "MULTIBYTE" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -!ELSE -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -!ENDIF - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_win32.def" /out:"$(OUTDIRBIN)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" -DEF_FILE= "psqlodbc_win32.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\dlg_wingui.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" \ - "$(INTDIR)\misc.obj" \ -!IF "$(CFG)" == "MultibyteRelease" - "$(INTDIR)\multibyte.obj" \ -!ENDIF - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIRBIN)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Debug" || "$(CFG)" == "MultibyteDebug" - -!IF "$(CFG)" == "MultibyteDebug" -OUTDIR=.\MultibyteDebug -INTDIR=.\MultibyteDebug -!ELSE -OUTDIR=.\Debug -INTDIR=.\Debug -!ENDIF - -ALL : "$(OUTDIR)\psqlodbc.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\dlg_wingui.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" -!IF "$(CFG)" == "MultibyteDebug" - -@erase "$(INTDIR)\multibyte.obj" -!ENDIF - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\psqlodbc.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.ilk" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pdb" - -@erase "$(OUTDIR)\psqlodbc.pch" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -!IF "$(CFG)" == "MultibyteDebug" -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "MULTIBYTE" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -!ELSE -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -!ENDIF - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_win32.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept -DEF_FILE= "psqlodbc_win32.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\dlg_wingui.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" - "$(INTDIR)\misc.obj" \ -!IF "$(CFG)" == "MultibyteDebug" - "$(INTDIR)\multibyte.obj" \ -!ENDIF - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -!IF "$(CFG)" == "Release" || "$(CFG)" == "Debug" || "$(CFG)" == "MultibyteRelease" || "$(CFG)" == "MultibyteDebug" - -SOURCE=bind.c - -"$(INTDIR)\bind.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=columninfo.c - -"$(INTDIR)\columninfo.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=connection.c - -"$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=convert.c - -"$(INTDIR)\convert.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_specific.c - -"$(INTDIR)\dlg_specific.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_wingui.c - -"$(INTDIR)\dlg_wingui.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=drvconn.c - -"$(INTDIR)\drvconn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=environ.c - -"$(INTDIR)\environ.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=execute.c - -"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=info.c - -"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=lobj.c - -"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=misc.c - -"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!IF "$(CFG)" == "MultibyteRelease" || "$(CFG)" == "MultibyteDebug" - -SOURCE=multibyte.c - -"$(INTDIR)\multibyte.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -!ENDIF - - -SOURCE=options.c - -"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=parse.c - -"$(INTDIR)\parse.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=pgtypes.c - -"$(INTDIR)\pgtypes.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.c - -"$(INTDIR)\psqlodbc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.rc - -!IF "$(CFG)" == "Release" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "MultibyteRelease" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "Debug" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "MultibyteDebug" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" /d "MULTIBYTE" $(SOURCE) -!ENDIF - - -SOURCE=qresult.c - -"$(INTDIR)\qresult.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=results.c - -"$(INTDIR)\results.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=setup.c - -"$(INTDIR)\setup.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=socket.c - -"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=statement.c - -"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuple.c - -"$(INTDIR)\tuple.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuplelist.c - -"$(INTDIR)\tuplelist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=win_md5.c - -"$(INTDIR)\win_md5.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=odbcapi.c - -"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - - - -!ENDIF diff --git a/src/interfaces/odbc/win32_30.mak b/src/interfaces/odbc/win32_30.mak deleted file mode 100755 index 1c25b3406b..0000000000 --- a/src/interfaces/odbc/win32_30.mak +++ /dev/null @@ -1,537 +0,0 @@ -# -# File: win32_30.mak -# -# Description: psqlodbc30 Makefile for Win32. -# -# Configurations: ODBC30Debug, ODBC30, MultibyteDebug30, MultibyteODBC30 -# Build Types: ALL, CLEAN -# Usage: NMAKE /f win32_30.mak CFG=[ODBC30 | ODBC30Debug | MultibyteODBC30 | MultibyteDebug30] [ALL | CLEAN] -# -# Comments: Created by Dave Page, 2001-02-12 -# - -!MESSAGE Building the PostgreSQL ODBC 3.0 Driver for Win32... -!MESSAGE -!IF "$(CFG)" == "" -CFG=MultibyteODBC30 -!MESSAGE No configuration specified. Defaulting to ODBC30. -!MESSAGE -!ENDIF - -!IF "$(CFG)" != "ODBC30" && "$(CFG)" != "ODBC30Debug" && "$(CFG)" != "MultibyteODBC30" && "$(CFG)" != "MultibyteDebug30" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f win32_30.mak CFG=[ODBC30 | ODBC30Debug | MultibyteODBC30 | MultiByteDebug] [ALL | CLEAN] -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ODBC30" (Win32 Release DLL) -!MESSAGE "ODBC30Debug" (Win32 Debug DLL) -!MESSAGE "MultibyteODBC30" (Win32 Release DLL with Multibyte support) -!MESSAGE "MultibyteDebug30" (Win32 Debug DLL with Multibyte support) -!MESSAGE -!ERROR An invalid configuration was specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "ODBC30" || "$(CFG)" == "MultibyteODBC30" - -!IF "$(CFG)" == "MultibyteODBC30" -OUTDIR=.\MultibyteODBC30 -OUTDIRBIN=.\MultibyteODBC30 -INTDIR=.\MultibyteODBC30 -!ELSE -OUTDIR=.\ODBC30 -OUTDIRBIN=.\ODBC30 -INTDIR=.\ODBC30 -!ENDIF - -ALL : "$(OUTDIRBIN)\psqlodbc30.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\dlg_wingui.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\info30.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" -!IF "$(CFG)" == "MultibyteODBC30" - -@erase "$(INTDIR)\multibyte.obj" -!ENDIF - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\odbcapi30.obj" - -@erase "$(INTDIR)\pgapi30.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\psqlodbc30.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pch" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -!IF "$(CFG)" == "MultibyteODBC30" -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "MULTIBYTE" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -!ELSE -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -!ENDIF - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_api30.def" /out:"$(OUTDIRBIN)\psqlodbc30.dll" /implib:"$(OUTDIR)\psqlodbc.lib" -DEF_FILE= "psqlodbc_api30.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\dlg_wingui.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\info30.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" \ - "$(INTDIR)\misc.obj" \ -!IF "$(CFG)" == "MultibyteODBC30" - "$(INTDIR)\multibyte.obj" \ -!ENDIF - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\odbcapi30.obj" \ - "$(INTDIR)\pgapi30.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIRBIN)\psqlodbc30.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "ODBC30Debug" || "$(CFG)" == "MultibyteDebug30" - -!IF "$(CFG)" == "MultibyteDebug30" -OUTDIR=.\MultibyteDebug30 -INTDIR=.\MultibyteDebug30 -!ELSE -OUTDIR=.\ODBC30Debug -INTDIR=.\ODBC30Debug -!ENDIF - -ALL : "$(OUTDIR)\psqlodbc30.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\dlg_wingui.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\info30.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" -!IF "$(CFG)" == "MultibyteDebug30" - -@erase "$(INTDIR)\multibyte.obj" -!ENDIF - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\odbcapi30.obj" - -@erase "$(INTDIR)\pgapi30.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\psqlodbc30.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.ilk" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pdb" - -@erase "$(OUTDIR)\psqlodbc.pch" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -!IF "$(CFG)" == "MultibyteDebug30" -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "MULTIBYTE" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -!ELSE -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -!ENDIF - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_api30.def" /out:"$(OUTDIR)\psqlodbc30.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept -DEF_FILE= "psqlodbc_api30.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\dlg_wingui.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\info30.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" - "$(INTDIR)\misc.obj" \ -!IF "$(CFG)" == "MultibyteDebug30" - "$(INTDIR)\multibyte.obj" \ -!ENDIF - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\odbcapi30.obj" \ - "$(INTDIR)\pgapi30.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIR)\psqlodbc30.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -!IF "$(CFG)" == "ODBC30" || "$(CFG)" == "ODBC30Debug" || "$(CFG)" == "MultibyteODBC30" || "$(CFG)" == "MultibyteDebug30" - -SOURCE=bind.c - -"$(INTDIR)\bind.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=columninfo.c - -"$(INTDIR)\columninfo.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=connection.c - -"$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=convert.c - -"$(INTDIR)\convert.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_specific.c - -"$(INTDIR)\dlg_specific.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_wingui.c - -"$(INTDIR)\dlg_wingui.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=drvconn.c - -"$(INTDIR)\drvconn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=environ.c - -"$(INTDIR)\environ.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=execute.c - -"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=info.c - -"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=info30.c - -"$(INTDIR)\info30.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=lobj.c - -"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=misc.c - -"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!IF "$(CFG)" == "MultibyteODBC30" || "$(CFG)" == "MultibyteDebug30" - -SOURCE=multibyte.c - -"$(INTDIR)\multibyte.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -!ENDIF - - -SOURCE=options.c - -"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=parse.c - -"$(INTDIR)\parse.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=pgtypes.c - -"$(INTDIR)\pgtypes.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.c - -"$(INTDIR)\psqlodbc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.rc - -!IF "$(CFG)" == "ODBC30" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "MultibyteODBC30" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "ODBC30Debug" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "MultibyteDebug30" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" /d "MULTIBYTE" $(SOURCE) -!ENDIF - - -SOURCE=qresult.c - -"$(INTDIR)\qresult.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=results.c - -"$(INTDIR)\results.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=setup.c - -"$(INTDIR)\setup.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=socket.c - -"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=statement.c - -"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuple.c - -"$(INTDIR)\tuple.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuplelist.c - -"$(INTDIR)\tuplelist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=win_md5.c - -"$(INTDIR)\win_md5.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=odbcapi.c - -"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=odbcapi30.c - -"$(INTDIR)\odbcapi30.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=pgcapi30.c - -"$(INTDIR)\pgcapi30.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF diff --git a/src/interfaces/odbc/win32_30w.mak b/src/interfaces/odbc/win32_30w.mak deleted file mode 100644 index 15e53dc06e..0000000000 --- a/src/interfaces/odbc/win32_30w.mak +++ /dev/null @@ -1,520 +0,0 @@ -# -# File: win32_30w.mak -# -# Description: psqlodbc30w Unicode version Makefile for Win32. -# -# Configurations: Unicode30Debug, Unicode30 -# Build Types: ALL, CLEAN -# Usage: NMAKE /f win32_30.mak CFG=[Unicode30 | Unicode30Debug] [ALL | CLEAN] -# -# Comments: Created by Dave Page, 2001-02-12 -# - -!MESSAGE Building the PostgreSQL Unicode 3.0 Driver for Win32... -!MESSAGE -!IF "$(CFG)" == "" -CFG=Unicode30 -!MESSAGE No configuration specified. Defaulting to Unicode30. -!MESSAGE -!ENDIF - -!IF "$(CFG)" != "Unicode30" && "$(CFG)" != "Unicode30Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f win32_30.mak CFG=[Unicode30 | Unicode30Debug] [ALL | CLEAN] -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Unicode30" (Win32 Release DLL) -!MESSAGE "Unicode30Debug" (Win32 Debug DLL) -!MESSAGE -!ERROR An invalid configuration was specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Unicode30" - -OUTDIR=.\Unicode30 -OUTDIRBIN=.\Unicode30 -INTDIR=.\Unicode30 - -ALL : "$(OUTDIRBIN)\psqlodbc30w.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\dlg_wingui.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\info30.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" - -@erase "$(INTDIR)\pgapi30.obj" - -@erase "$(INTDIR)\multibyte.obj" - -@erase "$(INTDIR)\odbcapiw.obj" - -@erase "$(INTDIR)\odbcapi30w.obj" - -@erase "$(INTDIR)\win_unicode.obj" - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\odbcapi30.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\psqlodbc30w.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pch" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_api30w.def" /out:"$(OUTDIRBIN)\psqlodbc30w.dll" /implib:"$(OUTDIR)\psqlodbc.lib" -DEF_FILE= "psqlodbc_api30w.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\dlg_wingui.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\info30.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" \ - "$(INTDIR)\misc.obj" \ - "$(INTDIR)\pgapi30.obj" \ - "$(INTDIR)\multibyte.obj" \ - "$(INTDIR)\odbcapiw.obj" \ - "$(INTDIR)\odbcapi30w.obj" \ - "$(INTDIR)\win_unicode.obj" \ - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\odbcapi30.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIRBIN)\psqlodbc30w.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Unicode30Debug" - -ALL : "$(OUTDIR)\psqlodbc30w.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\dlg_wingui.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\info30.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" - -@erase "$(INTDIR)\pgapi30.obj" - -@erase "$(INTDIR)\multibyte.obj" - -@erase "$(INTDIR)\odbcapiw.obj" - -@erase "$(INTDIR)\odbcapi30w.obj" - -@erase "$(INTDIR)\win_unicode.obj" - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\odbcapi30.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\psqlodbc30w.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.ilk" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pdb" - -@erase "$(OUTDIR)\psqlodbc.pch" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" $(ADD_DEFINES) /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_api30w.def" /out:"$(OUTDIR)\psqlodbc30w.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept -DEF_FILE= "psqlodbc_api30w.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\dlg_wingui.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\info30.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" - "$(INTDIR)\misc.obj" \ - "$(INTDIR)\pgapi30.obj" \ - "$(INTDIR)\multibyte.obj" \ - "$(INTDIR)\odbcapiw.obj" \ - "$(INTDIR)\odbcapi30w.obj" \ - "$(INTDIR)\win_unicode.obj" \ - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\odbcapi30.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIR)\psqlodbc30w.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -!IF "$(CFG)" == "Unicode30" || "$(CFG)" == "Unicode30Debug" - -SOURCE=bind.c - -"$(INTDIR)\bind.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=columninfo.c - -"$(INTDIR)\columninfo.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=connection.c - -"$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=convert.c - -"$(INTDIR)\convert.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_specific.c - -"$(INTDIR)\dlg_specific.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_wingui.c - -"$(INTDIR)\dlg_wingui.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=drvconn.c - -"$(INTDIR)\drvconn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=environ.c - -"$(INTDIR)\environ.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=execute.c - -"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=info.c - -"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=info30.c - -"$(INTDIR)\info30.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=lobj.c - -"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=misc.c - -"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=multibyte.c - -"$(INTDIR)\multibyte.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=odbcapiw.c - -"$(INTDIR)\odbcapiw.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=pgapi30.c - -"$(INTDIR)\pgapi30.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=odbcapi30w.c - -"$(INTDIR)\odbcapi30w.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=win_unicode.c - -"$(INTDIR)\win_unicode.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=options.c - -"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=parse.c - -"$(INTDIR)\parse.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=pgtypes.c - -"$(INTDIR)\pgtypes.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.c - -"$(INTDIR)\psqlodbc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.rc - -!IF "$(CFG)" == "Unicode30" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "Unicode30Debug" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" $(SOURCE) -!ENDIF - - -SOURCE=qresult.c - -"$(INTDIR)\qresult.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=results.c - -"$(INTDIR)\results.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=setup.c - -"$(INTDIR)\setup.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=socket.c - -"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=statement.c - -"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuple.c - -"$(INTDIR)\tuple.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuplelist.c - -"$(INTDIR)\tuplelist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=win_md5.c - -"$(INTDIR)\win_md5.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=odbcapi.c - -"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=odbcapi30.c - -"$(INTDIR)\odbcapi30.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - - - -!ENDIF diff --git a/src/interfaces/odbc/win32w.mak b/src/interfaces/odbc/win32w.mak deleted file mode 100644 index 24a57a129b..0000000000 --- a/src/interfaces/odbc/win32w.mak +++ /dev/null @@ -1,478 +0,0 @@ -# -# File: win32w.mak -# -# Description: psqlodbc Unicode version Makefile for Win32. -# -# Configurations: UnicodeDebug, Unicode -# Build Types: ALL, CLEAN -# Usage: NMAKE /f win32w.mak CFG=[Unicode | UnicodeDebug] [ALL | CLEAN] -# -# Comments: Created by Dave Page, 2001-02-12 -# - -!MESSAGE Building the PostgreSQL Unicode Driver for Win32... -!MESSAGE -!IF "$(CFG)" == "" -CFG=Unicode -!MESSAGE No configuration specified. Defaulting to Unicode. -!MESSAGE -!ENDIF - -!IF "$(CFG)" != "Unicode" && "$(CFG)" != "UnicodeDebug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f win32w.mak CFG=[Unicode | UnicodeDebug] [ALL | CLEAN] -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Unicode" (Win32 Release DLL) -!MESSAGE "UnicodeDebug" (Win32 Debug DLL) -!MESSAGE -!ERROR An invalid configuration was specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Unicode" - -OUTDIR=.\Unicode -OUTDIRBIN=.\Unicode -INTDIR=.\Unicode - -ALL : "$(OUTDIRBIN)\psqlodbc.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" - -@erase "$(INTDIR)\multibyte.obj" - -@erase "$(INTDIR)\odbcapiw.obj" - -@erase "$(INTDIR)\odbcapi25w.obj" - -@erase "$(INTDIR)\win_unicode.obj" - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\psqlodbc.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.lib" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0250" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_apiw.def" /out:"$(OUTDIRBIN)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" -DEF_FILE= "psqlodbc_apiw.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" \ - "$(INTDIR)\misc.obj" \ - "$(INTDIR)\multibyte.obj" \ - "$(INTDIR)\odbcapiw.obj" \ - "$(INTDIR)\odbcapi25w.obj" \ - "$(INTDIR)\win_unicode.obj" \ - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIRBIN)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "UnicodeDebug" - -ALL : "$(OUTDIR)\psqlodbc.dll" - - -CLEAN : - -@erase "$(INTDIR)\bind.obj" - -@erase "$(INTDIR)\columninfo.obj" - -@erase "$(INTDIR)\connection.obj" - -@erase "$(INTDIR)\convert.obj" - -@erase "$(INTDIR)\dlg_specific.obj" - -@erase "$(INTDIR)\drvconn.obj" - -@erase "$(INTDIR)\environ.obj" - -@erase "$(INTDIR)\execute.obj" - -@erase "$(INTDIR)\info.obj" - -@erase "$(INTDIR)\lobj.obj" - -@erase "$(INTDIR)\win_md5.obj" - -@erase "$(INTDIR)\misc.obj" - -@erase "$(INTDIR)\multibyte.obj" - -@erase "$(INTDIR)\odbcapiw.obj" - -@erase "$(INTDIR)\odbcapi25w.obj" - -@erase "$(INTDIR)\win_unicode.obj" - -@erase "$(INTDIR)\options.obj" - -@erase "$(INTDIR)\parse.obj" - -@erase "$(INTDIR)\pgtypes.obj" - -@erase "$(INTDIR)\psqlodbc.obj" - -@erase "$(INTDIR)\psqlodbc.res" - -@erase "$(INTDIR)\qresult.obj" - -@erase "$(INTDIR)\results.obj" - -@erase "$(INTDIR)\setup.obj" - -@erase "$(INTDIR)\socket.obj" - -@erase "$(INTDIR)\statement.obj" - -@erase "$(INTDIR)\tuple.obj" - -@erase "$(INTDIR)\tuplelist.obj" - -@erase "$(INTDIR)\odbcapi.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\psqlodbc.dll" - -@erase "$(OUTDIR)\psqlodbc.exp" - -@erase "$(OUTDIR)\psqlodbc.ilk" - -@erase "$(OUTDIR)\psqlodbc.lib" - -@erase "$(OUTDIR)\psqlodbc.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0250" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_apiw.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept -DEF_FILE= "psqlodbc_apiw.def" -LINK32_OBJS= \ - "$(INTDIR)\bind.obj" \ - "$(INTDIR)\columninfo.obj" \ - "$(INTDIR)\connection.obj" \ - "$(INTDIR)\convert.obj" \ - "$(INTDIR)\dlg_specific.obj" \ - "$(INTDIR)\drvconn.obj" \ - "$(INTDIR)\environ.obj" \ - "$(INTDIR)\execute.obj" \ - "$(INTDIR)\info.obj" \ - "$(INTDIR)\lobj.obj" \ - "$(INTDIR)\win_md5.obj" - "$(INTDIR)\misc.obj" \ - "$(INTDIR)\multibyte.obj" \ - "$(INTDIR)\odbcapiw.obj" \ - "$(INTDIR)\odbcapi25w.obj" \ - "$(INTDIR)\win_unicode.obj" \ - "$(INTDIR)\options.obj" \ - "$(INTDIR)\parse.obj" \ - "$(INTDIR)\pgtypes.obj" \ - "$(INTDIR)\psqlodbc.obj" \ - "$(INTDIR)\qresult.obj" \ - "$(INTDIR)\results.obj" \ - "$(INTDIR)\setup.obj" \ - "$(INTDIR)\socket.obj" \ - "$(INTDIR)\statement.obj" \ - "$(INTDIR)\tuple.obj" \ - "$(INTDIR)\tuplelist.obj" \ - "$(INTDIR)\odbcapi.obj" \ - "$(INTDIR)\psqlodbc.res" - -"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -!IF "$(CFG)" == "Unicode" || "$(CFG)" == "UnicodeDebug" - -SOURCE=bind.c - -"$(INTDIR)\bind.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=columninfo.c - -"$(INTDIR)\columninfo.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=connection.c - -"$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=convert.c - -"$(INTDIR)\convert.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=dlg_specific.c - -"$(INTDIR)\dlg_specific.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=drvconn.c - -"$(INTDIR)\drvconn.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=environ.c - -"$(INTDIR)\environ.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=execute.c - -"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=info.c - -"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=lobj.c - -"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=misc.c - -"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=multibyte.c - -"$(INTDIR)\multibyte.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=odbcapiw.c - -"$(INTDIR)\odbcapiw.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=odbcapi25w.c - -"$(INTDIR)\odbcapi25w.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=win_unicode.c - -"$(INTDIR)\win_unicode.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=options.c - -"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=parse.c - -"$(INTDIR)\parse.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=pgtypes.c - -"$(INTDIR)\pgtypes.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.c - -"$(INTDIR)\psqlodbc.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=psqlodbc.rc - -!IF "$(CFG)" == "Unicode" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE) -!ENDIF - -!IF "$(CFG)" == "UnicodeDebug" -"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" $(SOURCE) -!ENDIF - - -SOURCE=qresult.c - -"$(INTDIR)\qresult.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=results.c - -"$(INTDIR)\results.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=setup.c - -"$(INTDIR)\setup.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=socket.c - -"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=statement.c - -"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuple.c - -"$(INTDIR)\tuple.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=tuplelist.c - -"$(INTDIR)\tuplelist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=win_md5.c - -"$(INTDIR)\win_md5.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=odbcapi.c - -"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - - -!ENDIF diff --git a/src/interfaces/odbc/win_md5.c b/src/interfaces/odbc/win_md5.c deleted file mode 100644 index 2a7c4014c7..0000000000 --- a/src/interfaces/odbc/win_md5.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * win_md5.c - * Under Windows I don't love the following /D in makefiles. - inoue - */ -#define MD5_ODBC -#define FRONTEND - -/* - * md5.c is the exact copy of the src/backend/libpq/md5.c. - * - * psqlodbc driver stuff never refer(link) to other - * stuff directly. - * - */ -#include "md5.c" diff --git a/src/interfaces/odbc/win_setup.h b/src/interfaces/odbc/win_setup.h deleted file mode 100644 index 3c767d8302..0000000000 --- a/src/interfaces/odbc/win_setup.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _WIN_SETUP_H__ -#define _WIN_SETUP_H__ - -#ifndef INTFUNC -#define INTFUNC __stdcall -#endif /* INTFUNC */ -#define MAXDSNAME (32+1) /* Max data source name length */ -/* Globals */ -/* NOTE: All these are used by the dialog procedures */ -typedef struct tagSETUPDLG -{ - HWND hwndParent; /* Parent window handle */ - LPCSTR lpszDrvr; /* Driver description */ - ConnInfo ci; - char szDSN[MAXDSNAME]; /* Original data source name */ - BOOL fNewDSN; /* New data source flag */ - BOOL fDefault; /* Default data source flag */ - -} SETUPDLG, FAR * LPSETUPDLG; - -/* Prototypes */ -void INTFUNC CenterDialog(HWND hdlg); -int CALLBACK ConfigDlgProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam); -void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg); -BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg); - -#endif /* _WIN_SETUP_H__ */ diff --git a/src/interfaces/odbc/win_unicode.c b/src/interfaces/odbc/win_unicode.c deleted file mode 100644 index 112ea18be1..0000000000 --- a/src/interfaces/odbc/win_unicode.c +++ /dev/null @@ -1,149 +0,0 @@ -/*------- - * Module: win_unicode.c - * - * Description: This module contains utf8 <-> ucs2 conversion routines - * under WIndows - * - *------- - */ - -#include "psqlodbc.h" -#include -#include - -#define byte3check 0xf800 -#define byte2_base 0x80c0 -#define byte2_mask1 0x07c0 -#define byte2_mask2 0x003f -#define byte3_base 0x8080e0 -#define byte3_mask1 0xf000 -#define byte3_mask2 0x0fc0 -#define byte3_mask3 0x003f - -UInt4 ucs2strlen(const SQLWCHAR *ucs2str) -{ - UInt4 len; - for (len = 0; ucs2str[len]; len++) - ; - return len; -} -char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen) -{ - char * utf8str; -/*mylog("ucs2_to_utf8 %x ilen=%d ", ucs2str, ilen);*/ - - if (!ucs2str) - return NULL; - if (ilen < 0) - ilen = ucs2strlen(ucs2str); -/*mylog(" newlen=%d", ilen);*/ - utf8str = (char *) malloc(ilen * 3 + 1); - if (utf8str) - { - int i, len = 0; - UInt2 byte2code; - Int4 byte4code; - const SQLWCHAR *wstr; - - for (i = 0, wstr = ucs2str; i < ilen; i++, wstr++) - { - if (!*wstr) - break; - else if (0 == (*wstr & 0xff80)) - utf8str[len++] = (char) *wstr; - else if ((*wstr & byte3check) == 0) - { - byte2code = byte2_base | - ((byte2_mask1 & *wstr) >> 6) | - ((byte2_mask2 & *wstr) << 8); - memcpy(utf8str + len, (char *) &byte2code, sizeof(byte2code)); - len += 2; - } - else - { - byte4code = byte3_base | - ((byte3_mask1 & *wstr) >> 12) | - ((byte3_mask2 & *wstr) << 2) | - ((byte3_mask3 & *wstr) << 16); - memcpy(utf8str + len, (char *) &byte4code, 3); - len += 3; - } - } - utf8str[len] = '\0'; - if (olen) - *olen = len; - } -/*mylog(" olen=%d %s\n", *olen, utf8str ? utf8str : "");*/ - return utf8str; -} - -#define byte3_m1 0x0f -#define byte3_m2 0x3f -#define byte3_m3 0x3f -#define byte2_m1 0x1f -#define byte2_m2 0x3f -UInt4 utf8_to_ucs2_lf(const char *utf8str, Int4 ilen, BOOL lfconv, SQLWCHAR *ucs2str, UInt4 bufcount) -{ - int i; - UInt4 ocount, wcode; - const unsigned char *str; - -/*mylog("utf8_to_ucs2 ilen=%d bufcount=%d", ilen, bufcount);*/ - if (!utf8str || !ilen) - return 0; -/*mylog(" string=%s\n", utf8str);*/ - if (!bufcount) - ucs2str = NULL; - else if (!ucs2str) - bufcount = 0; - if (ilen < 0) - ilen = strlen(utf8str); - for (i = 0, ocount = 0, str = utf8str; i < ilen;) - { - if (iswascii(*str)) - { - if (lfconv && *str == '\n' && - (i == 0 || str[-1] != '\r')) - { - if (ocount < bufcount) - ucs2str[ocount] = '\r'; - ocount++; - } - if (ocount < bufcount) - ucs2str[ocount] = *str; - ocount++; - i++; - str++; - } - else if (0xe0 == (*str & 0xe0)) /* 3 byte code */ - { - if (ocount < bufcount) - { - wcode = ((((UInt4) *str) & byte3_m1) << 12) | - ((((UInt4) str[1]) & byte3_m2) << 6) | - (((UInt4) str[2]) & byte3_m3); - ucs2str[ocount] = (SQLWCHAR) wcode; - } - ocount++; - i += 3; - str += 3; - } - else - { - if (ocount < bufcount) - { - wcode = ((((UInt4) *str) & byte2_m1) << 6) | - (((UInt4) str[1]) & byte2_m2); - ucs2str[ocount] = (SQLWCHAR) wcode; - } - ocount++; - i += 2; - str += 2; - } - } - if (ocount && ocount < bufcount && ucs2str) - ucs2str[ocount] = 0; -/*mylog(" ocount=%d\n", ocount);*/ - return ocount; -} -