|
|
Choosing A Webhost: |
CVS update of odbsequoia (5 files): msg#00183db.carob.cvs
Date: Thursday, March 30, 2006 @ 21:23:52 Author: marc Path: /cvsroot/carob/odbsequoia Modified: odbcinst.ini (1.2 -> 1.3) src/connect.cpp (1.21 -> 1.22) src/env.cpp (1.10 -> 1.11) src/env.hpp (1.5 -> 1.6) src/inst.hpp (1.6 -> 1.7) Now letting empty ODBC.INI values go through carob (and fail with a more detailed error) Implemented FakeODBC2 in odbcinst.ini, fixes ODBSEQ-20 Documented cryptic SQLGetPrivateProfileString() in inst.hpp -----------------+ odbcinst.ini | 1 + src/connect.cpp | 33 +++++++++++++++++---------------- src/env.cpp | 24 +++++++++++++++++++++--- src/env.hpp | 4 +++- src/inst.hpp | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 20 deletions(-) Index: odbsequoia/odbcinst.ini diff -u odbsequoia/odbcinst.ini:1.2 odbsequoia/odbcinst.ini:1.3 --- odbsequoia/odbcinst.ini:1.2 Thu Mar 23 00:32:29 2006 +++ odbsequoia/odbcinst.ini Thu Mar 30 21:23:52 2006 @@ -4,3 +4,4 @@ Debug = 1 CommLog = 1 FileUsage = 1 +#FakeODBC2 = false (default = true) Index: odbsequoia/src/connect.cpp diff -u odbsequoia/src/connect.cpp:1.21 odbsequoia/src/connect.cpp:1.22 --- odbsequoia/src/connect.cpp:1.21 Thu Mar 30 18:53:31 2006 +++ odbsequoia/src/connect.cpp Thu Mar 30 21:23:52 2006 @@ -30,8 +30,6 @@ #include "StringCodecs.hpp" #include "Common.hpp" // setLogLevel() -#include <odbcinst.h> - #include <cstdlib> // for atoi() @@ -88,10 +86,6 @@ LPCSTR cdsn = narrow_dsn.c_str(); #endif - // The trick: providing a zero-length default value is like - // providing NO default value. Now we can throw an SQL_ERROR - // when we require the user to provide a value. - // TODO: call SQLInstallerError() to throw better diags // BTW how could we fail when providing a default value? @@ -99,36 +93,43 @@ // Slurp DSN information from odbc.ini into ConnectionParameters + // Behaviour of SQLGetPrivateProfileString is complex and weird, + // check comments in inst.hpp + + // For most keys, if the user sets an empty string then zero is + // returned and we let carob connection fail later on. We should + // be stricter and throw a good diag. + /* Server host name/IP address */ - if (0 >= SQLGetPrivateProfileString(cdsn, SERVER_INI, "localhost", + if (0 > SQLGetPrivateProfileString(cdsn, SERVER_INI, "localhost", temp, MAX_VALUE_LEN, ODBC_INI)) - return SQL_ERROR; // TODO: diags. On the other hand it can hardly fail. + return SQL_ERROR; std::wstring serverhost = fromString(std::string(temp)); /* Port number */ - if (0 >= SQLGetPrivateProfileString(cdsn, PORT_INI, "25322", + if (0 > SQLGetPrivateProfileString(cdsn, PORT_INI, "25322", temp, MAX_VALUE_LEN, ODBC_INI)) - return SQL_ERROR; // TODO: diags. On the other hand it can hardly fail. + return SQL_ERROR; in_port_t port = atoi(temp); - /* Virtual Database name (mandatory, no default) */ + /* Virtual Database name (mandatory, be stricter here) */ if (0 >= SQLGetPrivateProfileString(cdsn, DATABASE_INI, "", temp, MAX_VALUE_LEN, ODBC_INI)) throw ODBSeqException(L"08001", L"'" WIDENMACRO(DATABASE_INI) L"'" - L" parameter not found in .ini file"); + L" key not found or empty in " WIDENMACRO(ODBC_INI) L" file"); std::wstring vdbname = fromString(std::string(temp)); /* Prefix for diagnostics/exceptions/warnings coming from the backend */ - if (0 >= SQLGetPrivateProfileString(cdsn, BACKEND_IDS_INI, DEFAULT_BACKEND_IDS_INI, + if (0 > SQLGetPrivateProfileString(cdsn, BACKEND_IDS_INI, DEFAULT_BACKEND_IDS_INI, temp, MAX_VALUE_LEN, ODBC_INI)) return SQL_ERROR; // TODO: diags. On the other hand it can hardly fail. this->backend_diagids = fromString(std::string(temp)); - /* Log level (mainly for carob) */ - if (0 >= SQLGetPrivateProfileString(cdsn, LOG_LEVEL_INI, "DEFAULTLOGLEVEL", + /* Log level (mainly for carob) TODO: move this to inst.ini/Env ctor */ + if (0 > SQLGetPrivateProfileString(cdsn, LOG_LEVEL_INI, "DEFAULTCAROBLOGLEVEL", temp, MAX_VALUE_LEN, ODBC_INI)) return SQL_ERROR; // TODO: diags. On the other hand it can hardly fail. - if (0 != std::string(temp).compare("DEFAULTLOGLEVEL")) + if (0 != std::string(temp).compare("DEFAULTCAROBLOGLEVEL")) try { setLogLevel(StringLogLevel(temp)); } catch (const std::string& errmsg) { // unknown log level! Index: odbsequoia/src/env.cpp diff -u odbsequoia/src/env.cpp:1.10 odbsequoia/src/env.cpp:1.11 --- odbsequoia/src/env.cpp:1.10 Thu Mar 30 18:53:31 2006 +++ odbsequoia/src/env.cpp Thu Mar 30 21:23:52 2006 @@ -23,6 +23,7 @@ #include "connect.hpp" #include "odbc_exception.hpp" +#include "inst.hpp" #include "Common.hpp" // for the logger @@ -34,6 +35,26 @@ using namespace ODBSeqNS; +ODBCEnv::ODBCEnv() : ODBCItem(*this) // I have no father +{ +#define MAX_VALUE_LEN 30 + char temp[MAX_VALUE_LEN]; + + /* Fake ODBC version 2 */ + if (0 > SQLGetPrivateProfileString(MYDRIVER_NAME_INST_INI, FAKEODBC2_INST_INI, "true", + temp, MAX_VALUE_LEN, ODBCINST_INI)) + // FIXME: catch above & return diags + // Problem: how to return diags without any object? + // But how could this fail anyway? + throw ODBSeqException(L"TODO", + L"Invalid " WIDENMACRO(FAKEODBC2_INST_INI) L" value"); + + if (0 == std::string(temp).compare("false")) + fake_version2 = false; + else + fake_version2 = true; +} + namespace { const std::wstring SETENVATTR_FUNC = L"env.cpp:SQLSetEnvAttr"; } @@ -69,9 +90,6 @@ std::wstring func_witharg(SETENVATTR_FUNC + L"(ODBC_VERSION, 2, )"); - // TODO: move this constant to odbc.ini - bool fake_version2 = true; - if (!fake_version2) { std::wstring msg(L"faking ODBC version 2 is disabled"); CarobNS::logFatal(func_witharg, msg); Index: odbsequoia/src/env.hpp diff -u odbsequoia/src/env.hpp:1.5 odbsequoia/src/env.hpp:1.6 --- odbsequoia/src/env.hpp:1.5 Thu Mar 30 18:42:58 2006 +++ odbsequoia/src/env.hpp Thu Mar 30 21:23:52 2006 @@ -35,12 +35,14 @@ class ODBCEnv : public ODBCItem { public: - ODBCEnv() : ODBCItem(*this) { }; // I have no father + ODBCEnv(); SQLRETURN ODBCEnv::AllocConnect(SQLHANDLE * OutputHandle); SQLRETURN ODBCEnv::set_env_attr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER str_len); + + bool fake_version2; }; } Index: odbsequoia/src/inst.hpp diff -u odbsequoia/src/inst.hpp:1.6 odbsequoia/src/inst.hpp:1.7 --- odbsequoia/src/inst.hpp:1.6 Thu Mar 30 17:23:53 2006 +++ odbsequoia/src/inst.hpp Thu Mar 30 21:23:52 2006 @@ -22,6 +22,10 @@ #ifndef ODBSEQ_INST #define ODBSEQ_INST + +#include <odbcinst.h> + + /* ODBC initialization files */ #ifndef WIN32 #define ODBC_INI "odbc.ini" @@ -31,7 +35,42 @@ #define ODBCINST_INI "ODBCINST.INI" #endif +#define MYDRIVER_NAME_INST_INI "Sequoia" + + +// unixODBC 2.2 SQLGetPrivateProfileString() tips: + +// - in ODBCINST.INI - + +// Here SQLGetPrivateProfileString(INST) returns strlen(value) + 1, +// INCLUDING the terminating null, whatever the lpszDefault +// arg. Corner cases: + +// < 0 on error (?) +// 0 when key is missing (and lpszDefault is set) +// 1 when value is missing (= empty string + terminating null) + +// The default value is set only when 0 is returned (so the user can +// explicitely set an empty value if wanted). + +// - in ODBC.INI - + +// For more fun, the behaviour now differs: it returns strlen(value), +// EXCLUDING the terminating null. And it returns strlen(lpszDefault) +// when the key is missing. So it's now absolutely impossible to make +// the difference between a value explicity set in the file and the +// case missing key && lpszDefault set. Empty string value is still not +// an issue. + + +// These key names are not case-sensitive with unixODBC 2.2. +// However the associated values are returned case-untouched. +// Others DMs? + +// ODBINST.INI constants +#define FAKEODBC2_INST_INI "FakeODBC2" +// ODBC.INI constants #define SERVER_INI "Servername" #define DATABASE_INI "Database" #define USERNAME_INI "UserName"
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | CVS update of odbsequoia/src (4 files), marc-Tt5JLJuBijYiZlD9aYmxOGD2FQJk+8+b |
|---|---|
| Next by Date: | CVS update of odbsequoia/src (env.cpp env.hpp explicit_type.cpp), marc-Tt5JLJuBijYiZlD9aYmxOGD2FQJk+8+b |
| Previous by Thread: | CVS update of odbsequoia/src (4 files), marc-Tt5JLJuBijYiZlD9aYmxOGD2FQJk+8+b |
| Next by Thread: | CVS update of odbsequoia/src (env.cpp env.hpp explicit_type.cpp), marc-Tt5JLJuBijYiZlD9aYmxOGD2FQJk+8+b |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
Free MagazinesCisco NewsReceive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business. subscribe Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field. subscribe The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business. subscribe Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company. subscribe Total Telecom Total Telecom is "The Economist of the communications industry". subscribe |
Home
| advertise | OSDir is
an inevitable website.
|