summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/connect/filamdbf.cpp74
-rw-r--r--storage/connect/ha_connect.cc165
-rw-r--r--storage/connect/mycat.cc79
-rw-r--r--storage/connect/myconn.cpp225
-rw-r--r--storage/connect/myconn.h2
-rw-r--r--storage/connect/odbconn.cpp54
-rw-r--r--storage/connect/plgdbsem.h28
-rw-r--r--storage/connect/plgdbutl.cpp85
-rw-r--r--storage/connect/reldef.cpp2
-rw-r--r--storage/connect/reldef.h1
-rw-r--r--storage/connect/tabdos.cpp14
-rw-r--r--storage/connect/tabdos.h1
-rw-r--r--storage/connect/tabfix.h19
-rw-r--r--storage/connect/tabfmt.cpp141
-rw-r--r--storage/connect/tabfmt.h37
-rw-r--r--storage/connect/table.cpp181
-rw-r--r--storage/connect/tabmysql.cpp31
-rw-r--r--storage/connect/tabmysql.h29
-rw-r--r--storage/connect/tabodbc.cpp252
-rw-r--r--storage/connect/tabodbc.h101
-rw-r--r--storage/connect/tabwmi.cpp452
-rw-r--r--storage/connect/tabwmi.h79
-rw-r--r--storage/connect/xtable.h71
23 files changed, 937 insertions, 1186 deletions
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index e8aace3fc06..29cfb70c116 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -48,8 +48,6 @@
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
-//#include "catalog.h"
-//#include "kindex.h"
#include "filamdbf.h"
#include "tabdos.h"
#include "valblk.h"
@@ -65,12 +63,6 @@
#define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */
#define EOH 0x0D /* end-of-header marker in .dbf file */
-/****************************************************************************/
-/* Catalog utility function. */
-/****************************************************************************/
-PQRYRES PlgAllocResult(PGLOBAL, int, int, int, int *, int *,
- unsigned int *, bool blank = true, bool nonull = false);
-
extern "C" int trace; // The general trace value
/****************************************************************************/
@@ -186,10 +178,12 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf)
/****************************************************************************/
PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
{
- static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
- DB_INT, DB_INT, DB_SHORT};
- static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
- TYPE_INT, TYPE_INT, TYPE_SHORT};
+ static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
+ DB_INT, DB_INT, DB_SHORT};
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
+ TYPE_INT, TYPE_INT, TYPE_SHORT};
+ static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME,
+ FLD_PREC, FLD_LENGTH, FLD_SCALE};
static unsigned int length[] = {11, 6, 8, 10, 10, 6};
char buf[2], filename[_MAX_PATH];
int ncol = sizeof(dbtype) / sizeof(int);
@@ -204,35 +198,41 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
if (trace)
htrc("DBFColumns: File %s\n", SVP(fn));
- if (!fn) {
- strcpy(g->Message, MSG(MISSING_FNAME));
- return NULL;
- } // endif fn
+ if (!info) {
+ if (!fn) {
+ strcpy(g->Message, MSG(MISSING_FNAME));
+ return NULL;
+ } // endif fn
- /**************************************************************************/
- /* Open the input file. */
- /**************************************************************************/
- PlugSetPath(filename, fn, PlgGetDataPath(g));
+ /************************************************************************/
+ /* Open the input file. */
+ /************************************************************************/
+ PlugSetPath(filename, fn, PlgGetDataPath(g));
- if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
- return NULL;
+ if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
+ return NULL;
- /**************************************************************************/
- /* Get the first 32 bytes of the header. */
- /**************************************************************************/
- if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) {
- fclose(infile);
- return NULL;
- } // endif dbfhead
+ /************************************************************************/
+ /* Get the first 32 bytes of the header. */
+ /************************************************************************/
+ if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) {
+ fclose(infile);
+ return NULL;
+ } // endif dbfhead
+
+ /************************************************************************/
+ /* Allocate the structures used to refer to the result set. */
+ /************************************************************************/
+ fields = mainhead.Fields;
+ } else
+ fields = 0;
- /**************************************************************************/
- /* Allocate the structures used to refer to the result set. */
- /**************************************************************************/
-//fields = (mainhead.Headlen - 33) / 32;
- fields = mainhead.Fields;
qrp = PlgAllocResult(g, ncol, fields, IDS_COLUMNS + 3,
- dbtype, buftyp, length);
- qrp->Info = info || (rc == RC_INFO);
+ dbtype, buftyp, fldtyp, length, true, false);
+//qrp->Info = info || (rc == RC_INFO);
+
+ if (info)
+ return qrp;
if (trace) {
htrc("Structure of %s\n", filename);
@@ -316,6 +316,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
qrp->Nblin = field;
fclose(infile);
+#if 0
if (info) {
/************************************************************************/
/* Prepare return message for dbfinfo command. */
@@ -330,6 +331,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
strcat(g->Message, buf);
} // endif info
+#endif // 0
/**************************************************************************/
/* Return the result pointer for use by GetData routines. */
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index f8dff85dd71..4d1ee88c8a1 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -138,10 +138,6 @@
#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 */
-#endif
-
#ifdef LIBXML2_SUPPORT
void XmlInitParserLib(void);
void XmlCleanupParserLib(void);
@@ -1379,9 +1375,6 @@ int ha_connect::MakeRecord(char *buf)
// This is for variable_length rows
memset(buf, 0, table->s->null_bytes);
- // store needs a charset, why not this one?
- charset= table->s->table_charset;
-
// When sorting read_set selects all columns, so we use def_read_set
map= (const MY_BITMAP *)&table->def_read_set;
@@ -1389,6 +1382,9 @@ int ha_connect::MakeRecord(char *buf)
for (field= table->field; *field && !rc; field++) {
fp= *field;
+ // Default charset
+ charset= table->s->table_charset;
+
#if defined(MARIADB)
if (fp->vcol_info && !fp->stored_in_db)
continue; // This is a virtual column
@@ -1409,28 +1405,35 @@ int ha_connect::MakeRecord(char *buf)
value= colp->GetValue();
// All this could be better optimized
- if (value->GetType() == TYPE_DATE) {
- if (!sdval)
- sdval= AllocateValue(xp->g, TYPE_STRING, 20);
-
- switch (fp->type()) {
- case MYSQL_TYPE_DATE:
- fmt= "%Y-%m-%d";
- break;
- case MYSQL_TYPE_TIME:
- fmt= "%H:%M:%S";
- break;
- default:
- fmt= "%Y-%m-%d %H:%M:%S";
- } // endswitch type
-
- // Get date in the format required by MySQL fields
- value->FormatValue(sdval, fmt);
- p= sdval->GetCharValue();
- } else if (value->GetType() == TYPE_FLOAT)
- p= NULL;
- else
- p= value->GetCharString(val);
+ switch (value->GetType()) {
+ case TYPE_DATE:
+ if (!sdval)
+ sdval= AllocateValue(xp->g, TYPE_STRING, 20);
+
+ switch (fp->type()) {
+ case MYSQL_TYPE_DATE:
+ fmt= "%Y-%m-%d";
+ break;
+ case MYSQL_TYPE_TIME:
+ fmt= "%H:%M:%S";
+ break;
+ default:
+ fmt= "%Y-%m-%d %H:%M:%S";
+ } // endswitch type
+
+ // Get date in the format required by MySQL fields
+ value->FormatValue(sdval, fmt);
+ p= sdval->GetCharValue();
+ break;
+ case TYPE_FLOAT:
+ p= NULL;
+ break;
+ case TYPE_STRING:
+ charset= fp->charset();
+ // Passthru
+ default:
+ p= value->GetCharString(val);
+ } // endswitch Type
if (p) {
if (fp->store(p, strlen(p), charset, CHECK_FIELD_WARN)) {
@@ -3253,17 +3256,20 @@ 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, fnc= 0;
- const char *typn= "DOS";
+ char ttp= '?', spc= ',', qch= 0, fnc= '*';
+ const char *typn= "?";
const char *user;
- char *fn, *dsn, *tab, *db, *host, *pwd, *prt, *sep;
+ char *fn, *dsn, *tab, *db, *host, *pwd, *prt, *sep, *csn;
#if defined(WIN32)
char *nsp= NULL, *cls= NULL;
#endif // WIN32
+ char *supfnc = "*C";
int port= MYSQL_PORT, hdr= 0, mxr= 0;
+ uint tm;
bool b= false, ok= false, dbf= false;
LEX_STRING *comment, *name;
HA_CREATE_INFO *create_info= (HA_CREATE_INFO *)crt_info;
+ CHARSET_INFO *cs;
engine_option_value *pov;
PQRYRES qrp;
PCOLRES crp;
@@ -3325,6 +3331,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
else
ok= true;
+ supfnc = "*CTSD";
break;
#endif // ODBC_SUPPORT
case 'A': // DBF
@@ -3354,6 +3361,13 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
sprintf(g->Message, "Cannot get column info for table type %s", typn);
} // endif ttp
+ // Check for supported catalog function
+ if (ok && !strchr(supfnc, fnc)) {
+ sprintf(g->Message, "Unsupported catalog function %c for table type %s",
+ fnc, typn);
+ ok= false;
+ } // endif supfnc
+
if (ok) {
char *length, *decimals, *cnm, *rem;
int i, len, dec;
@@ -3368,7 +3382,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
switch (ttp) {
case 'A':
- qrp= DBFColumns(g, fn, false);
+ qrp= DBFColumns(g, fn, fnc == 'C');
break;
#if defined(ODBC_SUPPORT)
case 'O':
@@ -3394,15 +3408,16 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
#endif // ODBC_SUPPORT
#if defined(MYSQL_SUPPORT)
case 'Y':
- qrp= MyColumns(g, host, db, user, pwd, tab, NULL, port, false);
+ qrp= MyColumns(g, host, db, user, pwd, tab,
+ NULL, port, false, fnc == 'C');
break;
#endif // MYSQL_SUPPORT
case 'C':
- qrp= CSVColumns(g, fn, spc, qch, hdr, mxr);
+ qrp= CSVColumns(g, fn, spc, qch, hdr, mxr, fnc == 'C');
break;
#if defined(WIN32)
case 'W':
- qrp= WMIColumns(g, nsp, cls, NULL);
+ qrp= WMIColumns(g, nsp, cls, fnc == 'C');
break;
#endif // WIN32
} // endswitch ttp
@@ -3412,7 +3427,8 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
return true;
} // endif qrp
- if (fnc) {
+ if (fnc && fnc != '*') {
+ // Catalog table
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
cnm= encode(g, crp->Name);
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
@@ -3425,39 +3441,60 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
// Now add the field
b= add_fields(thd, alt_info, name, type, length, decimals,
- 0, comment, NULL, NULL, NULL);
+ NOT_NULL_FLAG, comment, NULL, NULL, NULL);
} // endfor crp
- } else
+ } else // Not a catalog table
for (i= 0; !b && i < qrp->Nblin; i++) {
- crp= qrp->Colresp; // Column Name
- cnm= encode(g, crp->Kdata->GetCharValue(i));
- name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
- crp= crp->Next; // Data Type
- type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true);
- crp= crp->Next; // Type Name
- crp= crp->Next; // Precision (length)
- len= crp->Kdata->GetIntValue(i);
- length= (char*)PlugSubAlloc(g, NULL, 8);
- sprintf(length, "%d", len);
- crp= crp->Next; // Length
- crp= crp->Next; // Scale (precision)
-
- if ((dec= crp->Kdata->GetIntValue(i))) {
- decimals= (char*)PlugSubAlloc(g, NULL, 8);
- sprintf(decimals, "%d", dec);
- } else
- decimals= NULL;
-
- if ((crp= crp->Next) && // Remark (comment)
- (rem= crp->Kdata->GetCharValue(i)))
- comment= thd->make_lex_string(NULL, rem, strlen(rem), true);
- else
- comment= thd->make_lex_string(NULL, "", 0, true);
+ rem= "";
+ length= "";
+ decimals= NULL;
+ tm= NOT_NULL_FLAG;
+ cs= NULL;
+
+ for (crp= qrp->Colresp; crp; crp= crp->Next)
+ switch (crp->Fld) {
+ case FLD_NAME:
+ cnm= encode(g, crp->Kdata->GetCharValue(i));
+ name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
+ break;
+ case FLD_TYPE:
+ type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true);
+ break;
+ case FLD_PREC:
+ len= crp->Kdata->GetIntValue(i);
+ length= (char*)PlugSubAlloc(g, NULL, 8);
+ sprintf(length, "%d", len);
+ break;
+ case FLD_SCALE:
+ if ((dec= crp->Kdata->GetIntValue(i))) {
+ decimals= (char*)PlugSubAlloc(g, NULL, 8);
+ sprintf(decimals, "%d", dec);
+ } else
+ decimals= NULL;
+
+ break;
+ case FLD_NULL:
+ if (crp->Kdata->GetIntValue(i))
+ tm= 0; // Nullable
+
+ break;
+ case FLD_REM:
+ rem= crp->Kdata->GetCharValue(i);
+ break;
+// case FLD_CHARSET:
+ // No good because remote table is already translated
+// if (*(csn= crp->Kdata->GetCharValue(i)))
+// cs= get_charset_by_name(csn, 0);
+
+// break;
+ } // endswitch Fld
+
+ comment= thd->make_lex_string(NULL, rem, strlen(rem), true);
// Now add the field
b= add_fields(thd, alt_info, name, type, length, decimals,
- 0, comment, NULL, NULL, NULL);
+ tm, comment, cs, NULL, NULL);
} // endfor i
return b;
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 4865711e3a4..bbf38fa0374 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -100,84 +100,9 @@ extern int xtrace;
/**************************************************************************/
//bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR);
//#if !defined(WIN32)
-extern "C" int GetRcString(int id, char *buf, int bufsize);
//#endif // !WIN32
//void ptrc(char const *fmt, ...);
-/**************************************************************************/
-/* 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 = false, bool nonull = false)
- {
- char cname[NAM_LEN+1];
- int i;
- PCOLRES *pcrp, crp;
- PQRYRES qrp;
-
- /************************************************************************/
- /* Allocate the structure used to contain the result set. */
- /************************************************************************/
- qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
- pcrp = &qrp->Colresp;
- qrp->Continued = false;
- qrp->Truncated = false;
- qrp->Info = false;
- qrp->Suball = true;
- qrp->Maxres = maxres;
- qrp->Maxsize = 0;
- qrp->Nblin = 0;
- qrp->Nbcol = 0; // will be ncol
- qrp->Cursor = 0;
- qrp->BadLines = 0;
-
- for (i = 0; i < ncol; i++) {
- *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
- crp = *pcrp;
- pcrp = &crp->Next;
- crp->Colp = NULL;
- crp->Ncol = ++qrp->Nbcol;
- crp->Type = buftyp[i];
- crp->Length = length[i];
- crp->Clen = GetTypeSize(crp->Type, length[i]);
- crp->Prec = 0;
- crp->DBtype = dbtype[i];
-
- if (ids > 0) {
-#if defined(XMSG)
- // Get header from message file
- strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
- cname[NAM_LEN] = 0; // for truncated long names
-//#elif defined(WIN32)
- // Get header from ressource file
-// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
-#else // !WIN32
- GetRcString(ids + crp->Ncol, cname, sizeof(cname));
-#endif // !WIN32
- crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1);
- strcpy(crp->Name, cname);
- } else
- crp->Name = NULL; // Will be set by caller
-
- // Allocate the Value Block that will contain data
- if (crp->Length || nonull)
- crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
- crp->Length, 0, true, blank);
- else
- crp->Kdata = NULL;
-
- if (g->Trace)
- htrc("Column(%d) %s type=%d len=%d value=%p\n",
- crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
-
- } // endfor i
-
- *pcrp = NULL;
-
- return qrp;
- } // end of PlgAllocResult
-
/***********************************************************************/
/* Get a unique char identifier for types. The letter used are: */
/* ABCDEF..I.KLM.O..R.T.VWXY.. */
@@ -345,14 +270,14 @@ char *MYCAT::GetStringCatInfo(PGLOBAL g, PSZ name, PSZ what, PSZ sdef)
/***********************************************************************/
int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
{
- char *type= GetStringCatInfo(g, NULL, "Type", "DOS");
+ char tc, *type= GetStringCatInfo(g, NULL, "Type", "DOS");
int i, loff, poff, nof, nlg;
void *field= NULL;
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
// Get a unique char identifier for type
- char tc= GetTypeID(type);
+ tc= (!defp->Catfunc) ? GetTypeID(type) : 0;
// Take care of the column definitions
i= poff= nof= nlg= 0;
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index d8e7a4425de..b4347f11094 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -1,11 +1,11 @@
/************** MyConn C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYCONN */
/* ------------- */
-/* Version 1.5 */
+/* Version 1.6 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2007-2012 */
+/* (C) Copyright to the author Olivier BERTRAND 2007-2013 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -63,13 +63,6 @@ static char *server_groups[] = {
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. */
@@ -78,13 +71,18 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
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)
+ int port, bool key, bool info)
{
- 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};
+ static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT,
+ DB_CHAR, DB_SHORT, DB_SHORT, DB_SHORT,
+ DB_CHAR, DB_CHAR, DB_CHAR};
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
+ TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
+ TYPE_STRING, TYPE_STRING, TYPE_STRING};
+ static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
+ FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
+ FLD_REM, FLD_NO, FLD_CHARSET};
+ static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
char *fld, *fmt, cmd[128];
int i, n, nf, ncol = sizeof(dbtype) / sizeof(int);
int len, type, prec, rc, k = 0;
@@ -92,44 +90,59 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
PCOLRES crp;
MYSQLC myc;
- /**********************************************************************/
- /* Open the connection with the MySQL server. */
- /**********************************************************************/
- if (myc.Open(g, host, db, user, pwd, port))
- return NULL;
+ if (!info) {
+ /********************************************************************/
+ /* 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);
+ /********************************************************************/
+ /* 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 (colpat)
+ strcat(strcat(cmd, " LIKE "), colpat);
- if (trace)
- htrc("MyColumns: cmd='%s'\n", cmd);
+ if (trace)
+ htrc("MyColumns: cmd='%s'\n", cmd);
- if ((n = myc.GetResultSize(g, cmd)) < 0) {
- myc.Close();
- return NULL;
- } // endif n
+ 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);
+ /********************************************************************/
+ /* Get the size of the name columns. */
+ /********************************************************************/
+ length[0] = myc.GetFieldLength(0);
+ } else {
+ n = 0;
+ length[0] = 128;
+ } // endif info
- if (!key) // We are not called from Create table
- ncol--; // No date format column
+//if (!key) // We are not called from Create table
+// ncol--; // No date format column yet
/**********************************************************************/
/* Allocate the structures used to refer to the result set. */
/**********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
- dbtype, buftyp, length);
+ dbtype, buftyp, fldtyp, length, true, true);
+
+ // Some columns must be renamed
+ for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
+ switch (++i) {
+ case 4: crp->Name = "Length"; break;
+ case 5: crp->Name = "Key"; break;
+ case 10: crp->Name = "Date_fmt"; break;
+ case 11: crp->Name = "Collation"; break;
+ } // endswitch i
+
+ if (info)
+ return qrp;
/**********************************************************************/
/* Now get the results into blocks. */
@@ -142,7 +155,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
// Get column name
fld = myc.GetCharField(0);
- crp = qrp->Colresp;
+ crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue(fld, i);
// Get type, type name, and precision
@@ -161,56 +174,45 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
return NULL;
} // endif type
- crp = crp->Next;
+ crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i);
- crp = crp->Next;
+ crp = crp->Next; // Type_Name
crp->Kdata->SetValue(cmd, i);
- if (key && type == TYPE_DATE) {
+ if (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 = crp->Next; // Precision
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; // was Length
+ fld = myc.GetCharField(4);
+ crp->Kdata->SetValue(fld, i);
- crp = crp->Next;
- crp->Name = "Prec";
+ crp = crp->Next; // Scale
crp->Kdata->SetValue(prec, i);
- // Get comment field
- crp = crp->Next;
- crp->Name = "Comment";
- fld = myc.GetCharField(8);
+ crp = crp->Next; // Radix
+ crp->Kdata->SetValue(0, i);
- if (fld && strlen(fld))
- crp->Kdata->SetValue(fld, i);
- else
- crp->Kdata->Reset(i);
+ crp = crp->Next; // Nullable
+ fld = myc.GetCharField(3);
+ crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i);
- if (key) {
- crp = crp->Next;
- crp->Name = "Date_Fmt";
-
- if (fmt)
- crp->Kdata->SetValue(fmt, i);
- else
- crp->Kdata->Reset(i);
+ crp = crp->Next; // Remark
+ fld = myc.GetCharField(8);
+ crp->Kdata->SetValue(fld, i);
- } // endif key
+ crp = crp->Next; // New
+ crp->Kdata->SetValue((fmt) ? fmt : "", i);
+ crp = crp->Next; // New (charset)
+ fld = myc.GetCharField(2);
+ crp->Kdata->SetValue(fld, i);
} // endfor i
if (k > 1) {
@@ -234,79 +236,6 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
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 fc462aaa22a..1aab55f1e01 100644
--- a/storage/connect/myconn.h
+++ b/storage/connect/myconn.h
@@ -38,7 +38,7 @@ typedef class MYSQLC *PMYC;
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);
+ int port, bool key, bool info);
/* -------------------------- MYCONN class --------------------------- */
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index d9e3e3f4d58..0519a8141e6 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -171,13 +171,6 @@ int TranslateSQLType(int stp, int prec, int& len)
HENV ODBConn::m_henv = SQL_NULL_HENV;
int ODBConn::m_nAlloc = 0; // per-Appl reference to HENV above
-/**************************************************************************/
-/* 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);
-
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
/***********************************************************************/
@@ -235,14 +228,18 @@ void ResetNullValues(CATPARM *cap)
PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table,
char *colpat)
{
- static int dbtype[] = {DB_CHAR, DB_CHAR,
- DB_CHAR, DB_SHORT, DB_CHAR,
- DB_INT, DB_INT, DB_SHORT,
- DB_SHORT, DB_SHORT, DB_CHAR};
- static int buftyp[] = {TYPE_STRING, TYPE_STRING,
- TYPE_STRING, TYPE_SHORT, TYPE_STRING,
- TYPE_INT, TYPE_INT, TYPE_SHORT,
- TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
+ static int dbtype[] = {DB_CHAR, DB_CHAR,
+ DB_CHAR, DB_SHORT, DB_CHAR,
+ DB_INT, DB_INT, DB_SHORT,
+ DB_SHORT, DB_SHORT, DB_CHAR};
+ static int buftyp[] = {TYPE_STRING, TYPE_STRING,
+ TYPE_STRING, TYPE_SHORT, TYPE_STRING,
+ TYPE_INT, TYPE_INT, TYPE_SHORT,
+ TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
+ static XFLD fldtyp[] = {FLD_NO, FLD_NO,
+ FLD_NAME, FLD_TYPE, FLD_TYPENAME,
+ FLD_PREC, FLD_LENGTH, FLD_SCALE,
+ FLD_RADIX, FLD_NULL, FLD_REM};
static unsigned int length[] = {0, 0, 0, 6, 20, 10, 10, 6, 6, 6, 128};
int n, ncol = 11;
int maxres;
@@ -277,7 +274,7 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table,
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS + 1,
- dbtype, buftyp, length);
+ dbtype, buftyp, NULL, length, true, true);
if (!ocp) // Info table
return qrp;
@@ -313,8 +310,8 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table,
/**************************************************************************/
PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
{
- int type, len, prec;
- PCOLRES crpt, crpl, crpp;
+// int i, type, len, prec;
+// PCOLRES crp, crpt, crpl, crpp;
PQRYRES qrp;
ODBConn *ocp;
@@ -342,6 +339,7 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
if (ocp)
ocp->Close();
+#if 0
if (!qrp)
return NULL; // Error in ODBCColumns
@@ -371,7 +369,13 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
} // endfor i
crpp->Next = crpp->Next->Next->Next; // Should be Remark
- qrp->Nbcol = 7; // Was 11, skipped 4
+
+ // Renumber crp's for flag comparison
+ for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
+ crp->Ncol = ++i;
+
+ qrp->Nbcol = i; // Should be 7; was 11, skipped 4
+#endif // 0
return qrp;
} // end of MyODBCCols
@@ -410,7 +414,8 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info)
/************************************************************************/
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
- qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC, dbtype, buftyp, length);
+ qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC,
+ dbtype, buftyp, NULL, length, true, true);
/************************************************************************/
/* Now get the results into blocks. */
@@ -455,7 +460,8 @@ PQRYRES ODBCDrivers(PGLOBAL g, bool info)
/************************************************************************/
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
- qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER, dbtype, buftyp, length);
+ qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER,
+ dbtype, buftyp, NULL, length, true, true);
/************************************************************************/
/* Now get the results into blocks. */
@@ -521,7 +527,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info)
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES + 1,
- dbtype, buftyp, length);
+ dbtype, buftyp, NULL, length, true, true);
if (info)
return qrp;
@@ -606,7 +612,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table)
/* Allocate the structure used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY + 1,
- dbtype, buftyp, length);
+ dbtype, buftyp, NULL, length, true, true);
#ifdef DEBTRACE
htrc("Getting pkey results ncol=%d\n", qrp->Nbcol);
@@ -693,7 +699,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
/* Allocate the structure used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT + 1,
- dbtype, buftyp, length);
+ dbtype, buftyp, NULL, length, true, true);
#ifdef DEBTRACE
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 0a412972ce1..7a8e13fa4c5 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -96,6 +96,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
TYPE_AM_SET = 180, /* SET Set tables am type no */
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
+ TYPE_AM_CAT = 193, /* Catalog access method type no */
TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */
@@ -441,6 +442,25 @@ typedef struct _tabs {
} TABS;
/***********************************************************************/
+/* Following definitions are used to define table fields (columns). */
+/***********************************************************************/
+enum XFLD {FLD_NO = 0, /* Not a field definition item */
+ FLD_NAME = 1, /* Field name */
+ FLD_TYPE = 2, /* Field type */
+ FLD_TYPENAME = 3, /* Field type name */
+ FLD_PREC = 4, /* Field precision (length?) */
+ FLD_LENGTH = 5, /* Field length (?) */
+ FLD_SCALE = 6, /* Field scale (precision) */
+ FLD_RADIX = 7, /* Field radix */
+ FLD_NULL = 8, /* Field nullable property */
+ FLD_REM = 9, /* Field comment (remark) */
+ FLD_CHARSET = 10, /* Field collation */
+ FLD_KEY = 11, /* Field key property */
+ FLD_DEFAULT = 12, /* Field default value */
+ FLD_PRIV = 13, /* Field priviledges */
+ FLD_DATEFMT = 14}; /* Field date format */
+
+/***********************************************************************/
/* Result of last SQL noconv query. */
/***********************************************************************/
typedef struct _qryres {
@@ -470,6 +490,7 @@ typedef struct _colres {
int Clen; /* Data individual internal size */
int Length; /* Data individual print length */
int Prec; /* Precision */
+ XFLD Fld; /* Type of field info */
} COLRES;
#if defined(WIN32) && !defined(NOEX)
@@ -491,6 +512,13 @@ void AddPointer(PTABS, void *);
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
int ExtractDate(char *, PDTP, int, int val[6]);
+/**************************************************************************/
+/* Allocate the result structure that will contain result data. */
+/**************************************************************************/
+PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
+ int *dbtype, int *buftyp, XFLD *fldtyp,
+ unsigned int *length, bool blank, bool nonull);
+
/***********************************************************************/
/* Exported utility routines. */
/***********************************************************************/
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index e980926c820..2e0564e8735 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -1,11 +1,11 @@
/********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: PLGDBUTL */
/* ------------- */
-/* Version 3.7 */
+/* Version 3.8 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -66,6 +66,7 @@
#include "colblk.h"
#include "xtable.h" // header of TBX, TDB and TDBASE classes
#include "tabcol.h" // header of XTAB and COLUMN classes
+#include "valblk.h"
/***********************************************************************/
/* Macro or external routine definition */
@@ -128,6 +129,7 @@ void CloseXMLFile(PGLOBAL, PFBLOCK, bool);
void CloseXML2File(PGLOBAL, PFBLOCK, bool);
#endif // LIBXML2_SUPPORT
+extern "C" int GetRcString(int id, char *buf, int bufsize);
/***********************************************************************/
/* Routines for file IO with error reporting to g->Message */
@@ -262,6 +264,85 @@ void ptrc(char const *fmt, ...)
} // end of ptrc
#endif // 0
+/**************************************************************************/
+/* Allocate the result structure that will contain result data. */
+/**************************************************************************/
+PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
+ int *dbtype, int *buftyp, XFLD *fldtyp,
+ unsigned int *length, bool blank, bool nonull)
+ {
+ char cname[NAM_LEN+1];
+ int i;
+ PCOLRES *pcrp, crp;
+ PQRYRES qrp;
+
+ /************************************************************************/
+ /* Allocate the structure used to contain the result set. */
+ /************************************************************************/
+ qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
+ pcrp = &qrp->Colresp;
+ qrp->Continued = false;
+ qrp->Truncated = false;
+ qrp->Info = false;
+ qrp->Suball = true;
+ qrp->Maxres = maxres;
+ qrp->Maxsize = 0;
+ qrp->Nblin = 0;
+ qrp->Nbcol = 0; // will be ncol
+ qrp->Cursor = 0;
+ qrp->BadLines = 0;
+
+ for (i = 0; i < ncol; i++) {
+ *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
+ crp = *pcrp;
+ pcrp = &crp->Next;
+ crp->Colp = NULL;
+ crp->Ncol = ++qrp->Nbcol;
+ crp->Type = buftyp[i];
+ crp->Length = length[i];
+ crp->Clen = GetTypeSize(crp->Type, length[i]);
+ crp->Prec = 0;
+ crp->DBtype = dbtype[i];
+
+ if (ids > 0) {
+#if defined(XMSG)
+ // Get header from message file
+ strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
+ cname[NAM_LEN] = 0; // for truncated long names
+//#elif defined(WIN32)
+ // Get header from ressource file
+// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
+#else // !WIN32
+ GetRcString(ids + crp->Ncol, cname, sizeof(cname));
+#endif // !WIN32
+ crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1);
+ strcpy(crp->Name, cname);
+ } else
+ crp->Name = NULL; // Will be set by caller
+
+ if (fldtyp)
+ crp->Fld = fldtyp[i];
+ else
+ crp->Fld = FLD_NO;
+
+ // Allocate the Value Block that will contain data
+ if (crp->Length || nonull)
+ crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
+ crp->Length, 0, true, blank);
+ else
+ crp->Kdata = NULL;
+
+ if (g->Trace)
+ htrc("Column(%d) %s type=%d len=%d value=%p\n",
+ crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
+
+ } // endfor i
+
+ *pcrp = NULL;
+
+ return qrp;
+ } // end of PlgAllocResult
+
/***********************************************************************/
/* Allocate and initialize the new DB User Block. */
/***********************************************************************/
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index bf129a2f54a..4f99b2da6d6 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -74,6 +74,7 @@ TABDEF::TABDEF(void)
{
Owner = NULL;
Desc = NULL;
+ Catfunc = 0;
Card = 0;
Elemt = 0;
Sort = 0;
@@ -95,6 +96,7 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am)
Name = (PSZ)PlugSubAlloc(g, memp, strlen(name) + 1);
strcpy(Name, name);
Cat = cat;
+ Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", ""));
Elemt = cat->GetIntCatInfo(name, "Elements", 0);
Multiple = cat->GetIntCatInfo(name, "Multiple", 0);
Degree = cat->GetIntCatInfo(name, "Degree", 0);
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index ac006f5c7e9..8f14d28599f 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -85,6 +85,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
// Members
PSZ Owner; /* Table owner (for ODBC) */
PSZ Desc; /* Table description */
+ char Catfunc; /* Catalog function */
int Card; /* (max) number of rows in table */
int Elemt; /* Number of rows in blocks or rowset */
int Sort; /* Table already sorted ??? */
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 5218a322ea6..930048346b9 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -297,12 +297,16 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
/* Column blocks will be allocated only when needed. */
/*********************************************************************/
if (Recfm == RECFM_DBF) {
- if (map)
- txfp = new(g) DBMFAM(this);
- else
- txfp = new(g) DBFFAM(this);
+ if (!Catfunc) {
+ if (map)
+ txfp = new(g) DBMFAM(this);
+ else
+ txfp = new(g) DBFFAM(this);
+
+ tdbp = new(g) TDBFIX(this, txfp);
+ } else // Catfunc should be 'C'
+ tdbp = new(g) TDBDCL(this);
- tdbp = new(g) TDBFIX(this, txfp);
} else if (Recfm != RECFM_VAR && Compressed < 2) {
if (Huge)
txfp = new(g) BGXFAM(this);
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index a1c5b0660cd..2f1f0a5ecf9 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -34,6 +34,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
virtual const char *GetType(void) {return "DOS";}
virtual PIXDEF GetIndx(void) {return To_Indx;}
virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;}
+ PSZ GetFn(void) {return Fn;}
PSZ GetOfn(void) {return Ofn;}
void SetBlock(int block) {Block = block;}
int GetBlock(void) {return Block;}
diff --git a/storage/connect/tabfix.h b/storage/connect/tabfix.h
index 0a4f9fc4872..bcd171b37bb 100644
--- a/storage/connect/tabfix.h
+++ b/storage/connect/tabfix.h
@@ -8,6 +8,7 @@
#ifndef __TABFIX__
#define __TABFIX__
#include "tabdos.h" /* Base class declares */
+#include "filamdbf.h"
typedef class FIXCOL *PFIXCOL;
typedef class BINCOL *PBINCOL;
@@ -77,4 +78,22 @@ class DllExport BINCOL : public DOSCOL {
// Members
char Fmt; // The column numeric format
}; // end of class BINCOL
+
+/***********************************************************************/
+/* This is the class declaration for the DBF columns catalog table. */
+/***********************************************************************/
+class TDBDCL : public TDBCAT {
+ public:
+ // Constructor
+ TDBDCL(PDOSDEF tdp) : TDBCAT(tdp) {Fn = tdp->GetFn();}
+
+ protected:
+ // Specific routines
+ virtual PQRYRES GetResult(PGLOBAL g) {return DBFColumns(g, Fn, false);}
+
+ // Members
+ char *Fn; // The DBF file (path) name
+ }; // end of class TDBOCL
+
+
#endif // __TABFIX__
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 9b4589a71a7..6834ca5ea28 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -1,7 +1,7 @@
/************* TabFmt C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFMT */
/* ------------- */
-/* Version 3.7 */
+/* Version 3.8 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -68,24 +68,21 @@
extern "C" int trace;
/***********************************************************************/
-/* CSV Catalog utility functions. */
-/***********************************************************************/
-PQRYRES PlgAllocResult(PGLOBAL, int, int, int, int *, int *,
- unsigned int *, bool blank = true, bool nonull = false);
-
-/***********************************************************************/
/* CSVColumns: constructs the result blocks containing the description */
/* of all the columns of a CSV file that will be retrieved by #GetData.*/
/* Note: the algorithm to set the type is based on the internal values */
/* of types (TYPE_STRING < TYPE_FLOAT < TYPE_INT) (1 < 2 < 7). */
/* If these values are changed, this will have to be revisited. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr)
+PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q,
+ int hdr, int mxr, bool info)
{
- static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
- DB_INT, DB_INT, DB_SHORT};
- static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
- TYPE_INT, TYPE_INT, TYPE_SHORT};
+ static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
+ DB_INT, DB_INT, DB_SHORT};
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
+ TYPE_INT, TYPE_INT, TYPE_SHORT};
+ static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME,
+ FLD_PREC, FLD_LENGTH, FLD_SCALE};
static unsigned int length[] = {6, 6, 8, 10, 10, 6};
char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
int i, imax, hmax, n, nerr, phase, blank, digit, dec, type;
@@ -96,9 +93,15 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr)
PQRYRES qrp;
PCOLRES crp;
+ if (info) {
+ imax = 0;
+ length[0] = 128;
+ goto skipit;
+ } // endif info
+
// num_max = atoi(p+1); // Max num of record to test
#if defined(WIN32)
- if (strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
+ if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
dechar = '.';
else
dechar = ',';
@@ -328,6 +331,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr)
fclose(infile);
+ skipit:
if (trace)
htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
imax, hmax, length[0]);
@@ -336,9 +340,12 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr)
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
- dbtype, buftyp, length);
+ dbtype, buftyp, fldtyp, length, true, false);
qrp->Nblin = imax;
+ if (info)
+ return qrp;
+
/*********************************************************************/
/* Now get the results into blocks. */
/*********************************************************************/
@@ -398,11 +405,12 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
char buf[8];
// Double check correctness of offset values
- for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
- if (cdp->GetOffset() < 1) {
- strcpy(g->Message, MSG(BAD_OFFSET_VAL));
- return true;
- } // endif Offset
+ if (!Catfunc)
+ for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
+ if (cdp->GetOffset() < 1) {
+ strcpy(g->Message, MSG(BAD_OFFSET_VAL));
+ return true;
+ } // endif Offset
// Call DOSDEF DefineAM with am=CSV so FMT is not confused with FIX
if (DOSDEF::DefineAM(g, "CSV", poff))
@@ -431,47 +439,52 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
{
- USETEMP tmp = PlgGetUser(g)->UseTemp;
- bool map = Mapped && mode != MODE_INSERT &&
- !(tmp != TMP_NO && mode == MODE_UPDATE) &&
- !(tmp == TMP_FORCE &&
- (mode == MODE_UPDATE || mode == MODE_DELETE));
- PTXF txfp;
PTDBASE tdbp;
- /*********************************************************************/
- /* Allocate a file processing class of the proper type. */
- /*********************************************************************/
- if (map) {
- // Should be now compatible with UNIX
- txfp = new(g) MAPFAM(this);
- } else if (Compressed) {
+ if (Catfunc != 'C') {
+ USETEMP tmp = PlgGetUser(g)->UseTemp;
+ bool map = Mapped && mode != MODE_INSERT &&
+ !(tmp != TMP_NO && mode == MODE_UPDATE) &&
+ !(tmp == TMP_FORCE &&
+ (mode == MODE_UPDATE || mode == MODE_DELETE));
+ PTXF txfp;
+
+ /*******************************************************************/
+ /* Allocate a file processing class of the proper type. */
+ /*******************************************************************/
+ if (map) {
+ // Should be now compatible with UNIX
+ txfp = new(g) MAPFAM(this);
+ } else if (Compressed) {
#if defined(ZIP_SUPPORT)
- if (Compressed == 1)
- txfp = new(g) ZIPFAM(this);
- else {
- strcpy(g->Message, "Compress 2 not supported yet");
-// txfp = new(g) ZLBFAM(defp);
- return NULL;
- } // endelse
+ if (Compressed == 1)
+ txfp = new(g) ZIPFAM(this);
+ else {
+ strcpy(g->Message, "Compress 2 not supported yet");
+// txfp = new(g) ZLBFAM(defp);
+ return NULL;
+ } // endelse
#else // !ZIP_SUPPORT
- strcpy(g->Message, "Compress not supported");
- return NULL;
+ strcpy(g->Message, "Compress not supported");
+ return NULL;
#endif // !ZIP_SUPPORT
- } else
- txfp = new(g) DOSFAM(this);
+ } else
+ txfp = new(g) DOSFAM(this);
- /*********************************************************************/
- /* Allocate a TDB of the proper type. */
- /* Column blocks will be allocated only when needed. */
- /*********************************************************************/
- if (!Fmtd)
- tdbp = new(g) TDBCSV(this, txfp);
- else
- tdbp = new(g) TDBFMT(this, txfp);
+ /*******************************************************************/
+ /* Allocate a TDB of the proper type. */
+ /* Column blocks will be allocated only when needed. */
+ /*******************************************************************/
+ if (!Fmtd)
+ tdbp = new(g) TDBCSV(this, txfp);
+ else
+ tdbp = new(g) TDBFMT(this, txfp);
- if (Multiple)
- tdbp = new(g) TDBMUL(tdbp);
+ if (Multiple)
+ tdbp = new(g) TDBMUL(tdbp);
+
+ } else
+ tdbp = new(g)TDBCCL(this);
return tdbp;
} // end of GetTable
@@ -1389,4 +1402,26 @@ void CSVCOL::WriteColumn(PGLOBAL g)
} // end of WriteColumn
+/* ---------------------------TDBCCL class --------------------------- */
+
+/***********************************************************************/
+/* TDBCCL class constructor. */
+/***********************************************************************/
+TDBCCL::TDBCCL(PCSVDEF tdp) : TDBCAT(tdp)
+ {
+ Fn = tdp->GetFn();
+ Hdr = tdp->Header;
+ Mxr = tdp->Maxerr;
+ Qtd = tdp->Quoted;
+ Sep = tdp->Sep;
+ } // end of TDBCCL constructor
+
+/***********************************************************************/
+/* GetResult: Get the list the CSV file columns. */
+/***********************************************************************/
+PQRYRES TDBCCL::GetResult(PGLOBAL g)
+ {
+ return CSVColumns(g, Fn, Sep, Qtd, Hdr, Mxr, false);
+ } // end of GetResult
+
/* ------------------------ End of TabFmt ---------------------------- */
diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h
index 95486a09881..05b9d6445c6 100644
--- a/storage/connect/tabfmt.h
+++ b/storage/connect/tabfmt.h
@@ -1,7 +1,7 @@
/*************** TabFmt H Declares Source Code File (.H) ***************/
-/* Name: TABFMT.H Version 2.2 */
+/* Name: TABFMT.H Version 2.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2012 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
/* */
/* This file contains the CSV and FMT classes declares. */
/***********************************************************************/
@@ -14,14 +14,15 @@ typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr);
+PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q,
+ int hdr, int mxr, bool info);
/***********************************************************************/
/* CSV table. */
/***********************************************************************/
class DllExport CSVDEF : public DOSDEF { /* Logical table description */
friend class TDBCSV;
-//friend class TDBMCV;
+ friend class TDBCCL;
public:
// Constructor
CSVDEF(void);
@@ -160,10 +161,30 @@ class TDBFMT : public TDBCSV {
protected:
// Members
- PSZ *FldFormat; // Field read format
- void *To_Fld; // To field test buffer
- int *FmtTest; // Test on ending by %n or %m
- int Linenum; // Last read line
+ PSZ *FldFormat; // Field read format
+ void *To_Fld; // To field test buffer
+ int *FmtTest; // Test on ending by %n or %m
+ int Linenum; // Last read line
}; // end of class TDBFMT
+/***********************************************************************/
+/* This is the class declaration for the CSV catalog table. */
+/***********************************************************************/
+class TDBCCL : public TDBCAT {
+ public:
+ // Constructor
+ TDBCCL(PCSVDEF tdp);
+
+ protected:
+ // Specific routines
+ virtual PQRYRES GetResult(PGLOBAL g);
+
+ // Members
+ char *Fn; // The CSV file (path) name
+ bool Hdr; // true if first line contains headers
+ int Mxr; // Maximum number of bad records
+ int Qtd; // Quoting level for quoted fields
+ char Sep; // Separator for standard CSV files
+ }; // end of class TDBCCL
+
/* ------------------------- End of TabFmt.H ------------------------- */
diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp
index 77c2fd4df3b..0c8e86c0457 100644
--- a/storage/connect/table.cpp
+++ b/storage/connect/table.cpp
@@ -1,7 +1,7 @@
/************** Table C++ Functions Source Code File (.CPP) ************/
-/* Name: TABLE.CPP Version 2.5 */
+/* Name: TABLE.CPP Version 2.6 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1999-2012 */
+/* (C) Copyright to the author Olivier BERTRAND 1999-2013 */
/* */
/* This file contains the TBX, TDB and OPJOIN classes functions. */
/***********************************************************************/
@@ -425,3 +425,180 @@ void TDBASE::MarkDB(PGLOBAL g, PTDB tdb2)
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB
+
+/* ---------------------------TDBCAT class --------------------------- */
+
+/***********************************************************************/
+/* Implementation of the TDBCAT class. */
+/***********************************************************************/
+TDBCAT::TDBCAT(PTABDEF tdp) : TDBASE(tdp)
+ {
+ Qrp = NULL;
+ Init = false;
+ N = -1;
+ } // end of TDBCAT constructor
+
+/***********************************************************************/
+/* Allocate CAT column description block. */
+/***********************************************************************/
+PCOL TDBCAT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
+ {
+ PCATCOL colp;
+
+ colp = (PCATCOL)new(g) CATCOL(cdp, this, n);
+
+ if (cprec) {
+ colp->SetNext(cprec->GetNext());
+ cprec->SetNext(colp);
+ } else {
+ colp->SetNext(Columns);
+ Columns = colp;
+ } // endif cprec
+
+ return colp;
+ } // end of MakeCol
+
+/***********************************************************************/
+/* Initialize: Get the result query block. */
+/***********************************************************************/
+bool TDBCAT::Initialize(PGLOBAL g)
+ {
+ if (Init)
+ return false;
+
+ if (!(Qrp = GetResult(g)))
+ return true;
+
+ Init = true;
+ return false;
+ } // end of Initialize
+
+/***********************************************************************/
+/* CAT: Get the number of properties. */
+/***********************************************************************/
+int TDBCAT::GetMaxSize(PGLOBAL g)
+ {
+ if (MaxSize < 0) {
+ if (Initialize(g))
+ return -1;
+
+ MaxSize = Qrp->Nblin;
+ } // endif MaxSize
+
+ return MaxSize;
+ } // end of GetMaxSize
+
+/***********************************************************************/
+/* CAT Access Method opening routine. */
+/***********************************************************************/
+bool TDBCAT::OpenDB(PGLOBAL g)
+ {
+ if (Use == USE_OPEN) {
+ /*******************************************************************/
+ /* Table already open. */
+ /*******************************************************************/
+ N = -1;
+ return false;
+ } // endif use
+
+ if (Mode != MODE_READ) {
+ /*******************************************************************/
+ /* ODBC Info tables cannot be modified. */
+ /*******************************************************************/
+ strcpy(g->Message, "CAT tables are read only");
+ return true;
+ } // endif Mode
+
+ /*********************************************************************/
+ /* Initialize the ODBC processing. */
+ /*********************************************************************/
+ if (Initialize(g))
+ return true;
+
+ return InitCol(g);
+ } // end of OpenDB
+
+/***********************************************************************/
+/* Initialize columns. */
+/***********************************************************************/
+bool TDBCAT::InitCol(PGLOBAL g)
+ {
+ PCATCOL colp;
+ PCOLRES crp;
+
+ for (colp = (PCATCOL)Columns; colp; colp = (PCATCOL)colp->GetNext()) {
+ for (crp = Qrp->Colresp; crp; crp = crp->Next)
+ if ((colp->Flag == crp->Ncol) ||
+ (!colp->Flag && !stricmp(colp->Name, crp->Name))) {
+ colp->Crp = crp;
+ break;
+ } // endif Flag
+
+
+ if (!colp->Crp /*&& !colp->GetValue()->IsConstant()*/) {
+ sprintf(g->Message, "Invalid flag %d for column %s",
+ colp->Flag, colp->Name);
+ return true;
+ } // endif Crp
+
+ } // endfor colp
+
+ return false;
+ } // end of InitCol
+
+/***********************************************************************/
+/* Data Base read routine for CAT access method. */
+/***********************************************************************/
+int TDBCAT::ReadDB(PGLOBAL g)
+ {
+ return (++N < Qrp->Nblin) ? RC_OK : RC_EF;
+ } // end of ReadDB
+
+/***********************************************************************/
+/* WriteDB: Data Base write routine for CAT access methods. */
+/***********************************************************************/
+int TDBCAT::WriteDB(PGLOBAL g)
+ {
+ strcpy(g->Message, "CAT tables are read only");
+ return RC_FX;
+ } // end of WriteDB
+
+/***********************************************************************/
+/* Data Base delete line routine for CAT access methods. */
+/***********************************************************************/
+int TDBCAT::DeleteDB(PGLOBAL g, int irc)
+ {
+ strcpy(g->Message, "Delete not enabled for CAT tables");
+ return RC_FX;
+ } // end of DeleteDB
+
+/***********************************************************************/
+/* Data Base close routine for WMI access method. */
+/***********************************************************************/
+void TDBCAT::CloseDB(PGLOBAL g)
+ {
+ // Nothing to do
+ } // end of CloseDB
+
+// ------------------------ CATCOL functions ----------------------------
+
+/***********************************************************************/
+/* CATCOL public constructor. */
+/***********************************************************************/
+CATCOL::CATCOL(PCOLDEF cdp, PTDB tdbp, int n)
+ : COLBLK(cdp, tdbp, n)
+ {
+ Tdbp = (PTDBCAT)tdbp;
+ Crp = NULL;
+ Flag = cdp->GetOffset();
+ } // end of WMICOL constructor
+
+/***********************************************************************/
+/* Read the next Data Source elements. */
+/***********************************************************************/
+void CATCOL::ReadColumn(PGLOBAL g)
+ {
+ // Get the value of the Name or Description property
+ Value->SetValue_pvblk(Crp->Kdata, Tdbp->N);
+ } // end of ReadColumn
+
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index a63526f1e8d..27489f4635e 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -1,7 +1,7 @@
/************* TabMySQL C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABMYSQL */
/* ------------- */
-/* Version 1.5 */
+/* Version 1.6 */
/* */
/* AUTHOR: */
/* ------- */
@@ -105,7 +105,11 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m)
{
- return new(g) TDBMYSQL(this);
+ if (Catfunc == 'C')
+ return new(g) TDBMCL(this);
+ else
+ return new(g) TDBMYSQL(this);
+
} // end of GetTable
/* ------------------------------------------------------------------- */
@@ -859,3 +863,26 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
} // endif Prep
} // end of WriteColumn
+
+/* ---------------------------TDBMCL class --------------------------- */
+
+/***********************************************************************/
+/* TDBMCL class constructor. */
+/***********************************************************************/
+TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
+ {
+ Host = tdp->Hostname;
+ Db = tdp->Database;
+ Tab = tdp->Tabname;
+ User = tdp->Username;
+ Pwd = tdp->Password;
+ Port = tdp->Portnumber;
+ } // end of TDBMCL constructor
+
+/***********************************************************************/
+/* GetResult: Get the list the MYSQL table columns. */
+/***********************************************************************/
+PQRYRES TDBMCL::GetResult(PGLOBAL g)
+ {
+ return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false, false);
+ } // end of GetResult
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 68fb9d89f24..abfdeeb13a3 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -1,4 +1,4 @@
-// TDBMYSQL.H Olivier Bertrand 2007-2012
+// TDBMYSQL.H Olivier Bertrand 2007-2013
#include "myconn.h" // MySQL connection declares
typedef class MYSQLDEF *PMYDEF;
@@ -18,6 +18,7 @@ typedef class MYSQLCOL *PMYCOL;
/***********************************************************************/
class MYSQLDEF : public TABDEF {/* Logical table description */
friend class TDBMYSQL;
+ friend class TDBMCL;
public:
// Constructor
MYSQLDEF(void);
@@ -104,7 +105,7 @@ class TDBMYSQL : public TDBASE {
int AftRows; // The number of affected rows
int N; // The current table index
int Port; // MySQL port number (0 = default)
- int Nparm; // The number of statement parameters
+ int Nparm; // The number of statement parameters
}; // end of class TDBMYSQL
/***********************************************************************/
@@ -132,12 +133,28 @@ class MYSQLCOL : public COLBLK {
// Members
MYSQL_BIND *Bind; // This column bind structure pointer
- PVAL To_Val; // To value used for Update/Insert
+ PVAL To_Val; // To value used for Update/Insert
unsigned long Slen; // Bind string lengh
int Rank; // Rank (position) number in the query
}; // end of class MYSQLCOL
+/***********************************************************************/
+/* This is the class declaration for the MYSQL column catalog table. */
+/***********************************************************************/
+class TDBMCL : public TDBCAT {
+ public:
+ // Constructor
+ TDBMCL(PMYDEF tdp);
-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);
+ protected:
+ // Specific routines
+ virtual PQRYRES GetResult(PGLOBAL g);
+
+ // Members
+ PSZ Host; // Host machine to use
+ PSZ Db; // Database to be used by server
+ PSZ Tab; // External table name
+ PSZ User; // User logon name
+ PSZ Pwd; // Password logon info
+ int Port; // MySQL port number (0 = default)
+ }; // end of class TDBMCL
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 7b8c62e3e53..55475852a62 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -89,7 +89,6 @@ extern int num_read, num_there, num_eq[2]; // Statistics
ODBCDEF::ODBCDEF(void)
{
Connect = Tabname = Tabowner = Tabqual = Qchar = NULL;
- Catfunc = 0;
Catver = Options = 0;
} // end of ODBCDEF constructor
@@ -101,7 +100,6 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
int dop = ODBConn::noOdbcDialog; // Default for options
Desc = Connect = Cat->GetStringCatInfo(g, Name, "Connect", "");
- Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", ""));
Tabname = Cat->GetStringCatInfo(g, Name, "Name",
Catfunc == 'T' ? NULL : Name);
Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname);
@@ -905,259 +903,53 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
} // end of WriteColumn
-/* ---------------------------TDBOIF class --------------------------- */
-
-/***********************************************************************/
-/* Implementation of the TDBOIF class. */
-/***********************************************************************/
-TDBOIF::TDBOIF(PODEF tdp) : TDBASE(tdp)
- {
- Qrp = NULL;
- ID = 0;
- NC = 0;
- Init = false;
- N = -1;
- } // end of TDBOIF constructor
-
-/***********************************************************************/
-/* Allocate OIF column description block. */
-/***********************************************************************/
-PCOL TDBOIF::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
- POIFCOL colp;
-
- colp = (POIFCOL)new(g) OIFCOL(cdp, this, n);
-
- if (cprec) {
- colp->SetNext(cprec->GetNext());
- cprec->SetNext(colp);
- } else {
- colp->SetNext(Columns);
- Columns = colp;
- } // endif cprec
-
- for (int i = 1; !colp->Flag && i <= NC; i++)
- if (!stricmp(colp->Name, GetMsgid(ID + i)))
- colp->Flag = i;
-
- return colp;
- } // end of MakeCol
-
-/***********************************************************************/
-/* OIF: Get the number of properties. */
-/***********************************************************************/
-int TDBOIF::GetMaxSize(PGLOBAL g)
- {
- if (MaxSize < 0) {
- if (Initialize(g))
- return -1;
-
- MaxSize = Qrp->Nblin;
- } // endif MaxSize
-
- return MaxSize;
- } // end of GetMaxSize
-
-/***********************************************************************/
-/* OIF Access Method opening routine. */
-/***********************************************************************/
-bool TDBOIF::OpenDB(PGLOBAL g)
- {
- if (Use == USE_OPEN) {
- /*******************************************************************/
- /* Table already open. */
- /*******************************************************************/
- N = -1;
- return false;
- } // endif use
-
- if (Mode != MODE_READ) {
- /*******************************************************************/
- /* ODBC Info tables cannot be modified. */
- /*******************************************************************/
- strcpy(g->Message, "OIF tables are read only");
- return true;
- } // endif Mode
-
- /*********************************************************************/
- /* Initialize the ODBC processing. */
- /*********************************************************************/
- if (Initialize(g))
- return true;
-
- return InitCol(g);
- } // end of OpenDB
-
-/***********************************************************************/
-/* Initialize columns. */
-/***********************************************************************/
-bool TDBOIF::InitCol(PGLOBAL g)
- {
- POIFCOL colp;
- PCOLRES crp;
-
- for (colp = (POIFCOL)Columns; colp; colp = (POIFCOL)colp->GetNext()) {
- for (crp = Qrp->Colresp; crp; crp = crp->Next)
- if (colp->Flag == crp->Ncol) {
- colp->Crp = crp;
- break;
- } // endif Flag
-
- if (!colp->Crp) {
- sprintf(g->Message, "Invalid flag %d for column %s",
- colp->Flag, colp->Name);
- return true;
- } // endif Crp
-
- } // endfor colp
-
- return false;
- } // end of InitCol
-
-/***********************************************************************/
-/* Data Base read routine for OIF access method. */
-/***********************************************************************/
-int TDBOIF::ReadDB(PGLOBAL g)
- {
- return (++N < Qrp->Nblin) ? RC_OK : RC_EF;
- } // end of ReadDB
-
-/***********************************************************************/
-/* WriteDB: Data Base write routine for OIF access methods. */
-/***********************************************************************/
-int TDBOIF::WriteDB(PGLOBAL g)
- {
- strcpy(g->Message, "OIF tables are read only");
- return RC_FX;
- } // end of WriteDB
-
-/***********************************************************************/
-/* Data Base delete line routine for OIF access methods. */
-/***********************************************************************/
-int TDBOIF::DeleteDB(PGLOBAL g, int irc)
- {
- strcpy(g->Message, "Delete not enabled for OIF tables");
- return RC_FX;
- } // end of DeleteDB
-
-/***********************************************************************/
-/* Data Base close routine for WMI access method. */
-/***********************************************************************/
-void TDBOIF::CloseDB(PGLOBAL g)
- {
- // Nothing to do
- } // end of CloseDB
-
-// ------------------------ OIFCOL functions ----------------------------
-
-/***********************************************************************/
-/* OIFCOL public constructor. */
-/***********************************************************************/
-OIFCOL::OIFCOL(PCOLDEF cdp, PTDB tdbp, int n)
- : COLBLK(cdp, tdbp, n)
- {
- Tdbp = (PTDBOIF)tdbp;
- Crp = NULL;
- Flag = cdp->GetOffset();
- } // end of WMICOL constructor
-
-/***********************************************************************/
-/* Read the next Data Source elements. */
-/***********************************************************************/
-void OIFCOL::ReadColumn(PGLOBAL g)
- {
- // Get the value of the Name or Description property
- Value->SetValue_pvblk(Crp->Kdata, Tdbp->N);
- } // end of ReadColumn
-
/* ---------------------------TDBSRC class --------------------------- */
/***********************************************************************/
-/* Initialize: Get the list of ODBC data sources. */
+/* GetResult: Get the list of ODBC data sources. */
/***********************************************************************/
-bool TDBSRC::Initialize(PGLOBAL g)
+PQRYRES TDBSRC::GetResult(PGLOBAL g)
{
- if (Init)
- return false;
-
- if (!(Qrp = ODBCDataSources(g, false)))
- return true;
-
- Init = true;
- return false;
- } // end of Initialize
+ return ODBCDataSources(g, false);
+ } // end of GetResult
/* ---------------------------TDBDRV class --------------------------- */
/***********************************************************************/
-/* Initialize: Get the list of ODBC drivers. */
+/* GetResult: Get the list of ODBC drivers. */
/***********************************************************************/
-bool TDBDRV::Initialize(PGLOBAL g)
+PQRYRES TDBDRV::GetResult(PGLOBAL g)
{
- if (Init)
- return false;
-
- if (!(Qrp = ODBCDrivers(g, false)))
- return true;
+ return ODBCDrivers(g, false);
+ } // end of GetResult
- Init = true;
- return false;
- } // end of Initialize
-
-/* ---------------------------TDBOCL class --------------------------- */
+/* ---------------------------TDBOTB class --------------------------- */
/***********************************************************************/
-/* TDBOCL class constructor. */
+/* TDBOTB class constructor. */
/***********************************************************************/
-TDBOCL::TDBOCL(PODEF tdp) : TDBOIF(tdp)
+TDBOTB::TDBOTB(PODEF tdp) : TDBCAT(tdp)
{
- ID = IDS_COLUMNS + 1;
- NC = 11;
Dsn = tdp->GetConnect();
- Tabn = tdp->GetTabname();
- } // end of TDBOCL constructor
+ Tab = tdp->GetTabname();
+ } // end of TDBOTB constructor
/***********************************************************************/
-/* Initialize: Get the list of ODBC table columns. */
+/* GetResult: Get the list of ODBC tables. */
/***********************************************************************/
-bool TDBOCL::Initialize(PGLOBAL g)
+PQRYRES TDBOTB::GetResult(PGLOBAL g)
{
- if (Init)
- return false;
+ return ODBCTables(g, Dsn, Tab, false);
+ } // end of GetResult
- 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
+/* ---------------------------TDBOCL class --------------------------- */
/***********************************************************************/
-/* Initialize: Get the list of ODBC tables. */
+/* GetResult: Get the list of ODBC table columns. */
/***********************************************************************/
-bool TDBOTB::Initialize(PGLOBAL g)
+PQRYRES TDBOCL::GetResult(PGLOBAL g)
{
- if (Init)
- return false;
-
- if (!(Qrp = ODBCTables(g, Dsn, Tabpat, false)))
- return true;
-
- Init = true;
- return false;
- } // end of Initialize
+ return MyODBCCols(g, Dsn, Tab, false);
+ } // end of GetResult
/* ------------------------ End of Tabodbc --------------------------- */
diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h
index f31c005e3d8..645426eef78 100644
--- a/storage/connect/tabodbc.h
+++ b/storage/connect/tabodbc.h
@@ -44,7 +44,6 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Tabowner; /* External table owner */
PSZ Tabqual; /* External table qualifier */
PSZ Qchar; /* Identifier quoting character */
- char Catfunc; /* Catalog function */
int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */
}; // end of ODBCDEF
@@ -164,127 +163,63 @@ class ODBCCOL : public COLBLK {
}; // end of class ODBCCOL
/***********************************************************************/
-/* This is the base class declaration for the ODBC info tables. */
-/***********************************************************************/
-class TDBOIF : public TDBASE {
- friend class OIFCOL;
- public:
- // Constructor
- TDBOIF(PODEF tdp);
-
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_ODBC;}
-
- // Methods
- virtual int GetRecpos(void) {return N;}
- virtual int GetProgCur(void) {return N;}
- virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;}
-
- // Database routines
- virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
- virtual int GetMaxSize(PGLOBAL g);
- virtual bool OpenDB(PGLOBAL g);
- virtual int ReadDB(PGLOBAL g);
- virtual int WriteDB(PGLOBAL g);
- virtual int DeleteDB(PGLOBAL g, int irc);
- virtual void CloseDB(PGLOBAL g);
-
- protected:
- // Specific routines
- virtual bool Initialize(PGLOBAL g) = 0;
- bool InitCol(PGLOBAL g);
-
- // Members
- PQRYRES Qrp;
- int ID; // Base of Column names
- int NC; // Number of valid flags
- int N; // Row number
- bool Init;
- }; // end of class TDBOIF
-
-/***********************************************************************/
-/* Class OIFCOL: ODBC info column. */
-/***********************************************************************/
-class OIFCOL : public COLBLK {
- friend class TDBOIF;
- public:
- // Constructors
- OIFCOL(PCOLDEF cdp, PTDB tdbp, int n);
-
- // Implementation
- virtual int GetAmType(void) {return TYPE_AM_ODBC;}
-
- // Methods
- virtual void ReadColumn(PGLOBAL g);
-
- protected:
- OIFCOL(void) {} // Default constructor not to be used
-
- // Members
- PTDBOIF Tdbp; // Points to ODBC table block
- PCOLRES Crp; // The column data array
- int Flag;
- }; // end of class OIFCOL
-
-/***********************************************************************/
/* This is the class declaration for the Data Sources catalog table. */
/***********************************************************************/
-class TDBSRC : public TDBOIF {
+class TDBSRC : public TDBCAT {
public:
// Constructor
- TDBSRC(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DSRC; NC = 2;}
+ TDBSRC(PODEF tdp) : TDBCAT(tdp) {}
protected:
// Specific routines
- virtual bool Initialize(PGLOBAL g);
+ virtual PQRYRES GetResult(PGLOBAL g);
}; // end of class TDBSRC
/***********************************************************************/
/* This is the class declaration for the Drivers catalog table. */
/***********************************************************************/
-class TDBDRV : public TDBOIF {
+class TDBDRV : public TDBCAT {
public:
// Constructor
- TDBDRV(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DRIVER; NC = 2;}
+ TDBDRV(PODEF tdp) : TDBCAT(tdp) {}
protected:
// Specific routines
- virtual bool Initialize(PGLOBAL g);
+ virtual PQRYRES GetResult(PGLOBAL g);
}; // end of class TDBDRV
/***********************************************************************/
-/* This is the class declaration for the columns catalog table. */
+/* This is the class declaration for the tables catalog table. */
/***********************************************************************/
-class TDBOCL : public TDBOIF {
+class TDBOTB : public TDBCAT {
public:
// Constructor
- TDBOCL(PODEF tdp);
+ TDBOTB(PODEF tdp);
protected:
// Specific routines
- virtual bool Initialize(PGLOBAL g);
+ virtual PQRYRES GetResult(PGLOBAL g);
// Members
char *Dsn; // Points to connection string
- char *Tabn; // Points to ODBC table name
- }; // end of class TDBOCL
+ char *Tab; // Points to ODBC table name or pattern
+ }; // end of class TDBOTB
/***********************************************************************/
-/* This is the class declaration for the tables catalog table. */
+/* This is the class declaration for the columns catalog table. */
/***********************************************************************/
-class TDBOTB : public TDBOIF {
+class TDBOCL : public TDBOTB {
public:
// Constructor
- TDBOTB(PODEF tdp);
+ TDBOCL(PODEF tdp) : TDBOTB(tdp) {}
protected:
// Specific routines
- virtual bool Initialize(PGLOBAL g);
+ virtual PQRYRES GetResult(PGLOBAL g);
// Members
- char *Dsn; // Points to connection string
- char *Tabpat; // Points to ODBC table pattern
- }; // end of class TDBOTB
+ }; // end of class TDBOCL
+
#endif // !NODBC
diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp
index e98dfd0cde0..e6a02e1871f 100644
--- a/storage/connect/tabwmi.cpp
+++ b/storage/connect/tabwmi.cpp
@@ -23,13 +23,6 @@
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);
-
/* ------------------- Functions WMI Column info --------------------- */
/***********************************************************************/
@@ -140,82 +133,90 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
/* WMIColumns: constructs the result blocks containing the description */
/* of all the columns of a WMI table of a specified class. */
/***********************************************************************/
-PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp)
+PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
{
- static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
- DB_INT, DB_INT, DB_SHORT};
- static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
- TYPE_INT, TYPE_INT, TYPE_SHORT};
+ static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
+ DB_INT, DB_INT, DB_SHORT};
+ static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
+ TYPE_INT, TYPE_INT, TYPE_SHORT};
+ static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME,
+ FLD_PREC, FLD_LENGTH, FLD_SCALE};
static unsigned int len, length[] = {0, 6, 8, 10, 10, 6};
int i = 0, n = 0, ncol = sizeof(dbtype) / sizeof(int);
int lng, typ, prec;
LONG low, upp;
- BOOL b1, b2 = TRUE;
BSTR propname;
VARIANT val;
CIMTYPE type;
HRESULT res;
+ PWMIUT wp;
SAFEARRAY *prnlist = NULL;
PQRYRES qrp = NULL;
PCOLRES crp;
- /*********************************************************************/
- /* Initialize WMI if not done yet. */
- /*********************************************************************/
- if ((b1 = !wp) && !(wp = InitWMI(g, nsp, classname)))
- return NULL;
-
- /*********************************************************************/
- /* Get the number of properties to return. */
- /*********************************************************************/
- res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL);
-
- if (FAILED(res)) {
- sprintf(g->Message, "failed Get(__Property_Count) res=%d\n", res);
- goto err;
- } // endif res
-
- if (!(n = val.lVal)) {
- sprintf(g->Message, "Class %s in %s has no properties\n",
- classname, nsp);
- goto err;
- } // endif res
+ if (!info) {
+ /*******************************************************************/
+ /* Initialize WMI if not done yet. */
+ /*******************************************************************/
+ if (!(wp = InitWMI(g, nsp, cls)))
+ return NULL;
- /*********************************************************************/
- /* Get max property name length. */
- /*********************************************************************/
- res = wp->Cobj->GetNames(NULL,
- WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY,
- NULL, &prnlist);
+ /*******************************************************************/
+ /* Get the number of properties to return. */
+ /*******************************************************************/
+ res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL);
- if (FAILED(res)) {
- sprintf(g->Message, "failed GetNames res=%d\n", res);
- goto err;
- } // endif res
+ if (FAILED(res)) {
+ sprintf(g->Message, "failed Get(__Property_Count) res=%d\n", res);
+ goto err;
+ } // endif res
- res = SafeArrayGetLBound(prnlist, 1, &low);
- res = SafeArrayGetUBound(prnlist, 1, &upp);
+ if (!(n = val.lVal)) {
+ sprintf(g->Message, "Class %s in %s has no properties\n",
+ cls, nsp);
+ goto err;
+ } // endif res
- for (long i = low; i <= upp; i++) {
- // Get this property name.
- res = SafeArrayGetElement(prnlist, &i, &propname);
+ /*******************************************************************/
+ /* Get max property name length. */
+ /*******************************************************************/
+ res = wp->Cobj->GetNames(NULL,
+ WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY,
+ NULL, &prnlist);
if (FAILED(res)) {
- sprintf(g->Message, "failed GetArrayElement res=%d\n", res);
+ sprintf(g->Message, "failed GetNames res=%d\n", res);
goto err;
} // endif res
- len = (unsigned)SysStringLen(propname);
- length[0] = max(length[0], len);
- } // enfor i
+ res = SafeArrayGetLBound(prnlist, 1, &low);
+ res = SafeArrayGetUBound(prnlist, 1, &upp);
+
+ for (long i = low; i <= upp; i++) {
+ // Get this property name.
+ res = SafeArrayGetElement(prnlist, &i, &propname);
+
+ if (FAILED(res)) {
+ sprintf(g->Message, "failed GetArrayElement res=%d\n", res);
+ goto err;
+ } // endif res
+
+ len = (unsigned)SysStringLen(propname);
+ length[0] = max(length[0], len);
+ } // enfor i
- res = SafeArrayDestroy(prnlist);
+ res = SafeArrayDestroy(prnlist);
+ } else
+ length[0] = 128;
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
- dbtype, buftyp, length);
+ dbtype, buftyp, fldtyp, length, true, true);
+
+ if (info)
+ return qrp;
/*********************************************************************/
/* Now get the results into blocks. */
@@ -309,16 +310,13 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp)
} // endfor i
qrp->Nblin = i;
- b2 = b1;
err:
- if (b2) {
- // Cleanup
- wp->Cobj->Release();
- wp->Svc->Release();
- wp->Svc = NULL; // MUST be set to NULL (why?)
- CoUninitialize();
- } // endif b
+ // Cleanup
+ wp->Cobj->Release();
+ wp->Svc->Release();
+ wp->Svc = NULL; // MUST be set to NULL (why?)
+ CoUninitialize();
/*********************************************************************/
/* Return the result pointer for use by GetData routines. */
@@ -346,7 +344,7 @@ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Wclass = strcat(strcpy(p, "Win32_"), Wclass);
} // endif Wclass
- if (!(Info = Cat->GetBoolCatInfo(Name, "Info", false)))
+ if (!Catfunc)
Ems = Cat->GetIntCatInfo(Name, "Estimate", 100);
return false;
@@ -357,17 +355,19 @@ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB WMIDEF::GetTable(PGLOBAL g, MODE m)
{
- if (Info)
- return new(g) TDBWCL(this);
- else
+ if (!Catfunc)
return new(g) TDBWMI(this);
+ else if (Catfunc == 'C')
+ return new(g) TDBWCL(this);
+ sprintf(g->Message, "Bad catfunc %c for WMI", Catfunc);
+ return NULL;
} // end of GetTable
/* ------------------------------------------------------------------- */
/***********************************************************************/
-/* Implementation of the TDBWMI class. */
+/* Implementation of the TDBWMI class. */
/***********************************************************************/
TDBWMI::TDBWMI(PWMIDEF tdp) : TDBASE(tdp)
{
@@ -826,320 +826,20 @@ void WMICOL::ReadColumn(PGLOBAL g)
/* ---------------------------TDBWCL class --------------------------- */
/***********************************************************************/
-/* Implementation of the TDBWCL class. */
+/* TDBWCL class constructor. */
/***********************************************************************/
-TDBWCL::TDBWCL(PWMIDEF tdp) : TDBASE(tdp)
+TDBWCL::TDBWCL(PWMIDEF tdp) : TDBCAT(tdp)
{
- Svc = NULL;
- ClsObj = NULL;
- Propname = NULL;
- Nspace = tdp->Nspace;
- Wclass = tdp->Wclass;
- Init = false;
- Done = false;
- Res = 0;
- N = -1;
- Lng = 0;
- Typ = 0;
- Prec = 0;
+ Nsp = tdp->Nspace;
+ Cls = tdp->Wclass;
} // end of TDBWCL constructor
/***********************************************************************/
-/* Allocate WCL column description block. */
-/***********************************************************************/
-PCOL TDBWCL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
- PWCLCOL colp;
-
- colp = (PWCLCOL)new(g) WCLCOL(cdp, this, n);
-
- if (cprec) {
- colp->SetNext(cprec->GetNext());
- cprec->SetNext(colp);
- } else {
- colp->SetNext(Columns);
- Columns = colp;
- } // endif cprec
-
- if (!colp->Flag) {
- if (!stricmp(colp->Name, "Column_Name"))
- colp->Flag = 1;
- else if (!stricmp(colp->Name, "Data_Type"))
- colp->Flag = 2;
- else if (!stricmp(colp->Name, "Type_Name"))
- colp->Flag = 3;
- else if (!stricmp(colp->Name, "Precision"))
- colp->Flag = 4;
- else if (!stricmp(colp->Name, "Length"))
- colp->Flag = 5;
- else if (!stricmp(colp->Name, "Scale"))
- colp->Flag = 6;
-
- } // endif Flag
-
- return colp;
- } // end of MakeCol
-
-/***********************************************************************/
-/* Initialize: Initialize WMI operations. */
+/* GetResult: Get the list of the WMI class properties. */
/***********************************************************************/
-bool TDBWCL::Initialize(PGLOBAL g)
+PQRYRES TDBWCL::GetResult(PGLOBAL g)
{
- if (Init)
- return false;
-
- // Initialize COM.
- Res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
-
- if (FAILED(Res)) {
- sprintf(g->Message, "Failed to initialize COM library. "
- "Error code = %p", Res);
- return true; // Program has failed.
- } // endif Res
-
- // Obtain the initial locator to Windows Management
- // on a particular host computer.
- IWbemLocator *loc; // Initial Windows Management locator
-
- Res = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
- IID_IWbemLocator, (LPVOID*) &loc);
-
- if (FAILED(Res)) {
- sprintf(g->Message, "Failed to create Locator. "
- "Error code = %p", Res);
- CoUninitialize();
- return true; // Program has failed.
- } // endif Res
-
- // Connect to the specified namespace with the
- // current user and obtain pointer to Svc
- // to make IWbemServices calls.
- Res = loc->ConnectServer(_bstr_t(Nspace),
- NULL, NULL,0, NULL, 0, 0, &Svc);
-
- if (FAILED(Res)) {
- sprintf(g->Message, "Could not connect. Error code = %p", Res);
- loc->Release();
- CoUninitialize();
- return true; // Program has failed.
- } // endif hres
-
- loc->Release(); // Not used anymore
+ return WMIColumns(g, Nsp, Cls, false);
+ } // end of GetResult
- // Perform a full class object retrieval
- Res = Svc->GetObject(bstr_t(Wclass), 0, 0, &ClsObj, 0);
- if (FAILED(Res)) {
- sprintf(g->Message, "failed GetObject %s in %s\n", Wclass, Nspace);
- Svc->Release();
- Svc = NULL; // MUST be set to NULL (why?)
- return true;
- } // endif res
-
- Init = true;
- return false;
- } // end of Initialize
-
-/***********************************************************************/
-/* WCL: Get the number of properties. */
-/***********************************************************************/
-int TDBWCL::GetMaxSize(PGLOBAL g)
- {
- if (MaxSize < 0) {
- VARIANT val;
-
- if (Initialize(g))
- return -1;
-
- Res = ClsObj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL);
-
- if (FAILED(Res)) {
- sprintf(g->Message, "failed Get(Property_Count) res=%d\n", Res);
- return -1;
- } // endif Res
-
- MaxSize = val.lVal;
- } // endif MaxSize
-
- return MaxSize;
- } // end of GetMaxSize
-
-/***********************************************************************/
-/* WCL Access Method opening routine. */
-/***********************************************************************/
-bool TDBWCL::OpenDB(PGLOBAL g)
- {
- if (Use == USE_OPEN) {
- /*******************************************************************/
- /* Table already open. */
- /*******************************************************************/
- ClsObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
- N = 0;
- return false;
- } // endif use
-
- if (Mode != MODE_READ) {
- /*******************************************************************/
- /* WMI tables cannot be modified. */
- /*******************************************************************/
- strcpy(g->Message, "WCL tables are read only");
- return true;
- } // endif Mode
-
- /*********************************************************************/
- /* Initialize the WMI processing. */
- /*********************************************************************/
- if (Initialize(g))
- return true;
-
- Res = ClsObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
-
- if (FAILED(Res)) {
- sprintf(g->Message, "failed BeginEnumeration hr=%d\n", Res);
- return NULL;
- } // endif hr
-
- return false;
- } // end of OpenDB
-
-/***********************************************************************/
-/* Data Base read routine for WCL access method. */
-/***********************************************************************/
-int TDBWCL::ReadDB(PGLOBAL g)
- {
- VARIANT val;
- CIMTYPE type;
-
- Res = ClsObj->Next(0, &Propname, &val, &type, NULL);
-
- if (FAILED(Res)) {
- sprintf(g->Message, "failed getting Next hr=%d\n", Res);
- return RC_FX;
- } else if (Res == WBEM_S_NO_MORE_DATA) {
- VariantClear(&val);
- return RC_EF;
- } // endif res
-
- Prec = 0;
-
- switch (type) {
- case CIM_STRING:
- Typ = TYPE_STRING;
- Lng = 255;
- Prec = 1; // Case insensitive
- break;
- case CIM_SINT32:
- case CIM_UINT32:
- case CIM_BOOLEAN:
- Typ = TYPE_INT;
- Lng = 9;
- break;
- case CIM_SINT8:
- case CIM_UINT8:
- case CIM_SINT16:
- case CIM_UINT16:
- Typ = TYPE_SHORT;
- Lng = 6;
- break;
- case CIM_REAL64:
- case CIM_REAL32:
- Prec = 2;
- case CIM_SINT64:
- case CIM_UINT64:
- Typ = TYPE_FLOAT;
- Lng = 15;
- break;
- case CIM_DATETIME:
- Typ = TYPE_DATE;
- Lng = 19;
- break;
- case CIM_CHAR16:
- Typ = TYPE_STRING;
- Lng = 16;
- break;
- case CIM_EMPTY:
- Typ = TYPE_STRING;
- Lng = 24; // ???
- break;
- default:
- return RC_NF;
- } // endswitch type
-
- N++;
- return RC_OK;
- } // end of ReadDB
-
-/***********************************************************************/
-/* WriteDB: Data Base write routine for WCL access methods. */
-/***********************************************************************/
-int TDBWCL::WriteDB(PGLOBAL g)
- {
- strcpy(g->Message, "WCL tables are read only");
- return RC_FX;
- } // end of WriteDB
-
-/***********************************************************************/
-/* Data Base delete line routine for WCL access methods. */
-/***********************************************************************/
-int TDBWCL::DeleteDB(PGLOBAL g, int irc)
- {
- strcpy(g->Message, "Delete not enabled for WCL tables");
- return RC_FX;
- } // end of DeleteDB
-
-/***********************************************************************/
-/* Data Base close routine for WMI access method. */
-/***********************************************************************/
-void TDBWCL::CloseDB(PGLOBAL g)
- {
- // Cleanup
- if (ClsObj)
- ClsObj->Release();
-
- if (Svc)
- Svc->Release();
-
- CoUninitialize();
- } // end of CloseDB
-
-// ------------------------ WCLCOL functions ----------------------------
-
-/***********************************************************************/
-/* WCLCOL public constructor. */
-/***********************************************************************/
-WCLCOL::WCLCOL(PCOLDEF cdp, PTDB tdbp, int n)
- : COLBLK(cdp, tdbp, n)
- {
- Tdbp = (PTDBWCL)tdbp;
- Flag = cdp->GetOffset();
- Res = 0;
- } // end of WMICOL constructor
-
-/***********************************************************************/
-/* Read the next WCL elements. */
-/***********************************************************************/
-void WCLCOL::ReadColumn(PGLOBAL g)
- {
- // Get the value of the Name property
- switch (Flag) {
- case 1:
- Value->SetValue_psz(_com_util::ConvertBSTRToString(Tdbp->Propname));
- break;
- case 2:
- Value->SetValue(Tdbp->Typ);
- break;
- case 3:
- Value->SetValue_psz(GetTypeName(Tdbp->Typ));
- break;
- case 4:
- case 5:
- Value->SetValue(Tdbp->Lng);
- break;
- case 6:
- Value->SetValue(Tdbp->Prec);
- break;
- default:
- Value->Reset();
- } // endswitch Flag
-
- } // end of ReadColumn
diff --git a/storage/connect/tabwmi.h b/storage/connect/tabwmi.h
index 853f2174434..9df57e7c579 100644
--- a/storage/connect/tabwmi.h
+++ b/storage/connect/tabwmi.h
@@ -27,7 +27,7 @@ typedef struct _WMIutil {
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp);
+PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info);
/* -------------------------- WMI classes ---------------------------- */
@@ -37,10 +37,10 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp);
class WMIDEF : public TABDEF { /* Logical table description */
friend class TDBWMI;
friend class TDBWCL;
+ friend class TDBWCX;
public:
// Constructor
- WMIDEF(void)
- {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0; Info = false;}
+ WMIDEF(void) {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0;}
// Implementation
virtual const char *GetType(void) {return "WMI";}
@@ -55,7 +55,6 @@ class WMIDEF : public TABDEF { /* Logical table description */
char *Nspace;
char *Wclass;
int Ems;
- bool Info;
}; // end of WMIDEF
/***********************************************************************/
@@ -99,13 +98,13 @@ class TDBWMI : public TDBASE {
char *Wclass; // Class name
char *ObjPath; // Used for direct access
char *Kvp; // Itou
- int Ems; // Estimated max size
+ int Ems; // Estimated max size
PCOL Kcol; // Key column
HRESULT Res;
PVBLK Vbp;
bool Init;
bool Done;
- ULONG Rc;
+ ULONG Rc;
int N; // Row number
}; // end of class TDBWMI
@@ -129,76 +128,24 @@ class WMICOL : public COLBLK {
// Members
PTDBWMI Tdbp; // Points to WMI table block
- VARIANT Prop; // Property value
- CIMTYPE Ctype; // CIM Type
+ VARIANT Prop; // Property value
+ CIMTYPE Ctype; // CIM Type
HRESULT Res;
}; // end of class WMICOL
/***********************************************************************/
-/* This is the class declaration for the WCL table. */
+/* This is the class declaration for the WMI catalog table. */
/***********************************************************************/
-class TDBWCL : public TDBASE {
- friend class WCLCOL;
+class TDBWCL : public TDBCAT {
public:
// Constructor
TDBWCL(PWMIDEF tdp);
- // Implementation
- virtual AMT GetAmType(void) {return TYPE_AM_WMI;}
-
- // Methods
- virtual int GetRecpos(void) {return N;}
- virtual int GetProgCur(void) {return N;}
- virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;}
-
- // Database routines
- virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
- virtual int GetMaxSize(PGLOBAL g);
- virtual bool OpenDB(PGLOBAL g);
- virtual int ReadDB(PGLOBAL g);
- virtual int WriteDB(PGLOBAL g);
- virtual int DeleteDB(PGLOBAL g, int irc);
- virtual void CloseDB(PGLOBAL g);
-
protected:
- // Specific routines
- bool Initialize(PGLOBAL g);
+ // Specific routines
+ virtual PQRYRES GetResult(PGLOBAL g);
// Members
- IWbemServices *Svc; // IWbemServices pointer
- IWbemClassObject *ClsObj;
- BSTR Propname;
- char *Nspace; // Namespace
- char *Wclass; // Class name
- HRESULT Res;
- bool Init;
- bool Done;
- int N; // Row number
- int Lng;
- int Typ;
- int Prec;
+ char *Nsp; // Name space
+ char *Cls; // Class
}; // end of class TDBWCL
-
-/***********************************************************************/
-/* Class WMICOL: WMI Address column. */
-/***********************************************************************/
-class WCLCOL : public COLBLK {
- friend class TDBWCL;
- public:
- // Constructors
- WCLCOL(PCOLDEF cdp, PTDB tdbp, int n);
-
- // Implementation
- virtual int GetAmType(void) {return TYPE_AM_WMI;}
-
- // Methods
- virtual void ReadColumn(PGLOBAL g);
-
- protected:
- WCLCOL(void) {} // Default constructor not to be used
-
- // Members
- PTDBWCL Tdbp; // Points to WMI table block
- HRESULT Res;
- int Flag;
- }; // end of class WCLCOL
diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h
index 73af45c7e0a..6932fe7337a 100644
--- a/storage/connect/xtable.h
+++ b/storage/connect/xtable.h
@@ -15,9 +15,12 @@
/***********************************************************************/
#include "assert.h"
#include "block.h"
+#include "colblk.h"
//pedef class INDEXDEF *PIXDEF;
-typedef char *PFIL; // Specific to CONNECT
+typedef char *PFIL; // Specific to CONNECT
+typedef class TDBCAT *PTDBCAT;
+typedef class CATCOL *PCATCOL;
/***********************************************************************/
/* Definition of class TBX (pure virtual class for TDB and OPJOIN) */
@@ -170,8 +173,8 @@ class DllExport TDBASE : public TDB {
virtual bool IsReadOnly(void) {return Read_Only;}
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
virtual int GetProgCur(void) {return GetRecpos();}
- virtual PSZ GetFile(PGLOBAL g) {return "Not a file";}
- virtual int GetRemote(void) {return 0;}
+ virtual PSZ GetFile(PGLOBAL g) {return "Not a file";}
+ virtual int GetRemote(void) {return 0;}
virtual void SetFile(PGLOBAL g, PSZ fn) {}
virtual void ResetDB(void) {}
virtual void ResetSize(void) {MaxSize = -1;}
@@ -198,4 +201,66 @@ class DllExport TDBASE : public TDB {
bool Read_Only; // True for read only tables
}; // end of class TDBASE
+/***********************************************************************/
+/* The abstract base class declaration for the catalog tables. */
+/***********************************************************************/
+class TDBCAT : public TDBASE {
+ friend class CATCOL;
+ public:
+ // Constructor
+ TDBCAT(PTABDEF tdp);
+
+ // Implementation
+ virtual AMT GetAmType(void) {return TYPE_AM_CAT;}
+
+ // Methods
+ virtual int GetRecpos(void) {return N;}
+ virtual int GetProgCur(void) {return N;}
+ virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;}
+
+ // Database routines
+ virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
+ virtual int GetMaxSize(PGLOBAL g);
+ virtual bool OpenDB(PGLOBAL g);
+ virtual int ReadDB(PGLOBAL g);
+ virtual int WriteDB(PGLOBAL g);
+ virtual int DeleteDB(PGLOBAL g, int irc);
+ virtual void CloseDB(PGLOBAL g);
+
+ protected:
+ // Specific routines
+ virtual PQRYRES GetResult(PGLOBAL g) = 0;
+ bool Initialize(PGLOBAL g);
+ bool InitCol(PGLOBAL g);
+
+ // Members
+ PQRYRES Qrp;
+ int N; // Row number
+ bool Init;
+ }; // end of class TDBCAT
+
+/***********************************************************************/
+/* Class CATCOL: ODBC info column. */
+/***********************************************************************/
+class CATCOL : public COLBLK {
+ friend class TDBCAT;
+ public:
+ // Constructors
+ CATCOL(PCOLDEF cdp, PTDB tdbp, int n);
+
+ // Implementation
+ virtual int GetAmType(void) {return TYPE_AM_ODBC;}
+
+ // Methods
+ virtual void ReadColumn(PGLOBAL g);
+
+ protected:
+ CATCOL(void) {} // Default constructor not to be used
+
+ // Members
+ PTDBCAT Tdbp; // Points to ODBC table block
+ PCOLRES Crp; // The column data array
+ int Flag;
+ }; // end of class CATCOL
+
#endif // TABLE_DEFINED