summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/connect/connect.cc4
-rw-r--r--storage/connect/connect.h21
-rw-r--r--storage/connect/filamdbf.h5
-rw-r--r--storage/connect/ha_connect.cc136
-rw-r--r--storage/connect/myconn.cpp248
-rw-r--r--storage/connect/myconn.h12
-rw-r--r--storage/connect/myutil.cpp4
-rw-r--r--storage/connect/myutil.h8
-rw-r--r--storage/connect/odbconn.cpp142
-rw-r--r--storage/connect/odbconn.h9
-rw-r--r--storage/connect/rcmsg.c4
-rw-r--r--storage/connect/resource.h3
-rw-r--r--storage/connect/tabfmt.h5
-rw-r--r--storage/connect/tabmysql.cpp250
-rw-r--r--storage/connect/tabodbc.cpp95
-rw-r--r--storage/connect/tabodbc.h39
-rw-r--r--storage/connect/tabwmi.cpp8
-rw-r--r--storage/connect/tabwmi.h13
18 files changed, 617 insertions, 389 deletions
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 436969c5932..15345ff47e7 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -36,8 +36,6 @@
#include "handler.h"
#undef OFFSET
-typedef class ha_connect *PHC;
-
#include "global.h"
#include "plgdbsem.h"
#include "xobject.h"
@@ -60,7 +58,7 @@ extern int xtrace;
/* Routines called internally by semantic routines. */
/***********************************************************************/
void CntEndDB(PGLOBAL);
-RCODE EvalColumns(PGLOBAL g, PTDB tdbp);
+RCODE EvalColumns(PGLOBAL g, PTDB tdbp);
/***********************************************************************/
/* MySQL routines called externally by semantic routines. */
diff --git a/storage/connect/connect.h b/storage/connect/connect.h
index f4f7b3aae33..3fd52d283c6 100644
--- a/storage/connect/connect.h
+++ b/storage/connect/connect.h
@@ -24,8 +24,27 @@
//typedef struct _tabdesc *PTABD; // For friend setting
typedef struct _xinfo *PXF;
typedef struct _create_xinfo *PCXF;
+typedef class ha_connect *PHC;
typedef class TDBDOX *PTDBDOX;
+/****************************************************************************/
+/* CONNECT functions called externally. */
+/****************************************************************************/
+bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname);
+PTDB CntGetTDB(PGLOBAL g, const char *name, MODE xmod, PHC);
+bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE, char *, char *, bool, PHC);
+bool CntRewindTable(PGLOBAL g, PTDB tdbp);
+int CntCloseTable(PGLOBAL g, PTDB tdbp);
+int CntIndexInit(PGLOBAL g, PTDB tdbp, int id);
+RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
+RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n);
+RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
+RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
+RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
+bool CntInfo(PGLOBAL g, PTDB tdbp, PXF info);
+int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
+ bool *incl, key_part_map *kmap);
+
/***********************************************************************/
/* Definition of classes XCOLCRT, XIXDEF, XKPDEF, DOXDEF, TDBDOX */
/* These classes purpose is chiefly to access protected items! */
@@ -74,4 +93,4 @@ class XKPDEF: public KPARTDEF {
bool HasNulls; /* Can have null values */
}; // end of class XKPDEF
-RCODE CheckRecord(PGLOBAL g, PTDB tdbp, char *oldbuf, char *newbuf);
+//RCODE CheckRecord(PGLOBAL g, PTDB tdbp, char *oldbuf, char *newbuf);
diff --git a/storage/connect/filamdbf.h b/storage/connect/filamdbf.h
index 5325f4f9deb..d38e7f9b90f 100644
--- a/storage/connect/filamdbf.h
+++ b/storage/connect/filamdbf.h
@@ -17,6 +17,11 @@ typedef class DBFFAM *PDBFFAM;
typedef class DBMFAM *PDBMFAM;
/****************************************************************************/
+/* Functions used externally. */
+/****************************************************************************/
+PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info);
+
+/****************************************************************************/
/* This is the base class for dBASE file access methods. */
/****************************************************************************/
class DllExport DBFBASE {
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index eaab8bf1f12..f8dff85dd71 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -104,6 +104,7 @@
#include "create_options.h"
#include "mysql_com.h"
#include "field.h"
+#include "sql_parse.h"
#undef OFFSET
#define NOPARSE
@@ -112,70 +113,40 @@
#endif // UNIX
#include "global.h"
#include "plgdbsem.h"
+#if defined(ODBC_SUPPORT)
+#include "odbconn.h"
+#endif // ODBC_SUPPORT
+#if defined(MYSQL_SUPPORT)
+#include "myconn.h"
+#endif // MYSQL_SUPPORT
+#include "filamdbf.h"
+#include "tabfmt.h"
#include "reldef.h"
#include "tabcol.h"
#include "xindex.h"
+#if defined(WIN32)
+#include "tabwmi.h"
+#endif // WIN32
#include "connect.h"
#include "user_connect.h"
#include "ha_connect.h"
#include "mycat.h"
+#include "myutil.h"
-#define PLGINI "plugdb.ini" /* Configuration settings file */
#define PLGXINI "plgcnx.ini" /* Configuration settings file */
-#define my_strupr(p) my_caseup_str(default_charset_info, (p));
-#define my_strlwr(p) my_casedn_str(default_charset_info, (p));
-#define my_stricmp(a, b) my_strcasecmp(default_charset_info, (a), (b))
+#define my_strupr(p) my_caseup_str(default_charset_info, (p));
+#define my_strlwr(p) my_casedn_str(default_charset_info, (p));
+#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b))
#if defined (WIN32)
-typedef struct _WMIutil *PWMIUT; /* Used to call WMIColumns */
+typedef struct _WMIutil *PWMIUT; /* Used to call WMIColumns */
#endif
-/****************************************************************************/
-/* CONNECT functions called externally. */
-/****************************************************************************/
-bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname);
-PTDB CntGetTDB(PGLOBAL g, const char *name, MODE xmod, PHC);
-bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE, char *, char *, bool, PHC);
-bool CntRewindTable(PGLOBAL g, PTDB tdbp);
-int CntCloseTable(PGLOBAL g, PTDB tdbp);
-int CntIndexInit(PGLOBAL g, PTDB tdbp, int id);
-RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
-RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n);
-RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
-RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
-RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
-bool CntInfo(PGLOBAL g, PTDB tdbp, PXF info);
-int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
- bool *incl, key_part_map *kmap);
+
#ifdef LIBXML2_SUPPORT
void XmlInitParserLib(void);
void XmlCleanupParserLib(void);
#endif // LIBXML2_SUPPORT
-/****************************************************************************/
-/* Functions called externally by pre_parser. */
-/****************************************************************************/
-PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info);
-PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr);
-#if defined(ODBC_SUPPORT)
-PQRYRES ODBCDataSources(PGLOBAL g, bool info = true);
-PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn, bool info);
-#endif // ODBC_SUPPORT
-#if defined(MYSQL_SUPPORT)
-PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
- const char *user, const char *pwd,
- const char *table, const char *colpat,
- int port, bool key);
-#endif // MYSQL_SUPPORT
-
-enum enum_field_types PLGtoMYSQL(int type, bool gdf);
-#if defined(WIN32)
-PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp= NULL);
-#endif // WIN32
-char GetTypeID(char *type);
-bool check_string_char_length(LEX_STRING *str, const char *err_msg,
- uint max_char_length, CHARSET_INFO *cs,
- bool no_error);
-
/***********************************************************************/
/* DB static variables. */
/***********************************************************************/
@@ -185,7 +156,7 @@ extern "C" char nmfile[];
extern "C" char pdebug[];
extern "C" {
- char version[]= "Version 1.00.0005 October 03, 2012";
+ char version[]= "Version 1.01.0001 February 08, 2013";
#if defined(XMSG)
char msglang[]; // Default message language
@@ -237,7 +208,7 @@ struct ha_table_option_struct {
const char *qchar;
const char *module;
const char *subtype;
- const char *info;
+ const char *catfunc;
const char *oplist;
int lrecl;
int elements;
@@ -268,7 +239,7 @@ ha_create_table_option connect_table_option_list[]=
HA_TOPTION_STRING("QCHAR", qchar),
HA_TOPTION_STRING("MODULE", module),
HA_TOPTION_STRING("SUBTYPE", subtype),
- HA_TOPTION_STRING("INFO", info),
+ HA_TOPTION_STRING("CATFUNC", catfunc),
HA_TOPTION_STRING("OPTION_LIST", oplist),
HA_TOPTION_NUMBER("LRECL", lrecl, 0, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("BLOCK_SIZE", elements, 0, 0, INT_MAX32, 1),
@@ -816,8 +787,8 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
opval= (char*)options->module;
else if (!stricmp(opname, "Subtype"))
opval= (char*)options->subtype;
- else if (!stricmp(opname, "Info"))
- opval= (char*)options->info;
+ else if (!stricmp(opname, "Catfunc"))
+ opval= (char*)options->catfunc;
if (!opval && options->oplist)
opval= GetListOption(opname, options->oplist);
@@ -3282,15 +3253,15 @@ bool ha_connect::add_fields(THD *thd, void *alt_info,
*/
bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
{
- char ttp= '?', spc= ',', qch= 0;
+ char ttp= '?', spc= ',', qch= 0, fnc= 0;
const char *typn= "DOS";
const char *user;
- char *fn, *dsn, *tab, *db, *host, *pwd, *prt, *sep, *inf;
+ char *fn, *dsn, *tab, *db, *host, *pwd, *prt, *sep;
#if defined(WIN32)
char *nsp= NULL, *cls= NULL;
#endif // WIN32
int port= MYSQL_PORT, hdr= 0, mxr= 0;
- bool b= false, ok= false, info= false;
+ bool b= false, ok= false, dbf= false;
LEX_STRING *comment, *name;
HA_CREATE_INFO *create_info= (HA_CREATE_INFO *)crt_info;
engine_option_value *pov;
@@ -3298,16 +3269,13 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
PCOLRES crp;
PGLOBAL g= GetPlug(thd);
- fn= dsn= tab= db= host= pwd= prt= sep= inf= NULL;
- user= NULL;
-
- if (g) {
- // Set default values
- tab= (char*)create_info->alias;
- db= thd->db;
- } else
+ if (!g)
return true;
+ fn= dsn= tab= host= pwd= prt= sep= NULL;
+ user= NULL;
+ db= thd->db; // Default value
+
// Get the useful create options
for (pov= create_info->option_list; pov; pov= pov->next)
if (!stricmp(pov->name.str, "table_type")) {
@@ -3319,8 +3287,8 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
tab= pov->value.str;
} else if (!stricmp(pov->name.str, "db_name")) {
db= pov->value.str;
- } else if (!stricmp(pov->name.str, "info")) {
- inf= pov->value.str;
+ } else if (!stricmp(pov->name.str, "catfunc")) {
+ fnc= toupper(*pov->value.str);
} else if (!stricmp(pov->name.str, "sep_char")) {
sep= pov->value.str;
spc= (!strcmp(sep, "\\t")) ? '\t' : *sep;
@@ -3343,15 +3311,16 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
cls= GetListOption("class", pov->value.str);
#endif // WIN32
mxr= atoi(GetListOption("maxerr", pov->value.str, "0"));
- inf= GetListOption("info", pov->value.str);
} // endelse option_list
+ if (!tab && fnc != 'T')
+ tab= (char*)create_info->alias;
+
switch (ttp) {
#if defined(ODBC_SUPPORT)
case 'O': // ODBC
- info= inf && !!strchr("1yYoO", *inf);
-
- if (!(dsn= create_info->connect_string.str) && !info)
+ if (!(dsn= create_info->connect_string.str)
+ && fnc != 'S'&& fnc != 'D')
sprintf(g->Message, "Missing %s connection string", typn);
else
ok= true;
@@ -3359,6 +3328,8 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
break;
#endif // ODBC_SUPPORT
case 'A': // DBF
+ dbf= true;
+ // Passthru
case 'C': // CSV
if (!fn)
sprintf(g->Message, "Missing %s file name", typn);
@@ -3401,10 +3372,23 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
break;
#if defined(ODBC_SUPPORT)
case 'O':
- if (dsn)
- qrp= MyODBCCols(g, tab, dsn, info);
- else
- qrp= ODBCDataSources(g);
+ switch (fnc) {
+ case 'C':
+ case '\0':
+ qrp= MyODBCCols(g, dsn, tab, fnc == 'C');
+ break;
+ case 'T':
+ qrp= ODBCTables(g, dsn, tab, true);
+ break;
+ case 'S':
+ qrp= ODBCDataSources(g, true);
+ break;
+ case 'D':
+ qrp= ODBCDrivers(g, true);
+ break;
+ default:
+ sprintf(g->Message, "invalid catfunc %c", fnc);
+ } // endswitch info
break;
#endif // ODBC_SUPPORT
@@ -3418,7 +3402,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
break;
#if defined(WIN32)
case 'W':
- qrp= WMIColumns(g, nsp, cls);
+ qrp= WMIColumns(g, nsp, cls, NULL);
break;
#endif // WIN32
} // endswitch ttp
@@ -3428,11 +3412,11 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
return true;
} // endif qrp
- if (info) {
+ if (fnc) {
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
cnm= encode(g, crp->Name);
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
- type= PLGtoMYSQL(crp->Type, true);
+ type= PLGtoMYSQL(crp->Type, dbf);
len= crp->Length;
length= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(length, "%d", len);
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 1d0071b1851..d8e7a4425de 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -39,6 +39,8 @@
#include "global.h"
#include "plgdbsem.h"
+#include "plgcnx.h" // For DB types
+#include "resource.h"
#include "value.h"
#include "valblk.h"
#define DLL_EXPORT // Items are exported from this DLL
@@ -59,6 +61,252 @@ static char *server_groups[] = {
};
#endif // EMBEDDED
+extern "C" int trace;
+
+/**************************************************************************/
+/* Allocate the result structure that will contain result data. */
+/**************************************************************************/
+PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
+ int *dbtype, int *buftyp, unsigned int *length,
+ bool blank = true, bool nonull = true);
+
+/************************************************************************/
+/* MyColumns: constructs the result blocks containing all columns */
+/* of a MySQL table that will be retrieved by GetData commands. */
+/* key = TRUE when called from Create Table to get key informations. */
+/************************************************************************/
+PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
+ const char *user, const char *pwd,
+ const char *table, const char *colpat,
+ int port, bool key)
+ {
+ static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT,
+ DB_INT, DB_SHORT, DB_CHAR, DB_CHAR};
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
+ TYPE_INT, TYPE_SHORT, TYPE_STRING, TYPE_STRING};
+ static unsigned int length[] = {0, 4, 16, 4, 4, 4, 0, 0};
+ char *fld, *fmt, cmd[128];
+ int i, n, nf, ncol = sizeof(dbtype) / sizeof(int);
+ int len, type, prec, rc, k = 0;
+ PQRYRES qrp;
+ PCOLRES crp;
+ MYSQLC myc;
+
+ /**********************************************************************/
+ /* Open the connection with the MySQL server. */
+ /**********************************************************************/
+ if (myc.Open(g, host, db, user, pwd, port))
+ return NULL;
+
+ /**********************************************************************/
+ /* Do an evaluation of the result size. */
+ /**********************************************************************/
+ sprintf(cmd, "SHOW FULL COLUMNS FROM %s", table);
+ strcat(strcat(cmd, " FROM "), (db) ? db : PlgGetUser(g)->DBName);
+
+ if (colpat)
+ strcat(strcat(cmd, " LIKE "), colpat);
+
+ if (trace)
+ htrc("MyColumns: cmd='%s'\n", cmd);
+
+ if ((n = myc.GetResultSize(g, cmd)) < 0) {
+ myc.Close();
+ return NULL;
+ } // endif n
+
+ /**********************************************************************/
+ /* Get the size of the name columns. */
+ /* Note that because the length is 0 for the last 2 columns (comment */
+ /* and date format) they will be STRBLK instead of CHRBLK. */
+ /**********************************************************************/
+ length[0] = myc.GetFieldLength(0);
+
+ if (!key) // We are not called from Create table
+ ncol--; // No date format column
+
+ /**********************************************************************/
+ /* Allocate the structures used to refer to the result set. */
+ /**********************************************************************/
+ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
+ dbtype, buftyp, length);
+
+ /**********************************************************************/
+ /* Now get the results into blocks. */
+ /**********************************************************************/
+ for (i = 0; i < n; i++) {
+ if ((rc = myc.Fetch(g, -1) == RC_FX))
+ return NULL;
+ else if (rc == RC_NF)
+ break;
+
+ // Get column name
+ fld = myc.GetCharField(0);
+ crp = qrp->Colresp;
+ crp->Kdata->SetValue(fld, i);
+
+ // Get type, type name, and precision
+ fld = myc.GetCharField(1);
+ prec = 0;
+ len = 256; // Default for text or blob
+
+ if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
+ sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
+ return NULL;
+ } else
+ qrp->Nblin++;
+
+ if ((type = MYSQLtoPLG(cmd)) == TYPE_ERROR) {
+ sprintf(g->Message, "Unsupported column type %s", cmd);
+ return NULL;
+ } // endif type
+
+ crp = crp->Next;
+ crp->Kdata->SetValue(type, i);
+ crp = crp->Next;
+ crp->Kdata->SetValue(cmd, i);
+
+ if (key && type == TYPE_DATE) {
+ // When creating tables we do need info about date columns
+ fmt = MyDateFmt(cmd);
+ len = strlen(fmt);
+ } else
+ fmt = NULL;
+
+ crp = crp->Next;
+ crp->Name = "Length";
+ crp->Kdata->SetValue(len, i);
+ crp = crp->Next;
+ crp->Name = "Key";
+
+ if (key) {
+ // Creating a table, we need key info
+ fld = myc.GetCharField(4);
+ crp->Kdata->SetValue((stricmp(fld, "PRI")) ? 0 : ++k, i);
+ } else
+ crp->Kdata->SetValue(len, i);
+
+ crp = crp->Next;
+ crp->Name = "Prec";
+ crp->Kdata->SetValue(prec, i);
+
+ // Get comment field
+ crp = crp->Next;
+ crp->Name = "Comment";
+ fld = myc.GetCharField(8);
+
+ if (fld && strlen(fld))
+ crp->Kdata->SetValue(fld, i);
+ else
+ crp->Kdata->Reset(i);
+
+ if (key) {
+ crp = crp->Next;
+ crp->Name = "Date_Fmt";
+
+ if (fmt)
+ crp->Kdata->SetValue(fmt, i);
+ else
+ crp->Kdata->Reset(i);
+
+ } // endif key
+
+ } // endfor i
+
+ if (k > 1) {
+ // Multicolumn primary key
+ PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;
+
+ for (i = 0; i < n; i++)
+ if (vbp->GetIntValue(i))
+ vbp->SetValue(k, i);
+
+ } // endif k
+
+ /**********************************************************************/
+ /* Close MySQL connection. */
+ /**********************************************************************/
+ myc.Close();
+
+ /**********************************************************************/
+ /* Return the result pointer for use by GetData routines. */
+ /**********************************************************************/
+ return qrp;
+ } // end of MyColumns
+
+#if 0
+/**************************************************************************/
+/* SemMySQLColumns: analyze a MySQL table for column format. */
+/**************************************************************************/
+void SemMySQLColumns(PGLOBAL g, PSEM semp)
+ {
+ PQRYRES qrp;
+ PPARM pp, parmp = semp->Parmp;
+
+ /*********************************************************************/
+ /* Test passed parameters. */
+ /*********************************************************************/
+ sprintf(g->Message, MSG(BAD_PARAMETERS), semp->Name);
+ semp->Value = g->Message;
+ semp->Type = TYPE_ERROR;
+
+ if (!parmp || parmp->Type != TYPE_LIST)
+ return;
+
+ /*********************************************************************/
+ /* Analyze the table specifications. */
+ /*********************************************************************/
+ PSZ host, db, user, pwd, table;
+ int port = 0;
+
+ host = db = user = pwd = table = NULL;
+
+ for (pp = (PPARM)parmp->Value; pp; pp = pp->Next)
+ switch (pp->Type) {
+ case TYPE_STRING:
+ switch (pp->Domain) {
+ case 5: table = (PSZ)pp->Value; break;
+ case 7: db = (PSZ)pp->Value; break;
+ case 30: host = (PSZ)pp->Value; break;
+ case 31: user = (PSZ)pp->Value; break;
+ case 32: pwd = (PSZ)pp->Value; break;
+ default:
+ return;
+ } // endswitch Domain
+
+ break;
+ case TYPE_INT:
+ if (pp->Domain == 33)
+ port = (int)*(int*)pp->Value;
+ else
+ return;
+
+ break;
+ default:
+ return;
+ } // endswitch Type
+
+ /************************************************************************/
+ /* Get and store the result pointer for use by GetData routines. */
+ /************************************************************************/
+ if (!(qrp = MyColumns(g, host, db, user, pwd, table, NULL, port, TRUE)))
+ return; // Error in MyColumns
+
+ PlgGetUser(g)->Result = qrp;
+
+#if defined(_CONSOLE)
+ PrintResult(g, semp, qrp);
+#else
+ /************************************************************************/
+ /* Make as result the qryresult description block. */
+ /************************************************************************/
+ semp->Type = TYPE_QRYRES;
+ semp->Domain = 0;
+ semp->Value = qrp;
+#endif // _CONSOLE
+ } // end of SemMySQLColumns
+#endif // 0
+
/* -------------------------- Class MYSQLC --------------------------- */
/***********************************************************************/
diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h
index cc07da31c38..fc462aaa22a 100644
--- a/storage/connect/myconn.h
+++ b/storage/connect/myconn.h
@@ -14,6 +14,7 @@
#endif // !WIN32
#include <mysql.h>
#include <errmsg.h>
+#include "myutil.h"
#if defined(WIN32) && defined(MYCONN_EXPORTS)
#if defined(DLL_EXPORT)
@@ -32,13 +33,12 @@
typedef class MYSQLC *PMYC;
/***********************************************************************/
-/* Exported/Imported functions. */
+/* Prototypes of info functions. */
/***********************************************************************/
-DllItem int MYSQLtoPLG(char *);
-DllItem int MYSQLtoPLG(int);
-DllItem enum enum_field_types PLGtoMYSQL(int, bool gdf = FALSE);
-DllItem char *MyDateFmt(int);
-DllItem char *MyDateFmt(char *);
+PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
+ const char *user, const char *pwd,
+ const char *table, const char *colpat,
+ int port, bool key);
/* -------------------------- MYCONN class --------------------------- */
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index 0a6e06ade87..f42b9029d01 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -59,7 +59,7 @@ int MYSQLtoPLG(char *typname)
/************************************************************************/
/* Convert from PlugDB type to MySQL type number */
/************************************************************************/
-enum enum_field_types PLGtoMYSQL(int type, bool gdf)
+enum enum_field_types PLGtoMYSQL(int type, bool dbf)
{
enum enum_field_types mytype;
@@ -74,7 +74,7 @@ enum enum_field_types PLGtoMYSQL(int type, bool gdf)
mytype = MYSQL_TYPE_DOUBLE;
break;
case TYPE_DATE:
- mytype = (gdf) ? MYSQL_TYPE_DATE : MYSQL_TYPE_DATETIME;
+ mytype = (dbf) ? MYSQL_TYPE_DATE : MYSQL_TYPE_DATETIME;
break;
case TYPE_STRING:
mytype = MYSQL_TYPE_VARCHAR;
diff --git a/storage/connect/myutil.h b/storage/connect/myutil.h
new file mode 100644
index 00000000000..d3d421418ca
--- /dev/null
+++ b/storage/connect/myutil.h
@@ -0,0 +1,8 @@
+/***********************************************************************/
+/* Prototypes of Functions used externally. */
+/***********************************************************************/
+enum enum_field_types PLGtoMYSQL(int type, bool dbf);
+int MYSQLtoPLG(char *typname);
+int MYSQLtoPLG(int mytype);
+char *MyDateFmt(int mytype);
+char *MyDateFmt(char *typname);
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index ac40fb8b4bb..d9e3e3f4d58 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -311,7 +311,7 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table,
/**************************************************************************/
/* MyODBCCols: returns column info as required by ha_connect::pre_create. */
/**************************************************************************/
-PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn, bool info)
+PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
{
int type, len, prec;
PCOLRES crpt, crpl, crpp;
@@ -388,7 +388,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info)
int n = 0, ncol = 2;
int maxres;
PQRYRES qrp;
- ODBConn *ocp;
+ ODBConn *ocp = NULL;
/************************************************************************/
/* Do an evaluation of the result size. */
@@ -424,14 +424,57 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info)
return qrp;
} // end of ODBCDataSources
-#if 0 // Currently not used by CONNECT
+/*************************************************************************/
+/* ODBCDrivers: constructs the result blocks containing all ODBC */
+/* drivers available on the local host. */
+/* Called with info=true to have result column names. */
+/*************************************************************************/
+PQRYRES ODBCDrivers(PGLOBAL g, bool info)
+ {
+ static int dbtype[] = {DB_CHAR, DB_CHAR};
+ static int buftyp[] = {TYPE_STRING, TYPE_STRING};
+ static unsigned int length[] = {128, 256};
+ int ncol = 2;
+ int maxres;
+ PQRYRES qrp;
+ ODBConn *ocp = NULL;
+
+ /************************************************************************/
+ /* Do an evaluation of the result size. */
+ /************************************************************************/
+ if (!info) {
+ ocp = new(g) ODBConn(g, NULL);
+ maxres = 256; // Estimated max number of drivers
+ } else
+ maxres = 0;
+
+#ifdef DEBTRACE
+ htrc("ODBCDrivers: max=%d len=%d\n", maxres, length[0]);
+#endif
+
+ /************************************************************************/
+ /* Allocate the structures used to refer to the result set. */
+ /************************************************************************/
+ qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER, dbtype, buftyp, length);
+
+ /************************************************************************/
+ /* Now get the results into blocks. */
+ /************************************************************************/
+ if (!info && ocp->GetDrivers(qrp))
+ qrp = NULL;
+
+ /************************************************************************/
+ /* Return the result pointer for use by GetData routines. */
+ /************************************************************************/
+ return qrp;
+ } // end of ODBCDrivers
+
/***********************************************************************/
/* ODBCTables: constructs the result blocks containing all tables in */
/* an ODBC database that will be retrieved by GetData commands. */
/* Note: The first two columns (Qualifier, Owner) are ignored. */
/***********************************************************************/
-PQRYRES ODBCTables(PGLOBAL g, ODBConn *op, char *dsn, char *tabpat,
- char *tabtyp)
+PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info)
{
static int dbtype[] = {DB_CHAR, DB_CHAR, DB_CHAR, DB_CHAR};
static int buftyp[] = {TYPE_STRING, TYPE_STRING,
@@ -441,9 +484,9 @@ PQRYRES ODBCTables(PGLOBAL g, ODBConn *op, char *dsn, char *tabpat,
int maxres;
PQRYRES qrp;
CATPARM *cap;
- ODBConn *ocp = op;
+ ODBConn *ocp;
- if (!op) {
+ if (!info) {
/**********************************************************************/
/* Open the connection with the ODBC data source. */
/**********************************************************************/
@@ -452,16 +495,22 @@ PQRYRES ODBCTables(PGLOBAL g, ODBConn *op, char *dsn, char *tabpat,
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;
- } // endif op
+ } // endif info
/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
- maxres = 512; // This is completely arbitrary
- n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
- length[0] = (n) ? (n + 1) : 128;
- n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
- length[1] = (n) ? (n + 1) : 128;
+ if (!info) {
+ maxres = 512; // This is completely arbitrary
+ n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
+ length[0] = (n) ? (n + 1) : 128;
+ n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
+ length[1] = (n) ? (n + 1) : 128;
+ } else {
+ maxres = 0;
+ length[0] = 128;
+ length[1] = 128;
+ } // endif info
#ifdef DEBTRACE
htrc("ODBCTables: max=%d len=%d,%d\n",
@@ -474,8 +523,11 @@ PQRYRES ODBCTables(PGLOBAL g, ODBConn *op, char *dsn, char *tabpat,
qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES + 1,
dbtype, buftyp, length);
+ if (info)
+ return qrp;
+
cap = AllocCatInfo(g, CAT_TAB, tabpat, qrp);
- cap->Pat = (PUCHAR)tabtyp;
+//cap->Pat = (PUCHAR)tabtyp;
#ifdef DEBTRACE
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
@@ -497,8 +549,7 @@ PQRYRES ODBCTables(PGLOBAL g, ODBConn *op, char *dsn, char *tabpat,
/************************************************************************/
/* Close any local connection. */
/************************************************************************/
- if (!op)
- ocp->Close();
+ ocp->Close();
/************************************************************************/
/* Return the result pointer for use by GetData routines. */
@@ -506,6 +557,7 @@ PQRYRES ODBCTables(PGLOBAL g, ODBConn *op, char *dsn, char *tabpat,
return qrp;
} // end of ODBCTables
+#if 0 // Currently not used by CONNECT
/**************************************************************************/
/* PrimaryKeys: constructs the result blocks containing all the */
/* ODBC catalog information concerning primary keys. */
@@ -1558,6 +1610,7 @@ bool ODBConn::BindParam(ODBCCOL *colp)
/***********************************************************************/
bool ODBConn::GetDataSources(PQRYRES qrp)
{
+ bool rv = false;
UCHAR *dsn, *des;
UWORD dir = SQL_FETCH_FIRST;
SWORD n1, n2, p1, p2;
@@ -1589,15 +1642,66 @@ bool ODBConn::GetDataSources(PQRYRES qrp)
} catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0));
- SQLFreeEnv(m_henv);
- return true;
+ rv = true;
} // end try/catch
SQLFreeEnv(m_henv);
- return false;
+ Close();
+ return rv;
} // end of GetDataSources
/***********************************************************************/
+/* Get the list of Drivers and set it in qrp. */
+/***********************************************************************/
+bool ODBConn::GetDrivers(PQRYRES qrp)
+ {
+ int i, n;
+ bool rv = false;
+ UCHAR *des, *att;
+ UWORD dir = SQL_FETCH_FIRST;
+ SWORD n1, n2, p1, p2;
+ PCOLRES crp1 = qrp->Colresp, crp2 = qrp->Colresp->Next;
+ RETCODE rc;
+
+ n1 = crp1->Clen;
+ n2 = crp2->Clen;
+
+ try {
+ rc = SQLAllocEnv(&m_henv);
+
+ if (!Check(rc))
+ ThrowDBX(rc); // Fatal
+
+ for (n = 0; n < qrp->Maxres; n++) {
+ des = (UCHAR*)crp1->Kdata->GetValPtr(n);
+ att = (UCHAR*)crp2->Kdata->GetValPtr(n);
+ rc = SQLDrivers(m_henv, dir, des, n1, &p1, att, n2, &p2);
+
+ if (rc == SQL_NO_DATA_FOUND)
+ break;
+ else if (!Check(rc))
+ ThrowDBX(rc); // Fatal
+
+ // The attributes being separated by '\0', set them to ';'
+ for (i = 0; i < p2; i++)
+ if (!att[i])
+ att[i] = ';';
+
+ qrp->Nblin++;
+ dir = SQL_FETCH_NEXT;
+ } // endfor n
+
+ } catch(DBX *x) {
+ strcpy(m_G->Message, x->GetErrorMessage(0));
+ rv = true;
+ } // end try/catch
+
+ SQLFreeEnv(m_henv);
+ Close();
+ return rv;
+ } // end of GetDrivers
+
+/***********************************************************************/
/* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */
/***********************************************************************/
int ODBConn::GetCatInfo(CATPARM *cap)
diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h
index 93435d7f7b3..6827a5a5ece 100644
--- a/storage/connect/odbconn.h
+++ b/storage/connect/odbconn.h
@@ -5,6 +5,14 @@
//nclude <windowsx.h> /* Message crackers */
/***********************************************************************/
+/* Catalog function prototypes. */
+/***********************************************************************/
+PQRYRES ODBCDataSources(PGLOBAL g, bool info);
+PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info);
+PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info);
+PQRYRES ODBCDrivers(PGLOBAL g, bool info);
+
+/***********************************************************************/
/* Included C-definition files required by the interface. */
/***********************************************************************/
#include "block.h"
@@ -143,6 +151,7 @@ class ODBConn : public BLOCK {
bool BindParam(ODBCCOL *colp);
int GetCatInfo(CATPARM *cap);
bool GetDataSources(PQRYRES qrp);
+ bool GetDrivers(PQRYRES qrp);
public:
// Set special options
diff --git a/storage/connect/rcmsg.c b/storage/connect/rcmsg.c
index 5eaa2e8e5ba..a5c4abc79a3 100644
--- a/storage/connect/rcmsg.c
+++ b/storage/connect/rcmsg.c
@@ -109,6 +109,8 @@ char *GetMsgid(int id)
case IDS_SPC_06: p = "Longueur"; break;
case IDS_SPC_07: p = "Echelle"; break;
case IDS_SPC_08: p = "Pseudo_Colonne"; break;
+ case IDS_DRV_01: p = "Description"; break;
+ case IDS_DRV_02: p = "Attributs"; break;
case IDS_DSC_01: p = "Nom"; break;
case IDS_DSC_02: p = "Description"; break;
#else // English
@@ -199,6 +201,8 @@ char *GetMsgid(int id)
case IDS_SPC_06: p = "Length"; break;
case IDS_SPC_07: p = "Scale"; break;
case IDS_SPC_08: p = "Pseudo_Column"; break;
+ case IDS_DRV_01: p = "Description"; break;
+ case IDS_DRV_02: p = "Attributes"; break;
case IDS_DSC_01: p = "Name"; break;
case IDS_DSC_02: p = "Description"; break;
#endif // English
diff --git a/storage/connect/resource.h b/storage/connect/resource.h
index 1f441ee7d92..773942cf280 100644
--- a/storage/connect/resource.h
+++ b/storage/connect/resource.h
@@ -118,6 +118,9 @@
#define IDS_PLG_07 1286
#define IDS_PLG_08 1287
#define IDS_PLG_09 1288
+#define IDS_DRIVER 1290
+#define IDS_DRV_01 1291
+#define IDS_DRV_02 1292
#define IDS_DSRC 1295
#define IDS_DSC_01 1296
#define IDS_DSC_02 1297
diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h
index 80ad1a6ae63..95486a09881 100644
--- a/storage/connect/tabfmt.h
+++ b/storage/connect/tabfmt.h
@@ -12,6 +12,11 @@
typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
+/* Functions used externally. */
+/***********************************************************************/
+PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr);
+
+/***********************************************************************/
/* CSV table. */
/***********************************************************************/
class DllExport CSVDEF : public DOSDEF { /* Logical table description */
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 4ed727d3bf0..a63526f1e8d 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -57,8 +57,6 @@
#include "reldef.h"
#include "tabmysql.h"
#include "valblk.h"
-#include "plgcnx.h" // For DB types
-#include "resource.h"
#if defined(_CONSOLE)
void PrintResult(PGLOBAL, PSEM, PQRYRES);
@@ -66,250 +64,6 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
extern "C" int trace;
-/**************************************************************************/
-/* Allocate the result structure that will contain result data. */
-/**************************************************************************/
-PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
- int *dbtype, int *buftyp, unsigned int *length,
- bool blank = true, bool nonull = true);
-
-/************************************************************************/
-/* MyColumns: constructs the result blocks containing all columns */
-/* of a MySQL table that will be retrieved by GetData commands. */
-/* key = TRUE when called from Create Table to get key informations. */
-/************************************************************************/
-PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
- const char *user, const char *pwd,
- const char *table, const char *colpat,
- int port, bool key)
- {
- static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT,
- DB_INT, DB_SHORT, DB_CHAR, DB_CHAR};
- static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
- TYPE_INT, TYPE_SHORT, TYPE_STRING, TYPE_STRING};
- static unsigned int length[] = {0, 4, 16, 4, 4, 4, 0, 0};
- char *fld, *fmt, cmd[128];
- int i, n, nf, ncol = sizeof(dbtype) / sizeof(int);
- int len, type, prec, rc, k = 0;
- PQRYRES qrp;
- PCOLRES crp;
- MYSQLC myc;
-
- /**********************************************************************/
- /* Open the connection with the MySQL server. */
- /**********************************************************************/
- if (myc.Open(g, host, db, user, pwd, port))
- return NULL;
-
- /**********************************************************************/
- /* Do an evaluation of the result size. */
- /**********************************************************************/
- sprintf(cmd, "SHOW FULL COLUMNS FROM %s", table);
- strcat(strcat(cmd, " FROM "), (db) ? db : PlgGetUser(g)->DBName);
-
- if (colpat)
- strcat(strcat(cmd, " LIKE "), colpat);
-
- if (trace)
- htrc("MyColumns: cmd='%s'\n", cmd);
-
- if ((n = myc.GetResultSize(g, cmd)) < 0) {
- myc.Close();
- return NULL;
- } // endif n
-
- /**********************************************************************/
- /* Get the size of the name columns. */
- /* Note that because the length is 0 for the last 2 columns (comment */
- /* and date format) they will be STRBLK instead of CHRBLK. */
- /**********************************************************************/
- length[0] = myc.GetFieldLength(0);
-
- if (!key) // We are not called from Create table
- ncol--; // No date format column
-
- /**********************************************************************/
- /* Allocate the structures used to refer to the result set. */
- /**********************************************************************/
- qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
- dbtype, buftyp, length);
-
- /**********************************************************************/
- /* Now get the results into blocks. */
- /**********************************************************************/
- for (i = 0; i < n; i++) {
- if ((rc = myc.Fetch(g, -1) == RC_FX))
- return NULL;
- else if (rc == RC_NF)
- break;
-
- // Get column name
- fld = myc.GetCharField(0);
- crp = qrp->Colresp;
- crp->Kdata->SetValue(fld, i);
-
- // Get type, type name, and precision
- fld = myc.GetCharField(1);
- prec = 0;
- len = 256; // Default for text or blob
-
- if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
- sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
- return NULL;
- } else
- qrp->Nblin++;
-
- if ((type = MYSQLtoPLG(cmd)) == TYPE_ERROR) {
- sprintf(g->Message, "Unsupported column type %s", cmd);
- return NULL;
- } // endif type
-
- crp = crp->Next;
- crp->Kdata->SetValue(type, i);
- crp = crp->Next;
- crp->Kdata->SetValue(cmd, i);
-
- if (key && type == TYPE_DATE) {
- // When creating tables we do need info about date columns
- fmt = MyDateFmt(cmd);
- len = strlen(fmt);
- } else
- fmt = NULL;
-
- crp = crp->Next;
- crp->Name = "Length";
- crp->Kdata->SetValue(len, i);
- crp = crp->Next;
- crp->Name = "Key";
-
- if (key) {
- // Creating a table, we need key info
- fld = myc.GetCharField(4);
- crp->Kdata->SetValue((stricmp(fld, "PRI")) ? 0 : ++k, i);
- } else
- crp->Kdata->SetValue(len, i);
-
- crp = crp->Next;
- crp->Name = "Prec";
- crp->Kdata->SetValue(prec, i);
-
- // Get comment field
- crp = crp->Next;
- crp->Name = "Comment";
- fld = myc.GetCharField(8);
-
- if (fld && strlen(fld))
- crp->Kdata->SetValue(fld, i);
- else
- crp->Kdata->Reset(i);
-
- if (key) {
- crp = crp->Next;
- crp->Name = "Date_Fmt";
-
- if (fmt)
- crp->Kdata->SetValue(fmt, i);
- else
- crp->Kdata->Reset(i);
-
- } // endif key
-
- } // endfor i
-
- if (k > 1) {
- // Multicolumn primary key
- PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;
-
- for (i = 0; i < n; i++)
- if (vbp->GetIntValue(i))
- vbp->SetValue(k, i);
-
- } // endif k
-
- /**********************************************************************/
- /* Close MySQL connection. */
- /**********************************************************************/
- myc.Close();
-
- /**********************************************************************/
- /* Return the result pointer for use by GetData routines. */
- /**********************************************************************/
- return qrp;
- } // end of MyColumns
-
-#if 0
-/**************************************************************************/
-/* SemMySQLColumns: analyze a MySQL table for column format. */
-/**************************************************************************/
-void SemMySQLColumns(PGLOBAL g, PSEM semp)
- {
- PQRYRES qrp;
- PPARM pp, parmp = semp->Parmp;
-
- /*********************************************************************/
- /* Test passed parameters. */
- /*********************************************************************/
- sprintf(g->Message, MSG(BAD_PARAMETERS), semp->Name);
- semp->Value = g->Message;
- semp->Type = TYPE_ERROR;
-
- if (!parmp || parmp->Type != TYPE_LIST)
- return;
-
- /*********************************************************************/
- /* Analyze the table specifications. */
- /*********************************************************************/
- PSZ host, db, user, pwd, table;
- int port = 0;
-
- host = db = user = pwd = table = NULL;
-
- for (pp = (PPARM)parmp->Value; pp; pp = pp->Next)
- switch (pp->Type) {
- case TYPE_STRING:
- switch (pp->Domain) {
- case 5: table = (PSZ)pp->Value; break;
- case 7: db = (PSZ)pp->Value; break;
- case 30: host = (PSZ)pp->Value; break;
- case 31: user = (PSZ)pp->Value; break;
- case 32: pwd = (PSZ)pp->Value; break;
- default:
- return;
- } // endswitch Domain
-
- break;
- case TYPE_INT:
- if (pp->Domain == 33)
- port = (int)*(int*)pp->Value;
- else
- return;
-
- break;
- default:
- return;
- } // endswitch Type
-
- /************************************************************************/
- /* Get and store the result pointer for use by GetData routines. */
- /************************************************************************/
- if (!(qrp = MyColumns(g, host, db, user, pwd, table, NULL, port, TRUE)))
- return; // Error in MyColumns
-
- PlgGetUser(g)->Result = qrp;
-
-#if defined(_CONSOLE)
- PrintResult(g, semp, qrp);
-#else
- /************************************************************************/
- /* Make as result the qryresult description block. */
- /************************************************************************/
- semp->Type = TYPE_QRYRES;
- semp->Domain = 0;
- semp->Value = qrp;
-#endif // _CONSOLE
- } // end of SemMySQLColumns
-#endif // 0
-
/* -------------- Implementation of the MYSQLDEF class --------------- */
/***********************************************************************/
@@ -1038,12 +792,12 @@ void MYSQLCOL::InitBind(PGLOBAL g)
// if (!((DTVAL*)Value)->IsFormatted())
((DTVAL*)Value)->SetFormat(g, "YYYY-MM-DD hh:mm:ss", 19);
- Bind->buffer_type = PLGtoMYSQL(TYPE_STRING);
+ Bind->buffer_type = PLGtoMYSQL(TYPE_STRING, false);
Bind->buffer = (char *)PlugSubAlloc(g,NULL, 20);
Bind->buffer_length = 20;
Bind->length = &Slen;
} else {
- Bind->buffer_type = PLGtoMYSQL(Buf_Type);
+ Bind->buffer_type = PLGtoMYSQL(Buf_Type, false);
Bind->buffer = (char *)Value->GetTo_Val();
Bind->buffer_length = Value->GetClen();
Bind->length = (IsTypeChar(Buf_Type)) ? &Slen : NULL;
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 31f696577cb..7b8c62e3e53 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -74,8 +74,6 @@
#include "sql_string.h"
extern "C" char *GetMsgid(int id);
-PQRYRES ODBCDataSources(PGLOBAL g, bool info = false);
-PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn, bool info);
/***********************************************************************/
/* DB static variables. */
@@ -90,7 +88,8 @@ extern int num_read, num_there, num_eq[2]; // Statistics
/***********************************************************************/
ODBCDEF::ODBCDEF(void)
{
- Connect = Tabname = Tabowner = Tabqual = Qchar = Info = NULL;
+ Connect = Tabname = Tabowner = Tabqual = Qchar = NULL;
+ Catfunc = 0;
Catver = Options = 0;
} // end of ODBCDEF constructor
@@ -99,20 +98,18 @@ ODBCDEF::ODBCDEF(void)
/***********************************************************************/
bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
-//void *memp = Cat->GetDescp();
-//PSZ dbfile = Cat->GetDescFile();
int dop = ODBConn::noOdbcDialog; // Default for options
Desc = Connect = Cat->GetStringCatInfo(g, Name, "Connect", "");
- Tabname = Cat->GetStringCatInfo(g, Name, "Name", Name); // Deprecated
+ Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", ""));
+ Tabname = Cat->GetStringCatInfo(g, Name, "Name",
+ Catfunc == 'T' ? NULL : Name);
Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname);
Tabowner = Cat->GetStringCatInfo(g, Name, "Owner", "");
Tabqual = Cat->GetStringCatInfo(g, Name, "Qualifier", "");
Qchar = Cat->GetStringCatInfo(g, Name, "Qchar", "");
- Info = Cat->GetStringCatInfo(g, Name, "Info", NULL);
Catver = Cat->GetIntCatInfo(Name, "Catver", 2);
Options = Cat->GetIntCatInfo(Name, "Options", dop);
-//Options = Cat->GetIntCatInfo(Name, "Options", 0);
Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
@@ -128,18 +125,27 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
/* Allocate a TDB of the proper type. */
/* Column blocks will be allocated only when needed. */
/*********************************************************************/
- if (!Info || !strchr("1yYoO", *Info)) {
- tdbp = new(g) TDBODBC(this);
-
- if (Multiple == 1)
- tdbp = new(g) TDBMUL(tdbp);
- else if (Multiple == 2)
- strcpy(g->Message, MSG(NO_ODBC_MUL));
-
- } else if (*Connect)
- tdbp = new(g) TDBOCL(this);
- else
- tdbp = new(g) TDBSRC(this);
+ switch (Catfunc) {
+ case 'C':
+ tdbp = new(g) TDBOCL(this);
+ break;
+ case 'T':
+ tdbp = new(g) TDBOTB(this);
+ break;
+ case 'S':
+ tdbp = new(g) TDBSRC(this);
+ break;
+ case 'D':
+ tdbp = new(g) TDBDRV(this);
+ break;
+ default:
+ tdbp = new(g) TDBODBC(this);
+
+ if (Multiple == 1)
+ tdbp = new(g) TDBMUL(tdbp);
+ else if (Multiple == 2)
+ strcpy(g->Message, MSG(NO_ODBC_MUL));
+ } // endswitch Catfunc
return tdbp;
} // end of GetTable
@@ -1074,7 +1080,24 @@ bool TDBSRC::Initialize(PGLOBAL g)
if (Init)
return false;
- if (!(Qrp = ODBCDataSources(g)))
+ if (!(Qrp = ODBCDataSources(g, false)))
+ return true;
+
+ Init = true;
+ return false;
+ } // end of Initialize
+
+/* ---------------------------TDBDRV class --------------------------- */
+
+/***********************************************************************/
+/* Initialize: Get the list of ODBC drivers. */
+/***********************************************************************/
+bool TDBDRV::Initialize(PGLOBAL g)
+ {
+ if (Init)
+ return false;
+
+ if (!(Qrp = ODBCDrivers(g, false)))
return true;
Init = true;
@@ -1102,7 +1125,35 @@ bool TDBOCL::Initialize(PGLOBAL g)
if (Init)
return false;
- if (!(Qrp = MyODBCCols(g, Tabn, Dsn, false)))
+ if (!(Qrp = MyODBCCols(g, Dsn, Tabn, false)))
+ return true;
+
+ Init = true;
+ return false;
+ } // end of Initialize
+
+/* ---------------------------TDBOTB class --------------------------- */
+
+/***********************************************************************/
+/* TDBOCL class constructor. */
+/***********************************************************************/
+TDBOTB::TDBOTB(PODEF tdp) : TDBOIF(tdp)
+ {
+ ID = IDS_TABLES + 1;
+ NC = 4;
+ Dsn = tdp->GetConnect();
+ Tabpat = tdp->GetTabname();
+ } // end of TDBOCL constructor
+
+/***********************************************************************/
+/* Initialize: Get the list of ODBC tables. */
+/***********************************************************************/
+bool TDBOTB::Initialize(PGLOBAL g)
+ {
+ if (Init)
+ return false;
+
+ if (!(Qrp = ODBCTables(g, Dsn, Tabpat, false)))
return true;
Init = true;
diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h
index c923d470a8b..f31c005e3d8 100644
--- a/storage/connect/tabodbc.h
+++ b/storage/connect/tabodbc.h
@@ -44,7 +44,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Tabowner; /* External table owner */
PSZ Tabqual; /* External table qualifier */
PSZ Qchar; /* Identifier quoting character */
- PSZ Info; /* Information value */
+ char Catfunc; /* Catalog function */
int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */
}; // end of ODBCDEF
@@ -118,7 +118,7 @@ class TDBODBC : public TDBASE {
int CurNum; // Current buffer line number
int Rbuf; // Number of lines read in buffer
int BufSize; // Size of connect string buffer
- int Nparm; // The number of statement parameters
+ int Nparm; // The number of statement parameters
}; // end of class TDBODBC
/***********************************************************************/
@@ -227,7 +227,7 @@ class OIFCOL : public COLBLK {
}; // end of class OIFCOL
/***********************************************************************/
-/* This is the class declaration for the Data Sources info table. */
+/* This is the class declaration for the Data Sources catalog table. */
/***********************************************************************/
class TDBSRC : public TDBOIF {
public:
@@ -241,7 +241,21 @@ class TDBSRC : public TDBOIF {
}; // end of class TDBSRC
/***********************************************************************/
-/* This is the class declaration for the columns info table. */
+/* This is the class declaration for the Drivers catalog table. */
+/***********************************************************************/
+class TDBDRV : public TDBOIF {
+ public:
+ // Constructor
+ TDBDRV(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DRIVER; NC = 2;}
+
+ protected:
+ // Specific routines
+ virtual bool Initialize(PGLOBAL g);
+
+ }; // end of class TDBDRV
+
+/***********************************************************************/
+/* This is the class declaration for the columns catalog table. */
/***********************************************************************/
class TDBOCL : public TDBOIF {
public:
@@ -256,4 +270,21 @@ class TDBOCL : public TDBOIF {
char *Dsn; // Points to connection string
char *Tabn; // Points to ODBC table name
}; // end of class TDBOCL
+
+/***********************************************************************/
+/* This is the class declaration for the tables catalog table. */
+/***********************************************************************/
+class TDBOTB : public TDBOIF {
+ public:
+ // Constructor
+ TDBOTB(PODEF tdp);
+
+ protected:
+ // Specific routines
+ virtual bool Initialize(PGLOBAL g);
+
+ // Members
+ char *Dsn; // Points to connection string
+ char *Tabpat; // Points to ODBC table pattern
+ }; // end of class TDBOTB
#endif // !NODBC
diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp
index fd7e6eb345d..e98dfd0cde0 100644
--- a/storage/connect/tabwmi.cpp
+++ b/storage/connect/tabwmi.cpp
@@ -33,14 +33,6 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
/* ------------------- Functions WMI Column info --------------------- */
/***********************************************************************/
-/* Structure used by WMI column info functions. */
-/***********************************************************************/
-typedef struct _WMIutil {
- IWbemServices *Svc;
- IWbemClassObject *Cobj;
-} WMIUTIL, *PWMIUT;
-
-/***********************************************************************/
/* Initialize WMI operations. */
/***********************************************************************/
PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
diff --git a/storage/connect/tabwmi.h b/storage/connect/tabwmi.h
index cff9f8eb716..853f2174434 100644
--- a/storage/connect/tabwmi.h
+++ b/storage/connect/tabwmi.h
@@ -16,6 +16,19 @@ typedef class WMICOL *PWMICOL;
typedef class TDBWCL *PTDBWCL;
typedef class WCLCOL *PWCLCOL;
+/***********************************************************************/
+/* Structure used by WMI column info functions. */
+/***********************************************************************/
+typedef struct _WMIutil {
+ IWbemServices *Svc;
+ IWbemClassObject *Cobj;
+} WMIUTIL, *PWMIUT;
+
+/***********************************************************************/
+/* Functions used externally. */
+/***********************************************************************/
+PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp);
+
/* -------------------------- WMI classes ---------------------------- */
/***********************************************************************/