Commit 4b47467a authored by Hiroshi Inoue's avatar Hiroshi Inoue

1) Implement SQLParamOptions().

2) Handle Multiple results and implement SQLMoreResult().
3) Improve multibyte handling thanks to Eiji Tokuya.
4) Add new options.
   LF <-> CR/LF converion.
   TRUE is -1 (for VB).
5) Introduce unicode(UCS-2) support.
6) Reduce the length of connection strings.
7) Improve SQLError, SQLGetDiagRec(ODBC 3.0).
8) Implement SQLTablePrivileges().
9) Miscellaneous changes for ODBC 3.0 support.
parent 21f8aa39
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Classes: BindInfoClass, ParameterInfoClass * Classes: BindInfoClass, ParameterInfoClass
* *
* API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams, * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
* SQLParamOptions(NI) * SQLParamOptions
* *
* Comments: See "notice.txt" for copyright and license information. * Comments: See "notice.txt" for copyright and license information.
*------- *-------
...@@ -331,17 +331,9 @@ PGAPI_ParamOptions( ...@@ -331,17 +331,9 @@ PGAPI_ParamOptions(
mylog("%s: entering... %d %x\n", func, crow, pirow); mylog("%s: entering... %d %x\n", func, crow, pirow);
if (crow == 1) /* temporary solution and must be stmt->options.paramset_size = crow;
* rewritten later */ stmt->options.param_processed_ptr = pirow;
{
if (pirow)
*pirow = 1;
return SQL_SUCCESS; return SQL_SUCCESS;
}
stmt->errornumber = CONN_UNSUPPORTED_OPTION;
stmt->errormsg = "Function not implemented";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR;
} }
......
This diff is collapsed.
...@@ -151,6 +151,8 @@ typedef struct ...@@ -151,6 +151,8 @@ typedef struct
char focus_password; char focus_password;
char disallow_premature; char disallow_premature;
char updatable_cursors; char updatable_cursors;
char lf_conversion;
char true_is_minus1;
GLOBAL_VALUES drivers; /* moved from driver's option */ GLOBAL_VALUES drivers; /* moved from driver's option */
} ConnInfo; } ConnInfo;
...@@ -271,6 +273,7 @@ struct ConnectionClass_ ...@@ -271,6 +273,7 @@ struct ConnectionClass_
char *client_encoding; char *client_encoding;
char *server_encoding; char *server_encoding;
#endif /* MULTIBYTE */ #endif /* MULTIBYTE */
int ccsc;
}; };
...@@ -290,6 +293,7 @@ struct ConnectionClass_ ...@@ -290,6 +293,7 @@ struct ConnectionClass_
/* prototypes */ /* prototypes */
ConnectionClass *CC_Constructor(void); ConnectionClass *CC_Constructor(void);
void CC_conninfo_init(ConnInfo *conninfo);
char CC_Destructor(ConnectionClass *self); char CC_Destructor(ConnectionClass *self);
int CC_cursor_count(ConnectionClass *self); int CC_cursor_count(ConnectionClass *self);
char CC_cleanup(ConnectionClass *self); char CC_cleanup(ConnectionClass *self);
...@@ -301,7 +305,7 @@ char CC_connect(ConnectionClass *self, char do_password); ...@@ -301,7 +305,7 @@ char CC_connect(ConnectionClass *self, char do_password);
char CC_add_statement(ConnectionClass *self, StatementClass *stmt); char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt); char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
char CC_get_error(ConnectionClass *self, int *number, char **message); char CC_get_error(ConnectionClass *self, int *number, char **message);
QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi); QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL);
void CC_clear_error(ConnectionClass *self); void CC_clear_error(ConnectionClass *self);
char *CC_create_errormsg(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); int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
...@@ -309,7 +313,7 @@ char CC_send_settings(ConnectionClass *self); ...@@ -309,7 +313,7 @@ char CC_send_settings(ConnectionClass *self);
void CC_lookup_lo(ConnectionClass *conn); void CC_lookup_lo(ConnectionClass *conn);
void CC_lookup_pg_version(ConnectionClass *conn); void CC_lookup_pg_version(ConnectionClass *conn);
void CC_initialize_pg_version(ConnectionClass *conn); void CC_initialize_pg_version(ConnectionClass *conn);
void CC_log_error(char *func, char *desc, ConnectionClass *self); void CC_log_error(const char *func, const char *desc, const ConnectionClass *self);
int CC_get_max_query_len(const ConnectionClass *self); int CC_get_max_query_len(const ConnectionClass *self);
#endif #endif
This diff is collapsed.
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
/* convert_escape results */ /* convert_escape results */
#define CONVERT_ESCAPE_OK 0 #define CONVERT_ESCAPE_OK 0
#define CONVERT_ESCAPE_OVERFLOW 1 #define CONVERT_ESCAPE_OVERFLOW 1
#define CONVERT_ESCAPE_ERROR 2 #define CONVERT_ESCAPE_ERROR -1
typedef struct typedef struct
{ {
...@@ -43,8 +43,8 @@ int convert_escape(const char *value, StatementClass *stmt, ...@@ -43,8 +43,8 @@ int convert_escape(const char *value, StatementClass *stmt,
int *npos, int *stsize, const char **val_resume); int *npos, int *stsize, const char **val_resume);
BOOL convert_money(const char *s, char *sout, size_t soutmax); BOOL convert_money(const char *s, char *sout, size_t soutmax);
char parse_datetime(char *buf, SIMPLE_TIME *st); char parse_datetime(char *buf, SIMPLE_TIME *st);
int convert_linefeeds(const char *s, char *dst, size_t max, BOOL *changed); 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); 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_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_from_pgbinary(const unsigned char *value, unsigned char *rgbValue, int cbValueMax);
......
This diff is collapsed.
...@@ -89,6 +89,35 @@ ...@@ -89,6 +89,35 @@
#define INI_TRANSLATIONOPTION "TranslationOption" #define INI_TRANSLATIONOPTION "TranslationOption"
#define INI_DISALLOWPREMATURE "DisallowPremature" #define INI_DISALLOWPREMATURE "DisallowPremature"
#define INI_UPDATABLECURSORS "UpdatableCursors" #define INI_UPDATABLECURSORS "UpdatableCursors"
#define INI_LFCONVERSION "LFConversion"
#define INI_TRUEISMINUS1 "TrueIsMinus1"
/* 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 */ /* Connection Defaults */
...@@ -119,6 +148,19 @@ ...@@ -119,6 +148,19 @@
#define DEFAULT_EXTRASYSTABLEPREFIXES "dd_;" #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 */
/* prototypes */ /* prototypes */
void getCommonDefaults(const char *section, const char *filename, ConnInfo *ci); void getCommonDefaults(const char *section, const char *filename, ConnInfo *ci);
......
...@@ -242,7 +242,7 @@ dialog: ...@@ -242,7 +242,7 @@ dialog:
qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut); qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut);
mylog("PGAPI_DRiverConnect: returning %d\n", result); mylog("PGAPI_DriverConnect: returning %d\n", result);
return result; return result;
} }
...@@ -351,10 +351,7 @@ dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci) ...@@ -351,10 +351,7 @@ dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
*equals; *equals;
char *strtok_arg; char *strtok_arg;
memset(ci, 0, sizeof(ConnInfo)); CC_conninfo_init(ci);
#ifdef DRIVER_CURSOR_IMPLEMENT
ci->updatable_cursors = 1;
#endif /* DRIVER_CURSOR_IMPLEMENT */
our_connect_string = strdup(connect_string); our_connect_string = strdup(connect_string);
strtok_arg = our_connect_string; strtok_arg = our_connect_string;
......
...@@ -78,37 +78,35 @@ PGAPI_FreeEnv(HENV henv) ...@@ -78,37 +78,35 @@ PGAPI_FreeEnv(HENV henv)
} }
#define DRVMNGRDIV 511
/* Returns the next SQL error information. */ /* Returns the next SQL error information. */
RETCODE SQL_API RETCODE SQL_API
PGAPI_Error( PGAPI_StmtError( HSTMT hstmt,
HENV henv, SWORD RecNumber,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR * szSqlState, UCHAR FAR * szSqlState,
SDWORD FAR * pfNativeError, SDWORD FAR * pfNativeError,
UCHAR FAR * szErrorMsg, UCHAR FAR * szErrorMsg,
SWORD cbErrorMsgMax, SWORD cbErrorMsgMax,
SWORD FAR * pcbErrorMsg) SWORD FAR * pcbErrorMsg,
UWORD flag)
{ {
/* CC: return an error of a hstmt */
StatementClass *stmt = (StatementClass *) hstmt;
char *msg; char *msg;
int status; int status;
BOOL once_again = FALSE; BOOL once_again = FALSE,
SWORD msglen; partial_ok = (flag & PODBC_ALLOW_PARTIAL_EXTRACT != 0),
clear_str = (flag & PODBC_ERROR_CLEAR != 0);
SWORD msglen, stapos, wrtlen, pcblen;
mylog("**** PGAPI_Error: henv=%u, hdbc=%u, hstmt=%u <%d>\n", henv, hdbc, hstmt, cbErrorMsgMax); mylog("**** PGAPI_StmtError: hstmt=%u <%d>\n", hstmt, cbErrorMsgMax);
if (cbErrorMsgMax < 0) if (cbErrorMsgMax < 0)
return SQL_ERROR; return SQL_ERROR;
if (SQL_NULL_HSTMT != hstmt)
{
/* CC: return an error of a hstmt */
StatementClass *stmt = (StatementClass *) hstmt;
if (SC_get_error(stmt, &status, &msg)) if (!SC_get_error(stmt, &status, &msg) || NULL == msg || !msg[0])
{
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL == msg)
{ {
mylog("SC_Get_error returned nothing.\n");
if (NULL != szSqlState) if (NULL != szSqlState)
strcpy(szSqlState, "00000"); strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg) if (NULL != pcbErrorMsg)
...@@ -118,21 +116,54 @@ PGAPI_Error( ...@@ -118,21 +116,54 @@ PGAPI_Error(
return SQL_NO_DATA_FOUND; return SQL_NO_DATA_FOUND;
} }
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
msglen = (SWORD) strlen(msg); msglen = (SWORD) strlen(msg);
if (NULL != pcbErrorMsg) /*
* 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)
{ {
*pcbErrorMsg = msglen; if (cbErrorMsgMax > 0)
if (cbErrorMsgMax == 0) stmt->error_recsize = cbErrorMsgMax - 1; /* apply the first request */
once_again = TRUE; else
else if (msglen >= cbErrorMsgMax) stmt->error_recsize = DRVMNGRDIV;
}
if (RecNumber < 0)
{ {
once_again = TRUE; if (0 == stmt->errorpos)
*pcbErrorMsg = cbErrorMsgMax - 1; 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)) if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax); {
memcpy(szErrorMsg, msg + stapos, wrtlen);
szErrorMsg[wrtlen] = '\0';
}
if (NULL != pfNativeError) if (NULL != pfNativeError)
*pfNativeError = status; *pfNativeError = status;
...@@ -251,55 +282,42 @@ PGAPI_Error( ...@@ -251,55 +282,42 @@ PGAPI_Error(
/* also a general error */ /* also a general error */
break; break;
} }
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg); mylog(" szSqlState = '%s',len=%d, szError='%s'\n", szSqlState, pcblen, szErrorMsg);
} if (clear_str)
else
{ {
if (NULL != szSqlState) stmt->errorpos = stapos + wrtlen;
strcpy(szSqlState, "00000"); if (stmt->errorpos >= msglen)
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
mylog(" returning NO_DATA_FOUND\n");
return SQL_NO_DATA_FOUND;
}
if (once_again)
{
int outlen;
stmt->errornumber = status;
if (cbErrorMsgMax > 0)
outlen = *pcbErrorMsg;
else
outlen = 0;
if (!stmt->errormsg_malloced || !stmt->errormsg)
{
stmt->errormsg = malloc(msglen - outlen + 1);
stmt->errormsg_malloced = TRUE;
}
memmove(stmt->errormsg, msg + outlen, msglen - outlen + 1);
}
else if (stmt->errormsg_malloced)
SC_clear_error(stmt); SC_clear_error(stmt);
if (cbErrorMsgMax == 0) }
if (wrtlen == 0)
return SQL_SUCCESS_WITH_INFO; return SQL_SUCCESS_WITH_INFO;
else else
return SQL_SUCCESS; return SQL_SUCCESS;
} }
else if (SQL_NULL_HDBC != hdbc)
{ 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; ConnectionClass *conn = (ConnectionClass *) hdbc;
char *msg;
int status;
BOOL once_again = FALSE;
SWORD msglen;
mylog("calling CC_get_error\n"); if (RecNumber != 1)
if (CC_get_error(conn, &status, &msg)) return SQL_NO_DATA_FOUND;
{ if (cbErrorMsgMax < 0)
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg); return SQL_ERROR;
if (NULL == msg) if (!CC_get_error(conn, &status, &msg) || NULL == msg)
{ {
mylog("CC_Get_error returned nothing.\n");
if (NULL != szSqlState) if (NULL != szSqlState)
strcpy(szSqlState, "00000"); strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg) if (NULL != pcbErrorMsg)
...@@ -309,6 +327,7 @@ PGAPI_Error( ...@@ -309,6 +327,7 @@ PGAPI_Error(
return SQL_NO_DATA_FOUND; return SQL_NO_DATA_FOUND;
} }
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg);
msglen = strlen(msg); msglen = strlen(msg);
if (NULL != pcbErrorMsg) if (NULL != pcbErrorMsg)
...@@ -391,19 +410,6 @@ PGAPI_Error( ...@@ -391,19 +410,6 @@ PGAPI_Error(
/* general error */ /* general error */
break; break;
} }
}
else
{
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;
}
if (once_again) if (once_again)
{ {
...@@ -412,16 +418,30 @@ PGAPI_Error( ...@@ -412,16 +418,30 @@ PGAPI_Error(
} }
else else
return SQL_SUCCESS; return SQL_SUCCESS;
} }
else if (SQL_NULL_HENV != henv)
{ 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; EnvironmentClass *env = (EnvironmentClass *) henv;
char *msg;
int status;
if (EN_get_error(env, &status, &msg)) if (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); mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL == msg)
{
if (NULL != szSqlState) if (NULL != szSqlState)
strcpy(szSqlState, "00000"); strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg) if (NULL != pcbErrorMsg)
...@@ -431,6 +451,7 @@ PGAPI_Error( ...@@ -431,6 +451,7 @@ PGAPI_Error(
return SQL_NO_DATA_FOUND; return SQL_NO_DATA_FOUND;
} }
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL != pcbErrorMsg) if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD) strlen(msg); *pcbErrorMsg = (SWORD) strlen(msg);
...@@ -453,22 +474,41 @@ PGAPI_Error( ...@@ -453,22 +474,41 @@ PGAPI_Error(
break; break;
} }
} }
}
else
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
return SQL_SUCCESS; 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) if (NULL != szSqlState)
strcpy(szSqlState, "00000"); strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg) if (NULL != pcbErrorMsg)
...@@ -476,10 +516,12 @@ PGAPI_Error( ...@@ -476,10 +516,12 @@ PGAPI_Error(
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0'; szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND; ret = SQL_NO_DATA_FOUND;
}
mylog("**** PGAPI_Error exit code=%d\n", ret);
return ret;
} }
/* /*
* EnvironmentClass implementation * EnvironmentClass implementation
*/ */
...@@ -493,6 +535,7 @@ EN_Constructor(void) ...@@ -493,6 +535,7 @@ EN_Constructor(void)
{ {
rv->errormsg = 0; rv->errormsg = 0;
rv->errornumber = 0; rv->errornumber = 0;
rv->flag = 0;
} }
return rv; return rv;
......
...@@ -18,6 +18,7 @@ struct EnvironmentClass_ ...@@ -18,6 +18,7 @@ struct EnvironmentClass_
{ {
char *errormsg; char *errormsg;
int errornumber; int errornumber;
Int4 flag;
}; };
/* Environment prototypes */ /* Environment prototypes */
...@@ -28,4 +29,10 @@ char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn); ...@@ -28,4 +29,10 @@ char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn); char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
void EN_log_error(char *func, char *desc, EnvironmentClass *self); 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 #endif
...@@ -267,6 +267,7 @@ PGAPI_Execute( ...@@ -267,6 +267,7 @@ PGAPI_Execute(
if (stmt->status == STMT_FINISHED) if (stmt->status == STMT_FINISHED)
{ {
mylog("%s: recycling statement (should have been done by app)...\n", func); mylog("%s: recycling statement (should have been done by app)...\n", func);
/******** Is this really NEEDED ? ******/
SC_recycle_statement(stmt); SC_recycle_statement(stmt);
} }
...@@ -291,6 +292,7 @@ PGAPI_Execute( ...@@ -291,6 +292,7 @@ PGAPI_Execute(
{ {
if (stmt->options.param_processed_ptr) if (stmt->options.param_processed_ptr)
*stmt->options.param_processed_ptr = 0; *stmt->options.param_processed_ptr = 0;
SC_recycle_statement(stmt);
} }
next_param_row: next_param_row:
...@@ -434,16 +436,15 @@ next_param_row: ...@@ -434,16 +436,15 @@ next_param_row:
} }
/* we are now in a transaction */ /* we are now in a transaction */
CC_set_in_trans(conn); CC_set_in_trans(conn);
stmt->result = res = CC_send_query(conn, stmt->stmt_with_params, NULL); res = CC_send_query(conn, stmt->stmt_with_params, NULL, TRUE);
if (!res || QR_aborted(res)) if (!res)
{ {
CC_abort(conn); CC_abort(conn);
stmt->errornumber = STMT_EXEC_ERROR; stmt->errornumber = STMT_EXEC_ERROR;
stmt->errormsg = "Handle prepare error"; stmt->errormsg = "Handle prepare error";
return SQL_ERROR; return SQL_ERROR;
} }
else SC_set_Result(stmt, res);
{
if (CC_is_in_autocommit(conn)) if (CC_is_in_autocommit(conn))
{ {
if (issued_begin) if (issued_begin)
...@@ -454,7 +455,6 @@ next_param_row: ...@@ -454,7 +455,6 @@ next_param_row:
stmt->status = STMT_FINISHED; stmt->status = STMT_FINISHED;
return SQL_SUCCESS; return SQL_SUCCESS;
} }
}
else else
return SQL_SUCCESS; return SQL_SUCCESS;
} }
...@@ -518,7 +518,7 @@ PGAPI_Transact( ...@@ -518,7 +518,7 @@ PGAPI_Transact(
{ {
mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string); mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string);
res = CC_send_query(conn, stmt_string, NULL); res = CC_send_query(conn, stmt_string, NULL, TRUE);
CC_set_no_trans(conn); CC_set_no_trans(conn);
if (!res) if (!res)
...@@ -721,7 +721,7 @@ PGAPI_ParamData( ...@@ -721,7 +721,7 @@ PGAPI_ParamData(
/* commit transaction if needed */ /* commit transaction if needed */
if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
{ {
if (!CC_commit(stmt->hdbc)) if (CC_commit(stmt->hdbc))
{ {
stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errormsg = "Could not commit (in-line) a transaction";
stmt->errornumber = STMT_EXEC_ERROR; stmt->errornumber = STMT_EXEC_ERROR;
...@@ -902,6 +902,14 @@ PGAPI_PutData( ...@@ -902,6 +902,14 @@ PGAPI_PutData(
} }
else 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 */ /* for handling fields */
if (cbValue == SQL_NTS) if (cbValue == SQL_NTS)
{ {
...@@ -916,11 +924,11 @@ PGAPI_PutData( ...@@ -916,11 +924,11 @@ PGAPI_PutData(
} }
else else
{ {
Int2 ctype = current_param->CType; #ifdef UNICODE_SUPPORT
if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY || ctype == SQL_C_WCHAR)
if (ctype == SQL_C_DEFAULT) #else
ctype = sqltype_to_default_ctype(current_param->SQLType);
if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY) if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY)
#endif /* UNICODE_SUPPORT */
{ {
current_param->EXEC_buffer = malloc(cbValue + 1); current_param->EXEC_buffer = malloc(cbValue + 1);
if (!current_param->EXEC_buffer) if (!current_param->EXEC_buffer)
...@@ -965,31 +973,31 @@ PGAPI_PutData( ...@@ -965,31 +973,31 @@ PGAPI_PutData(
} }
else else
{ {
buffer = current_param->EXEC_buffer; Int2 ctype = current_param->CType;
if (cbValue == SQL_NTS) if (ctype == SQL_C_DEFAULT)
{ ctype = sqltype_to_default_ctype(current_param->SQLType);
buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1); buffer = current_param->EXEC_buffer;
if (!buffer) if (old_pos = *current_param->EXEC_used, SQL_NTS == old_pos)
{ {
stmt->errornumber = STMT_NO_MEMORY_ERROR; #ifdef UNICODE_SUPPORT
stmt->errormsg = "Out of memory in PGAPI_PutData (3)"; if (SQL_C_WCHAR == ctype)
SC_log_error(func, "", stmt); old_pos = 2 * ucs2strlen((SQLWCHAR *) buffer);
return SQL_ERROR; else
#endif /* UNICODE_SUPPORT */
old_pos = strlen(buffer);
} }
strcat(buffer, rgbValue); if (SQL_NTS == cbValue)
{
mylog(" cbValue = SQL_NTS: strlen(buffer) = %d\n", strlen(buffer)); #ifdef UNICODE_SUPPORT
if (SQL_C_WCHAR == ctype)
*current_param->EXEC_used = cbValue; cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
else
/* reassign buffer incase realloc moved it */ #endif /* UNICODE_SUPPORT */
current_param->EXEC_buffer = buffer; cbValue = strlen(rgbValue);
} }
else if (cbValue > 0) if (cbValue > 0)
{ {
old_pos = *current_param->EXEC_used;
*current_param->EXEC_used += cbValue; *current_param->EXEC_used += cbValue;
mylog(" cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used); mylog(" cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used);
......
This diff is collapsed.
...@@ -19,6 +19,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -19,6 +19,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
{ {
static char *func = "PGAPI_GetInfo30"; static char *func = "PGAPI_GetInfo30";
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
ConnInfo *ci = &(conn->connInfo);
char *p = NULL; char *p = NULL;
int len = 0, int len = 0,
value = 0; value = 0;
...@@ -50,35 +51,60 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -50,35 +51,60 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
| SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK
| SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION
| SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
| SQL_CA1_POS_REFRESH | SQL_CA1_POS_REFRESH;
/* | SQL_CA1_BULK_ADD if (ci->drivers.lie)
value |=
( SQL_CA1_BULK_ADD
| SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_UPDATE_BY_BOOKMARK
| SQL_CA1_BULK_DELETE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK
| SQL_CA1_BULK_FETCH_BY_BOOKMARK */ | SQL_CA1_BULK_FETCH_BY_BOOKMARK
;
| SQL_CA1_LOCK_EXCLUSIVE
| SQL_CA1_LOCK_UNLOCK
| SQL_CA1_POSITIONED_UPDATE
| SQL_CA1_POSITIONED_DELETE
| SQL_CA1_SELECT_FOR_UPDATE
);
break; break;
case SQL_KEYSET_CURSOR_ATTRIBUTES2: case SQL_KEYSET_CURSOR_ATTRIBUTES2:
len = 4; len = 4;
value = SQL_CA2_OPT_ROWVER_CONCURRENCY | value = SQL_CA2_OPT_ROWVER_CONCURRENCY
SQL_CA2_SENSITIVITY_ADDITIONS | | SQL_CA2_SENSITIVITY_ADDITIONS
SQL_CA2_SENSITIVITY_DELETIONS | | SQL_CA2_SENSITIVITY_DELETIONS
SQL_CA2_SENSITIVITY_UPDATES; | SQL_CA2_SENSITIVITY_UPDATES;
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_CRC_EXACT
| SQL_CA2_CRC_APPROXIMATE
| SQL_CA2_SIMULATE_NON_UNIQUE
| SQL_CA2_SIMULATE_TRY_UNIQUE
| SQL_CA2_SIMULATE_UNIQUE
);
break; break;
case SQL_STATIC_CURSOR_ATTRIBUTES1: case SQL_STATIC_CURSOR_ATTRIBUTES1:
len = 4; len = 4;
value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE
SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK
SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION | | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION
SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE | | SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
SQL_CA1_POS_REFRESH; | SQL_CA1_POS_REFRESH;
break; break;
case SQL_STATIC_CURSOR_ATTRIBUTES2: case SQL_STATIC_CURSOR_ATTRIBUTES2:
len = 4; len = 4;
value = SQL_CA2_OPT_ROWVER_CONCURRENCY | value = SQL_CA2_OPT_ROWVER_CONCURRENCY
SQL_CA2_SENSITIVITY_ADDITIONS | | SQL_CA2_SENSITIVITY_ADDITIONS
SQL_CA2_SENSITIVITY_DELETIONS | | SQL_CA2_SENSITIVITY_DELETIONS
SQL_CA2_SENSITIVITY_UPDATES; | SQL_CA2_SENSITIVITY_UPDATES;
break; break;
case SQL_ODBC_INTERFACE_CONFORMANCE: case SQL_ODBC_INTERFACE_CONFORMANCE:
...@@ -103,11 +129,11 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -103,11 +129,11 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
break; break;
case SQL_BATCH_ROW_COUNT: case SQL_BATCH_ROW_COUNT:
len = 4; len = 4;
value = SQL_BRC_ROLLED_UP | SQL_BRC_EXPLICIT; value = SQL_BRC_EXPLICIT;
break; break;
case SQL_BATCH_SUPPORT: case SQL_BATCH_SUPPORT:
len = 4; len = 4;
value = SQL_BS_ROW_COUNT_EXPLICIT; value = SQL_BS_SELECT_EXPLICIT | SQL_BS_ROW_COUNT_EXPLICIT;
break; break;
case SQL_CATALOG_NAME: case SQL_CATALOG_NAME:
len = 0; len = 0;
...@@ -194,7 +220,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -194,7 +220,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
len = 4; len = 4;
value = SQL_DT_DROP_TABLE; value = SQL_DT_DROP_TABLE;
if (PG_VERSION_GT(conn, 7.2)) /* hopefully */ if (PG_VERSION_GT(conn, 7.2)) /* hopefully */
value |= SQL_DT_RESTRICT | SQL_DT_CASCADE; value |= (SQL_DT_RESTRICT | SQL_DT_CASCADE);
break; break;
case SQL_DROP_TRANSLATION: case SQL_DROP_TRANSLATION:
len = 4; len = 4;
...@@ -204,7 +230,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -204,7 +230,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
len = 4; len = 4;
value = SQL_DV_DROP_VIEW; value = SQL_DV_DROP_VIEW;
if (PG_VERSION_GT(conn, 7.2)) /* hopefully */ if (PG_VERSION_GT(conn, 7.2)) /* hopefully */
value |= SQL_DV_RESTRICT | SQL_DV_CASCADE; value |= (SQL_DV_RESTRICT | SQL_DV_CASCADE);
break; break;
case SQL_INDEX_KEYWORDS: case SQL_INDEX_KEYWORDS:
len = 4; len = 4;
...@@ -227,11 +253,11 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -227,11 +253,11 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
break; break;
case SQL_PARAM_ARRAY_ROW_COUNTS: case SQL_PARAM_ARRAY_ROW_COUNTS:
len = 4; len = 4;
value = SQL_PARC_NO_BATCH; value = SQL_PARC_BATCH;
break; break;
case SQL_PARAM_ARRAY_SELECTS: case SQL_PARAM_ARRAY_SELECTS:
len = 4; len = 4;
value = SQL_PAS_NO_SELECT; value = SQL_PAS_BATCH;
break; break;
case SQL_SQL_CONFORMANCE: case SQL_SQL_CONFORMANCE:
len = 4; len = 4;
...@@ -316,6 +342,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -316,6 +342,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
return SQL_ERROR; return SQL_ERROR;
} }
result = SQL_SUCCESS; result = SQL_SUCCESS;
mylog("%s: p='%s', len=%d, value=%d, cbMax=%d\n", func, p ? p : "<NULL>", len, value, cbInfoValueMax);
if (p) if (p)
{ {
/* char/binary data */ /* char/binary data */
...@@ -323,6 +350,14 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, ...@@ -323,6 +350,14 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
if (rgbInfoValue) 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); strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax);
if (len >= cbInfoValueMax) if (len >= cbInfoValueMax)
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "psqlodbc.h" #include "psqlodbc.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#define MYLOGDIR "c:" #define MYLOGDIR "c:"
#endif #endif
extern void mylog(char *fmt,...); extern void mylog(char *fmt,...);
#define inolog mylog /* for really temporary debug */
#else #else
#ifndef WIN32 #ifndef WIN32
......
...@@ -16,13 +16,6 @@ ...@@ -16,13 +16,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
int PG_CCST; /* Client Charcter Status */
int PG_SCSC; /* Server Charcter Set (code) */
int PG_CCSC; /* Client Charcter Set (code) */
unsigned char *PG_SCSS; /* Server Charcter Set (string) */
unsigned char *PG_CCSS; /* Client Charcter Set (string) */
pg_CS CS_Table[] = pg_CS CS_Table[] =
{ {
{ "SQL_ASCII", SQL_ASCII }, { "SQL_ASCII", SQL_ASCII },
...@@ -78,19 +71,29 @@ pg_ismb(int characterset_code) ...@@ -78,19 +71,29 @@ pg_ismb(int characterset_code)
int int
pg_CS_code(const unsigned char *characterset_string) pg_CS_code(const unsigned char *characterset_string)
{ {
int i = 0, c; int i = 0, c = -1;
unsigned len = 0;
for(i = 0; CS_Table[i].code != OTHER; i++) for(i = 0; CS_Table[i].code != OTHER; i++)
{ {
if (strstr(characterset_string,CS_Table[i].name)) 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; c = CS_Table[i].code;
} }
}
}
if (c < 0)
c = i;
return (c); return (c);
} }
unsigned char * unsigned char *
pg_CS_name(const int characterset_code) pg_CS_name(int characterset_code)
{ {
int i = 0; int i;
for (i = 0; CS_Table[i].code != OTHER; i++) for (i = 0; CS_Table[i].code != OTHER; i++)
{ {
if (CS_Table[i].code == characterset_code) if (CS_Table[i].code == characterset_code)
...@@ -242,7 +245,7 @@ pg_CS_stat(int stat,unsigned int character,int characterset_code) ...@@ -242,7 +245,7 @@ pg_CS_stat(int stat,unsigned int character,int characterset_code)
unsigned char * unsigned char *
pg_mbschr(const unsigned char *string, unsigned int character) pg_mbschr(int csc, const unsigned char *string, unsigned int character)
{ {
int mb_st = 0; int mb_st = 0;
unsigned char *s; unsigned char *s;
...@@ -250,7 +253,7 @@ pg_mbschr(const unsigned char *string, unsigned int character) ...@@ -250,7 +253,7 @@ pg_mbschr(const unsigned char *string, unsigned int character)
for(;;) for(;;)
{ {
mb_st = pg_CS_stat(mb_st, (unsigned char) *s,PG_CCSC); mb_st = pg_CS_stat(mb_st, (unsigned char) *s, csc);
if (mb_st == 0 && (*s == character || *s == 0)) if (mb_st == 0 && (*s == character || *s == 0))
break; break;
else else
...@@ -260,13 +263,13 @@ pg_mbschr(const unsigned char *string, unsigned int character) ...@@ -260,13 +263,13 @@ pg_mbschr(const unsigned char *string, unsigned int character)
} }
int int
pg_mbslen(const unsigned char *string) pg_mbslen(int csc, const unsigned char *string)
{ {
unsigned char *s; unsigned char *s;
int len, cs_stat; int len, cs_stat;
for (len = 0, cs_stat = 0, s = (unsigned char *) string; *s != 0; s++) for (len = 0, cs_stat = 0, s = (unsigned char *) string; *s != 0; s++)
{ {
cs_stat = pg_CS_stat(cs_stat,(unsigned int) *s, PG_CCSC); cs_stat = pg_CS_stat(cs_stat,(unsigned int) *s, csc);
if (cs_stat < 2) if (cs_stat < 2)
len++; len++;
} }
...@@ -274,12 +277,12 @@ pg_mbslen(const unsigned char *string) ...@@ -274,12 +277,12 @@ pg_mbslen(const unsigned char *string)
} }
unsigned char * unsigned char *
pg_mbsinc(const unsigned char *current ) pg_mbsinc(int csc, const unsigned char *current )
{ {
int mb_stat = 0; int mb_stat = 0;
if (*current != 0) if (*current != 0)
{ {
mb_stat = (int) pg_CS_stat(mb_stat, *current, PG_CCSC); mb_stat = (int) pg_CS_stat(mb_stat, *current, csc);
if (mb_stat == 0) if (mb_stat == 0)
mb_stat = 1; mb_stat = 1;
return ((unsigned char *) current + mb_stat); return ((unsigned char *) current + mb_stat);
...@@ -288,43 +291,100 @@ pg_mbsinc(const unsigned char *current ) ...@@ -288,43 +291,100 @@ pg_mbsinc(const unsigned char *current )
return NULL; return NULL;
} }
void static char *
CC_lookup_characterset(ConnectionClass *self) CC_lookup_cs_new(ConnectionClass *self)
{ {
char *encstr = NULL;
QResultClass *res;
res = CC_send_query(self, "select pg_client_encoding()", NULL, TRUE);
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; HSTMT hstmt;
StatementClass *stmt;
RETCODE result; RETCODE result;
static char *func = "CC_lookup_characterset";
mylog("%s: entering...\n", func);
PG_SCSS = malloc(MAX_CHARACTERSET_NAME);
PG_CCSS = malloc(MAX_CHARACTERSET_NAME);
result = PGAPI_AllocStmt(self, &hstmt); result = PGAPI_AllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
return; return encstr;
stmt = (StatementClass *) hstmt;
result = PGAPI_ExecDirect(hstmt, "Show Client_Encoding", SQL_NTS); result = PGAPI_ExecDirect(hstmt, "Show Client_Encoding", SQL_NTS);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) if (result == SQL_SUCCESS_WITH_INFO)
{ {
PGAPI_FreeStmt(hstmt, SQL_DROP); char sqlState[8], errormsg[128], enc[32];
return;
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);
} }
result = PGAPI_AllocStmt(self, &hstmt); PGAPI_FreeStmt(hstmt, SQL_DROP);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return encstr;
return; }
stmt = (StatementClass *) hstmt;
result = PGAPI_ExecDirect(hstmt, "Show Server_Encoding", SQL_NTS); void
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) 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);
if (encstr)
{ {
PGAPI_FreeStmt(hstmt, SQL_DROP); self->client_encoding = encstr;
return; 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;
}
}
strcpy(PG_SCSS , pg_CS_name(PG_SCSC = pg_CS_code(PG_SCSS))); void encoded_str_constr(encoded_str *encstr, int ccsc, const char *str)
strcpy(PG_CCSS , pg_CS_name(PG_CCSC = pg_CS_code(PG_CCSS))); {
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;
qlog(" [ Server encoding = '%s' (code = %d), Client encoding = '%s' (code = %d) ]\n", PG_SCSS, PG_SCSC, PG_CCSS, PG_CCSC); chr = encstr->encstr[encstr->pos = abspos];
encstr->ccst = pg_CS_stat(encstr->ccst, (unsigned int) chr, encstr->ccsc);
return chr;
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* *
*/ */
#include "psqlodbc.h" #include "psqlodbc.h"
#include "qresult.h"
/* PostgreSQL client encoding */ /* PostgreSQL client encoding */
#define SQL_ASCII 0 /* SQL/ASCII */ #define SQL_ASCII 0 /* SQL/ASCII */
...@@ -56,32 +57,33 @@ ...@@ -56,32 +57,33 @@
/* New Type */ /* New Type */
extern int PG_CCST; /* Client Character StaTus */
extern int PG_SCSC; /* Server Character Set (Code) */
extern int PG_CCSC; /* Client Character Set (Code) */
extern unsigned char *PG_SCSS; /* Server Character Set (String) */
extern unsigned char *PG_CCSS; /* Client Character Set (String) */
extern void CC_lookup_characterset(ConnectionClass *self); extern void CC_lookup_characterset(ConnectionClass *self);
extern int pg_CS_stat(int stat,unsigned int charcter,int characterset_code); extern int pg_CS_stat(int stat,unsigned int charcter,int characterset_code);
extern int pg_CS_code(const unsigned char *stat_string); extern int pg_CS_code(const unsigned char *stat_string);
extern unsigned char *pg_CS_name(const int code); extern unsigned char *pg_CS_name(int code);
typedef struct pg_CS typedef struct pg_CS
{ {
unsigned char *name; unsigned char *name;
int code; int code;
}pg_CS; }pg_CS;
extern pg_CS CS_Table[]; 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 int pg_mbslen(const unsigned char *string); extern unsigned char *pg_mbsinc(int ccsc, const unsigned char *current );
extern unsigned char *pg_mbschr(const unsigned char *string, unsigned int character);
extern unsigned char *pg_mbsinc( const unsigned char *current );
/* Old Type Compatible */ /* Old Type Compatible */
#define multibyte_init() (PG_CCST = 0) typedef struct
#define multibyte_char_check(X) pg_CS_stat(PG_CCST, (unsigned int) X, PG_CCSC) {
#define multibyte_strchr(X,Y) pg_mbschr(X,Y) int ccsc;
#define check_client_encoding(X) pg_CS_name(PG_CCSC = pg_CS_code(X)) 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))
...@@ -174,7 +174,8 @@ SQLError(HENV EnvironmentHandle, ...@@ -174,7 +174,8 @@ SQLError(HENV EnvironmentHandle,
{ {
mylog("[SQLError]"); mylog("[SQLError]");
return PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle, return PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle,
Sqlstate, NativeError, MessageText, BufferLength, TextLength); Sqlstate, NativeError, MessageText, BufferLength,
TextLength);
} }
RETCODE SQL_API RETCODE SQL_API
...@@ -281,23 +282,31 @@ SQLGetInfo(HDBC ConnectionHandle, ...@@ -281,23 +282,31 @@ SQLGetInfo(HDBC ConnectionHandle,
SQLUSMALLINT InfoType, PTR InfoValue, SQLUSMALLINT InfoType, PTR InfoValue,
SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
{ {
#if (ODBCVER >= 0x0300)
RETCODE ret; RETCODE ret;
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
CC_clear_error(conn);
#if (ODBCVER >= 0x0300)
mylog("[SQLGetInfo(30)]"); mylog("[SQLGetInfo(30)]");
if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength)) == SQL_ERROR) BufferLength, StringLength)) == SQL_ERROR)
{ {
if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300) if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300)
return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, {
CC_clear_error(conn);
ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength); BufferLength, StringLength);
} }
return ret; }
if (SQL_ERROR == ret)
CC_log_error("SQLGetInfo30", "", conn);
#else #else
mylog("[SQLGetInfo]"); mylog("[SQLGetInfo]");
return PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, if (ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength); BufferLength, StringLength), SQL_ERROR == ret)
CC_log_error("PGAPI_GetInfo", "", conn);
#endif #endif
return ret;
} }
RETCODE SQL_API RETCODE SQL_API
...@@ -638,7 +647,7 @@ SQLTablePrivileges( ...@@ -638,7 +647,7 @@ SQLTablePrivileges(
{ {
mylog("[SQLTablePrivileges]"); mylog("[SQLTablePrivileges]");
return PGAPI_TablePrivileges(hstmt, szCatalogName, cbCatalogName, return PGAPI_TablePrivileges(hstmt, szCatalogName, cbCatalogName,
szSchemaName, cbSchemaName, szTableName, cbTableName); szSchemaName, cbSchemaName, szTableName, cbTableName, 0);
} }
RETCODE SQL_API RETCODE SQL_API
......
...@@ -25,21 +25,26 @@ RETCODE SQL_API SQLErrorW(HENV EnvironmentHandle, ...@@ -25,21 +25,26 @@ RETCODE SQL_API SQLErrorW(HENV EnvironmentHandle,
SQLSMALLINT *TextLength) SQLSMALLINT *TextLength)
{ {
RETCODE ret; RETCODE ret;
SWORD tlen; SWORD tlen, buflen;
char *qst = NULL, *mtxt = NULL; char *qst = NULL, *mtxt = NULL;
mylog("[SQLErrorW]"); mylog("[SQLErrorW]");
if (Sqlstate) if (Sqlstate)
qst = malloc(8); qst = malloc(8);
if (MessageText) buflen = 0;
mtxt = malloc(BufferLength); if (MessageText && BufferLength > 0)
{
buflen = BufferLength * 3 + 1;
mtxt = malloc(buflen);
}
ret = PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle, ret = PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle,
qst, NativeError, mtxt, BufferLength, &tlen); qst, NativeError, mtxt, buflen, &tlen);
if (qst) if (qst)
utf8_to_ucs2(qst, strlen(qst), Sqlstate, 5); utf8_to_ucs2(qst, strlen(qst), Sqlstate, 5);
if (TextLength) if (TextLength)
*TextLength = utf8_to_ucs2(mtxt, tlen, MessageText, BufferLength); *TextLength = utf8_to_ucs2(mtxt, tlen, MessageText, BufferLength);
free(qst); free(qst);
if (mtxt)
free(mtxt); free(mtxt);
return ret; return ret;
} }
...@@ -56,6 +61,7 @@ RETCODE SQL_API SQLSetConnectOptionW(HDBC ConnectionHandle, ...@@ -56,6 +61,7 @@ RETCODE SQL_API SQLSetConnectOptionW(HDBC ConnectionHandle,
SQLUSMALLINT Option, SQLUINTEGER Value) SQLUSMALLINT Option, SQLUINTEGER Value)
{ {
mylog("[SQLSetConnectionOptionW]"); mylog("[SQLSetConnectionOptionW]");
if (!ConnectionHandle) return SQL_ERROR;
((ConnectionClass *) ConnectionHandle)->unicode = 1; ((ConnectionClass *) ConnectionHandle)->unicode = 1;
return PGAPI_SetConnectOption(ConnectionHandle, Option, Value); return PGAPI_SetConnectOption(ConnectionHandle, Option, Value);
} }
......
...@@ -144,9 +144,7 @@ SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, ...@@ -144,9 +144,7 @@ SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
default: default:
break; break;
} }
return SQL_ERROR; /* SQLSTATE HY092 ("Invalid return SQL_ERROR;
* attribute/option identifier") */
} }
/* SQLExtendedFetch -> SQLFetchScroll */ /* SQLExtendedFetch -> SQLFetchScroll */
...@@ -246,39 +244,9 @@ SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, ...@@ -246,39 +244,9 @@ SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLINTEGER *NativeError, SQLCHAR *MessageText,
SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
{ {
RETCODE ret;
mylog("[[SQLGetDiagRec]]\n"); mylog("[[SQLGetDiagRec]]\n");
switch (HandleType) return PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
{ NativeError, MessageText, BufferLength, TextLength);
case SQL_HANDLE_ENV:
ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError,
MessageText, BufferLength, TextLength);
break;
case SQL_HANDLE_DBC:
ret = PGAPI_Error(NULL, Handle, NULL, Sqlstate, NativeError,
MessageText, BufferLength, TextLength);
break;
case SQL_HANDLE_STMT:
ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError,
MessageText, BufferLength, TextLength);
break;
default:
ret = SQL_ERROR;
}
if (ret == SQL_SUCCESS_WITH_INFO &&
BufferLength == 0 &&
*TextLength)
{
SQLSMALLINT BufferLength = *TextLength + 4;
SQLCHAR *MessageText = malloc(BufferLength);
ret = SQLGetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
NativeError, MessageText, BufferLength,
TextLength);
free(MessageText);
}
return ret;
} }
/* new function */ /* new function */
...@@ -299,7 +267,7 @@ SQLGetEnvAttr(HENV EnvironmentHandle, ...@@ -299,7 +267,7 @@ SQLGetEnvAttr(HENV EnvironmentHandle,
*((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH;
break; break;
case SQL_ATTR_ODBC_VERSION: case SQL_ATTR_ODBC_VERSION:
*((unsigned int *) Value) = SQL_OV_ODBC3; *((unsigned int *) Value) = EN_is_odbc2(env) ? SQL_OV_ODBC2 : SQL_OV_ODBC3;
break; break;
case SQL_ATTR_OUTPUT_NTS: case SQL_ATTR_OUTPUT_NTS:
*((unsigned int *) Value) = SQL_TRUE; *((unsigned int *) Value) = SQL_TRUE;
...@@ -456,6 +424,7 @@ ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, ...@@ -456,6 +424,7 @@ ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength) SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{ {
RETCODE ret = SQL_SUCCESS; RETCODE ret = SQL_SUCCESS;
PTR tptr;
switch (FieldIdentifier) switch (FieldIdentifier)
{ {
case SQL_DESC_ARRAY_SIZE: case SQL_DESC_ARRAY_SIZE:
...@@ -470,8 +439,34 @@ ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, ...@@ -470,8 +439,34 @@ ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
case SQL_DESC_BIND_TYPE: case SQL_DESC_BIND_TYPE:
stmt->options.bind_size = (SQLUINTEGER) Value; stmt->options.bind_size = (SQLUINTEGER) Value;
break; break;
case SQL_DESC_DATA_PTR:
if (!RecNumber)
stmt->bookmark.buffer = Value;
else
stmt->bindings[RecNumber - 1].buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
if (!RecNumber)
tptr = stmt->bookmark.used;
else
tptr = stmt->bindings[RecNumber - 1].used;
if (Value != tptr)
{
ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR";
}
break;
case SQL_DESC_OCTET_LENGTH_PTR:
if (!RecNumber)
stmt->bookmark.used = Value;
else
stmt->bindings[RecNumber - 1].used = Value;
break;
default:ret = SQL_ERROR; default:ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "not implemedted yet";
} }
return ret; return ret;
} }
...@@ -495,6 +490,26 @@ APDSetField(StatementClass *stmt, SQLSMALLINT RecNumber, ...@@ -495,6 +490,26 @@ APDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
case SQL_DESC_BIND_TYPE: case SQL_DESC_BIND_TYPE:
stmt->options.param_bind_type = (SQLUINTEGER) Value; stmt->options.param_bind_type = (SQLUINTEGER) Value;
break; break;
case SQL_DESC_DATA_PTR:
if (stmt->parameters_allocated < RecNumber)
PGAPI_BindParameter(stmt, RecNumber, 0, 0, 0, 0, 0, 0, 0, 0);
stmt->parameters[RecNumber - 1].buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
if (stmt->parameters_allocated < RecNumber ||
Value != stmt->parameters[RecNumber - 1].used)
{
ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR";
}
break;
case SQL_DESC_OCTET_LENGTH_PTR:
if (stmt->parameters_allocated < RecNumber)
PGAPI_BindParameter(stmt, RecNumber, 0, 0, 0, 0, 0, 0, 0, 0);
stmt->parameters[RecNumber - 1].used = Value;
break;
default:ret = SQL_ERROR; default:ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
} }
...@@ -549,6 +564,8 @@ SQLSetDescField(SQLHDESC DescriptorHandle, ...@@ -549,6 +564,8 @@ SQLSetDescField(SQLHDESC DescriptorHandle,
HSTMT hstmt; HSTMT hstmt;
SQLUINTEGER descType; SQLUINTEGER descType;
StatementClass *stmt; StatementClass *stmt;
static const char *func = "SQLSetDescField";
mylog("[[SQLSetDescField]] h=%u rec=%d field=%d val=%x\n", DescriptorHandle, RecNumber, FieldIdentifier, Value); mylog("[[SQLSetDescField]] h=%u rec=%d field=%d val=%x\n", DescriptorHandle, RecNumber, FieldIdentifier, Value);
hstmt = statementHandleFromDescHandle(DescriptorHandle, &descType); hstmt = statementHandleFromDescHandle(DescriptorHandle, &descType);
mylog("stmt=%x type=%d\n", hstmt, descType); mylog("stmt=%x type=%d\n", hstmt, descType);
...@@ -569,8 +586,10 @@ SQLSetDescField(SQLHDESC DescriptorHandle, ...@@ -569,8 +586,10 @@ SQLSetDescField(SQLHDESC DescriptorHandle,
break; break;
default:ret = SQL_ERROR; default:ret = SQL_ERROR;
stmt->errornumber = STMT_INTERNAL_ERROR; stmt->errornumber = STMT_INTERNAL_ERROR;
mylog("Error not implemented\n"); stmt->errormsg = "Error not implemented";
} }
if (ret == SQL_ERROR)
SC_log_error(func, "", stmt);
return ret; return ret;
} }
...@@ -583,6 +602,8 @@ SQLSetDescRec(SQLHDESC DescriptorHandle, ...@@ -583,6 +602,8 @@ SQLSetDescRec(SQLHDESC DescriptorHandle,
PTR Data, SQLINTEGER *StringLength, PTR Data, SQLINTEGER *StringLength,
SQLINTEGER *Indicator) SQLINTEGER *Indicator)
{ {
const char *func = "SQLSetDescField";
mylog("[[SQLSetDescRec]]\n"); mylog("[[SQLSetDescRec]]\n");
mylog("Error not implemented\n"); mylog("Error not implemented\n");
return SQL_ERROR; return SQL_ERROR;
...@@ -608,6 +629,9 @@ SQLSetEnvAttr(HENV EnvironmentHandle, ...@@ -608,6 +629,9 @@ SQLSetEnvAttr(HENV EnvironmentHandle,
return SQL_SUCCESS; return SQL_SUCCESS;
case SQL_ATTR_ODBC_VERSION: case SQL_ATTR_ODBC_VERSION:
if ((SQLUINTEGER) Value == SQL_OV_ODBC2) if ((SQLUINTEGER) Value == SQL_OV_ODBC2)
EN_set_odbc2(env);
else
EN_set_odbc3(env);
return SQL_SUCCESS; return SQL_SUCCESS;
break; break;
case SQL_ATTR_OUTPUT_NTS: case SQL_ATTR_OUTPUT_NTS:
...@@ -652,44 +676,46 @@ SQLSetStmtAttr(HSTMT StatementHandle, ...@@ -652,44 +676,46 @@ SQLSetStmtAttr(HSTMT StatementHandle,
* case SQL_ATTR_PREDICATE_PTR: case * case SQL_ATTR_PREDICATE_PTR: case
* SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: * SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
*/ */
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER; stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "Unsupported statement option (Set)"; stmt->errormsg = "Unsupported statement option (Set)";
SC_log_error(func, "", stmt); SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
stmt->options.param_offset_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
stmt->options.row_offset_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */ case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
stmt->options.bookmark_ptr = Value; stmt->options.bookmark_ptr = Value;
break; break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
stmt->options.param_offset_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */ case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
stmt->options.param_bind_type = (SQLUINTEGER) Value; stmt->options.param_bind_type = (SQLUINTEGER) Value;
break; break;
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
stmt->options.param_operation_ptr = Value;
break;
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
stmt->options.param_status_ptr = (SQLUSMALLINT *) Value;
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */ case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
stmt->options.param_processed_ptr = (SQLUINTEGER *) Value; stmt->options.param_processed_ptr = (SQLUINTEGER *) Value;
break; break;
case SQL_ATTR_PARAMSET_SIZE: /* 22 */ case SQL_ATTR_PARAMSET_SIZE: /* 22 */
stmt->options.paramset_size = (SQLUINTEGER) Value; stmt->options.paramset_size = (SQLUINTEGER) Value;
break; break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
stmt->options.row_offset_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
stmt->options.row_operation_ptr = Value;
break;
case SQL_ATTR_ROW_STATUS_PTR: /* 25 */ case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
stmt->options.rowStatusArray = (SQLUSMALLINT *) Value; stmt->options.rowStatusArray = (SQLUSMALLINT *) Value;
break; break;
case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */ case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
stmt->options.rowsFetched = (SQLUINTEGER *) Value; stmt->options.rowsFetched = (SQLUINTEGER *) Value;
break; break;
case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */ case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
stmt->options.rowset_size = (SQLUINTEGER) Value; stmt->options.rowset_size = (SQLUINTEGER) Value;
break; break;
default: default:
return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value); return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value);
...@@ -755,17 +781,14 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists) ...@@ -755,17 +781,14 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */
/* /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */
* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50
* deprecated
*/
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */ /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */
SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */
if (ci->drivers.lie) if (ci->drivers.lie)
SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implmented yet */ SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implemented yet */
SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 */
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); 59 deprecated */ /* SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); 59 deprecated */
...@@ -781,12 +804,11 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists) ...@@ -781,12 +804,11 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */ /* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */
if (ci->drivers.lie) if (ci->drivers.lie)
SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 not implmented yet */ 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_SQLPROCEDURES); /* 67 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); /* 69 deprecated */ /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); 69 deprecated */
if (ci->drivers.lie) SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 not implemented yet */
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */ /* 71 */ /* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */ /* 71 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */
...@@ -810,7 +832,9 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists) ...@@ -810,7 +832,9 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 */
if (ci->drivers.lie) if (ci->drivers.lie)
{
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */ 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_SQLSETENVATTR); /* 1019 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */
SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */ SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */
......
...@@ -85,21 +85,36 @@ RETCODE SQL_API SQLGetDiagRecW(SWORD fHandleType, ...@@ -85,21 +85,36 @@ RETCODE SQL_API SQLGetDiagRecW(SWORD fHandleType,
SQLSMALLINT *pcbErrorMsg) SQLSMALLINT *pcbErrorMsg)
{ {
RETCODE ret; RETCODE ret;
SWORD tlen; SWORD buflen, tlen;
char *qst = NULL, *mtxt = NULL; char *qstr = NULL, *mtxt = NULL;
mylog("[SQLGetDiagRecW]"); mylog("[SQLGetDiagRecW]");
if (szSqlState) if (szSqlState)
qst = malloc(8); qstr = malloc(8);
if (szErrorMsg) buflen = 0;
mtxt = malloc(cbErrorMsgMax); if (szErrorMsg && cbErrorMsgMax > 0)
ret = PGAPI_GetDiagRec(fHandleType, handle, iRecord, qst, {
pfNativeError, mtxt, cbErrorMsgMax, &tlen); buflen = cbErrorMsgMax;
if (qst) mtxt = malloc(buflen);
utf8_to_ucs2(qst, strlen(qst), szSqlState, 5); }
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) if (pcbErrorMsg)
*pcbErrorMsg = utf8_to_ucs2(mtxt, tlen, szErrorMsg, cbErrorMsgMax); *pcbErrorMsg = tlen;
free(qst); }
if (qstr);
free(qstr);
if (mtxt)
free(mtxt); free(mtxt);
return ret; return ret;
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
SQLPrepareW, SQLPrimaryKeysW, SQLProcedureColumnsW, SQLPrepareW, SQLPrimaryKeysW, SQLProcedureColumnsW,
SQLProceduresW, SQLSetCursorNameW, SQLProceduresW, SQLSetCursorNameW,
SQLSpecialColumnsW, SQLStatisticsW, SQLTablesW, SQLSpecialColumnsW, SQLStatisticsW, SQLTablesW,
SQLTablePrivilegesW SQLTablePrivilegesW, SQLGetTypeInfoW
*------- *-------
*/ */
...@@ -102,7 +102,11 @@ RETCODE SQL_API SQLDriverConnectW(HDBC hdbc, ...@@ -102,7 +102,11 @@ RETCODE SQL_API SQLDriverConnectW(HDBC hdbc,
ret = PGAPI_DriverConnect(hdbc, hwnd, szIn, (SWORD) inlen, ret = PGAPI_DriverConnect(hdbc, hwnd, szIn, (SWORD) inlen,
szOut, cbConnStrOutMax, &olen, fDriverCompletion); szOut, cbConnStrOutMax, &olen, fDriverCompletion);
if (ret != SQL_ERROR) if (ret != SQL_ERROR)
*pcbConnStrOut = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax); {
UInt4 outlen = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
if (pcbConnStrOut)
*pcbConnStrOut = outlen;
}
free(szOut); free(szOut);
if (szIn); if (szIn);
free(szIn); free(szIn);
...@@ -129,7 +133,11 @@ RETCODE SQL_API SQLBrowseConnectW( ...@@ -129,7 +133,11 @@ RETCODE SQL_API SQLBrowseConnectW(
ret = PGAPI_BrowseConnect(hdbc, szIn, (SWORD) inlen, ret = PGAPI_BrowseConnect(hdbc, szIn, (SWORD) inlen,
szOut, cbConnStrOutMax, &olen); szOut, cbConnStrOutMax, &olen);
if (ret != SQL_ERROR) if (ret != SQL_ERROR)
*pcbConnStrOut = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax); {
UInt4 outlen = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
if (pcbConnStrOut)
*pcbConnStrOut = outlen;
}
free(szOut); free(szOut);
if (szIn); if (szIn);
free(szIn); free(szIn);
...@@ -158,15 +166,28 @@ RETCODE SQL_API SQLDescribeColW(HSTMT StatementHandle, ...@@ -158,15 +166,28 @@ RETCODE SQL_API SQLDescribeColW(HSTMT StatementHandle,
SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
{ {
RETCODE ret; RETCODE ret;
SWORD nmlen; SWORD buflen, nmlen;
char *clName; char *clName;
mylog("[SQLDescribeColW]"); mylog("[SQLDescribeColW]");
clName = malloc(BufferLength); buflen = BufferLength * 3 + 1;
clName = malloc(buflen);
ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber, ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber,
clName, BufferLength, &nmlen, clName, buflen, &nmlen, DataType, ColumnSize,
DataType, ColumnSize, DecimalDigits, Nullable); DecimalDigits, Nullable);
*NameLength = utf8_to_ucs2(clName, nmlen, ColumnName, BufferLength); 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); free(clName);
return ret; return ret;
} }
...@@ -192,13 +213,25 @@ RETCODE SQL_API SQLGetCursorNameW(HSTMT StatementHandle, ...@@ -192,13 +213,25 @@ RETCODE SQL_API SQLGetCursorNameW(HSTMT StatementHandle,
{ {
RETCODE ret; RETCODE ret;
char *crName; char *crName;
SWORD clen; SWORD clen, buflen;
mylog("[SQLGetCursorNameW]"); mylog("[SQLGetCursorNameW]");
crName = malloc(BufferLength); buflen = BufferLength * 3 + 1;
ret = PGAPI_GetCursorName(StatementHandle, crName, BufferLength, crName = malloc(buflen);
&clen); 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); *NameLength = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength);
}
free(crName); free(crName);
return ret; return ret;
} }
...@@ -207,23 +240,33 @@ RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle, ...@@ -207,23 +240,33 @@ RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle,
SQLUSMALLINT InfoType, PTR InfoValue, SQLUSMALLINT InfoType, PTR InfoValue,
SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
{ {
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
RETCODE ret; RETCODE ret;
((ConnectionClass *) ConnectionHandle)->unicode = 1;
conn->unicode = 1;
CC_clear_error(conn);
#if (ODBCVER >= 0x0300) #if (ODBCVER >= 0x0300)
mylog("[SQLGetInfoW(30)]"); mylog("[SQLGetInfoW(30)]");
if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength)) == SQL_ERROR) BufferLength, StringLength)) == SQL_ERROR)
{ {
if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300) if (conn->driver_version >= 0x0300)
return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, {
CC_clear_error(conn);
ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength); BufferLength, StringLength);
} }
return ret; }
if (SQL_ERROR == ret)
CC_log_error("SQLGetInfoW(30)", "", conn);
#else #else
mylog("[SQLGetInfoW]"); mylog("[SQLGetInfoW]");
return PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength); BufferLength, StringLength);
if (SQL_ERROR == ret)
CC_log_error("SQLGetInfoW", "", conn);
#endif #endif
return ret;
} }
RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle, RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle,
...@@ -428,17 +471,31 @@ RETCODE SQL_API SQLNativeSqlW( ...@@ -428,17 +471,31 @@ RETCODE SQL_API SQLNativeSqlW(
RETCODE ret; RETCODE ret;
char *szIn, *szOut; char *szIn, *szOut;
UInt4 slen; UInt4 slen;
SQLINTEGER olen; SQLINTEGER buflen, olen;
mylog("[SQLNativeSqlW]"); mylog("[SQLNativeSqlW]");
((ConnectionClass *) hdbc)->unicode = 1; ((ConnectionClass *) hdbc)->unicode = 1;
szIn = ucs2_to_utf8(szSqlStrIn, cbSqlStrIn, &slen); szIn = ucs2_to_utf8(szSqlStrIn, cbSqlStrIn, &slen);
szOut = malloc(cbSqlStrMax); buflen = 3 * cbSqlStrMax + 1;
szOut = malloc(buflen);
ret = PGAPI_NativeSql(hdbc, szIn, (SQLINTEGER) slen, ret = PGAPI_NativeSql(hdbc, szIn, (SQLINTEGER) slen,
szOut, cbSqlStrMax, &olen); szOut, buflen, &olen);
if (szIn); if (szIn);
free(szIn); free(szIn);
*pcbSqlStr = utf8_to_ucs2(szOut, olen, szSqlStr, cbSqlStrMax); 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); free(szOut);
return ret; return ret;
} }
...@@ -560,3 +617,10 @@ RETCODE SQL_API SQLTablePrivilegesW( ...@@ -560,3 +617,10 @@ RETCODE SQL_API SQLTablePrivilegesW(
free(tbName); free(tbName);
return ret; return ret;
} }
RETCODE SQL_API SQLGetTypeInfoW(
SQLHSTMT StatementHandle,
SQLSMALLINT DataType)
{
return PGAPI_GetTypeInfo(StatementHandle, DataType);
}
...@@ -342,12 +342,13 @@ PGAPI_SetConnectOption( ...@@ -342,12 +342,13 @@ PGAPI_SetConnectOption(
break; break;
case SQL_AUTOCOMMIT: case SQL_AUTOCOMMIT:
if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn)) if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_trans(conn))
break; break;
else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn)) else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_trans(conn))
break; break;
if (CC_is_in_trans(conn)) if (CC_is_in_trans(conn))
CC_commit(conn); CC_commit(conn);
mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam); mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
switch (vParam) switch (vParam)
...@@ -401,8 +402,21 @@ PGAPI_SetConnectOption( ...@@ -401,8 +402,21 @@ PGAPI_SetConnectOption(
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
if (fOption == 30002 && vParam) if (fOption == 30002 && vParam)
{ {
if (strcmp((char *) vParam, "Microsoft Jet") == 0) 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->errornumber = 0;
conn->ms_jet = 1; conn->ms_jet = 1;
return SQL_SUCCESS; return SQL_SUCCESS;
...@@ -456,7 +470,7 @@ PGAPI_GetConnectOption( ...@@ -456,7 +470,7 @@ PGAPI_GetConnectOption(
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */ case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
if (pvParam) if (pvParam)
strcpy(pvParam, ""); ((char *) pvParam)[0] = ((char *) pvParam)[1] = '\0';
break; break;
...@@ -557,7 +571,7 @@ PGAPI_GetStmtOption( ...@@ -557,7 +571,7 @@ PGAPI_GetStmtOption(
case SQL_GET_BOOKMARK: case SQL_GET_BOOKMARK:
case SQL_ROW_NUMBER: case SQL_ROW_NUMBER:
res = stmt->result; res = SC_get_Curres(stmt);
if (stmt->manual_result || !ci->drivers.use_declarefetch) if (stmt->manual_result || !ci->drivers.use_declarefetch)
{ {
......
...@@ -42,18 +42,29 @@ ...@@ -42,18 +42,29 @@
#define TAB_INCR 8 #define TAB_INCR 8
#define COL_INCR 16 #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); 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); void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k);
char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi); char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi);
char * char *
getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric) 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 i = 0;
int out = 0; int out = 0;
char qc, char qc,
in_escape = FALSE; in_escape = FALSE;
#ifdef MULTIBYTE
encoded_str encstr;
#endif
if (smax <= 1) if (smax <= 1)
return NULL; return NULL;
...@@ -80,17 +91,22 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu ...@@ -80,17 +91,22 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
if (numeric) if (numeric)
*numeric = FALSE; *numeric = FALSE;
#ifdef MULTIBYTE
encoded_str_constr(&encstr, ccsc, &s[i]);
#endif
/* get the next token */ /* get the next token */
while (!isspace((unsigned char) s[i]) && s[i] != ',' && while (s[i] != '\0' && out < smax)
s[i] != '\0' && out != smax)
{ {
#ifdef MULTIBYTE #ifdef MULTIBYTE
if (multibyte_char_check(s[i]) != 0) encoded_nextchar(&encstr);
if (ENCODE_STATUS(encstr) != 0)
{ {
token[out++] = s[i++]; token[out++] = s[i++];
continue; continue;
} }
#endif #endif
if (isspace((unsigned char) s[i]) || s[i] == ',')
break;
/* Handle quoted stuff */ /* Handle quoted stuff */
if (out == 0 && (s[i] == '\"' || s[i] == '\'')) if (out == 0 && (s[i] == '\"' || s[i] == '\''))
{ {
...@@ -110,7 +126,8 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu ...@@ -110,7 +126,8 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
while (s[i] != '\0' && out != smax) while (s[i] != '\0' && out != smax)
{ {
#ifdef MULTIBYTE #ifdef MULTIBYTE
if (multibyte_char_check(s[i]) != 0) encoded_nextchar(&encstr);
if (ENCODE_STATUS(encstr) != 0)
{ {
token[out++] = s[i++]; token[out++] = s[i++];
continue; continue;
...@@ -197,22 +214,22 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu ...@@ -197,22 +214,22 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
#if 0 #if 0
QR_set_num_fields(stmt->result, 14); QR_set_num_fields(SC_get_Curres(stmt), 14);
QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(SC_get_Curres(stmt), 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING);
QR_set_field_info(stmt->result, 1, "TABLE_OWNER", 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(stmt->result, 2, "TABLE_NAME", 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(stmt->result, 3, "COLUMN_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(stmt->result, 4, "DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info(SC_get_Curres(stmt), 4, "DATA_TYPE", PG_TYPE_INT2, 2);
QR_set_field_info(stmt->result, 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(SC_get_Curres(stmt), 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
QR_set_field_info(stmt->result, 6, "PRECISION", PG_TYPE_INT4, 4); QR_set_field_info(SC_get_Curres(stmt), 6, "PRECISION", PG_TYPE_INT4, 4);
QR_set_field_info(stmt->result, 7, "LENGTH", PG_TYPE_INT4, 4); QR_set_field_info(SC_get_Curres(stmt), 7, "LENGTH", PG_TYPE_INT4, 4);
QR_set_field_info(stmt->result, 8, "SCALE", PG_TYPE_INT2, 2); QR_set_field_info(SC_get_Curres(stmt), 8, "SCALE", PG_TYPE_INT2, 2);
QR_set_field_info(stmt->result, 9, "RADIX", PG_TYPE_INT2, 2); QR_set_field_info(SC_get_Curres(stmt), 9, "RADIX", PG_TYPE_INT2, 2);
QR_set_field_info(stmt->result, 10, "NULLABLE", PG_TYPE_INT2, 2); QR_set_field_info(SC_get_Curres(stmt), 10, "NULLABLE", PG_TYPE_INT2, 2);
QR_set_field_info(stmt->result, 11, "REMARKS", PG_TYPE_TEXT, 254); QR_set_field_info(SC_get_Curres(stmt), 11, "REMARKS", PG_TYPE_TEXT, 254);
/* User defined fields */ /* User defined fields */
QR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4); QR_set_field_info(SC_get_Curres(stmt), 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4);
QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4); QR_set_field_info(SC_get_Curres(stmt), 13, "FIELD_TYPE", PG_TYPE_INT4, 4);
#endif #endif
void void
...@@ -312,9 +329,10 @@ parse_statement(StatementClass *stmt) ...@@ -312,9 +329,10 @@ parse_statement(StatementClass *stmt)
stmt->ntab = 0; stmt->ntab = 0;
#ifdef MULTIBYTE #ifdef MULTIBYTE
multibyte_init(); while (pptr = ptr, (ptr = getNextToken(conn->ccsc, pptr, token, sizeof(token), &delim, &quote, &dquote, &numeric)) != NULL)
#endif #else
while (pptr = ptr, (ptr = getNextToken(pptr, token, sizeof(token), &delim, &quote, &dquote, &numeric)) != NULL) while (pptr = ptr, (ptr = getNextToken(pptr, token, sizeof(token), &delim, &quote, &dquote, &numeric)) != NULL)
#endif
{ {
unquoted = !(quote || dquote); unquoted = !(quote || dquote);
...@@ -607,12 +625,17 @@ parse_statement(StatementClass *stmt) ...@@ -607,12 +625,17 @@ parse_statement(StatementClass *stmt)
if (!dquote) if (!dquote)
{ {
char *ptr; char *ptr;
#ifdef MULTIBYTE
encoded_str encstr;
make_encoded_str(&encstr, conn, ti[stmt->ntab]->name);
#endif /* MULTIBYTE */
/* lower case table name */ /* lower case table name */
for (ptr = ti[stmt->ntab]->name; *ptr; ptr++) for (ptr = ti[stmt->ntab]->name; *ptr; ptr++)
{ {
#ifdef MULTIBYTE #ifdef MULTIBYTE
if ((unsigned char) *ptr >= 0x80) encoded_nextchar(&encstr);
if (ENCODE_STATUS(encstr) != 0)
ptr++; ptr++;
else else
#endif /* MULTIBYTE */ #endif /* MULTIBYTE */
...@@ -773,13 +796,13 @@ parse_statement(StatementClass *stmt) ...@@ -773,13 +796,13 @@ parse_statement(StatementClass *stmt)
* structure * structure
*/ */
strcpy(conn->col_info[conn->ntables]->name, ti[i]->name); strcpy(conn->col_info[conn->ntables]->name, ti[i]->name);
conn->col_info[conn->ntables]->result = col_stmt->result; conn->col_info[conn->ntables]->result = SC_get_Curres(col_stmt);
/* /*
* The connection will now free the result structures, so * The connection will now free the result structures, so
* make sure that the statement doesn't free it * make sure that the statement doesn't free it
*/ */
col_stmt->result = NULL; SC_set_Result(col_stmt, NULL);
conn->ntables++; conn->ntables++;
......
...@@ -36,37 +36,92 @@ PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, ...@@ -36,37 +36,92 @@ PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
RETCODE ret; RETCODE ret;
static const char *func = "PGAPI_GetDiagRec"; static const char *func = "PGAPI_GetDiagRec";
mylog("%s entering ", func); mylog("%s entering rec=%d", func, RecNumber);
switch (HandleType) switch (HandleType)
{ {
case SQL_HANDLE_ENV: case SQL_HANDLE_ENV:
ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError, ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate,
MessageText, BufferLength, TextLength); NativeError, MessageText,
BufferLength, TextLength, 0);
break; break;
case SQL_HANDLE_DBC: case SQL_HANDLE_DBC:
ret = PGAPI_Error(NULL, Handle, NULL, Sqlstate, NativeError, ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate,
MessageText, BufferLength, TextLength); NativeError, MessageText, BufferLength,
TextLength, 0);
break; break;
case SQL_HANDLE_STMT: case SQL_HANDLE_STMT:
ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError, ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate,
MessageText, BufferLength, TextLength); NativeError, MessageText, BufferLength,
TextLength, 0);
break; break;
default: default:
ret = SQL_ERROR; ret = SQL_ERROR;
} }
if (ret == SQL_SUCCESS_WITH_INFO && mylog("%s exiting %d\n", func, ret);
BufferLength == 0 && return ret;
*TextLength) }
{
SQLSMALLINT BufferLength = *TextLength + 4;
SQLCHAR *MessageText = malloc(BufferLength);
ret = PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate, RETCODE SQL_API
NativeError, MessageText, BufferLength, PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
TextLength); SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
free(MessageText); PTR DiagInfoPtr, SQLSMALLINT BufferLength,
SQLSMALLINT *StringLengthPtr)
{
RETCODE ret = SQL_SUCCESS;
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_MESSAGE_TEXT:
case SQL_DIAG_NATIVE:
case SQL_DIAG_NUMBER:
case SQL_DIAG_RETURNCODE:
case SQL_DIAG_SERVER_NAME:
case SQL_DIAG_SQLSTATE:
break;
}
break;
case SQL_HANDLE_DBC:
switch (DiagIdentifier)
{
case SQL_DIAG_CLASS_ORIGIN:
case SQL_DIAG_SUBCLASS_ORIGIN:
case SQL_DIAG_CONNECTION_NAME:
case SQL_DIAG_MESSAGE_TEXT:
case SQL_DIAG_NATIVE:
case SQL_DIAG_NUMBER:
case SQL_DIAG_RETURNCODE:
case SQL_DIAG_SERVER_NAME:
case SQL_DIAG_SQLSTATE:
break;
}
break;
case SQL_HANDLE_STMT:
switch (DiagIdentifier)
{
case SQL_DIAG_CLASS_ORIGIN:
case SQL_DIAG_SUBCLASS_ORIGIN:
case SQL_DIAG_CONNECTION_NAME:
case SQL_DIAG_MESSAGE_TEXT:
case SQL_DIAG_NATIVE:
case SQL_DIAG_NUMBER:
case SQL_DIAG_RETURNCODE:
case SQL_DIAG_SERVER_NAME:
case SQL_DIAG_SQLSTATE:
break;
}
break;
default:
ret = SQL_ERROR;
} }
mylog("%s exiting\n", func); mylog("%s exiting %d\n", func, ret);
return ret; return ret;
} }
...@@ -87,7 +142,7 @@ PGAPI_GetConnectAttr(HDBC ConnectionHandle, ...@@ -87,7 +142,7 @@ PGAPI_GetConnectAttr(HDBC ConnectionHandle,
case SQL_ATTR_CONNECTION_TIMEOUT: case SQL_ATTR_CONNECTION_TIMEOUT:
case SQL_ATTR_METADATA_ID: case SQL_ATTR_METADATA_ID:
conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER; conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
conn->errormsg = "Unsupported connection option (Set)"; conn->errormsg = "Unsupported connect attribute (Get)";
return SQL_ERROR; return SQL_ERROR;
} }
return PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value); return PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value);
...@@ -373,7 +428,7 @@ PGAPI_SetConnectAttr(HDBC ConnectionHandle, ...@@ -373,7 +428,7 @@ PGAPI_SetConnectAttr(HDBC ConnectionHandle,
case SQL_ATTR_CONNECTION_TIMEOUT: case SQL_ATTR_CONNECTION_TIMEOUT:
case SQL_ATTR_METADATA_ID: case SQL_ATTR_METADATA_ID:
conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER; conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
conn->errormsg = "Unsupported connection option (Set)"; conn->errormsg = "Unsupported connect attribute (Set)";
return SQL_ERROR; return SQL_ERROR;
} }
return PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value); return PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value);
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <string.h> #include <string.h>
#define PODBC_NOT_SEARCH_PATTERN 1L #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, RETCODE SQL_API PGAPI_AllocConnect(HENV EnvironmentHandle,
HDBC FAR * ConnectionHandle); HDBC FAR * ConnectionHandle);
...@@ -56,6 +58,20 @@ RETCODE SQL_API PGAPI_Error(HENV EnvironmentHandle, ...@@ -56,6 +58,20 @@ RETCODE SQL_API PGAPI_Error(HENV EnvironmentHandle,
SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLCHAR *MessageText, SQLSMALLINT BufferLength,
SQLSMALLINT *TextLength); 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, RETCODE SQL_API PGAPI_ExecDirect(HSTMT StatementHandle,
SQLCHAR *StatementText, SQLINTEGER TextLength); SQLCHAR *StatementText, SQLINTEGER TextLength);
RETCODE SQL_API PGAPI_Execute(HSTMT StatementHandle); RETCODE SQL_API PGAPI_Execute(HSTMT StatementHandle);
...@@ -225,7 +241,8 @@ RETCODE SQL_API PGAPI_TablePrivileges( ...@@ -225,7 +241,8 @@ RETCODE SQL_API PGAPI_TablePrivileges(
SQLCHAR *szSchemaName, SQLCHAR *szSchemaName,
SQLSMALLINT cbSchemaName, SQLSMALLINT cbSchemaName,
SQLCHAR *szTableName, SQLCHAR *szTableName,
SQLSMALLINT cbTableName); SQLSMALLINT cbTableName,
UWORD flag);
RETCODE SQL_API PGAPI_BindParameter( RETCODE SQL_API PGAPI_BindParameter(
HSTMT hstmt, HSTMT hstmt,
SQLUSMALLINT ipar, SQLUSMALLINT ipar,
...@@ -243,4 +260,25 @@ RETCODE SQL_API PGAPI_SetScrollOptions( ...@@ -243,4 +260,25 @@ RETCODE SQL_API PGAPI_SetScrollOptions(
SDWORD crowKeyset, SDWORD crowKeyset,
UWORD crowRowset); 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_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_SetDescField(SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
PTR Value, SQLINTEGER BufferLength);
#endif /* ODBCVER */
#endif /* define_PG_API_FUNC_H__ */ #endif /* define_PG_API_FUNC_H__ */
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Comments: See "notice.txt" for copyright and license information. * Comments: See "notice.txt" for copyright and license information.
* *
* $Id: psqlodbc.h,v 1.57 2002/02/18 03:16:11 inoue Exp $ * $Id: psqlodbc.h,v 1.58 2002/03/08 08:52:53 inoue Exp $
* *
*/ */
...@@ -87,7 +87,7 @@ typedef UInt4 Oid; ...@@ -87,7 +87,7 @@ typedef UInt4 Oid;
#define DBMS_NAME "PostgreSQL" #define DBMS_NAME "PostgreSQL"
#endif /* ODBCVER */ #endif /* ODBCVER */
#define POSTGRESDRIVERVERSION "07.01.0010" #define POSTGRESDRIVERVERSION "07.01.0011"
#ifdef WIN32 #ifdef WIN32
#if (ODBCVER >= 0x0300) #if (ODBCVER >= 0x0300)
...@@ -254,6 +254,11 @@ void logs_on_off(int cnopen, int, int); ...@@ -254,6 +254,11 @@ void logs_on_off(int cnopen, int, int);
#include "misc.h" #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(const char * utf8str, Int4 ilen, SQLWCHAR *ucs2str, UInt4 buflen);
#endif /* UNICODE_SUPPORT */
#ifdef _MEMORY_DEBUG_ #ifdef _MEMORY_DEBUG_
void *debug_alloc(size_t); void *debug_alloc(size_t);
void *debug_realloc(void *, size_t); void *debug_realloc(void *, size_t);
......
...@@ -138,7 +138,7 @@ BEGIN ...@@ -138,7 +138,7 @@ BEGIN
BS_NOTIFY | WS_TABSTOP,247,205,40,10 BS_NOTIFY | WS_TABSTOP,247,205,40,10
END END
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 161 DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 176
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced Options (DataSource)" CAPTION "Advanced Options (DataSource)"
FONT 10, "Terminal" FONT 10, "Terminal"
...@@ -151,23 +151,27 @@ BEGIN ...@@ -151,23 +151,27 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,45,28,88,10 BS_AUTOCHECKBOX | WS_TABSTOP,45,28,88,10
CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button", CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,149,28,86,10 BS_AUTOCHECKBOX | WS_TABSTOP,149,28,86,10
GROUPBOX "Protocol",IDC_STATIC,43,44,180,25 CONTROL "LF <-> CR/LF convert",DS_LFCONVERSION,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,45,43,92,10
CONTROL "True is -1",DS_TRUEISMINUS1,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,149,43,86,10
GROUPBOX "Protocol",IDC_STATIC,43,59,180,25
CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON |
WS_GROUP,53,54,47,10 WS_GROUP,53,69,47,10
CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
131,54,26,10 131,69,26,10
CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
187,54,26,10 187,69,26,10
GROUPBOX "OID Options",IDC_STATIC,43,74,180,25 GROUPBOX "OID Options",IDC_STATIC,43,89,180,25
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX | CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,53,85,59,10 WS_GROUP | WS_TABSTOP,53,100,59,10
CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX | CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,161,85,55,10 WS_GROUP | WS_TABSTOP,161,100,55,10
LTEXT "Connect &Settings:",IDC_STATIC,10,105,35,25 LTEXT "Connect &Settings:",IDC_STATIC,10,120,35,25
EDITTEXT DS_CONNSETTINGS,50,105,200,20,ES_MULTILINE | EDITTEXT DS_CONNSETTINGS,50,120,200,20,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,71,135,50,14,WS_GROUP DEFPUSHBUTTON "OK",IDOK,71,150,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,146,135,50,14 PUSHBUTTON "Cancel",IDCANCEL,146,150,50,14
END END
#else #else
DLG_CONFIG DIALOG DISCARDABLE 65, 43, 292, 116 DLG_CONFIG DIALOG DISCARDABLE 65, 43, 292, 116
...@@ -255,7 +259,7 @@ BEGIN ...@@ -255,7 +259,7 @@ BEGIN
BS_NOTIFY | WS_TABSTOP,233,224,40,10 BS_NOTIFY | WS_TABSTOP,233,224,40,10
END END
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 161 DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 176
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced Options (DataSource)" CAPTION "Advanced Options (DataSource)"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
...@@ -268,23 +272,27 @@ BEGIN ...@@ -268,23 +272,27 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,25,25,85,10 BS_AUTOCHECKBOX | WS_TABSTOP,25,25,85,10
CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button", CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,130,25,85,10 BS_AUTOCHECKBOX | WS_TABSTOP,130,25,85,10
GROUPBOX "Protocol",IDC_STATIC,15,40,180,25 CONTROL "LF <-> CR/LF convert",DS_LFCONVERSION,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,45,40,92,10
CONTROL "True is -1",DS_TRUEISMINUS1,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,149,40,86,10
GROUPBOX "Protocol",IDC_STATIC,15,55,180,25
CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,25, CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,25,
50,35,10 65,35,10
CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
75,50,26,10 75,65,26,10
CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP, CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
130,50,26,10 130,65,26,10
GROUPBOX "OID Options",IDC_STATIC,15,70,180,25 GROUPBOX "OID Options",IDC_STATIC,15,86,180,25
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX | CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,25,81,59,10 WS_GROUP | WS_TABSTOP,25,96,59,10
CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX | CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,115,81,51,10 WS_GROUP | WS_TABSTOP,115,96,51,10
RTEXT "Connect &Settings:",IDC_STATIC,10,105,35,25 RTEXT "Connect &Settings:",IDC_STATIC,10,120,35,25
EDITTEXT DS_CONNSETTINGS,50,105,200,20,ES_MULTILINE | EDITTEXT DS_CONNSETTINGS,50,120,200,20,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,71,135,50,14,WS_GROUP DEFPUSHBUTTON "OK",IDOK,71,150,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,146,135,50,14 PUSHBUTTON "Cancel",IDCANCEL,146,150,50,14
END END
#endif #endif
...@@ -354,8 +362,8 @@ END ...@@ -354,8 +362,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 7,1,0,10 FILEVERSION 7,1,0,11
PRODUCTVERSION 7,1,0,10 PRODUCTVERSION 7,1,0,11
FILEFLAGSMASK 0x3L FILEFLAGSMASK 0x3L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
...@@ -377,14 +385,14 @@ BEGIN ...@@ -377,14 +385,14 @@ BEGIN
VALUE "CompanyName", "Insight Distribution Systems\0" VALUE "CompanyName", "Insight Distribution Systems\0"
#endif #endif
VALUE "FileDescription", "PostgreSQL Driver\0" VALUE "FileDescription", "PostgreSQL Driver\0"
VALUE "FileVersion", " 07.01.0010\0" VALUE "FileVersion", " 07.01.0011\0"
VALUE "InternalName", "psqlodbc\0" VALUE "InternalName", "psqlodbc\0"
VALUE "LegalCopyright", "\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 "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 "OriginalFilename", "psqlodbc.dll\0"
VALUE "PrivateBuild", "\0" VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Microsoft Open Database Connectivity\0" VALUE "ProductName", "Microsoft Open Database Connectivity\0"
VALUE "ProductVersion", " 07.01.0010\0" VALUE "ProductVersion", " 07.01.0011\0"
VALUE "SpecialBuild", "\0" VALUE "SpecialBuild", "\0"
END END
END END
......
This diff is collapsed.
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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment