Commit ba3f4a2c authored by Olivier Bertrand's avatar Olivier Bertrand

- Add new features to ODBC table type

  Srcdef definition
  Execute command tables
  uncomplete connect string

modified:
  storage/connect/ha_connect.cc
  storage/connect/odbccat.h
  storage/connect/odbconn.cpp
  storage/connect/odbconn.h
  storage/connect/plgdbsem.h
  storage/connect/plgdbutl.cpp
  storage/connect/tabodbc.cpp
parent c0907d57
......@@ -3616,6 +3616,7 @@ static int init_table_share(THD *thd,
static int init_table_share(THD* thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *create_info,
// char *dsn,
String *sql)
{
bool oom= false;
......@@ -3674,10 +3675,12 @@ static int init_table_share(THD* thd,
} // endfor opt
if (create_info->connect_string.length) {
//if (dsn) {
oom|= sql->append(' ');
oom|= sql->append("CONNECTION='");
oom|= sql->append_for_single_quote(create_info->connect_string.str,
create_info->connect_string.length);
// oom|= sql->append_for_single_quote(dsn, strlen(dsn));
oom|= sql->append('\'');
if (oom)
......@@ -3737,13 +3740,13 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
{
char spc= ',', qch= 0;
const char *fncn= "?";
const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src;
const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src, *cnp;
const char *col, *ocl, *rnk, *pic, *fcl;
char *tab, *dsn;
#if defined(WIN32)
char *nsp= NULL, *cls= NULL;
#endif // WIN32
int port= 0, hdr= 0, mxr= 0, rc= 0;
int port= 0, hdr= 0, mxr= 0, rc= 0, cop= 0;
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool bif, ok= false, dbf= false;
TABTYPE ttp= TAB_UNDEF;
......@@ -3764,7 +3767,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (!g)
return HA_ERR_INTERNAL_ERROR;
user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= dsn= NULL;
user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= cnp= dsn= NULL;
// Get the useful create options
ttp= GetTypeID(topt->type);
......@@ -3782,23 +3785,25 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
col= topt->colist;
if (topt->oplist) {
host= GetListOption(g,"host", topt->oplist, "localhost");
user= GetListOption(g,"user", topt->oplist, "root");
host= GetListOption(g, "host", topt->oplist, "localhost");
user= GetListOption(g, "user", topt->oplist, "root");
// Default value db can come from the DBNAME=xxx option.
db= GetListOption(g,"database", topt->oplist, db);
col= GetListOption(g,"colist", topt->oplist, col);
ocl= GetListOption(g,"occurcol", topt->oplist, NULL);
pic= GetListOption(g,"pivotcol", topt->oplist, NULL);
fcl= GetListOption(g,"fnccol", topt->oplist, NULL);
rnk= GetListOption(g,"rankcol", topt->oplist, NULL);
pwd= GetListOption(g,"password", topt->oplist);
prt= GetListOption(g,"port", topt->oplist);
db= GetListOption(g, "database", topt->oplist, db);
col= GetListOption(g, "colist", topt->oplist, col);
ocl= GetListOption(g, "occurcol", topt->oplist, NULL);
pic= GetListOption(g, "pivotcol", topt->oplist, NULL);
fcl= GetListOption(g, "fnccol", topt->oplist, NULL);
rnk= GetListOption(g, "rankcol", topt->oplist, NULL);
pwd= GetListOption(g, "password", topt->oplist);
prt= GetListOption(g, "port", topt->oplist);
port= (prt) ? atoi(prt) : 0;
#if defined(WIN32)
nsp= GetListOption(g,"namespace", topt->oplist);
cls= GetListOption(g,"class", topt->oplist);
nsp= GetListOption(g, "namespace", topt->oplist);
cls= GetListOption(g, "class", topt->oplist);
#endif // WIN32
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
cnp= GetListOption(g, "createopt", topt->oplist);
cop= (cnp) ? atoi(cnp) : 0;
} else {
host= "localhost";
user= "root";
......@@ -3854,8 +3859,20 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
switch (ttp) {
#if defined(ODBC_SUPPORT)
case TAB_ODBC:
if (!(dsn= create_info->connect_string.str)
&& !(fnc & (FNC_DSN | FNC_DRIVER)))
dsn= create_info->connect_string.str;
if (fnc & (FNC_DSN | FNC_DRIVER))
ok= true;
else if (!stricmp(thd->main_security_ctx.host, "localhost")
&& cop != 2) {
if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
create_info->connect_string.str= dsn;
create_info->connect_string.length= strlen(dsn);
ok= true;
} // endif dsn
} else if (!dsn)
sprintf(g->Message, "Missing %s connection string", topt->type);
else
ok= true;
......@@ -4139,6 +4156,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
#else // !NEW_WAY
if (!rc)
rc= init_table_share(thd, table_s, create_info, &sql);
// rc= init_table_share(thd, table_s, create_info, dsn, &sql);
#endif // !NEW_WAY
return rc;
......
/***********************************************************************/
/* ODBC catalog function prototypes. */
/***********************************************************************/
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
PQRYRES ODBCDataSources(PGLOBAL g, bool info);
PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
char *colpat, bool info);
......
......@@ -13,6 +13,7 @@
#if defined(WIN32)
//nclude <io.h>
//nclude <fcntl.h>
#include <direct.h> // for getcwd
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif
......@@ -172,10 +173,36 @@ int TranslateSQLType(int stp, int prec, int& len)
} // end of TranslateSQLType
/***********************************************************************/
/* ODBConn static members initialization. */
/* ODBCCheckConnection: Check completeness of connection string. */
/***********************************************************************/
//HENV ODBConn::m_henv = SQL_NULL_HENV;
//int ODBConn::m_nAlloc = 0; // per-Appl reference to HENV above
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop)
{
char *newdsn, dir[_MAX_PATH], buf[_MAX_PATH];
int rc;
DWORD options = ODBConn::openReadOnly;
ODBConn *ocp = new(g) ODBConn(g, NULL);
(void) getcwd(dir, sizeof(dir) - 1);
switch (cop) {
case 1: options |= ODBConn::forceOdbcDialog; break;
case 2: options |= ODBConn::noOdbcDialog; break;
} // endswitch cop
if (ocp->Open(dsn, options) < 1)
newdsn = NULL;
else
newdsn = ocp->GetConnect();
(void) getcwd(buf, sizeof(buf) - 1);
// Some data sources change the current directory
if (strcmp(dir, buf))
rc = chdir(dir);
ocp->Close();
return newdsn; // Return complete connection string
} // end of ODBCCheckConnection
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
......@@ -254,7 +281,7 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
if (!info) {
ocp = new(g) ODBConn(g, NULL);
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
if (ocp->Open(dsn, 10) < 1) // openReadOnly + noODBCdialog
return NULL;
// We fix a MySQL limit because some data sources return 32767
......@@ -1662,7 +1689,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
RETCODE rc;
HSTMT hstmt;
if (Open(dsn, 2) < 1) // 2 is openReadOnly
if (Open(dsn, 10) < 1) // openReadOnly + noOdbcDialog
return NULL;
try {
......
......@@ -115,7 +115,7 @@ class ODBConn : public BLOCK {
public:
ODBConn(PGLOBAL g, TDBODBC *tdbp);
enum DOP { // Db Open oPtions
static enum DOP { // Db Open oPtions
traceSQL = 0x0001, // Trace SQL calls
openReadOnly = 0x0002, // Open database read only
useCursorLib = 0x0004, // Use ODBC cursor lib
......
......@@ -583,5 +583,6 @@ FILE *global_fopen(GLOBAL *g, int msgid, const char *path, const char *mode);
int global_open(GLOBAL *g, int msgid, const char *filename, int flags);
int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode);
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
char *MakeEscape(PGLOBAL g, char* str, char q);
bool PushWarning(PGLOBAL, PTDBASE);
......@@ -731,6 +731,34 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
return (b);
} /* end of EvalLikePattern */
/***********************************************************************/
/* MakeEscape: Escape some characters in a string. */
/***********************************************************************/
char *MakeEscape(PGLOBAL g, char* str, char q)
{
char *bufp;
int i, k, n = 0, len = (int)strlen(str);
for (i = 0; i < len; i++)
if (str[i] == q || str[i] == '\\')
n++;
if (!n)
return str;
else
bufp = (char*)PlugSubAlloc(g, NULL, len + n + 1);
for (i = k = 0; i < len; i++) {
if (str[i] == q || str[i] == '\\')
bufp[k++] = '\\';
bufp[k++] = str[i];
} // endfor i
bufp[k] = 0;
return bufp;
} /* end of MakeEscape */
/***********************************************************************/
/* PlugConvertConstant: convert a Plug constant to an Xobject. */
/***********************************************************************/
......
......@@ -100,8 +100,6 @@ ODBCDEF::ODBCDEF(void)
/***********************************************************************/
bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
int dop = ODBConn::noOdbcDialog; // Default for options
Desc = Connect = Cat->GetStringCatInfo(g, "Connect", "");
Tabname = Cat->GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
......@@ -111,8 +109,8 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
Catver = Cat->GetIntCatInfo("Catver", 2);
Options = Cat->GetIntCatInfo("Options", dop);
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Options = ODBConn::noOdbcDialog;
Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
......@@ -534,8 +532,12 @@ void TDBODBC::ResetSize(void)
int TDBODBC::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
// Make MariaDB happy
MaxSize = 100;
#if 0
// This is unuseful and takes time
if (Srcdef) {
// Give a reasonable guess
// Return a reasonable guess
MaxSize = 100;
return MaxSize;
} // endif Srcdef
......@@ -558,7 +560,7 @@ int TDBODBC::GetMaxSize(PGLOBAL g)
if ((MaxSize = Ocp->GetResultSize(Count, Cnp)) < 0)
return -3;
#endif // 0
} // endif MaxSize
return MaxSize;
......
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