diff options
-rw-r--r-- | storage/connect/connect.cc | 4 | ||||
-rw-r--r-- | storage/connect/connect.h | 21 | ||||
-rw-r--r-- | storage/connect/filamdbf.h | 5 | ||||
-rw-r--r-- | storage/connect/ha_connect.cc | 136 | ||||
-rw-r--r-- | storage/connect/myconn.cpp | 248 | ||||
-rw-r--r-- | storage/connect/myconn.h | 12 | ||||
-rw-r--r-- | storage/connect/myutil.cpp | 4 | ||||
-rw-r--r-- | storage/connect/myutil.h | 8 | ||||
-rw-r--r-- | storage/connect/odbconn.cpp | 142 | ||||
-rw-r--r-- | storage/connect/odbconn.h | 9 | ||||
-rw-r--r-- | storage/connect/rcmsg.c | 4 | ||||
-rw-r--r-- | storage/connect/resource.h | 3 | ||||
-rw-r--r-- | storage/connect/tabfmt.h | 5 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 250 | ||||
-rw-r--r-- | storage/connect/tabodbc.cpp | 95 | ||||
-rw-r--r-- | storage/connect/tabodbc.h | 39 | ||||
-rw-r--r-- | storage/connect/tabwmi.cpp | 8 | ||||
-rw-r--r-- | storage/connect/tabwmi.h | 13 |
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 ---------------------------- */ /***********************************************************************/ |