psqlodbc.git / summary / log / commit / refs
commit 64501e33ea195500748fb967939cd4e76da8d8f3
Author: Hiroshi Inoue <inoue@tpf.co.jp>
Date: Thu Aug 27 15:03:34 2009 +0000
Changes for 8.4.0101.
1.Fix a column uodatability problem reported by Tom Goodman.
2.Display SSL mode list properly on setup dialog.
3.Don't truncate the result of msgtowstr()/wstrtomsg().
4.Implement ConfigDriver() function.
convert.c | 20 ++++++++++++---
dlg_wingui.c | 13 +++++++---
parse.c | 12 +++++----
psqlodbc.def | 1 +
psqlodbca.def | 1 +
results.c | 19 ++++++++------
setup.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
statement.c | 2 +-
statement.h | 9 ++++---
version.h | 8 +++---
win_unicode.c | 4 +--
11 files changed, 138 insertions(+), 31 deletions(-)
diff --git a/convert.c b/convert.c
index 9cf522c..fbb97d7 100644
--- a/convert.c
+++ b/convert.c
@@ -2004,7 +2004,7 @@ do { \
/*----------
* Append a binary data.
- * Newly reqeuired size may be overestimated currently.
+ * Newly required size may be overestimated currently.
*----------
*/
#define CVT_APPEND_BINARY(qb, buf, used) \
@@ -2538,7 +2538,7 @@ inolog("%s: enter prepared=%d\n", func, stmt->prepared);
{
if (SC_update_not_ready(stmt))
parse_statement(stmt, TRUE);
- if (stmt->updatable &&
+ if (SC_is_updatable(stmt) &&
stmt->ntab > 0)
{
if (bestitem = GET_NAME(stmt->ti[0]->bestitem), NULL == bestitem)
@@ -4916,7 +4916,7 @@ convert_from_pgbinary(const UCHAR *value, UCHAR *rgbValue, SQLLEN cbValueMax)
size_t i,
ilen = strlen(value);
size_t o = 0;
-
+ BOOL hexmode = FALSE;
for (i = 0; i < ilen;)
{
@@ -4928,6 +4928,11 @@ convert_from_pgbinary(const UCHAR *value, UCHAR *rgbValue, SQLLEN cbValueMax)
rgbValue[o] = value[i];
i += 2;
}
+ else if (value[i + 1] == 'x')
+ {
+ hexmode = TRUE;
+ i += 2;
+ }
else
{
if (rgbValue)
@@ -4935,6 +4940,13 @@ convert_from_pgbinary(const UCHAR *value, UCHAR *rgbValue, SQLLEN cbValueMax)
i += 4;
}
}
+ else if (hexmode)
+ {
+ if (rgbValue)
+ pg_hex2bin(value + i, rgbValue, ilen - 2);
+ o = (ilen - 2) / 2;
+ break;
+ }
else
{
if (rgbValue)
@@ -5007,7 +5019,7 @@ convert_to_pgbinary(const UCHAR *in, char *out, size_t len, QueryBuild *qb)
for (i = 0; i < len; i++)
{
inc = in[i];
- mylog("%s: in[%d] = %d, %c\n", func, i, inc, inc);
+ inolog("%s: in[%d] = %d, %c\n", func, i, inc, inc);
if (inc < 128 && (isalnum(inc) || inc == ' '))
out[o++] = inc;
else
diff --git a/dlg_wingui.c b/dlg_wingui.c
index b0f2464..6405ab5 100644
--- a/dlg_wingui.c
+++ b/dlg_wingui.c
@@ -70,16 +70,21 @@ SetDlgStuff(HWND hdlg, const ConnInfo *ci)
libpq_exist = SSLLIB_check();
mylog("libpq_exist=%d\n", libpq_exist);
if (libpq_exist)
- ShowWindow(GetDlgItem(hdlg, IDC_NOTICE_USER), SW_HIDE);
- else
{
-mylog("SendMessage CTL_COLOR\n");
- SendMessage(GetDlgItem(hdlg, IDC_NOTICE_USER), WM_CTLCOLOR, 0, 0);
+ ShowWindow(GetDlgItem(hdlg, IDC_NOTICE_USER), SW_HIDE);
if (ssl_verify_available())
dsplevel = 2;
else
dsplevel = 1;
}
+ else
+ {
+mylog("SendMessage CTL_COLOR\n");
+ SendMessage(GetDlgItem(hdlg, IDC_NOTICE_USER), WM_CTLCOLOR, 0, 0);
+#ifdef USE_SSPI
+ dsplevel = 1;
+#endif /* USE_SSPI */
+ }
selidx = -1;
for (i = 0; i < sizeof(modetab) / sizeof(modetab[0]); i++)
diff --git a/parse.c b/parse.c
index 40a560c..a1bc3e5 100644
--- a/parse.c
+++ b/parse.c
@@ -485,7 +485,7 @@ void SC_initialize_cols_info(StatementClass *stmt, BOOL DCdestroy, BOOL parseRes
if (parseReset)
{
stmt->parse_status = STMT_PARSE_NONE;
- stmt->updatable = FALSE;
+ SC_reset_updatable(stmt);
}
}
@@ -637,6 +637,8 @@ mylog("updatable=%d tab=%d fields=%d", updatable, stmt->ntab, num_fields);
updatable = FALSE;
}
mylog("->%d\n", updatable);
+ if (stmt->updatable < 0)
+ SC_set_updatable(stmt, updatable);
for (i = 0; i < num_fields; i++)
{
if (reloid == (OID) QR_get_relid(res, i))
@@ -1018,7 +1020,7 @@ inolog("fi=%p greloid=%d col_info=%p\n", wti, greloid, wti->col_info);
{
SC_set_parse_status(stmt, STMT_PARSE_FATAL);
SC_set_error(stmt, STMT_EXEC_ERROR, "Table not found", func);
- stmt->updatable = FALSE;
+ SC_reset_updatable(stmt);
}
return FALSE;
}
@@ -1260,7 +1262,7 @@ parse_the_statement(StatementClass *stmt, BOOL check_hasoids, BOOL sqlsvr_check)
}
else
{
- stmt->updatable = FALSE;
+ SC_set_updatable(stmt, FALSE);
irdflds = SC_get_IRDF(stmt);
fi = irdflds->fi;
ti = stmt->ti;
@@ -1879,7 +1881,7 @@ mylog("blevel=%d btoken=%s in_dot=%d in_field=%d tbname=%s\n", blevel, btoken, i
{
SC_set_parse_status(stmt, STMT_PARSE_FATAL);
SC_set_error(stmt, STMT_EXEC_ERROR, "duplicated Table name", func);
- stmt->updatable = FALSE;
+ SC_reset_updatable(stmt);
goto cleanup;
}
}
@@ -2124,7 +2126,7 @@ mylog("blevel=%d btoken=%s in_dot=%d in_field=%d tbname=%s\n", blevel, btoken, i
wfi->flag |= FIELD_PARSED_OK;
}
- stmt->updatable = updatable;
+ SC_set_updatable(stmt, updatable);
cleanup:
#undef return
if (!sqlsvr_check && STMT_PARSE_FATAL == SC_parsed_status(stmt))
diff --git a/psqlodbc.def b/psqlodbc.def
index 99b090d..093c403 100644
--- a/psqlodbc.def
+++ b/psqlodbc.def
@@ -77,6 +77,7 @@ SQLDummyOrdinal @199
dconn_FDriverConnectProc @200
DllMain @201
ConfigDSN @202
+ConfigDriver @203
SQLColAttributeW @101
SQLColumnPrivilegesW @102
diff --git a/psqlodbca.def b/psqlodbca.def
index 327c4ed..6880cdf 100644
--- a/psqlodbca.def
+++ b/psqlodbca.def
@@ -80,6 +80,7 @@ SQLDummyOrdinal @199
dconn_FDriverConnectProc @200
DllMain @201
ConfigDSN @202
+ConfigDriver @203
forcelog
mylog
diff --git a/results.c b/results.c
index 8a67008..56865c9 100644
--- a/results.c
+++ b/results.c
@@ -476,7 +476,11 @@ PGAPI_ColAttributes(
SC_log_error(func, NULL_STRING, NULL);
return SQL_INVALID_HANDLE;
}
- stmt_updatable = stmt->updatable && stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY;
+ stmt_updatable = SC_is_updatable(stmt)
+ /* The folllowing doesn't seem appropriate for client side cursors
+ && stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY
+ */
+ ;
if (pcbDesc)
*pcbDesc = 0;
@@ -1109,6 +1113,7 @@ cleanup:
#undef return
if (stmt->internal)
result = DiscardStatementSvp(stmt, result, FALSE);
+inolog("%s returning %d\n", __FUNCTION__, result);
return result;
}
@@ -2978,7 +2983,7 @@ SC_pos_reload_with_tid(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count,
if (SC_update_not_ready(stmt))
parse_statement(stmt, TRUE); /* not preferable */
- if (!stmt->updatable)
+ if (!SC_is_updatable(stmt))
{
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func);
@@ -3267,7 +3272,7 @@ SC_pos_reload_needed(StatementClass *stmt, SQLULEN req_size, UDWORD flag)
}
if (SC_update_not_ready(stmt))
parse_statement(stmt, TRUE); /* not preferable */
- if (!stmt->updatable)
+ if (!SC_is_updatable(stmt))
{
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func);
@@ -3350,7 +3355,7 @@ SC_pos_newload(StatementClass *stmt, const UInt4 *oidint, BOOL tidRef, const cha
}
if (SC_update_not_ready(stmt))
parse_statement(stmt, TRUE); /* not preferable */
- if (!stmt->updatable)
+ if (!SC_is_updatable(stmt))
{
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func);
@@ -3604,7 +3609,7 @@ SC_pos_update(StatementClass *stmt,
mylog("POS UPDATE %d+%d fi=%p ti=%p\n", s.irow, QR_get_rowstart_in_cache(s.res), fi, s.stmt->ti);
if (SC_update_not_ready(stmt))
parse_statement(s.stmt, TRUE); /* not preferable */
- if (!s.stmt->updatable)
+ if (!SC_is_updatable(s.stmt))
{
s.stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
SC_set_error(s.stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func);
@@ -3763,7 +3768,7 @@ SC_pos_delete(StatementClass *stmt,
}
if (SC_update_not_ready(stmt))
parse_statement(stmt, TRUE); /* not preferable */
- if (!stmt->updatable)
+ if (!SC_is_updatable(stmt))
{
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func);
@@ -4051,7 +4056,7 @@ SC_pos_add(StatementClass *stmt,
}
if (SC_update_not_ready(stmt))
parse_statement(s.stmt, TRUE); /* not preferable */
- if (!s.stmt->updatable)
+ if (!SC_is_updatable(s.stmt))
{
s.stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
SC_set_error(s.stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func);
diff --git a/setup.c b/setup.c
index 1e08b0d..618b5be 100644
--- a/setup.c
+++ b/setup.c
@@ -7,7 +7,7 @@
*
* Classes: n/a
*
- * API functions: ConfigDSN
+ * API functions: ConfigDSN, ConfigDriver
*
* Comments: See "notice.txt" for copyright and license information.
*-------
@@ -123,6 +123,44 @@ ConfigDSN(HWND hwnd,
return fSuccess;
}
+/*--------
+ * ConfigDriver
+ *
+ * Description: ODBC Setup entry point
+ * This entry point is called by the ODBC Installer
+ * (see file header for more details)
+ * Arguments : hwnd ----------- Parent window handle
+ * fRequest ------- Request type (i.e., add, config, or remove)
+ * lpszDriver ----- Driver name
+ * lpszArgs ------- A null-terminated string containing
+ arguments for a driver specific fRequest
+ * lpszMsg -------- A null-terimated string containing
+ an output message from the driver setup
+ * cnMsgMax ------- Length of lpszMSg
+ * pcbMsgOut ------ Total number of bytes available to
+ return in lpszMsg
+ * Returns : TRUE success, FALSE otherwise
+ *--------
+ */
+static BOOL SetDriverAttributes(LPCSTR lpszDriver);
+BOOL CALLBACK
+ConfigDriver(HWND hwnd,
+ WORD fRequest,
+ LPCSTR lpszDriver,
+ LPCSTR lpszArgs,
+ LPSTR lpszMsg,
+ WORD cbMsgMax,
+ WORD *pcbMsgOut)
+{
+ BOOL fSuccess = TRUE; /* Success/fail flag */
+
+ /* Add the driver */
+ if (ODBC_INSTALL_DRIVER == fRequest)
+ fSuccess = SetDriverAttributes(lpszDriver);
+
+ return fSuccess;
+}
+
/*-------
* CenterDialog
@@ -512,6 +550,46 @@ SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg, DWORD *errcode)
return TRUE;
}
+/*--------
+ * SetDriverAttributes
+ *
+ * Description: Write driver information attributes to ODBCINST.INI
+ * Input : lpszDriver - The driver name
+ * Output : TRUE if successful, FALSE otherwise
+ *--------
+ */
+static BOOL
+SetDriverAttributes(LPCSTR lpszDriver)
+{
+ BOOL ret = FALSE;
+
+ /* Validate arguments */
+ if (!lpszDriver || !lpszDriver[0])
+ return FALSE;
+
+ if (!SQLWritePrivateProfileString(lpszDriver, "APILevel", "1", ODBCINST_INI))
+ goto cleanup;
+ if (!SQLWritePrivateProfileString(lpszDriver, "ConnectFunctions", "YYN", ODBCINST_INI))
+ goto cleanup;
+ if (!SQLWritePrivateProfileString(lpszDriver, "DriverODBCVer",
+#ifdef UNICODE_SUPPORT
+ "03.51",
+#else
+ "03.00",
+#endif
+ ODBCINST_INI))
+ goto cleanup;
+ if (!SQLWritePrivateProfileString(lpszDriver, "FileUsage", "0", ODBCINST_INI))
+ goto cleanup;
+ if (!SQLWritePrivateProfileString(lpszDriver, "SQLLevel", "1", ODBCINST_INI))
+ goto cleanup;
+
+ ret = TRUE;
+cleanup:
+
+ return ret;
+}
+
#ifdef WIN32
diff --git a/statement.c b/statement.c
index 49e42e6..975a81e 100644
--- a/statement.c
+++ b/statement.c
@@ -428,7 +428,7 @@ SC_Constructor(ConnectionClass *conn)
rv->inaccurate_result = FALSE;
rv->miscinfo = 0;
rv->rbonerr = 0;
- rv->updatable = FALSE;
+ SC_reset_updatable(rv);
rv->diag_row_count = 0;
rv->stmt_time = 0;
rv->execute_delegate = NULL;
diff --git a/statement.h b/statement.h
index a9c4127..776cef9 100644
--- a/statement.h
+++ b/statement.h
@@ -255,11 +255,11 @@ struct StatementClass_
SQLLEN exec_end_row;
SQLLEN exec_current_row;
- char pre_executing; /* This statement is prematurely executing */
- char inaccurate_result; /* Current status is PREMATURE but
+ po_ind_t pre_executing; /* This statement is prematurely executing */
+ po_ind_t inaccurate_result; /* Current status is PREMATURE but
* result is inaccurate */
unsigned char miscinfo;
- char updatable;
+ po_ind_t updatable;
SQLLEN diag_row_count;
char *load_statement; /* to (re)load updatable individual rows */
char *execute_statement; /* to execute the prepared plans */
@@ -327,6 +327,9 @@ do { \
#define SC_checked_hasoids(a) (0 != (a->parse_status & STMT_PARSED_OIDS))
#define SC_set_delegate(p, c) (p->execute_delegate = c, c->execute_parent = p)
+#define SC_is_updatable(s) (0 < ((s)->updatable))
+#define SC_reset_updatable(s) ((s)->updatable = -1)
+#define SC_set_updatable(s, b) ((s)->updatable = (b))
#define SC_clear_parse_method(s) ((s)->parse_method = 0)
#define SC_is_parse_forced(s) (0 != ((s)->parse_method & 1L))
#define SC_set_parse_forced(s) ((s)->parse_method |= 1L)
diff --git a/version.h b/version.h
index 57b99d9..1c63e04 100644
--- a/version.h
+++ b/version.h
@@ -9,9 +9,9 @@
#ifndef __VERSION_H__
#define __VERSION_H__
-#define POSTGRESDRIVERVERSION "08.04.0100"
-#define POSTGRES_RESOURCE_VERSION "08.04.0100\0"
-#define PG_DRVFILE_VERSION 8,4,01,00
-#define PG_BUILD_VERSION "200907060001"
+#define POSTGRESDRIVERVERSION "08.04.0101"
+#define POSTGRES_RESOURCE_VERSION "08.04.0101\0"
+#define PG_DRVFILE_VERSION 8,4,01,01
+#define PG_BUILD_VERSION "200908270001"
#endif
diff --git a/win_unicode.c b/win_unicode.c
index f992fd8..21cf6f9 100644
--- a/win_unicode.c
+++ b/win_unicode.c
@@ -321,7 +321,7 @@ int msgtowstr(const char *enc, const char *inmsg, int inlen, LPWSTR outmsg, int
wlen = MultiByteToWideChar(cp, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
inmsg, inlen, outmsg, buflen);
mylog(" out=%dchars\n", wlen);
- outlen = (SQLSMALLINT) wlen;
+ outlen = wlen;
#else
#ifdef HAVE_MBSTOWCS_L
outlen = 0;
@@ -344,7 +344,7 @@ int wstrtomsg(const char *enc, const LPWSTR wstr, int wstrlen, char * outmsg, in
if (NULL != enc && 0 != atoi(enc))
cp = atoi(enc);
len = WideCharToMultiByte(cp, 0, wstr, (int) wstrlen, outmsg, buflen, NULL, NULL);
- outlen = (SQLSMALLINT) len;
+ outlen = len;
#else
#ifdef HAVE_MBSTOWCS_L
outlen = 0;
[parent: 14d6724ebc69]