summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-10-26 00:43:03 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2013-10-26 00:43:03 +0200
commitba3f4a2cc9ec5337f7677def0a1366cbb7332922 (patch)
treec125f165a39d3c283e6a0dba698b12cb4b64886f /storage/connect
parentc0907d57b1493e75ac16d8b24cb91a644f078750 (diff)
downloadmariadb-git-ba3f4a2cc9ec5337f7677def0a1366cbb7332922.tar.gz
- 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
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/ha_connect.cc52
-rw-r--r--storage/connect/odbccat.h1
-rw-r--r--storage/connect/odbconn.cpp37
-rw-r--r--storage/connect/odbconn.h2
-rw-r--r--storage/connect/plgdbsem.h1
-rw-r--r--storage/connect/plgdbutl.cpp28
-rw-r--r--storage/connect/tabodbc.cpp12
7 files changed, 105 insertions, 28 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 00ab4d8124e..ee2c9a7eea6 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -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;
diff --git a/storage/connect/odbccat.h b/storage/connect/odbccat.h
index b3a170f4efe..ba4074bf276 100644
--- a/storage/connect/odbccat.h
+++ b/storage/connect/odbccat.h
@@ -1,6 +1,7 @@
/***********************************************************************/
/* 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);
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index a9610c86f18..8dcf71c2953 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -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 {
diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h
index 448ce2d428f..311a6ee6406 100644
--- a/storage/connect/odbconn.h
+++ b/storage/connect/odbconn.h
@@ -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
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 0d2dfde3eb3..550153921a5 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -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);
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 5ea8457f25e..270a0381bad 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -732,6 +732,34 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
} /* 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. */
/***********************************************************************/
void PlugConvertConstant(PGLOBAL g, void* & value, short& type)
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 38699b9d8e5..d9d794ef4e4 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -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;