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]