Commit 82e746ea authored by Olivier Bertrand's avatar Olivier Bertrand

Put almost all function prototypes in header files that are

included by the program using them.

Continuing implementing the "catalog" tables (ex "info").
Already existing were the ODBC data source table and the
WMI column info table.

A common way to handle them will permit to develop many
other such tables. Implemented:

The ODBC column catalog table.
The ODBC tables catalog table.
The ODBC drivers catalog table.

The INFO table option is replaced by the CATFUNC string option
whode first letter specifies the information to retrieve:
C: Columns (of a table)
T: Tables  (of a database)
S: Data sources
D: Drivers

Modified:
ha_connect.cc
odbconn.cpp
odbconn.h
tabodbc.h
tabodbc.cpp
rcmsg.c
tabfmt.h
tabmysql.cpp
tabwmi.cpp
tabwmi.h
resource.h
myconn.h
filamdbf.h
connect.cc
connect.h

Added:
myutil.h
parent ec2112f3
......@@ -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. */
......
......@@ -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);
......@@ -16,6 +16,11 @@ typedef class DBFBASE *PDBF;
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. */
/****************************************************************************/
......
......@@ -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);
......
......@@ -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 --------------------------- */
/***********************************************************************/
......
......@@ -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 --------------------------- */
......
......@@ -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;
......
/***********************************************************************/
/* 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);
......@@ -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,14 +1642,65 @@ 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. */
/***********************************************************************/
......
......@@ -4,6 +4,14 @@
//nclude <windows.h> /* Windows include file */
//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. */
/***********************************************************************/
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -11,6 +11,11 @@
//pedef struct _tabdesc *PTABD; // For friend setting
typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr);
/***********************************************************************/
/* CSV table. */
/***********************************************************************/
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
......@@ -32,14 +32,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. */
/***********************************************************************/
......
......@@ -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 ---------------------------- */
/***********************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment