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