2001-07-10 22:36:20 +00:00
|
|
|
/* MDB Tools - A library for reading MS Access database file
|
|
|
|
|
* Copyright (C) 2000 Brian Bruns
|
|
|
|
|
*
|
|
|
|
|
* 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., 59 Temple Place - Suite 330,
|
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef UNIXODBC
|
|
|
|
|
#include <sql.h>
|
|
|
|
|
#include <sqlext.h>
|
|
|
|
|
#else
|
|
|
|
|
#include "isql.h"
|
|
|
|
|
#include "isqlext.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <mdbodbc.h>
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
#include "connectparams.h"
|
|
|
|
|
|
2004-03-06 05:13:27 +00:00
|
|
|
static char software_version[] = "$Id: odbc.c,v 1.13 2004/03/06 05:13:28 brianb Exp $";
|
2001-07-10 22:36:20 +00:00
|
|
|
static void *no_unused_var_warn[] = {software_version,
|
|
|
|
|
no_unused_var_warn};
|
|
|
|
|
|
|
|
|
|
static SQLSMALLINT _odbc_get_client_type(int srv_type);
|
|
|
|
|
static int _odbc_fix_literals(struct _hstmt *stmt);
|
|
|
|
|
static int _odbc_get_server_type(int clt_type);
|
|
|
|
|
static int _odbc_get_string_size(int size, char *str);
|
|
|
|
|
static SQLRETURN SQL_API _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR *phdbc);
|
|
|
|
|
static SQLRETURN SQL_API _SQLAllocEnv(SQLHENV FAR *phenv);
|
|
|
|
|
static SQLRETURN SQL_API _SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR *phstmt);
|
|
|
|
|
static SQLRETURN SQL_API _SQLFreeConnect(SQLHDBC hdbc);
|
|
|
|
|
static SQLRETURN SQL_API _SQLFreeEnv(SQLHENV henv);
|
|
|
|
|
static SQLRETURN SQL_API _SQLFreeStmt(SQLHSTMT hstmt, SQLUSMALLINT fOption);
|
|
|
|
|
|
2004-01-06 03:18:19 +00:00
|
|
|
static void bind_columns (struct _hstmt*);
|
|
|
|
|
|
|
|
|
|
#ifndef MIN
|
2002-01-24 12:34:10 +00:00
|
|
|
#define MIN(a,b) (a>b ? b : a)
|
2004-01-06 03:18:19 +00:00
|
|
|
#endif
|
2001-07-10 22:36:20 +00:00
|
|
|
#define _MAX_ERROR_LEN 255
|
|
|
|
|
static char lastError[_MAX_ERROR_LEN+1];
|
|
|
|
|
|
2003-01-15 02:02:07 +00:00
|
|
|
//#define TRACE(x) fprintf(stderr,"Function %s\n", x);
|
|
|
|
|
#define TRACE(x)
|
2002-04-09 01:19:26 +00:00
|
|
|
|
2002-01-24 12:34:10 +00:00
|
|
|
/* The SQL engine is presently non-reenterrant and non-thread safe.
|
|
|
|
|
See _SQLExecute for details.
|
|
|
|
|
*/
|
2001-07-24 11:00:00 +00:00
|
|
|
|
2001-07-10 22:36:20 +00:00
|
|
|
static void LogError (const char* error)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Someday, I might make this store more than one error.
|
|
|
|
|
*/
|
|
|
|
|
strncpy (lastError, error, _MAX_ERROR_LEN);
|
|
|
|
|
lastError[_MAX_ERROR_LEN] = '\0'; /* in case we had a long message */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Driver specific connectionn information
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
struct _hdbc hdbc;
|
|
|
|
|
ConnectParams* params;
|
|
|
|
|
} ODBCConnection;
|
|
|
|
|
|
|
|
|
|
static SQLRETURN do_connect (
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLCHAR FAR *database
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
struct _hdbc *dbc = (struct _hdbc *) hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
|
|
|
|
|
|
|
|
|
if (mdb_sql_open(env->sql,database)) {
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
} else {
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLDriverConnect(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLHWND hwnd,
|
|
|
|
|
SQLCHAR FAR *szConnStrIn,
|
|
|
|
|
SQLSMALLINT cbConnStrIn,
|
|
|
|
|
SQLCHAR FAR *szConnStrOut,
|
|
|
|
|
SQLSMALLINT cbConnStrOutMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbConnStrOut,
|
|
|
|
|
SQLUSMALLINT fDriverCompletion)
|
|
|
|
|
{
|
|
|
|
|
SQLCHAR FAR* dsn = NULL;
|
|
|
|
|
SQLCHAR FAR* database = NULL;
|
|
|
|
|
ConnectParams* params;
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("DriverConnect");
|
|
|
|
|
|
2001-07-10 22:36:20 +00:00
|
|
|
strcpy (lastError, "");
|
|
|
|
|
|
|
|
|
|
params = ((ODBCConnection*) hdbc)->params;
|
|
|
|
|
|
|
|
|
|
if (!(dsn = ExtractDSN (params, szConnStrIn)))
|
|
|
|
|
{
|
|
|
|
|
LogError ("Could not find DSN in connect string");
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
else if (!LookupDSN (params, dsn))
|
|
|
|
|
{
|
|
|
|
|
LogError ("Could not find DSN in odbc.ini");
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetConnectString (params, szConnStrIn);
|
|
|
|
|
|
|
|
|
|
if (!(database = GetConnectParam (params, "Database")))
|
|
|
|
|
{
|
|
|
|
|
LogError ("Could not find Database parameter");
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ret = do_connect (hdbc, database);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLBrowseConnect(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLCHAR FAR *szConnStrIn,
|
|
|
|
|
SQLSMALLINT cbConnStrIn,
|
|
|
|
|
SQLCHAR FAR *szConnStrOut,
|
|
|
|
|
SQLSMALLINT cbConnStrOutMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbConnStrOut)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("BrowseConnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLColumnPrivileges(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName,
|
|
|
|
|
SQLCHAR FAR *szColumnName,
|
|
|
|
|
SQLSMALLINT cbColumnName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLColumnPrivileges");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLDescribeParam(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT ipar,
|
|
|
|
|
SQLSMALLINT FAR *pfSqlType,
|
|
|
|
|
SQLUINTEGER FAR *pcbParamDef,
|
|
|
|
|
SQLSMALLINT FAR *pibScale,
|
|
|
|
|
SQLSMALLINT FAR *pfNullable)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLDescribeParam");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLExtendedFetch(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT fFetchType,
|
|
|
|
|
SQLINTEGER irow,
|
|
|
|
|
SQLUINTEGER FAR *pcrow,
|
|
|
|
|
SQLUSMALLINT FAR *rgfRowStatus)
|
|
|
|
|
{
|
2003-01-07 02:24:35 +00:00
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLExtendedFetch");
|
2003-01-07 02:24:35 +00:00
|
|
|
if (fFetchType!=SQL_FETCH_NEXT) {
|
|
|
|
|
LogError("Fetch type not supported in SQLExtendedFetch");
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
if (pcrow)
|
|
|
|
|
*pcrow=1;
|
|
|
|
|
if (rgfRowStatus)
|
|
|
|
|
*rgfRowStatus = SQL_SUCCESS; /* what is the row status value? */
|
|
|
|
|
|
|
|
|
|
bind_columns(stmt);
|
|
|
|
|
|
|
|
|
|
if (mdb_fetch_row(env->sql->cur_table)) {
|
|
|
|
|
stmt->rows_affected++;
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
} else {
|
|
|
|
|
return SQL_NO_DATA_FOUND;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLForeignKeys(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szPkCatalogName,
|
|
|
|
|
SQLSMALLINT cbPkCatalogName,
|
|
|
|
|
SQLCHAR FAR *szPkSchemaName,
|
|
|
|
|
SQLSMALLINT cbPkSchemaName,
|
|
|
|
|
SQLCHAR FAR *szPkTableName,
|
|
|
|
|
SQLSMALLINT cbPkTableName,
|
|
|
|
|
SQLCHAR FAR *szFkCatalogName,
|
|
|
|
|
SQLSMALLINT cbFkCatalogName,
|
|
|
|
|
SQLCHAR FAR *szFkSchemaName,
|
|
|
|
|
SQLSMALLINT cbFkSchemaName,
|
|
|
|
|
SQLCHAR FAR *szFkTableName,
|
|
|
|
|
SQLSMALLINT cbFkTableName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLForeignKeys");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLMoreResults(
|
|
|
|
|
SQLHSTMT hstmt)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLMoreResults");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLNativeSql(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLCHAR FAR *szSqlStrIn,
|
|
|
|
|
SQLINTEGER cbSqlStrIn,
|
|
|
|
|
SQLCHAR FAR *szSqlStr,
|
|
|
|
|
SQLINTEGER cbSqlStrMax,
|
|
|
|
|
SQLINTEGER FAR *pcbSqlStr)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLNativeSql");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLNumParams(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLSMALLINT FAR *pcpar)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLNumParams");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLParamOptions(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUINTEGER crow,
|
|
|
|
|
SQLUINTEGER FAR *pirow)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLParamOptions");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLPrimaryKeys(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLPrimaryKeys");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLProcedureColumns(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szProcName,
|
|
|
|
|
SQLSMALLINT cbProcName,
|
|
|
|
|
SQLCHAR FAR *szColumnName,
|
|
|
|
|
SQLSMALLINT cbColumnName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLProcedureColumns");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLProcedures(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szProcName,
|
|
|
|
|
SQLSMALLINT cbProcName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLProcedures");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLSetPos(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT irow,
|
|
|
|
|
SQLUSMALLINT fOption,
|
|
|
|
|
SQLUSMALLINT fLock)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLSetPos");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLTablePrivileges(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLTablePrivileges");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLDrivers(
|
|
|
|
|
SQLHENV henv,
|
|
|
|
|
SQLUSMALLINT fDirection,
|
|
|
|
|
SQLCHAR FAR *szDriverDesc,
|
|
|
|
|
SQLSMALLINT cbDriverDescMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbDriverDesc,
|
|
|
|
|
SQLCHAR FAR *szDriverAttributes,
|
|
|
|
|
SQLSMALLINT cbDrvrAttrMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbDrvrAttr)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLDrivers");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLSetEnvAttr (
|
|
|
|
|
SQLHENV EnvironmentHandle,
|
|
|
|
|
SQLINTEGER Attribute,
|
|
|
|
|
SQLPOINTER Value,
|
|
|
|
|
SQLINTEGER StringLength)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLSetEnvAttr");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLBindParameter(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT ipar,
|
|
|
|
|
SQLSMALLINT fParamType,
|
|
|
|
|
SQLSMALLINT fCType,
|
|
|
|
|
SQLSMALLINT fSqlType,
|
|
|
|
|
SQLUINTEGER cbColDef,
|
|
|
|
|
SQLSMALLINT ibScale,
|
|
|
|
|
SQLPOINTER rgbValue,
|
|
|
|
|
SQLINTEGER cbValueMax,
|
|
|
|
|
SQLINTEGER FAR *pcbValue)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLBindParameter");
|
2001-07-10 22:36:20 +00:00
|
|
|
stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLAllocHandle(
|
|
|
|
|
SQLSMALLINT HandleType,
|
|
|
|
|
SQLHANDLE InputHandle,
|
|
|
|
|
SQLHANDLE * OutputHandle)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLAllocHandle");
|
2001-07-10 22:36:20 +00:00
|
|
|
switch(HandleType) {
|
|
|
|
|
case SQL_HANDLE_STMT:
|
|
|
|
|
return _SQLAllocStmt(InputHandle,OutputHandle);
|
|
|
|
|
break;
|
|
|
|
|
case SQL_HANDLE_DBC:
|
|
|
|
|
return _SQLAllocConnect(InputHandle,OutputHandle);
|
|
|
|
|
break;
|
|
|
|
|
case SQL_HANDLE_ENV:
|
|
|
|
|
return _SQLAllocEnv(OutputHandle);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
static SQLRETURN SQL_API _SQLAllocConnect(
|
|
|
|
|
SQLHENV henv,
|
|
|
|
|
SQLHDBC FAR *phdbc)
|
|
|
|
|
{
|
|
|
|
|
struct _henv *env;
|
|
|
|
|
ODBCConnection* dbc;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLAllocConnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
env = (struct _henv *) henv;
|
|
|
|
|
dbc = (SQLHDBC) malloc (sizeof (ODBCConnection));
|
|
|
|
|
memset(dbc,'\0',sizeof (ODBCConnection));
|
|
|
|
|
dbc->hdbc.henv=env;
|
|
|
|
|
|
|
|
|
|
dbc->params = NewConnectParams ();
|
|
|
|
|
*phdbc=dbc;
|
|
|
|
|
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLAllocConnect(
|
|
|
|
|
SQLHENV henv,
|
|
|
|
|
SQLHDBC FAR *phdbc)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLAllocConnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLAllocConnect(henv, phdbc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SQLRETURN SQL_API _SQLAllocEnv(
|
|
|
|
|
SQLHENV FAR *phenv)
|
|
|
|
|
{
|
|
|
|
|
struct _henv *env;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLAllocEnv");
|
2001-07-10 22:36:20 +00:00
|
|
|
env = (SQLHENV) malloc(sizeof(struct _henv));
|
|
|
|
|
memset(env,'\0',sizeof(struct _henv));
|
|
|
|
|
*phenv=env;
|
|
|
|
|
env->sql = mdb_sql_init();
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLAllocEnv(
|
|
|
|
|
SQLHENV FAR *phenv)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLAllocEnv");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLAllocEnv(phenv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SQLRETURN SQL_API _SQLAllocStmt(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLHSTMT FAR *phstmt)
|
|
|
|
|
{
|
|
|
|
|
struct _hdbc *dbc;
|
|
|
|
|
struct _hstmt *stmt;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLAllocStmt");
|
2001-07-10 22:36:20 +00:00
|
|
|
dbc = (struct _hdbc *) hdbc;
|
|
|
|
|
|
|
|
|
|
stmt = (SQLHSTMT) malloc(sizeof(struct _hstmt));
|
|
|
|
|
memset(stmt,'\0',sizeof(struct _hstmt));
|
|
|
|
|
stmt->hdbc=hdbc;
|
|
|
|
|
*phstmt = stmt;
|
|
|
|
|
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLAllocStmt(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLHSTMT FAR *phstmt)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLAllocStmt");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLAllocStmt(hdbc,phstmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLBindCol(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT icol,
|
|
|
|
|
SQLSMALLINT fCType,
|
|
|
|
|
SQLPOINTER rgbValue,
|
|
|
|
|
SQLINTEGER cbValueMax,
|
|
|
|
|
SQLINTEGER FAR *pcbValue)
|
|
|
|
|
{
|
2001-07-25 01:55:43 +00:00
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
2002-04-09 01:19:26 +00:00
|
|
|
struct _sql_bind_info *cur, *prev, *newitem;
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLBindCol");
|
|
|
|
|
/* find available item in list */
|
|
|
|
|
cur = stmt->bind_head;
|
|
|
|
|
while (cur) {
|
|
|
|
|
if (cur->column_number==icol)
|
|
|
|
|
break;
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
}
|
|
|
|
|
/* if this is a repeat */
|
|
|
|
|
if (cur) {
|
|
|
|
|
cur->column_bindtype = fCType;
|
|
|
|
|
cur->column_bindlen = cbValueMax;
|
|
|
|
|
cur->varaddr = (char *) rgbValue;
|
|
|
|
|
} else {
|
|
|
|
|
/* didn't find it create a new one */
|
|
|
|
|
newitem = (struct _sql_bind_info *) malloc(sizeof(struct _sql_bind_info));
|
|
|
|
|
memset(newitem, 0, sizeof(struct _sql_bind_info));
|
|
|
|
|
newitem->column_number = icol;
|
|
|
|
|
newitem->column_bindtype = fCType;
|
|
|
|
|
newitem->column_bindlen = cbValueMax;
|
|
|
|
|
newitem->column_lenbind = pcbValue;
|
|
|
|
|
newitem->varaddr = (char *) rgbValue;
|
|
|
|
|
/* if there's no head yet */
|
|
|
|
|
if (! stmt->bind_head) {
|
|
|
|
|
stmt->bind_head = newitem;
|
|
|
|
|
} else {
|
|
|
|
|
/* find the tail of the list */
|
|
|
|
|
cur = stmt->bind_head;
|
|
|
|
|
while (cur) {
|
|
|
|
|
prev = cur;
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
}
|
|
|
|
|
prev->next = newitem;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2001-07-25 01:55:43 +00:00
|
|
|
return SQL_SUCCESS;
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLCancel(
|
|
|
|
|
SQLHSTMT hstmt)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLCancel");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLConnect(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLCHAR FAR *szDSN,
|
|
|
|
|
SQLSMALLINT cbDSN,
|
|
|
|
|
SQLCHAR FAR *szUID,
|
|
|
|
|
SQLSMALLINT cbUID,
|
|
|
|
|
SQLCHAR FAR *szAuthStr,
|
|
|
|
|
SQLSMALLINT cbAuthStr)
|
|
|
|
|
{
|
|
|
|
|
SQLCHAR FAR* database = NULL;
|
|
|
|
|
ConnectParams* params;
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLConnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
strcpy (lastError, "");
|
|
|
|
|
|
|
|
|
|
params = ((ODBCConnection*) hdbc)->params;
|
|
|
|
|
|
|
|
|
|
if (!LookupDSN (params, szDSN))
|
|
|
|
|
{
|
|
|
|
|
LogError ("Could not find DSN in odbc.ini");
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
else if (!(database = GetConnectParam (params, "Database")))
|
|
|
|
|
{
|
|
|
|
|
LogError ("Could not find Database parameter");
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = do_connect (hdbc, database);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLDescribeCol(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT icol,
|
|
|
|
|
SQLCHAR FAR *szColName,
|
|
|
|
|
SQLSMALLINT cbColNameMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbColName,
|
|
|
|
|
SQLSMALLINT FAR *pfSqlType,
|
2002-01-24 12:34:10 +00:00
|
|
|
SQLUINTEGER FAR *pcbColDef, /* precision */
|
2001-07-10 22:36:20 +00:00
|
|
|
SQLSMALLINT FAR *pibScale,
|
|
|
|
|
SQLSMALLINT FAR *pfNullable)
|
|
|
|
|
{
|
|
|
|
|
int cplen, namelen, i;
|
|
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
2002-01-24 12:34:10 +00:00
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
|
|
|
|
MdbSQL *sql = env->sql;
|
|
|
|
|
MdbSQLColumn *sqlcol;
|
|
|
|
|
MdbColumn *col;
|
|
|
|
|
MdbTableDef *table;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLDescribeCol");
|
2002-01-24 12:34:10 +00:00
|
|
|
if (icol<1 || icol>sql->num_columns) {
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
sqlcol = g_ptr_array_index(sql->columns,icol - 1);
|
|
|
|
|
table = sql->cur_table;
|
|
|
|
|
for (i=0;i<table->num_cols;i++) {
|
|
|
|
|
col=g_ptr_array_index(table->columns,i);
|
|
|
|
|
if (!strcasecmp(sqlcol->name, col->name)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (szColName) {
|
|
|
|
|
namelen = MIN(cbColNameMax,strlen(sqlcol->name));
|
|
|
|
|
strncpy(szColName, sqlcol->name, namelen);
|
|
|
|
|
szColName[namelen]='\0';
|
|
|
|
|
}
|
|
|
|
|
if (pfSqlType) {
|
|
|
|
|
*pfSqlType = _odbc_get_client_type(col->col_type);
|
|
|
|
|
}
|
|
|
|
|
if (pcbColDef) {
|
|
|
|
|
*pcbColDef = col->col_size;
|
|
|
|
|
}
|
|
|
|
|
if (pibScale) {
|
|
|
|
|
/* FIX ME */
|
|
|
|
|
*pibScale = 0;
|
|
|
|
|
}
|
|
|
|
|
if (pfNullable) {
|
|
|
|
|
*pfNullable = !col->is_fixed;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLColAttributes(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT icol,
|
|
|
|
|
SQLUSMALLINT fDescType,
|
|
|
|
|
SQLPOINTER rgbDesc,
|
|
|
|
|
SQLSMALLINT cbDescMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbDesc,
|
|
|
|
|
SQLINTEGER FAR *pfDesc)
|
|
|
|
|
{
|
|
|
|
|
int cplen, len = 0;
|
2002-04-03 23:02:53 +00:00
|
|
|
int namelen, i;
|
2001-07-10 22:36:20 +00:00
|
|
|
struct _hstmt *stmt;
|
|
|
|
|
struct _hdbc *dbc;
|
2002-04-03 23:02:53 +00:00
|
|
|
struct _henv *env;
|
|
|
|
|
MdbSQL *sql;
|
|
|
|
|
MdbSQLColumn *sqlcol;
|
|
|
|
|
MdbColumn *col;
|
|
|
|
|
MdbTableDef *table;
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLColAttributes");
|
2001-07-10 22:36:20 +00:00
|
|
|
stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
dbc = (struct _hdbc *) stmt->hdbc;
|
2002-04-03 23:02:53 +00:00
|
|
|
env = (struct _henv *) dbc->henv;
|
|
|
|
|
sql = env->sql;
|
2001-07-10 22:36:20 +00:00
|
|
|
|
|
|
|
|
/* dont check column index for these */
|
|
|
|
|
switch(fDescType) {
|
|
|
|
|
case SQL_COLUMN_COUNT:
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-03 23:02:53 +00:00
|
|
|
if (icol<1 || icol>sql->num_columns) {
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* find the column */
|
|
|
|
|
sqlcol = g_ptr_array_index(sql->columns,icol - 1);
|
|
|
|
|
table = sql->cur_table;
|
|
|
|
|
for (i=0;i<table->num_cols;i++) {
|
|
|
|
|
col=g_ptr_array_index(table->columns,i);
|
|
|
|
|
if (!strcasecmp(sqlcol->name, col->name)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
// fprintf(stderr,"fDescType = %d\n", fDescType);
|
2001-07-10 22:36:20 +00:00
|
|
|
switch(fDescType) {
|
|
|
|
|
case SQL_COLUMN_NAME:
|
2002-04-03 23:02:53 +00:00
|
|
|
case SQL_COLUMN_LABEL:
|
|
|
|
|
namelen = MIN(cbDescMax,strlen(sqlcol->name));
|
|
|
|
|
strncpy(rgbDesc, sqlcol->name, namelen);
|
|
|
|
|
*((char *)&rgbDesc[namelen])='\0';
|
2001-07-10 22:36:20 +00:00
|
|
|
break;
|
|
|
|
|
case SQL_COLUMN_TYPE:
|
2002-04-09 01:19:26 +00:00
|
|
|
*pfDesc = SQL_CHAR;
|
2001-07-10 22:36:20 +00:00
|
|
|
break;
|
|
|
|
|
case SQL_COLUMN_LENGTH:
|
|
|
|
|
break;
|
2002-04-03 23:02:53 +00:00
|
|
|
//case SQL_COLUMN_DISPLAY_SIZE:
|
|
|
|
|
case SQL_DESC_DISPLAY_SIZE:
|
|
|
|
|
switch(_odbc_get_client_type(col->col_type)) {
|
2001-07-10 22:36:20 +00:00
|
|
|
case SQL_CHAR:
|
|
|
|
|
case SQL_VARCHAR:
|
2002-04-03 23:02:53 +00:00
|
|
|
*pfDesc = col->col_size;
|
2001-07-10 22:36:20 +00:00
|
|
|
break;
|
|
|
|
|
case SQL_INTEGER:
|
|
|
|
|
*pfDesc = 8;
|
|
|
|
|
break;
|
|
|
|
|
case SQL_SMALLINT:
|
|
|
|
|
*pfDesc = 6;
|
|
|
|
|
break;
|
|
|
|
|
case SQL_TINYINT:
|
|
|
|
|
*pfDesc = 4;
|
|
|
|
|
break;
|
2002-04-03 23:02:53 +00:00
|
|
|
default:
|
|
|
|
|
//fprintf(stderr,"\nUnknown type %d\n", _odbc_get_client_type(col->col_type));
|
|
|
|
|
break;
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLDisconnect(
|
|
|
|
|
SQLHDBC hdbc)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLDisconnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLError(
|
|
|
|
|
SQLHENV henv,
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szSqlState,
|
|
|
|
|
SQLINTEGER FAR *pfNativeError,
|
|
|
|
|
SQLCHAR FAR *szErrorMsg,
|
|
|
|
|
SQLSMALLINT cbErrorMsgMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbErrorMsg)
|
|
|
|
|
{
|
|
|
|
|
SQLRETURN result = SQL_NO_DATA_FOUND;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLError");
|
2001-07-10 22:36:20 +00:00
|
|
|
if (strlen (lastError) > 0)
|
|
|
|
|
{
|
|
|
|
|
strcpy (szSqlState, "08001");
|
|
|
|
|
strcpy (szErrorMsg, lastError);
|
|
|
|
|
if (pcbErrorMsg)
|
|
|
|
|
*pcbErrorMsg = strlen (lastError);
|
|
|
|
|
if (pfNativeError)
|
|
|
|
|
*pfNativeError = 1;
|
|
|
|
|
|
|
|
|
|
result = SQL_SUCCESS;
|
|
|
|
|
strcpy (lastError, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SQLRETURN SQL_API _SQLExecute( SQLHSTMT hstmt)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
2001-07-24 11:00:00 +00:00
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
2001-07-10 22:36:20 +00:00
|
|
|
int ret;
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLExecute");
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
/* fprintf(stderr,"query = %s\n",stmt->query); */
|
2001-07-10 22:36:20 +00:00
|
|
|
_odbc_fix_literals(stmt);
|
|
|
|
|
|
2002-01-24 12:34:10 +00:00
|
|
|
mdb_sql_reset(env->sql);
|
|
|
|
|
|
2001-07-24 11:00:00 +00:00
|
|
|
/* calls to yyparse would need to be serialized for thread safety */
|
|
|
|
|
|
|
|
|
|
/* begin unsafe */
|
|
|
|
|
g_input_ptr = stmt->query;
|
2002-01-24 12:34:10 +00:00
|
|
|
_mdb_sql(env->sql);
|
2001-07-24 11:00:00 +00:00
|
|
|
if (yyparse()) {
|
|
|
|
|
/* end unsafe */
|
|
|
|
|
LogError("Couldn't parse SQL\n");
|
|
|
|
|
mdb_sql_reset(env->sql);
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
} else {
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLExecDirect(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szSqlStr,
|
|
|
|
|
SQLINTEGER cbSqlStr)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
int ret;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLExecDirect");
|
2001-07-10 22:36:20 +00:00
|
|
|
strcpy(stmt->query, szSqlStr);
|
|
|
|
|
|
|
|
|
|
return _SQLExecute(hstmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLExecute(
|
|
|
|
|
SQLHSTMT hstmt)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLExecute");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLExecute(hstmt);
|
|
|
|
|
}
|
2003-01-07 02:24:35 +00:00
|
|
|
static void
|
|
|
|
|
bind_columns(struct _hstmt *stmt)
|
2001-07-10 22:36:20 +00:00
|
|
|
{
|
2001-07-25 01:55:43 +00:00
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
2002-04-09 01:19:26 +00:00
|
|
|
struct _sql_bind_info *cur;
|
|
|
|
|
|
|
|
|
|
if (stmt->rows_affected==0) {
|
|
|
|
|
cur = stmt->bind_head;
|
|
|
|
|
while (cur) {
|
|
|
|
|
if (cur->column_number>0 &&
|
|
|
|
|
cur->column_number <= env->sql->num_columns) {
|
2004-02-08 21:54:20 +00:00
|
|
|
mdb_sql_bind_column(env->sql,
|
2002-04-09 01:19:26 +00:00
|
|
|
cur->column_number, cur->varaddr);
|
|
|
|
|
if (cur->column_lenbind)
|
2004-02-08 21:54:20 +00:00
|
|
|
mdb_sql_bind_len(env->sql,
|
2002-04-09 01:19:26 +00:00
|
|
|
cur->column_number, cur->column_lenbind);
|
|
|
|
|
} else {
|
|
|
|
|
/* log error ? */
|
|
|
|
|
}
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-01-07 02:24:35 +00:00
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLFetch(
|
|
|
|
|
SQLHSTMT hstmt)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
|
|
|
|
|
|
|
|
|
TRACE("SQLFetch");
|
|
|
|
|
/* if we bound columns, transfer them to res_info now that we have one */
|
|
|
|
|
bind_columns(stmt);
|
2002-04-09 01:19:26 +00:00
|
|
|
//cur = stmt->bind_head;
|
|
|
|
|
//while (cur) {
|
|
|
|
|
//if (cur->column_number>0 &&
|
|
|
|
|
//cur->column_number <= env->sql->num_columns) {
|
|
|
|
|
// if (cur->column_lenbind) *(cur->column_lenbind) = 4;
|
|
|
|
|
//}
|
|
|
|
|
//cur = cur->next;
|
|
|
|
|
//}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2004-03-06 05:13:27 +00:00
|
|
|
if (mdb_sql_fetch_row(env->sql, env->sql->cur_table)) {
|
2002-04-09 01:19:26 +00:00
|
|
|
stmt->rows_affected++;
|
2001-07-25 01:55:43 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
} else {
|
|
|
|
|
return SQL_NO_DATA_FOUND;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLFreeHandle(
|
|
|
|
|
SQLSMALLINT HandleType,
|
|
|
|
|
SQLHANDLE Handle)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLFreeHandle");
|
2001-07-10 22:36:20 +00:00
|
|
|
switch(HandleType) {
|
|
|
|
|
case SQL_HANDLE_STMT:
|
|
|
|
|
_SQLFreeStmt(Handle,SQL_DROP);
|
|
|
|
|
break;
|
|
|
|
|
case SQL_HANDLE_DBC:
|
|
|
|
|
_SQLFreeConnect(Handle);
|
|
|
|
|
break;
|
|
|
|
|
case SQL_HANDLE_ENV:
|
|
|
|
|
_SQLFreeEnv(Handle);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SQLRETURN SQL_API _SQLFreeConnect(
|
|
|
|
|
SQLHDBC hdbc)
|
|
|
|
|
{
|
|
|
|
|
ODBCConnection* dbc = (ODBCConnection*) hdbc;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLFreeConnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
|
|
|
|
|
FreeConnectParams (dbc->params);
|
|
|
|
|
free (dbc);
|
|
|
|
|
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLFreeConnect(
|
|
|
|
|
SQLHDBC hdbc)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLFreeConnect");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLFreeConnect(hdbc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SQLRETURN SQL_API _SQLFreeEnv(
|
|
|
|
|
SQLHENV henv)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLFreeEnv");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLFreeEnv(
|
|
|
|
|
SQLHENV henv)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLFreeEnv");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLFreeEnv(henv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SQLRETURN SQL_API _SQLFreeStmt(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT fOption)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt=(struct _hstmt *)hstmt;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("_SQLFreeStmt");
|
2001-07-10 22:36:20 +00:00
|
|
|
if (fOption==SQL_DROP) {
|
|
|
|
|
free (hstmt);
|
|
|
|
|
} else if (fOption==SQL_CLOSE) {
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
SQLRETURN SQL_API SQLFreeStmt(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT fOption)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLFreeStmt");
|
2001-07-10 22:36:20 +00:00
|
|
|
return _SQLFreeStmt(hstmt, fOption);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetStmtAttr (
|
|
|
|
|
SQLHSTMT StatementHandle,
|
|
|
|
|
SQLINTEGER Attribute,
|
|
|
|
|
SQLPOINTER Value,
|
|
|
|
|
SQLINTEGER BufferLength,
|
|
|
|
|
SQLINTEGER * StringLength)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetStmtAttr");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetCursorName(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCursor,
|
|
|
|
|
SQLSMALLINT cbCursorMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbCursor)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetCursorName");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLNumResultCols(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLSMALLINT FAR *pccol)
|
|
|
|
|
{
|
2002-01-24 12:34:10 +00:00
|
|
|
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
struct _henv *env = (struct _henv *) dbc->henv;
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLNumResultCols");
|
2002-01-24 12:34:10 +00:00
|
|
|
*pccol = env->sql->num_columns;
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLPrepare(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szSqlStr,
|
|
|
|
|
SQLINTEGER cbSqlStr)
|
|
|
|
|
{
|
2002-04-03 23:02:53 +00:00
|
|
|
struct _hstmt *stmt=(struct _hstmt *)hstmt;
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLPrepare");
|
2001-07-10 22:36:20 +00:00
|
|
|
if (cbSqlStr!=SQL_NTS) {
|
|
|
|
|
strncpy(stmt->query, szSqlStr, cbSqlStr);
|
|
|
|
|
stmt->query[cbSqlStr]='\0';
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(stmt->query, szSqlStr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLRowCount(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLINTEGER FAR *pcrow)
|
|
|
|
|
{
|
2002-04-03 23:02:53 +00:00
|
|
|
struct _hstmt *stmt=(struct _hstmt *)hstmt;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLRowCount");
|
|
|
|
|
*pcrow = stmt->rows_affected;
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLSetCursorName(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCursor,
|
|
|
|
|
SQLSMALLINT cbCursor)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLSetCursorName");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLTransact(
|
|
|
|
|
SQLHENV henv,
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLUSMALLINT fType)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLTransact");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLSetParam( /* Use SQLBindParameter */
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT ipar,
|
|
|
|
|
SQLSMALLINT fCType,
|
|
|
|
|
SQLSMALLINT fSqlType,
|
|
|
|
|
SQLUINTEGER cbParamDef,
|
|
|
|
|
SQLSMALLINT ibScale,
|
|
|
|
|
SQLPOINTER rgbValue,
|
|
|
|
|
SQLINTEGER FAR *pcbValue)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLSetParam");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLColumns(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName,
|
|
|
|
|
SQLCHAR FAR *szColumnName,
|
|
|
|
|
SQLSMALLINT cbColumnName)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLColumns");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetConnectOption(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLUSMALLINT fOption,
|
|
|
|
|
SQLPOINTER pvParam)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetConnectOption");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetData(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT icol,
|
|
|
|
|
SQLSMALLINT fCType,
|
|
|
|
|
SQLPOINTER rgbValue,
|
|
|
|
|
SQLINTEGER cbValueMax,
|
|
|
|
|
SQLINTEGER FAR *pcbValue)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt;
|
2002-04-03 23:02:53 +00:00
|
|
|
struct _hdbc *dbc;
|
|
|
|
|
struct _henv *env;
|
2001-07-10 22:36:20 +00:00
|
|
|
unsigned char *src;
|
|
|
|
|
int srclen;
|
2002-04-03 23:02:53 +00:00
|
|
|
MdbSQL *sql;
|
|
|
|
|
MdbHandle *mdb;
|
|
|
|
|
MdbSQLColumn *sqlcol;
|
|
|
|
|
MdbColumn *col;
|
|
|
|
|
MdbTableDef *table;
|
|
|
|
|
int i;
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetData");
|
2001-07-10 22:36:20 +00:00
|
|
|
stmt = (struct _hstmt *) hstmt;
|
2002-04-03 23:02:53 +00:00
|
|
|
dbc = (struct _hdbc *) stmt->hdbc;
|
|
|
|
|
env = (struct _henv *) dbc->henv;
|
|
|
|
|
sql = env->sql;
|
|
|
|
|
mdb = sql->mdb;
|
|
|
|
|
|
|
|
|
|
if (icol<1 || icol>sql->num_columns) {
|
|
|
|
|
return SQL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sqlcol = g_ptr_array_index(sql->columns,icol - 1);
|
|
|
|
|
table = sql->cur_table;
|
|
|
|
|
for (i=0;i<table->num_cols;i++) {
|
|
|
|
|
col=g_ptr_array_index(table->columns,i);
|
|
|
|
|
if (!strcasecmp(sqlcol->name, col->name)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(rgbValue,
|
2003-04-29 17:55:09 +00:00
|
|
|
mdb_col_to_string(mdb, mdb->pg_buf, col->cur_value_start, col->col_type,
|
2002-04-03 23:02:53 +00:00
|
|
|
col->cur_value_len));
|
|
|
|
|
//*((char *)&rgbValue[col->cur_value_len])='\0';
|
|
|
|
|
*pcbValue = col->cur_value_len;
|
2001-07-10 22:36:20 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-14 23:35:39 +00:00
|
|
|
static void _set_func_exists(SQLUSMALLINT FAR *pfExists, SQLUSMALLINT fFunction)
|
|
|
|
|
{
|
|
|
|
|
SQLUSMALLINT FAR *mod;
|
|
|
|
|
|
|
|
|
|
mod = pfExists + (fFunction >> 4);
|
|
|
|
|
*mod |= (1 << (fFunction & 0x0f));
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
SQLRETURN SQL_API SQLGetFunctions(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLUSMALLINT fFunction,
|
|
|
|
|
SQLUSMALLINT FAR *pfExists)
|
|
|
|
|
{
|
2002-04-14 23:35:39 +00:00
|
|
|
int i;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetFunctions");
|
2002-04-14 23:35:39 +00:00
|
|
|
switch (fFunction) {
|
|
|
|
|
#if ODBCVER >= 0x0300
|
|
|
|
|
case SQL_API_ODBC3_ALL_FUNCTIONS:
|
|
|
|
|
|
|
|
|
|
/* for (i=0;i<SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;i++) {
|
|
|
|
|
pfExists[i] = 0xFFFF;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCCONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCENV);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCHANDLE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCSTMT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLBINDCOL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLBINDPARAMETER);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCANCEL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCLOSECURSOR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCOLATTRIBUTE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCOLUMNS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCOPYDESC);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLDATASOURCES);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLDESCRIBECOL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLDISCONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLENDTRAN);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLERROR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLEXECDIRECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLEXECUTE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFETCH);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFETCHSCROLL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREECONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREEENV);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREEHANDLE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREESTMT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETCONNECTATTR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETCONNECTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETCURSORNAME);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETDATA);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETDESCFIELD);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETDESCREC);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETDIAGFIELD);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETDIAGREC);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETENVATTR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETFUNCTIONS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETINFO);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETSTMTATTR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETSTMTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETTYPEINFO);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLNUMRESULTCOLS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLPARAMDATA);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLPREPARE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLPUTDATA);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLROWCOUNT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETCONNECTATTR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETCONNECTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETCURSORNAME);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETDESCFIELD);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETDESCREC);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETENVATTR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETPARAM);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETSTMTATTR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETSTMTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSPECIALCOLUMNS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSTATISTICS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLTABLES);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLTRANSACT);
|
|
|
|
|
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
case SQL_API_ALL_FUNCTIONS:
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCCONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCENV);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLALLOCSTMT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLBINDCOL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCANCEL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCOLATTRIBUTES);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCOLUMNS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLCONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLDATASOURCES);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLDESCRIBECOL);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLDISCONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLERROR);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLEXECDIRECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLEXECUTE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFETCH);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREECONNECT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREEENV);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLFREESTMT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETCONNECTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETCURSORNAME);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETDATA);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETFUNCTIONS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETINFO);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETSTMTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLGETTYPEINFO);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLNUMRESULTCOLS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLPARAMDATA);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLPREPARE);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLPUTDATA);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLROWCOUNT);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETCONNECTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETCURSORNAME);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETPARAM);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSETSTMTOPTION);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSPECIALCOLUMNS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLSTATISTICS);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLTABLES);
|
|
|
|
|
_set_func_exists(pfExists,SQL_API_SQLTRANSACT);
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
*pfExists = 1; /* SQL_TRUE */
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetInfo(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLUSMALLINT fInfoType,
|
|
|
|
|
SQLPOINTER rgbInfoValue,
|
|
|
|
|
SQLSMALLINT cbInfoValueMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbInfoValue)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetInfo");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetStmtOption(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT fOption,
|
|
|
|
|
SQLPOINTER pvParam)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetStmtOption");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLGetTypeInfo(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLSMALLINT fSqlType)
|
|
|
|
|
{
|
|
|
|
|
struct _hstmt *stmt;
|
|
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLGetStmtOption");
|
2001-07-10 22:36:20 +00:00
|
|
|
stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
if (!fSqlType) {
|
2002-04-09 01:19:26 +00:00
|
|
|
strcpy(stmt->query, "SELECT * FROM typeinfo");
|
2001-07-10 22:36:20 +00:00
|
|
|
} else {
|
2002-04-09 01:19:26 +00:00
|
|
|
sprintf(stmt->query, "SELECT * FROM typeinfo WHERE SQL_DATA_TYPE = %d", fSqlType);
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
2002-04-09 01:19:26 +00:00
|
|
|
|
|
|
|
|
/* return _SQLExecute(hstmt); */
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLParamData(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLPOINTER FAR *prgbValue)
|
|
|
|
|
{
|
|
|
|
|
TRACE("SQLParamData");
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLPutData(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLPOINTER rgbValue,
|
|
|
|
|
SQLINTEGER cbValue)
|
|
|
|
|
{
|
|
|
|
|
TRACE("SQLPutData");
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLSetConnectOption(
|
|
|
|
|
SQLHDBC hdbc,
|
|
|
|
|
SQLUSMALLINT fOption,
|
|
|
|
|
SQLUINTEGER vParam)
|
|
|
|
|
{
|
|
|
|
|
TRACE("SQLSetConnectOption");
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLSetStmtOption(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT fOption,
|
|
|
|
|
SQLUINTEGER vParam)
|
|
|
|
|
{
|
|
|
|
|
TRACE("SQLSetStmtOption");
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLSpecialColumns(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLUSMALLINT fColType,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName,
|
|
|
|
|
SQLUSMALLINT fScope,
|
|
|
|
|
SQLUSMALLINT fNullable)
|
|
|
|
|
{
|
|
|
|
|
TRACE("SQLSpecialColumns");
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLStatistics(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName,
|
|
|
|
|
SQLUSMALLINT fUnique,
|
|
|
|
|
SQLUSMALLINT fAccuracy)
|
|
|
|
|
{
|
|
|
|
|
TRACE("SQLStatistics");
|
|
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
2001-07-10 22:36:20 +00:00
|
|
|
|
2002-04-09 01:19:26 +00:00
|
|
|
SQLRETURN SQL_API SQLTables(
|
|
|
|
|
SQLHSTMT hstmt,
|
|
|
|
|
SQLCHAR FAR *szCatalogName,
|
|
|
|
|
SQLSMALLINT cbCatalogName,
|
|
|
|
|
SQLCHAR FAR *szSchemaName,
|
|
|
|
|
SQLSMALLINT cbSchemaName,
|
|
|
|
|
SQLCHAR FAR *szTableName,
|
|
|
|
|
SQLSMALLINT cbTableName,
|
|
|
|
|
SQLCHAR FAR *szTableType,
|
|
|
|
|
SQLSMALLINT cbTableType)
|
|
|
|
|
{
|
|
|
|
|
char *query, *p;
|
|
|
|
|
char *sptables = "exec sp_tables ";
|
|
|
|
|
int querylen, clen, slen, tlen, ttlen;
|
|
|
|
|
int first = 1;
|
|
|
|
|
struct _hstmt *stmt;
|
|
|
|
|
|
|
|
|
|
TRACE("SQLTables");
|
|
|
|
|
stmt = (struct _hstmt *) hstmt;
|
|
|
|
|
|
|
|
|
|
clen = _odbc_get_string_size(cbCatalogName, szCatalogName);
|
|
|
|
|
slen = _odbc_get_string_size(cbSchemaName, szSchemaName);
|
|
|
|
|
tlen = _odbc_get_string_size(cbTableName, szTableName);
|
|
|
|
|
ttlen = _odbc_get_string_size(cbTableType, szTableType);
|
|
|
|
|
|
|
|
|
|
querylen = strlen(sptables) + clen + slen + tlen + ttlen + 40; /* a little padding for quotes and commas */
|
|
|
|
|
query = (char *) malloc(querylen);
|
|
|
|
|
p = query;
|
|
|
|
|
|
|
|
|
|
strcpy(p, sptables);
|
|
|
|
|
p += strlen(sptables);
|
|
|
|
|
|
|
|
|
|
if (tlen) {
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
strncpy(p, szTableName, tlen); *p+=tlen;
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
if (slen) {
|
|
|
|
|
if (!first) *p++ = ',';
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
strncpy(p, szSchemaName, slen); *p+=slen;
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
if (clen) {
|
|
|
|
|
if (!first) *p++ = ',';
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
strncpy(p, szCatalogName, clen); *p+=clen;
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
if (ttlen) {
|
|
|
|
|
if (!first) *p++ = ',';
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
strncpy(p, szTableType, ttlen); *p+=ttlen;
|
|
|
|
|
*p++ = '"';
|
|
|
|
|
first = 0;
|
|
|
|
|
}
|
|
|
|
|
*p++ = '\0';
|
|
|
|
|
// fprintf(stderr,"\nquery = %s\n",query);
|
2001-07-10 22:36:20 +00:00
|
|
|
|
|
|
|
|
strcpy(stmt->query, query);
|
|
|
|
|
return _SQLExecute(hstmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLRETURN SQL_API SQLDataSources(
|
|
|
|
|
SQLHENV henv,
|
|
|
|
|
SQLUSMALLINT fDirection,
|
|
|
|
|
SQLCHAR FAR *szDSN,
|
|
|
|
|
SQLSMALLINT cbDSNMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbDSN,
|
|
|
|
|
SQLCHAR FAR *szDescription,
|
|
|
|
|
SQLSMALLINT cbDescriptionMax,
|
|
|
|
|
SQLSMALLINT FAR *pcbDescription)
|
|
|
|
|
{
|
2002-04-09 01:19:26 +00:00
|
|
|
TRACE("SQLDataSources");
|
2001-07-10 22:36:20 +00:00
|
|
|
return SQL_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int _odbc_fix_literals(struct _hstmt *stmt)
|
|
|
|
|
{
|
|
|
|
|
char tmp[4096],begin_tag[11];
|
|
|
|
|
char *s, *d, *p;
|
|
|
|
|
int i, quoted = 0, find_end = 0;
|
|
|
|
|
char quote_char;
|
|
|
|
|
|
|
|
|
|
s=stmt->query;
|
|
|
|
|
d=tmp;
|
|
|
|
|
while (*s) {
|
|
|
|
|
if (!quoted && (*s=='"' || *s=='\'')) {
|
|
|
|
|
quoted = 1;
|
|
|
|
|
quote_char = *s;
|
|
|
|
|
} else if (quoted && *s==quote_char) {
|
|
|
|
|
quoted = 0;
|
|
|
|
|
}
|
|
|
|
|
if (!quoted && find_end && *s=='}') {
|
|
|
|
|
s++; /* ignore the end of tag */
|
|
|
|
|
} else if (!quoted && *s=='{') {
|
|
|
|
|
for (p=s,i=0;*p && *p!=' ';p++) i++;
|
|
|
|
|
if (i>10) {
|
|
|
|
|
/* garbage */
|
|
|
|
|
*d++=*s++;
|
|
|
|
|
} else {
|
|
|
|
|
strncpy(begin_tag, s, i);
|
|
|
|
|
begin_tag[i] = '\0';
|
|
|
|
|
/* printf("begin tag %s\n", begin_tag); */
|
|
|
|
|
s += i;
|
|
|
|
|
find_end = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
*d++=*s++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*d='\0';
|
|
|
|
|
strcpy(stmt->query,tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int _odbc_get_string_size(int size, char *str)
|
|
|
|
|
{
|
|
|
|
|
if (!str) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (size==SQL_NTS) {
|
|
|
|
|
return strlen(str);
|
|
|
|
|
} else {
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
static int _odbc_get_server_type(int clt_type)
|
|
|
|
|
{
|
|
|
|
|
switch (clt_type) {
|
|
|
|
|
case SQL_CHAR:
|
|
|
|
|
case SQL_VARCHAR:
|
|
|
|
|
case SQL_BIT:
|
|
|
|
|
case SQL_TINYINT:
|
|
|
|
|
case SQL_SMALLINT:
|
|
|
|
|
case SQL_INTEGER:
|
|
|
|
|
case SQL_DOUBLE:
|
|
|
|
|
case SQL_DECIMAL:
|
|
|
|
|
case SQL_NUMERIC:
|
|
|
|
|
case SQL_FLOAT:
|
2004-01-06 03:18:19 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
static SQLSMALLINT _odbc_get_client_type(int srv_type)
|
|
|
|
|
{
|
|
|
|
|
switch (srv_type) {
|
2002-04-03 23:02:53 +00:00
|
|
|
case MDB_BOOL:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_BIT;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
case MDB_BYTE:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_TINYINT;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
case MDB_INT:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_SMALLINT;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
case MDB_LONGINT:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_INTEGER;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
case MDB_FLOAT:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_FLOAT;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
case MDB_DOUBLE:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_DOUBLE;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
case MDB_TEXT:
|
2002-01-24 12:34:10 +00:00
|
|
|
return SQL_VARCHAR;
|
2002-04-03 23:02:53 +00:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// fprintf(stderr,"Unknown type %d\n",srv_type);
|
|
|
|
|
break;
|
2001-07-10 22:36:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
2001-07-24 11:00:00 +00:00
|
|
|
|