mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Bug fixed: Column charset were not handled on read.
Modified: ha_connect.cc (MakeRecord) Moved PlgAllocResult to plgdbutl.cpp Modified: mycat.cpp plgdbutl.cpp Continuing implementing the "catalog" tables (ex "info"). Already existing were the ODBC data source table and the WMI column info table. The common way to handle them was modified to enable each table types to send personalized data. Now takes care of all existing catalog functions for table types that can retrieve and use such information. Modified: ha_connect.cc odbconn.cpp tabodbc.h tabodbc.cpp tabfmt.h tabfmt.cpp tabmysql.h tabmysql.cpp tabwmi.h tabwmi.cpp myconn.h myconn.cpp filamdbf.cpp plgdbsem.h reldef.h reldef.cpp tabdos.h tabdos.cpp tabfix.h xtable.h table.cpp
This commit is contained in:
@@ -48,8 +48,6 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "plgdbsem.h"
|
#include "plgdbsem.h"
|
||||||
//#include "catalog.h"
|
|
||||||
//#include "kindex.h"
|
|
||||||
#include "filamdbf.h"
|
#include "filamdbf.h"
|
||||||
#include "tabdos.h"
|
#include "tabdos.h"
|
||||||
#include "valblk.h"
|
#include "valblk.h"
|
||||||
@@ -65,12 +63,6 @@
|
|||||||
#define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */
|
#define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */
|
||||||
#define EOH 0x0D /* end-of-header marker in .dbf file */
|
#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
|
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)
|
PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
|
||||||
{
|
{
|
||||||
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
|
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
|
||||||
DB_INT, DB_INT, DB_SHORT};
|
DB_INT, DB_INT, DB_SHORT};
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
||||||
TYPE_INT, TYPE_INT, TYPE_SHORT};
|
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};
|
static unsigned int length[] = {11, 6, 8, 10, 10, 6};
|
||||||
char buf[2], filename[_MAX_PATH];
|
char buf[2], filename[_MAX_PATH];
|
||||||
int ncol = sizeof(dbtype) / sizeof(int);
|
int ncol = sizeof(dbtype) / sizeof(int);
|
||||||
@@ -204,35 +198,41 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
|
|||||||
if (trace)
|
if (trace)
|
||||||
htrc("DBFColumns: File %s\n", SVP(fn));
|
htrc("DBFColumns: File %s\n", SVP(fn));
|
||||||
|
|
||||||
if (!fn) {
|
if (!info) {
|
||||||
strcpy(g->Message, MSG(MISSING_FNAME));
|
if (!fn) {
|
||||||
return NULL;
|
strcpy(g->Message, MSG(MISSING_FNAME));
|
||||||
} // endif fn
|
return NULL;
|
||||||
|
} // endif fn
|
||||||
|
|
||||||
/**************************************************************************/
|
/************************************************************************/
|
||||||
/* Open the input file. */
|
/* Open the input file. */
|
||||||
/**************************************************************************/
|
/************************************************************************/
|
||||||
PlugSetPath(filename, fn, PlgGetDataPath(g));
|
PlugSetPath(filename, fn, PlgGetDataPath(g));
|
||||||
|
|
||||||
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
|
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/**************************************************************************/
|
/************************************************************************/
|
||||||
/* Get the first 32 bytes of the header. */
|
/* Get the first 32 bytes of the header. */
|
||||||
/**************************************************************************/
|
/************************************************************************/
|
||||||
if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) {
|
if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) {
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
return NULL;
|
return NULL;
|
||||||
} // endif dbfhead
|
} // 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,
|
qrp = PlgAllocResult(g, ncol, fields, IDS_COLUMNS + 3,
|
||||||
dbtype, buftyp, length);
|
dbtype, buftyp, fldtyp, length, true, false);
|
||||||
qrp->Info = info || (rc == RC_INFO);
|
//qrp->Info = info || (rc == RC_INFO);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
return qrp;
|
||||||
|
|
||||||
if (trace) {
|
if (trace) {
|
||||||
htrc("Structure of %s\n", filename);
|
htrc("Structure of %s\n", filename);
|
||||||
@@ -316,6 +316,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
|
|||||||
qrp->Nblin = field;
|
qrp->Nblin = field;
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (info) {
|
if (info) {
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Prepare return message for dbfinfo command. */
|
/* Prepare return message for dbfinfo command. */
|
||||||
@@ -330,6 +331,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info)
|
|||||||
|
|
||||||
strcat(g->Message, buf);
|
strcat(g->Message, buf);
|
||||||
} // endif info
|
} // endif info
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Return the result pointer for use by GetData routines. */
|
/* Return the result pointer for use by GetData routines. */
|
||||||
|
@@ -138,10 +138,6 @@
|
|||||||
#define my_strlwr(p) my_casedn_str(default_charset_info, (p));
|
#define my_strlwr(p) my_casedn_str(default_charset_info, (p));
|
||||||
#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b))
|
#define my_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
|
#ifdef LIBXML2_SUPPORT
|
||||||
void XmlInitParserLib(void);
|
void XmlInitParserLib(void);
|
||||||
void XmlCleanupParserLib(void);
|
void XmlCleanupParserLib(void);
|
||||||
@@ -1379,9 +1375,6 @@ int ha_connect::MakeRecord(char *buf)
|
|||||||
// This is for variable_length rows
|
// This is for variable_length rows
|
||||||
memset(buf, 0, table->s->null_bytes);
|
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
|
// When sorting read_set selects all columns, so we use def_read_set
|
||||||
map= (const MY_BITMAP *)&table->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++) {
|
for (field= table->field; *field && !rc; field++) {
|
||||||
fp= *field;
|
fp= *field;
|
||||||
|
|
||||||
|
// Default charset
|
||||||
|
charset= table->s->table_charset;
|
||||||
|
|
||||||
#if defined(MARIADB)
|
#if defined(MARIADB)
|
||||||
if (fp->vcol_info && !fp->stored_in_db)
|
if (fp->vcol_info && !fp->stored_in_db)
|
||||||
continue; // This is a virtual column
|
continue; // This is a virtual column
|
||||||
@@ -1409,28 +1405,35 @@ int ha_connect::MakeRecord(char *buf)
|
|||||||
value= colp->GetValue();
|
value= colp->GetValue();
|
||||||
|
|
||||||
// All this could be better optimized
|
// All this could be better optimized
|
||||||
if (value->GetType() == TYPE_DATE) {
|
switch (value->GetType()) {
|
||||||
if (!sdval)
|
case TYPE_DATE:
|
||||||
sdval= AllocateValue(xp->g, TYPE_STRING, 20);
|
if (!sdval)
|
||||||
|
sdval= AllocateValue(xp->g, TYPE_STRING, 20);
|
||||||
|
|
||||||
switch (fp->type()) {
|
switch (fp->type()) {
|
||||||
case MYSQL_TYPE_DATE:
|
case MYSQL_TYPE_DATE:
|
||||||
fmt= "%Y-%m-%d";
|
fmt= "%Y-%m-%d";
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TIME:
|
case MYSQL_TYPE_TIME:
|
||||||
fmt= "%H:%M:%S";
|
fmt= "%H:%M:%S";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fmt= "%Y-%m-%d %H:%M:%S";
|
fmt= "%Y-%m-%d %H:%M:%S";
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
// Get date in the format required by MySQL fields
|
// Get date in the format required by MySQL fields
|
||||||
value->FormatValue(sdval, fmt);
|
value->FormatValue(sdval, fmt);
|
||||||
p= sdval->GetCharValue();
|
p= sdval->GetCharValue();
|
||||||
} else if (value->GetType() == TYPE_FLOAT)
|
break;
|
||||||
p= NULL;
|
case TYPE_FLOAT:
|
||||||
else
|
p= NULL;
|
||||||
p= value->GetCharString(val);
|
break;
|
||||||
|
case TYPE_STRING:
|
||||||
|
charset= fp->charset();
|
||||||
|
// Passthru
|
||||||
|
default:
|
||||||
|
p= value->GetCharString(val);
|
||||||
|
} // endswitch Type
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
if (fp->store(p, strlen(p), charset, CHECK_FIELD_WARN)) {
|
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)
|
bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
|
||||||
{
|
{
|
||||||
char ttp= '?', spc= ',', qch= 0, fnc= 0;
|
char ttp= '?', spc= ',', qch= 0, fnc= '*';
|
||||||
const char *typn= "DOS";
|
const char *typn= "?";
|
||||||
const char *user;
|
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)
|
#if defined(WIN32)
|
||||||
char *nsp= NULL, *cls= NULL;
|
char *nsp= NULL, *cls= NULL;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
char *supfnc = "*C";
|
||||||
int port= MYSQL_PORT, hdr= 0, mxr= 0;
|
int port= MYSQL_PORT, hdr= 0, mxr= 0;
|
||||||
|
uint tm;
|
||||||
bool b= false, ok= false, dbf= false;
|
bool b= false, ok= false, dbf= false;
|
||||||
LEX_STRING *comment, *name;
|
LEX_STRING *comment, *name;
|
||||||
HA_CREATE_INFO *create_info= (HA_CREATE_INFO *)crt_info;
|
HA_CREATE_INFO *create_info= (HA_CREATE_INFO *)crt_info;
|
||||||
|
CHARSET_INFO *cs;
|
||||||
engine_option_value *pov;
|
engine_option_value *pov;
|
||||||
PQRYRES qrp;
|
PQRYRES qrp;
|
||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
@@ -3325,6 +3331,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
|
|||||||
else
|
else
|
||||||
ok= true;
|
ok= true;
|
||||||
|
|
||||||
|
supfnc = "*CTSD";
|
||||||
break;
|
break;
|
||||||
#endif // ODBC_SUPPORT
|
#endif // ODBC_SUPPORT
|
||||||
case 'A': // DBF
|
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);
|
sprintf(g->Message, "Cannot get column info for table type %s", typn);
|
||||||
} // endif ttp
|
} // 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) {
|
if (ok) {
|
||||||
char *length, *decimals, *cnm, *rem;
|
char *length, *decimals, *cnm, *rem;
|
||||||
int i, len, dec;
|
int i, len, dec;
|
||||||
@@ -3368,7 +3382,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
|
|||||||
|
|
||||||
switch (ttp) {
|
switch (ttp) {
|
||||||
case 'A':
|
case 'A':
|
||||||
qrp= DBFColumns(g, fn, false);
|
qrp= DBFColumns(g, fn, fnc == 'C');
|
||||||
break;
|
break;
|
||||||
#if defined(ODBC_SUPPORT)
|
#if defined(ODBC_SUPPORT)
|
||||||
case 'O':
|
case 'O':
|
||||||
@@ -3394,15 +3408,16 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
|
|||||||
#endif // ODBC_SUPPORT
|
#endif // ODBC_SUPPORT
|
||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
case 'Y':
|
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;
|
break;
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
case 'C':
|
case 'C':
|
||||||
qrp= CSVColumns(g, fn, spc, qch, hdr, mxr);
|
qrp= CSVColumns(g, fn, spc, qch, hdr, mxr, fnc == 'C');
|
||||||
break;
|
break;
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
case 'W':
|
case 'W':
|
||||||
qrp= WMIColumns(g, nsp, cls, NULL);
|
qrp= WMIColumns(g, nsp, cls, fnc == 'C');
|
||||||
break;
|
break;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
} // endswitch ttp
|
} // endswitch ttp
|
||||||
@@ -3412,7 +3427,8 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
|
|||||||
return true;
|
return true;
|
||||||
} // endif qrp
|
} // endif qrp
|
||||||
|
|
||||||
if (fnc) {
|
if (fnc && fnc != '*') {
|
||||||
|
// Catalog table
|
||||||
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
|
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
|
||||||
cnm= encode(g, crp->Name);
|
cnm= encode(g, crp->Name);
|
||||||
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
|
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
|
// Now add the field
|
||||||
b= add_fields(thd, alt_info, name, type, length, decimals,
|
b= add_fields(thd, alt_info, name, type, length, decimals,
|
||||||
0, comment, NULL, NULL, NULL);
|
NOT_NULL_FLAG, comment, NULL, NULL, NULL);
|
||||||
} // endfor crp
|
} // endfor crp
|
||||||
|
|
||||||
} else
|
} else // Not a catalog table
|
||||||
for (i= 0; !b && i < qrp->Nblin; i++) {
|
for (i= 0; !b && i < qrp->Nblin; i++) {
|
||||||
crp= qrp->Colresp; // Column Name
|
rem= "";
|
||||||
cnm= encode(g, crp->Kdata->GetCharValue(i));
|
length= "";
|
||||||
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
|
decimals= NULL;
|
||||||
crp= crp->Next; // Data Type
|
tm= NOT_NULL_FLAG;
|
||||||
type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true);
|
cs= NULL;
|
||||||
crp= crp->Next; // Type Name
|
|
||||||
crp= crp->Next; // Precision (length)
|
for (crp= qrp->Colresp; crp; crp= crp->Next)
|
||||||
len= crp->Kdata->GetIntValue(i);
|
switch (crp->Fld) {
|
||||||
length= (char*)PlugSubAlloc(g, NULL, 8);
|
case FLD_NAME:
|
||||||
sprintf(length, "%d", len);
|
cnm= encode(g, crp->Kdata->GetCharValue(i));
|
||||||
crp= crp->Next; // Length
|
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
|
||||||
crp= crp->Next; // Scale (precision)
|
break;
|
||||||
|
case FLD_TYPE:
|
||||||
if ((dec= crp->Kdata->GetIntValue(i))) {
|
type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true);
|
||||||
decimals= (char*)PlugSubAlloc(g, NULL, 8);
|
break;
|
||||||
sprintf(decimals, "%d", dec);
|
case FLD_PREC:
|
||||||
} else
|
len= crp->Kdata->GetIntValue(i);
|
||||||
decimals= NULL;
|
length= (char*)PlugSubAlloc(g, NULL, 8);
|
||||||
|
sprintf(length, "%d", len);
|
||||||
if ((crp= crp->Next) && // Remark (comment)
|
break;
|
||||||
(rem= crp->Kdata->GetCharValue(i)))
|
case FLD_SCALE:
|
||||||
comment= thd->make_lex_string(NULL, rem, strlen(rem), true);
|
if ((dec= crp->Kdata->GetIntValue(i))) {
|
||||||
else
|
decimals= (char*)PlugSubAlloc(g, NULL, 8);
|
||||||
comment= thd->make_lex_string(NULL, "", 0, true);
|
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
|
// Now add the field
|
||||||
b= add_fields(thd, alt_info, name, type, length, decimals,
|
b= add_fields(thd, alt_info, name, type, length, decimals,
|
||||||
0, comment, NULL, NULL, NULL);
|
tm, comment, cs, NULL, NULL);
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
|
@@ -100,84 +100,9 @@ extern int xtrace;
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
//bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR);
|
//bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR);
|
||||||
//#if !defined(WIN32)
|
//#if !defined(WIN32)
|
||||||
extern "C" int GetRcString(int id, char *buf, int bufsize);
|
|
||||||
//#endif // !WIN32
|
//#endif // !WIN32
|
||||||
//void ptrc(char const *fmt, ...);
|
//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: */
|
/* Get a unique char identifier for types. The letter used are: */
|
||||||
/* ABCDEF..I.KLM.O..R.T.VWXY.. */
|
/* 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)
|
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;
|
int i, loff, poff, nof, nlg;
|
||||||
void *field= NULL;
|
void *field= NULL;
|
||||||
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
|
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
|
||||||
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
||||||
|
|
||||||
// Get a unique char identifier for type
|
// Get a unique char identifier for type
|
||||||
char tc= GetTypeID(type);
|
tc= (!defp->Catfunc) ? GetTypeID(type) : 0;
|
||||||
|
|
||||||
// Take care of the column definitions
|
// Take care of the column definitions
|
||||||
i= poff= nof= nlg= 0;
|
i= poff= nof= nlg= 0;
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/************** MyConn C++ Program Source Code File (.CPP) **************/
|
/************** MyConn C++ Program Source Code File (.CPP) **************/
|
||||||
/* PROGRAM NAME: MYCONN */
|
/* PROGRAM NAME: MYCONN */
|
||||||
/* ------------- */
|
/* ------------- */
|
||||||
/* Version 1.5 */
|
/* Version 1.6 */
|
||||||
/* */
|
/* */
|
||||||
/* COPYRIGHT: */
|
/* COPYRIGHT: */
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2007-2012 */
|
/* (C) Copyright to the author Olivier BERTRAND 2007-2013 */
|
||||||
/* */
|
/* */
|
||||||
/* WHAT THIS PROGRAM DOES: */
|
/* WHAT THIS PROGRAM DOES: */
|
||||||
/* ----------------------- */
|
/* ----------------------- */
|
||||||
@@ -63,13 +63,6 @@ static char *server_groups[] = {
|
|||||||
|
|
||||||
extern "C" int trace;
|
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 */
|
/* MyColumns: constructs the result blocks containing all columns */
|
||||||
/* of a MySQL table that will be retrieved by GetData commands. */
|
/* 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,
|
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
const char *table, const char *colpat,
|
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,
|
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT,
|
||||||
DB_INT, DB_SHORT, DB_CHAR, DB_CHAR};
|
DB_CHAR, DB_SHORT, DB_SHORT, DB_SHORT,
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
DB_CHAR, DB_CHAR, DB_CHAR};
|
||||||
TYPE_INT, TYPE_SHORT, TYPE_STRING, TYPE_STRING};
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
||||||
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 0, 0};
|
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];
|
char *fld, *fmt, cmd[128];
|
||||||
int i, n, nf, ncol = sizeof(dbtype) / sizeof(int);
|
int i, n, nf, ncol = sizeof(dbtype) / sizeof(int);
|
||||||
int len, type, prec, rc, k = 0;
|
int len, type, prec, rc, k = 0;
|
||||||
@@ -92,44 +90,59 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
MYSQLC myc;
|
MYSQLC myc;
|
||||||
|
|
||||||
/**********************************************************************/
|
if (!info) {
|
||||||
/* Open the connection with the MySQL server. */
|
/********************************************************************/
|
||||||
/**********************************************************************/
|
/* Open the connection with the MySQL server. */
|
||||||
if (myc.Open(g, host, db, user, pwd, port))
|
/********************************************************************/
|
||||||
return NULL;
|
if (myc.Open(g, host, db, user, pwd, port))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/**********************************************************************/
|
/********************************************************************/
|
||||||
/* Do an evaluation of the result size. */
|
/* Do an evaluation of the result size. */
|
||||||
/**********************************************************************/
|
/********************************************************************/
|
||||||
sprintf(cmd, "SHOW FULL COLUMNS FROM %s", table);
|
sprintf(cmd, "SHOW FULL COLUMNS FROM %s", table);
|
||||||
strcat(strcat(cmd, " FROM "), (db) ? db : PlgGetUser(g)->DBName);
|
strcat(strcat(cmd, " FROM "), (db) ? db : PlgGetUser(g)->DBName);
|
||||||
|
|
||||||
if (colpat)
|
if (colpat)
|
||||||
strcat(strcat(cmd, " LIKE "), colpat);
|
strcat(strcat(cmd, " LIKE "), colpat);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("MyColumns: cmd='%s'\n", cmd);
|
htrc("MyColumns: cmd='%s'\n", cmd);
|
||||||
|
|
||||||
if ((n = myc.GetResultSize(g, cmd)) < 0) {
|
if ((n = myc.GetResultSize(g, cmd)) < 0) {
|
||||||
myc.Close();
|
myc.Close();
|
||||||
return NULL;
|
return NULL;
|
||||||
} // endif n
|
} // endif n
|
||||||
|
|
||||||
/**********************************************************************/
|
/********************************************************************/
|
||||||
/* Get the size of the name columns. */
|
/* 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);
|
||||||
/**********************************************************************/
|
} else {
|
||||||
length[0] = myc.GetFieldLength(0);
|
n = 0;
|
||||||
|
length[0] = 128;
|
||||||
|
} // endif info
|
||||||
|
|
||||||
if (!key) // We are not called from Create table
|
//if (!key) // We are not called from Create table
|
||||||
ncol--; // No date format column
|
// ncol--; // No date format column yet
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Allocate the structures used to refer to the result set. */
|
/* Allocate the structures used to refer to the result set. */
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
|
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. */
|
/* Now get the results into blocks. */
|
||||||
@@ -142,7 +155,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
|
|
||||||
// Get column name
|
// Get column name
|
||||||
fld = myc.GetCharField(0);
|
fld = myc.GetCharField(0);
|
||||||
crp = qrp->Colresp;
|
crp = qrp->Colresp; // Column_Name
|
||||||
crp->Kdata->SetValue(fld, i);
|
crp->Kdata->SetValue(fld, i);
|
||||||
|
|
||||||
// Get type, type name, and precision
|
// Get type, type name, and precision
|
||||||
@@ -161,56 +174,45 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
return NULL;
|
return NULL;
|
||||||
} // endif type
|
} // endif type
|
||||||
|
|
||||||
crp = crp->Next;
|
crp = crp->Next; // Data_Type
|
||||||
crp->Kdata->SetValue(type, i);
|
crp->Kdata->SetValue(type, i);
|
||||||
crp = crp->Next;
|
crp = crp->Next; // Type_Name
|
||||||
crp->Kdata->SetValue(cmd, i);
|
crp->Kdata->SetValue(cmd, i);
|
||||||
|
|
||||||
if (key && type == TYPE_DATE) {
|
if (type == TYPE_DATE) {
|
||||||
// When creating tables we do need info about date columns
|
// When creating tables we do need info about date columns
|
||||||
fmt = MyDateFmt(cmd);
|
fmt = MyDateFmt(cmd);
|
||||||
len = strlen(fmt);
|
len = strlen(fmt);
|
||||||
} else
|
} else
|
||||||
fmt = NULL;
|
fmt = NULL;
|
||||||
|
|
||||||
crp = crp->Next;
|
crp = crp->Next; // Precision
|
||||||
crp->Name = "Length";
|
|
||||||
crp->Kdata->SetValue(len, i);
|
crp->Kdata->SetValue(len, i);
|
||||||
crp = crp->Next;
|
|
||||||
crp->Name = "Key";
|
|
||||||
|
|
||||||
if (key) {
|
crp = crp->Next; // was Length
|
||||||
// Creating a table, we need key info
|
fld = myc.GetCharField(4);
|
||||||
fld = myc.GetCharField(4);
|
crp->Kdata->SetValue(fld, i);
|
||||||
crp->Kdata->SetValue((stricmp(fld, "PRI")) ? 0 : ++k, i);
|
|
||||||
} else
|
|
||||||
crp->Kdata->SetValue(len, i);
|
|
||||||
|
|
||||||
crp = crp->Next;
|
crp = crp->Next; // Scale
|
||||||
crp->Name = "Prec";
|
|
||||||
crp->Kdata->SetValue(prec, i);
|
crp->Kdata->SetValue(prec, i);
|
||||||
|
|
||||||
// Get comment field
|
crp = crp->Next; // Radix
|
||||||
crp = crp->Next;
|
crp->Kdata->SetValue(0, i);
|
||||||
crp->Name = "Comment";
|
|
||||||
|
crp = crp->Next; // Nullable
|
||||||
|
fld = myc.GetCharField(3);
|
||||||
|
crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i);
|
||||||
|
|
||||||
|
crp = crp->Next; // Remark
|
||||||
fld = myc.GetCharField(8);
|
fld = myc.GetCharField(8);
|
||||||
|
crp->Kdata->SetValue(fld, i);
|
||||||
|
|
||||||
if (fld && strlen(fld))
|
crp = crp->Next; // New
|
||||||
crp->Kdata->SetValue(fld, i);
|
crp->Kdata->SetValue((fmt) ? fmt : "", i);
|
||||||
else
|
|
||||||
crp->Kdata->Reset(i);
|
|
||||||
|
|
||||||
if (key) {
|
|
||||||
crp = crp->Next;
|
|
||||||
crp->Name = "Date_Fmt";
|
|
||||||
|
|
||||||
if (fmt)
|
|
||||||
crp->Kdata->SetValue(fmt, i);
|
|
||||||
else
|
|
||||||
crp->Kdata->Reset(i);
|
|
||||||
|
|
||||||
} // endif key
|
|
||||||
|
|
||||||
|
crp = crp->Next; // New (charset)
|
||||||
|
fld = myc.GetCharField(2);
|
||||||
|
crp->Kdata->SetValue(fld, i);
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
if (k > 1) {
|
if (k > 1) {
|
||||||
@@ -234,79 +236,6 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
return qrp;
|
return qrp;
|
||||||
} // end of MyColumns
|
} // 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 --------------------------- */
|
/* -------------------------- Class MYSQLC --------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -38,7 +38,7 @@ typedef class MYSQLC *PMYC;
|
|||||||
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
const char *table, const char *colpat,
|
const char *table, const char *colpat,
|
||||||
int port, bool key);
|
int port, bool key, bool info);
|
||||||
|
|
||||||
/* -------------------------- MYCONN class --------------------------- */
|
/* -------------------------- MYCONN class --------------------------- */
|
||||||
|
|
||||||
|
@@ -171,13 +171,6 @@ int TranslateSQLType(int stp, int prec, int& len)
|
|||||||
HENV ODBConn::m_henv = SQL_NULL_HENV;
|
HENV ODBConn::m_henv = SQL_NULL_HENV;
|
||||||
int ODBConn::m_nAlloc = 0; // per-Appl reference to HENV above
|
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. */
|
/* 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,
|
PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table,
|
||||||
char *colpat)
|
char *colpat)
|
||||||
{
|
{
|
||||||
static int dbtype[] = {DB_CHAR, DB_CHAR,
|
static int dbtype[] = {DB_CHAR, DB_CHAR,
|
||||||
DB_CHAR, DB_SHORT, DB_CHAR,
|
DB_CHAR, DB_SHORT, DB_CHAR,
|
||||||
DB_INT, DB_INT, DB_SHORT,
|
DB_INT, DB_INT, DB_SHORT,
|
||||||
DB_SHORT, DB_SHORT, DB_CHAR};
|
DB_SHORT, DB_SHORT, DB_CHAR};
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_STRING,
|
static int buftyp[] = {TYPE_STRING, TYPE_STRING,
|
||||||
TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
||||||
TYPE_INT, TYPE_INT, TYPE_SHORT,
|
TYPE_INT, TYPE_INT, TYPE_SHORT,
|
||||||
TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
|
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};
|
static unsigned int length[] = {0, 0, 0, 6, 20, 10, 10, 6, 6, 6, 128};
|
||||||
int n, ncol = 11;
|
int n, ncol = 11;
|
||||||
int maxres;
|
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. */
|
/* Allocate the structures used to refer to the result set. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS + 1,
|
qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS + 1,
|
||||||
dbtype, buftyp, length);
|
dbtype, buftyp, NULL, length, true, true);
|
||||||
|
|
||||||
if (!ocp) // Info table
|
if (!ocp) // Info table
|
||||||
return qrp;
|
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)
|
PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
|
||||||
{
|
{
|
||||||
int type, len, prec;
|
// int i, type, len, prec;
|
||||||
PCOLRES crpt, crpl, crpp;
|
// PCOLRES crp, crpt, crpl, crpp;
|
||||||
PQRYRES qrp;
|
PQRYRES qrp;
|
||||||
ODBConn *ocp;
|
ODBConn *ocp;
|
||||||
|
|
||||||
@@ -342,6 +339,7 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
|
|||||||
if (ocp)
|
if (ocp)
|
||||||
ocp->Close();
|
ocp->Close();
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (!qrp)
|
if (!qrp)
|
||||||
return NULL; // Error in ODBCColumns
|
return NULL; // Error in ODBCColumns
|
||||||
|
|
||||||
@@ -371,7 +369,13 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
|
|||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
crpp->Next = crpp->Next->Next->Next; // Should be Remark
|
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;
|
return qrp;
|
||||||
} // end of MyODBCCols
|
} // end of MyODBCCols
|
||||||
|
|
||||||
@@ -410,7 +414,8 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Allocate the structures used to refer to the result set. */
|
/* 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. */
|
/* 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. */
|
/* 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. */
|
/* 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. */
|
/* Allocate the structures used to refer to the result set. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES + 1,
|
qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES + 1,
|
||||||
dbtype, buftyp, length);
|
dbtype, buftyp, NULL, length, true, true);
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
return qrp;
|
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. */
|
/* Allocate the structure used to refer to the result set. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY + 1,
|
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY + 1,
|
||||||
dbtype, buftyp, length);
|
dbtype, buftyp, NULL, length, true, true);
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
#ifdef DEBTRACE
|
||||||
htrc("Getting pkey results ncol=%d\n", qrp->Nbcol);
|
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. */
|
/* Allocate the structure used to refer to the result set. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT + 1,
|
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT + 1,
|
||||||
dbtype, buftyp, length);
|
dbtype, buftyp, NULL, length, true, true);
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
#ifdef DEBTRACE
|
||||||
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
|
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
|
||||||
|
@@ -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_DMY = 172, /* DMY Dummy tables am type no */
|
||||||
TYPE_AM_SET = 180, /* SET Set 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_MYSQL = 192, /* MYSQL access method type no */
|
||||||
|
TYPE_AM_CAT = 193, /* Catalog access method type no */
|
||||||
TYPE_AM_OUT = 200}; /* Output relations (storage) */
|
TYPE_AM_OUT = 200}; /* Output relations (storage) */
|
||||||
|
|
||||||
enum RECFM {RECFM_NAF = -2, /* Not a file */
|
enum RECFM {RECFM_NAF = -2, /* Not a file */
|
||||||
@@ -440,6 +441,25 @@ typedef struct _tabs {
|
|||||||
PTABADR P3;
|
PTABADR P3;
|
||||||
} 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. */
|
/* Result of last SQL noconv query. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -470,6 +490,7 @@ typedef struct _colres {
|
|||||||
int Clen; /* Data individual internal size */
|
int Clen; /* Data individual internal size */
|
||||||
int Length; /* Data individual print length */
|
int Length; /* Data individual print length */
|
||||||
int Prec; /* Precision */
|
int Prec; /* Precision */
|
||||||
|
XFLD Fld; /* Type of field info */
|
||||||
} COLRES;
|
} COLRES;
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(NOEX)
|
#if defined(WIN32) && !defined(NOEX)
|
||||||
@@ -491,6 +512,13 @@ void AddPointer(PTABS, void *);
|
|||||||
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
|
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
|
||||||
int ExtractDate(char *, PDTP, int, int val[6]);
|
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. */
|
/* Exported utility routines. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/
|
/********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/
|
||||||
/* PROGRAM NAME: PLGDBUTL */
|
/* PROGRAM NAME: PLGDBUTL */
|
||||||
/* ------------- */
|
/* ------------- */
|
||||||
/* Version 3.7 */
|
/* Version 3.8 */
|
||||||
/* */
|
/* */
|
||||||
/* COPYRIGHT: */
|
/* COPYRIGHT: */
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */
|
/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
|
||||||
/* */
|
/* */
|
||||||
/* WHAT THIS PROGRAM DOES: */
|
/* WHAT THIS PROGRAM DOES: */
|
||||||
/* ----------------------- */
|
/* ----------------------- */
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
#include "colblk.h"
|
#include "colblk.h"
|
||||||
#include "xtable.h" // header of TBX, TDB and TDBASE classes
|
#include "xtable.h" // header of TBX, TDB and TDBASE classes
|
||||||
#include "tabcol.h" // header of XTAB and COLUMN classes
|
#include "tabcol.h" // header of XTAB and COLUMN classes
|
||||||
|
#include "valblk.h"
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Macro or external routine definition */
|
/* Macro or external routine definition */
|
||||||
@@ -128,6 +129,7 @@ void CloseXMLFile(PGLOBAL, PFBLOCK, bool);
|
|||||||
void CloseXML2File(PGLOBAL, PFBLOCK, bool);
|
void CloseXML2File(PGLOBAL, PFBLOCK, bool);
|
||||||
#endif // LIBXML2_SUPPORT
|
#endif // LIBXML2_SUPPORT
|
||||||
|
|
||||||
|
extern "C" int GetRcString(int id, char *buf, int bufsize);
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Routines for file IO with error reporting to g->Message */
|
/* Routines for file IO with error reporting to g->Message */
|
||||||
@@ -262,6 +264,85 @@ void ptrc(char const *fmt, ...)
|
|||||||
} // end of ptrc
|
} // end of ptrc
|
||||||
#endif // 0
|
#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. */
|
/* Allocate and initialize the new DB User Block. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -74,6 +74,7 @@ TABDEF::TABDEF(void)
|
|||||||
{
|
{
|
||||||
Owner = NULL;
|
Owner = NULL;
|
||||||
Desc = NULL;
|
Desc = NULL;
|
||||||
|
Catfunc = 0;
|
||||||
Card = 0;
|
Card = 0;
|
||||||
Elemt = 0;
|
Elemt = 0;
|
||||||
Sort = 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);
|
Name = (PSZ)PlugSubAlloc(g, memp, strlen(name) + 1);
|
||||||
strcpy(Name, name);
|
strcpy(Name, name);
|
||||||
Cat = cat;
|
Cat = cat;
|
||||||
|
Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", ""));
|
||||||
Elemt = cat->GetIntCatInfo(name, "Elements", 0);
|
Elemt = cat->GetIntCatInfo(name, "Elements", 0);
|
||||||
Multiple = cat->GetIntCatInfo(name, "Multiple", 0);
|
Multiple = cat->GetIntCatInfo(name, "Multiple", 0);
|
||||||
Degree = cat->GetIntCatInfo(name, "Degree", 0);
|
Degree = cat->GetIntCatInfo(name, "Degree", 0);
|
||||||
|
@@ -85,6 +85,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
|
|||||||
// Members
|
// Members
|
||||||
PSZ Owner; /* Table owner (for ODBC) */
|
PSZ Owner; /* Table owner (for ODBC) */
|
||||||
PSZ Desc; /* Table description */
|
PSZ Desc; /* Table description */
|
||||||
|
char Catfunc; /* Catalog function */
|
||||||
int Card; /* (max) number of rows in table */
|
int Card; /* (max) number of rows in table */
|
||||||
int Elemt; /* Number of rows in blocks or rowset */
|
int Elemt; /* Number of rows in blocks or rowset */
|
||||||
int Sort; /* Table already sorted ??? */
|
int Sort; /* Table already sorted ??? */
|
||||||
|
@@ -297,12 +297,16 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
|
|||||||
/* Column blocks will be allocated only when needed. */
|
/* Column blocks will be allocated only when needed. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Recfm == RECFM_DBF) {
|
if (Recfm == RECFM_DBF) {
|
||||||
if (map)
|
if (!Catfunc) {
|
||||||
txfp = new(g) DBMFAM(this);
|
if (map)
|
||||||
else
|
txfp = new(g) DBMFAM(this);
|
||||||
txfp = new(g) DBFFAM(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) {
|
} else if (Recfm != RECFM_VAR && Compressed < 2) {
|
||||||
if (Huge)
|
if (Huge)
|
||||||
txfp = new(g) BGXFAM(this);
|
txfp = new(g) BGXFAM(this);
|
||||||
|
@@ -34,6 +34,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
|
|||||||
virtual const char *GetType(void) {return "DOS";}
|
virtual const char *GetType(void) {return "DOS";}
|
||||||
virtual PIXDEF GetIndx(void) {return To_Indx;}
|
virtual PIXDEF GetIndx(void) {return To_Indx;}
|
||||||
virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;}
|
virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;}
|
||||||
|
PSZ GetFn(void) {return Fn;}
|
||||||
PSZ GetOfn(void) {return Ofn;}
|
PSZ GetOfn(void) {return Ofn;}
|
||||||
void SetBlock(int block) {Block = block;}
|
void SetBlock(int block) {Block = block;}
|
||||||
int GetBlock(void) {return Block;}
|
int GetBlock(void) {return Block;}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#ifndef __TABFIX__
|
#ifndef __TABFIX__
|
||||||
#define __TABFIX__
|
#define __TABFIX__
|
||||||
#include "tabdos.h" /* Base class declares */
|
#include "tabdos.h" /* Base class declares */
|
||||||
|
#include "filamdbf.h"
|
||||||
|
|
||||||
typedef class FIXCOL *PFIXCOL;
|
typedef class FIXCOL *PFIXCOL;
|
||||||
typedef class BINCOL *PBINCOL;
|
typedef class BINCOL *PBINCOL;
|
||||||
@@ -77,4 +78,22 @@ class DllExport BINCOL : public DOSCOL {
|
|||||||
// Members
|
// Members
|
||||||
char Fmt; // The column numeric format
|
char Fmt; // The column numeric format
|
||||||
}; // end of class BINCOL
|
}; // 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__
|
#endif // __TABFIX__
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/************* TabFmt C++ Program Source Code File (.CPP) **************/
|
/************* TabFmt C++ Program Source Code File (.CPP) **************/
|
||||||
/* PROGRAM NAME: TABFMT */
|
/* PROGRAM NAME: TABFMT */
|
||||||
/* ------------- */
|
/* ------------- */
|
||||||
/* Version 3.7 */
|
/* Version 3.8 */
|
||||||
/* */
|
/* */
|
||||||
/* COPYRIGHT: */
|
/* COPYRIGHT: */
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
@@ -67,12 +67,6 @@
|
|||||||
|
|
||||||
extern "C" int trace;
|
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 */
|
/* CSVColumns: constructs the result blocks containing the description */
|
||||||
/* of all the columns of a CSV file that will be retrieved by #GetData.*/
|
/* of all the columns of a CSV file that will be retrieved by #GetData.*/
|
||||||
@@ -80,12 +74,15 @@ PQRYRES PlgAllocResult(PGLOBAL, int, int, int, int *, int *,
|
|||||||
/* of types (TYPE_STRING < TYPE_FLOAT < TYPE_INT) (1 < 2 < 7). */
|
/* of types (TYPE_STRING < TYPE_FLOAT < TYPE_INT) (1 < 2 < 7). */
|
||||||
/* If these values are changed, this will have to be revisited. */
|
/* 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,
|
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
|
||||||
DB_INT, DB_INT, DB_SHORT};
|
DB_INT, DB_INT, DB_SHORT};
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
||||||
TYPE_INT, TYPE_INT, TYPE_SHORT};
|
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};
|
static unsigned int length[] = {6, 6, 8, 10, 10, 6};
|
||||||
char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
|
char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
|
||||||
int i, imax, hmax, n, nerr, phase, blank, digit, dec, type;
|
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;
|
PQRYRES qrp;
|
||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
imax = 0;
|
||||||
|
length[0] = 128;
|
||||||
|
goto skipit;
|
||||||
|
} // endif info
|
||||||
|
|
||||||
// num_max = atoi(p+1); // Max num of record to test
|
// num_max = atoi(p+1); // Max num of record to test
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
if (strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
|
if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
|
||||||
dechar = '.';
|
dechar = '.';
|
||||||
else
|
else
|
||||||
dechar = ',';
|
dechar = ',';
|
||||||
@@ -328,6 +331,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr)
|
|||||||
|
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
|
|
||||||
|
skipit:
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
|
htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
|
||||||
imax, hmax, length[0]);
|
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. */
|
/* Allocate the structures used to refer to the result set. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
|
qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
|
||||||
dbtype, buftyp, length);
|
dbtype, buftyp, fldtyp, length, true, false);
|
||||||
qrp->Nblin = imax;
|
qrp->Nblin = imax;
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
return qrp;
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Now get the results into blocks. */
|
/* Now get the results into blocks. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
@@ -398,11 +405,12 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
char buf[8];
|
char buf[8];
|
||||||
|
|
||||||
// Double check correctness of offset values
|
// Double check correctness of offset values
|
||||||
for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
|
if (!Catfunc)
|
||||||
if (cdp->GetOffset() < 1) {
|
for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
|
||||||
strcpy(g->Message, MSG(BAD_OFFSET_VAL));
|
if (cdp->GetOffset() < 1) {
|
||||||
return true;
|
strcpy(g->Message, MSG(BAD_OFFSET_VAL));
|
||||||
} // endif Offset
|
return true;
|
||||||
|
} // endif Offset
|
||||||
|
|
||||||
// Call DOSDEF DefineAM with am=CSV so FMT is not confused with FIX
|
// Call DOSDEF DefineAM with am=CSV so FMT is not confused with FIX
|
||||||
if (DOSDEF::DefineAM(g, "CSV", poff))
|
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)
|
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;
|
PTDBASE tdbp;
|
||||||
|
|
||||||
/*********************************************************************/
|
if (Catfunc != 'C') {
|
||||||
/* Allocate a file processing class of the proper type. */
|
USETEMP tmp = PlgGetUser(g)->UseTemp;
|
||||||
/*********************************************************************/
|
bool map = Mapped && mode != MODE_INSERT &&
|
||||||
if (map) {
|
!(tmp != TMP_NO && mode == MODE_UPDATE) &&
|
||||||
// Should be now compatible with UNIX
|
!(tmp == TMP_FORCE &&
|
||||||
txfp = new(g) MAPFAM(this);
|
(mode == MODE_UPDATE || mode == MODE_DELETE));
|
||||||
} else if (Compressed) {
|
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 defined(ZIP_SUPPORT)
|
||||||
if (Compressed == 1)
|
if (Compressed == 1)
|
||||||
txfp = new(g) ZIPFAM(this);
|
txfp = new(g) ZIPFAM(this);
|
||||||
else {
|
else {
|
||||||
strcpy(g->Message, "Compress 2 not supported yet");
|
strcpy(g->Message, "Compress 2 not supported yet");
|
||||||
// txfp = new(g) ZLBFAM(defp);
|
// txfp = new(g) ZLBFAM(defp);
|
||||||
return NULL;
|
return NULL;
|
||||||
} // endelse
|
} // endelse
|
||||||
#else // !ZIP_SUPPORT
|
#else // !ZIP_SUPPORT
|
||||||
strcpy(g->Message, "Compress not supported");
|
strcpy(g->Message, "Compress not supported");
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif // !ZIP_SUPPORT
|
#endif // !ZIP_SUPPORT
|
||||||
|
} 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);
|
||||||
|
|
||||||
|
if (Multiple)
|
||||||
|
tdbp = new(g) TDBMUL(tdbp);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
txfp = new(g) DOSFAM(this);
|
tdbp = new(g)TDBCCL(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);
|
|
||||||
|
|
||||||
if (Multiple)
|
|
||||||
tdbp = new(g) TDBMUL(tdbp);
|
|
||||||
|
|
||||||
return tdbp;
|
return tdbp;
|
||||||
} // end of GetTable
|
} // end of GetTable
|
||||||
@@ -1389,4 +1402,26 @@ void CSVCOL::WriteColumn(PGLOBAL g)
|
|||||||
|
|
||||||
} // end of WriteColumn
|
} // 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 ---------------------------- */
|
/* ------------------------ End of TabFmt ---------------------------- */
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*************** TabFmt H Declares Source Code File (.H) ***************/
|
/*************** 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. */
|
/* This file contains the CSV and FMT classes declares. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -14,14 +14,15 @@ typedef class TDBFMT *PTDBFMT;
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Functions used externally. */
|
/* 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. */
|
/* CSV table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class DllExport CSVDEF : public DOSDEF { /* Logical table description */
|
class DllExport CSVDEF : public DOSDEF { /* Logical table description */
|
||||||
friend class TDBCSV;
|
friend class TDBCSV;
|
||||||
//friend class TDBMCV;
|
friend class TDBCCL;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
CSVDEF(void);
|
CSVDEF(void);
|
||||||
@@ -160,10 +161,30 @@ class TDBFMT : public TDBCSV {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
PSZ *FldFormat; // Field read format
|
PSZ *FldFormat; // Field read format
|
||||||
void *To_Fld; // To field test buffer
|
void *To_Fld; // To field test buffer
|
||||||
int *FmtTest; // Test on ending by %n or %m
|
int *FmtTest; // Test on ending by %n or %m
|
||||||
int Linenum; // Last read line
|
int Linenum; // Last read line
|
||||||
}; // end of class TDBFMT
|
}; // 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 ------------------------- */
|
/* ------------------------- End of TabFmt.H ------------------------- */
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/************** Table C++ Functions Source Code File (.CPP) ************/
|
/************** 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. */
|
/* 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);
|
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
|
||||||
|
|
||||||
} // end of MarkDB
|
} // 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
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/************* TabMySQL C++ Program Source Code File (.CPP) *************/
|
/************* TabMySQL C++ Program Source Code File (.CPP) *************/
|
||||||
/* PROGRAM NAME: TABMYSQL */
|
/* PROGRAM NAME: TABMYSQL */
|
||||||
/* ------------- */
|
/* ------------- */
|
||||||
/* Version 1.5 */
|
/* Version 1.6 */
|
||||||
/* */
|
/* */
|
||||||
/* AUTHOR: */
|
/* AUTHOR: */
|
||||||
/* ------- */
|
/* ------- */
|
||||||
@@ -105,7 +105,11 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m)
|
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
|
} // end of GetTable
|
||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
@@ -859,3 +863,26 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
|
|||||||
} // endif Prep
|
} // endif Prep
|
||||||
|
|
||||||
} // end of WriteColumn
|
} // 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
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// TDBMYSQL.H Olivier Bertrand 2007-2012
|
// TDBMYSQL.H Olivier Bertrand 2007-2013
|
||||||
#include "myconn.h" // MySQL connection declares
|
#include "myconn.h" // MySQL connection declares
|
||||||
|
|
||||||
typedef class MYSQLDEF *PMYDEF;
|
typedef class MYSQLDEF *PMYDEF;
|
||||||
@@ -18,6 +18,7 @@ typedef class MYSQLCOL *PMYCOL;
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class MYSQLDEF : public TABDEF {/* Logical table description */
|
class MYSQLDEF : public TABDEF {/* Logical table description */
|
||||||
friend class TDBMYSQL;
|
friend class TDBMYSQL;
|
||||||
|
friend class TDBMCL;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
MYSQLDEF(void);
|
MYSQLDEF(void);
|
||||||
@@ -104,7 +105,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
int AftRows; // The number of affected rows
|
int AftRows; // The number of affected rows
|
||||||
int N; // The current table index
|
int N; // The current table index
|
||||||
int Port; // MySQL port number (0 = default)
|
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
|
}; // end of class TDBMYSQL
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -132,12 +133,28 @@ class MYSQLCOL : public COLBLK {
|
|||||||
|
|
||||||
// Members
|
// Members
|
||||||
MYSQL_BIND *Bind; // This column bind structure pointer
|
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
|
unsigned long Slen; // Bind string lengh
|
||||||
int Rank; // Rank (position) number in the query
|
int Rank; // Rank (position) number in the query
|
||||||
}; // end of class MYSQLCOL
|
}; // 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,
|
protected:
|
||||||
const char *user, const char *pwd,
|
// Specific routines
|
||||||
const char *table, const char *colpat, int port, bool key);
|
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
|
||||||
|
@@ -89,7 +89,6 @@ extern int num_read, num_there, num_eq[2]; // Statistics
|
|||||||
ODBCDEF::ODBCDEF(void)
|
ODBCDEF::ODBCDEF(void)
|
||||||
{
|
{
|
||||||
Connect = Tabname = Tabowner = Tabqual = Qchar = NULL;
|
Connect = Tabname = Tabowner = Tabqual = Qchar = NULL;
|
||||||
Catfunc = 0;
|
|
||||||
Catver = Options = 0;
|
Catver = Options = 0;
|
||||||
} // end of ODBCDEF constructor
|
} // end of ODBCDEF constructor
|
||||||
|
|
||||||
@@ -101,7 +100,6 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
int dop = ODBConn::noOdbcDialog; // Default for options
|
int dop = ODBConn::noOdbcDialog; // Default for options
|
||||||
|
|
||||||
Desc = Connect = Cat->GetStringCatInfo(g, Name, "Connect", "");
|
Desc = Connect = Cat->GetStringCatInfo(g, Name, "Connect", "");
|
||||||
Catfunc = toupper(*Cat->GetStringCatInfo(g, Name, "Catfunc", ""));
|
|
||||||
Tabname = Cat->GetStringCatInfo(g, Name, "Name",
|
Tabname = Cat->GetStringCatInfo(g, Name, "Name",
|
||||||
Catfunc == 'T' ? NULL : Name);
|
Catfunc == 'T' ? NULL : Name);
|
||||||
Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname);
|
Tabname = Cat->GetStringCatInfo(g, Name, "Tabname", Tabname);
|
||||||
@@ -905,259 +903,53 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
|
|||||||
|
|
||||||
} // end of WriteColumn
|
} // 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 --------------------------- */
|
/* ---------------------------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 ODBCDataSources(g, false);
|
||||||
return false;
|
} // end of GetResult
|
||||||
|
|
||||||
if (!(Qrp = ODBCDataSources(g, false)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Init = true;
|
|
||||||
return false;
|
|
||||||
} // end of Initialize
|
|
||||||
|
|
||||||
/* ---------------------------TDBDRV class --------------------------- */
|
/* ---------------------------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 ODBCDrivers(g, false);
|
||||||
return false;
|
} // end of GetResult
|
||||||
|
|
||||||
if (!(Qrp = ODBCDrivers(g, false)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Init = true;
|
|
||||||
return false;
|
|
||||||
} // end of Initialize
|
|
||||||
|
|
||||||
/* ---------------------------TDBOCL class --------------------------- */
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* TDBOCL class constructor. */
|
|
||||||
/***********************************************************************/
|
|
||||||
TDBOCL::TDBOCL(PODEF tdp) : TDBOIF(tdp)
|
|
||||||
{
|
|
||||||
ID = IDS_COLUMNS + 1;
|
|
||||||
NC = 11;
|
|
||||||
Dsn = tdp->GetConnect();
|
|
||||||
Tabn = tdp->GetTabname();
|
|
||||||
} // end of TDBOCL constructor
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* Initialize: Get the list of ODBC table columns. */
|
|
||||||
/***********************************************************************/
|
|
||||||
bool TDBOCL::Initialize(PGLOBAL g)
|
|
||||||
{
|
|
||||||
if (Init)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!(Qrp = MyODBCCols(g, Dsn, Tabn, false)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Init = true;
|
|
||||||
return false;
|
|
||||||
} // end of Initialize
|
|
||||||
|
|
||||||
/* ---------------------------TDBOTB class --------------------------- */
|
/* ---------------------------TDBOTB class --------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TDBOCL class constructor. */
|
/* TDBOTB class constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
TDBOTB::TDBOTB(PODEF tdp) : TDBOIF(tdp)
|
TDBOTB::TDBOTB(PODEF tdp) : TDBCAT(tdp)
|
||||||
{
|
{
|
||||||
ID = IDS_TABLES + 1;
|
|
||||||
NC = 4;
|
|
||||||
Dsn = tdp->GetConnect();
|
Dsn = tdp->GetConnect();
|
||||||
Tabpat = tdp->GetTabname();
|
Tab = tdp->GetTabname();
|
||||||
} // end of TDBOCL constructor
|
} // end of TDBOTB constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Initialize: Get the list of ODBC tables. */
|
/* GetResult: Get the list of ODBC tables. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBOTB::Initialize(PGLOBAL g)
|
PQRYRES TDBOTB::GetResult(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (Init)
|
return ODBCTables(g, Dsn, Tab, false);
|
||||||
return false;
|
} // end of GetResult
|
||||||
|
|
||||||
if (!(Qrp = ODBCTables(g, Dsn, Tabpat, false)))
|
/* ---------------------------TDBOCL class --------------------------- */
|
||||||
return true;
|
|
||||||
|
|
||||||
Init = true;
|
/***********************************************************************/
|
||||||
return false;
|
/* GetResult: Get the list of ODBC table columns. */
|
||||||
} // end of Initialize
|
/***********************************************************************/
|
||||||
|
PQRYRES TDBOCL::GetResult(PGLOBAL g)
|
||||||
|
{
|
||||||
|
return MyODBCCols(g, Dsn, Tab, false);
|
||||||
|
} // end of GetResult
|
||||||
|
|
||||||
/* ------------------------ End of Tabodbc --------------------------- */
|
/* ------------------------ End of Tabodbc --------------------------- */
|
||||||
|
@@ -44,7 +44,6 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||||||
PSZ Tabowner; /* External table owner */
|
PSZ Tabowner; /* External table owner */
|
||||||
PSZ Tabqual; /* External table qualifier */
|
PSZ Tabqual; /* External table qualifier */
|
||||||
PSZ Qchar; /* Identifier quoting character */
|
PSZ Qchar; /* Identifier quoting character */
|
||||||
char Catfunc; /* Catalog function */
|
|
||||||
int Catver; /* ODBC version for catalog functions */
|
int Catver; /* ODBC version for catalog functions */
|
||||||
int Options; /* Open connection options */
|
int Options; /* Open connection options */
|
||||||
}; // end of ODBCDEF
|
}; // end of ODBCDEF
|
||||||
@@ -163,128 +162,64 @@ class ODBCCOL : public COLBLK {
|
|||||||
int Rank; // Rank (position) number in the query
|
int Rank; // Rank (position) number in the query
|
||||||
}; // end of class ODBCCOL
|
}; // 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. */
|
/* This is the class declaration for the Data Sources catalog table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class TDBSRC : public TDBOIF {
|
class TDBSRC : public TDBCAT {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TDBSRC(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DSRC; NC = 2;}
|
TDBSRC(PODEF tdp) : TDBCAT(tdp) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Specific routines
|
// Specific routines
|
||||||
virtual bool Initialize(PGLOBAL g);
|
virtual PQRYRES GetResult(PGLOBAL g);
|
||||||
|
|
||||||
}; // end of class TDBSRC
|
}; // end of class TDBSRC
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This is the class declaration for the Drivers catalog table. */
|
/* This is the class declaration for the Drivers catalog table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class TDBDRV : public TDBOIF {
|
class TDBDRV : public TDBCAT {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TDBDRV(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DRIVER; NC = 2;}
|
TDBDRV(PODEF tdp) : TDBCAT(tdp) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Specific routines
|
// Specific routines
|
||||||
virtual bool Initialize(PGLOBAL g);
|
virtual PQRYRES GetResult(PGLOBAL g);
|
||||||
|
|
||||||
}; // end of class TDBDRV
|
}; // end of class TDBDRV
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* This is the class declaration for the columns catalog table. */
|
|
||||||
/***********************************************************************/
|
|
||||||
class TDBOCL : public TDBOIF {
|
|
||||||
public:
|
|
||||||
// Constructor
|
|
||||||
TDBOCL(PODEF tdp);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Specific routines
|
|
||||||
virtual bool Initialize(PGLOBAL g);
|
|
||||||
|
|
||||||
// Members
|
|
||||||
char *Dsn; // Points to connection string
|
|
||||||
char *Tabn; // Points to ODBC table name
|
|
||||||
}; // end of class TDBOCL
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This is the class declaration for the tables catalog table. */
|
/* This is the class declaration for the tables catalog table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class TDBOTB : public TDBOIF {
|
class TDBOTB : public TDBCAT {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TDBOTB(PODEF tdp);
|
TDBOTB(PODEF tdp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Specific routines
|
// Specific routines
|
||||||
virtual bool Initialize(PGLOBAL g);
|
virtual PQRYRES GetResult(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
char *Dsn; // Points to connection string
|
char *Dsn; // Points to connection string
|
||||||
char *Tabpat; // Points to ODBC table pattern
|
char *Tab; // Points to ODBC table name or pattern
|
||||||
}; // end of class TDBOTB
|
}; // end of class TDBOTB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This is the class declaration for the columns catalog table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class TDBOCL : public TDBOTB {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
TDBOCL(PODEF tdp) : TDBOTB(tdp) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Specific routines
|
||||||
|
virtual PQRYRES GetResult(PGLOBAL g);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
}; // end of class TDBOCL
|
||||||
|
|
||||||
#endif // !NODBC
|
#endif // !NODBC
|
||||||
|
@@ -23,13 +23,6 @@
|
|||||||
|
|
||||||
extern "C" int trace;
|
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 --------------------- */
|
/* ------------------- Functions WMI Column info --------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -140,82 +133,90 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
|
|||||||
/* WMIColumns: constructs the result blocks containing the description */
|
/* WMIColumns: constructs the result blocks containing the description */
|
||||||
/* of all the columns of a WMI table of a specified class. */
|
/* 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,
|
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR,
|
||||||
DB_INT, DB_INT, DB_SHORT};
|
DB_INT, DB_INT, DB_SHORT};
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
||||||
TYPE_INT, TYPE_INT, TYPE_SHORT};
|
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};
|
static unsigned int len, length[] = {0, 6, 8, 10, 10, 6};
|
||||||
int i = 0, n = 0, ncol = sizeof(dbtype) / sizeof(int);
|
int i = 0, n = 0, ncol = sizeof(dbtype) / sizeof(int);
|
||||||
int lng, typ, prec;
|
int lng, typ, prec;
|
||||||
LONG low, upp;
|
LONG low, upp;
|
||||||
BOOL b1, b2 = TRUE;
|
|
||||||
BSTR propname;
|
BSTR propname;
|
||||||
VARIANT val;
|
VARIANT val;
|
||||||
CIMTYPE type;
|
CIMTYPE type;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
PWMIUT wp;
|
||||||
SAFEARRAY *prnlist = NULL;
|
SAFEARRAY *prnlist = NULL;
|
||||||
PQRYRES qrp = NULL;
|
PQRYRES qrp = NULL;
|
||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
|
|
||||||
/*********************************************************************/
|
if (!info) {
|
||||||
/* Initialize WMI if not done yet. */
|
/*******************************************************************/
|
||||||
/*********************************************************************/
|
/* Initialize WMI if not done yet. */
|
||||||
if ((b1 = !wp) && !(wp = InitWMI(g, nsp, classname)))
|
/*******************************************************************/
|
||||||
return NULL;
|
if (!(wp = InitWMI(g, nsp, cls)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/*********************************************************************/
|
/*******************************************************************/
|
||||||
/* Get the number of properties to return. */
|
/* Get the number of properties to return. */
|
||||||
/*********************************************************************/
|
/*******************************************************************/
|
||||||
res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL);
|
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
|
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
/* 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 GetNames res=%d\n", res);
|
|
||||||
goto err;
|
|
||||||
} // endif res
|
|
||||||
|
|
||||||
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)) {
|
if (FAILED(res)) {
|
||||||
sprintf(g->Message, "failed GetArrayElement res=%d\n", res);
|
sprintf(g->Message, "failed Get(__Property_Count) res=%d\n", res);
|
||||||
goto err;
|
goto err;
|
||||||
} // endif res
|
} // endif res
|
||||||
|
|
||||||
len = (unsigned)SysStringLen(propname);
|
if (!(n = val.lVal)) {
|
||||||
length[0] = max(length[0], len);
|
sprintf(g->Message, "Class %s in %s has no properties\n",
|
||||||
} // enfor i
|
cls, nsp);
|
||||||
|
goto err;
|
||||||
|
} // endif res
|
||||||
|
|
||||||
res = SafeArrayDestroy(prnlist);
|
/*******************************************************************/
|
||||||
|
/* 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 GetNames res=%d\n", res);
|
||||||
|
goto err;
|
||||||
|
} // endif res
|
||||||
|
|
||||||
|
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);
|
||||||
|
} else
|
||||||
|
length[0] = 128;
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Allocate the structures used to refer to the result set. */
|
/* Allocate the structures used to refer to the result set. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
|
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. */
|
/* Now get the results into blocks. */
|
||||||
@@ -309,16 +310,13 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp)
|
|||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
qrp->Nblin = i;
|
qrp->Nblin = i;
|
||||||
b2 = b1;
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (b2) {
|
// Cleanup
|
||||||
// Cleanup
|
wp->Cobj->Release();
|
||||||
wp->Cobj->Release();
|
wp->Svc->Release();
|
||||||
wp->Svc->Release();
|
wp->Svc = NULL; // MUST be set to NULL (why?)
|
||||||
wp->Svc = NULL; // MUST be set to NULL (why?)
|
CoUninitialize();
|
||||||
CoUninitialize();
|
|
||||||
} // endif b
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Return the result pointer for use by GetData routines. */
|
/* 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);
|
Wclass = strcat(strcpy(p, "Win32_"), Wclass);
|
||||||
} // endif Wclass
|
} // endif Wclass
|
||||||
|
|
||||||
if (!(Info = Cat->GetBoolCatInfo(Name, "Info", false)))
|
if (!Catfunc)
|
||||||
Ems = Cat->GetIntCatInfo(Name, "Estimate", 100);
|
Ems = Cat->GetIntCatInfo(Name, "Estimate", 100);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -357,17 +355,19 @@ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PTDB WMIDEF::GetTable(PGLOBAL g, MODE m)
|
PTDB WMIDEF::GetTable(PGLOBAL g, MODE m)
|
||||||
{
|
{
|
||||||
if (Info)
|
if (!Catfunc)
|
||||||
return new(g) TDBWCL(this);
|
|
||||||
else
|
|
||||||
return new(g) TDBWMI(this);
|
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
|
} // end of GetTable
|
||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Implementation of the TDBWMI class. */
|
/* Implementation of the TDBWMI class. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
TDBWMI::TDBWMI(PWMIDEF tdp) : TDBASE(tdp)
|
TDBWMI::TDBWMI(PWMIDEF tdp) : TDBASE(tdp)
|
||||||
{
|
{
|
||||||
@@ -826,320 +826,20 @@ void WMICOL::ReadColumn(PGLOBAL g)
|
|||||||
/* ---------------------------TDBWCL class --------------------------- */
|
/* ---------------------------TDBWCL class --------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Implementation of the TDBWCL class. */
|
/* TDBWCL class constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
TDBWCL::TDBWCL(PWMIDEF tdp) : TDBASE(tdp)
|
TDBWCL::TDBWCL(PWMIDEF tdp) : TDBCAT(tdp)
|
||||||
{
|
{
|
||||||
Svc = NULL;
|
Nsp = tdp->Nspace;
|
||||||
ClsObj = NULL;
|
Cls = tdp->Wclass;
|
||||||
Propname = NULL;
|
|
||||||
Nspace = tdp->Nspace;
|
|
||||||
Wclass = tdp->Wclass;
|
|
||||||
Init = false;
|
|
||||||
Done = false;
|
|
||||||
Res = 0;
|
|
||||||
N = -1;
|
|
||||||
Lng = 0;
|
|
||||||
Typ = 0;
|
|
||||||
Prec = 0;
|
|
||||||
} // end of TDBWCL constructor
|
} // end of TDBWCL constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate WCL column description block. */
|
/* GetResult: Get the list of the WMI class properties. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PCOL TDBWCL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
PQRYRES TDBWCL::GetResult(PGLOBAL g)
|
||||||
{
|
{
|
||||||
PWCLCOL colp;
|
return WMIColumns(g, Nsp, Cls, false);
|
||||||
|
} // end of GetResult
|
||||||
|
|
||||||
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. */
|
|
||||||
/***********************************************************************/
|
|
||||||
bool TDBWCL::Initialize(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
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
@@ -27,7 +27,7 @@ typedef struct _WMIutil {
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Functions used externally. */
|
/* 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 ---------------------------- */
|
/* -------------------------- WMI classes ---------------------------- */
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *classname, PWMIUT wp);
|
|||||||
class WMIDEF : public TABDEF { /* Logical table description */
|
class WMIDEF : public TABDEF { /* Logical table description */
|
||||||
friend class TDBWMI;
|
friend class TDBWMI;
|
||||||
friend class TDBWCL;
|
friend class TDBWCL;
|
||||||
|
friend class TDBWCX;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
WMIDEF(void)
|
WMIDEF(void) {Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0;}
|
||||||
{Pseudo = 3; Nspace = NULL; Wclass = NULL; Ems = 0; Info = false;}
|
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual const char *GetType(void) {return "WMI";}
|
virtual const char *GetType(void) {return "WMI";}
|
||||||
@@ -55,7 +55,6 @@ class WMIDEF : public TABDEF { /* Logical table description */
|
|||||||
char *Nspace;
|
char *Nspace;
|
||||||
char *Wclass;
|
char *Wclass;
|
||||||
int Ems;
|
int Ems;
|
||||||
bool Info;
|
|
||||||
}; // end of WMIDEF
|
}; // end of WMIDEF
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -99,13 +98,13 @@ class TDBWMI : public TDBASE {
|
|||||||
char *Wclass; // Class name
|
char *Wclass; // Class name
|
||||||
char *ObjPath; // Used for direct access
|
char *ObjPath; // Used for direct access
|
||||||
char *Kvp; // Itou
|
char *Kvp; // Itou
|
||||||
int Ems; // Estimated max size
|
int Ems; // Estimated max size
|
||||||
PCOL Kcol; // Key column
|
PCOL Kcol; // Key column
|
||||||
HRESULT Res;
|
HRESULT Res;
|
||||||
PVBLK Vbp;
|
PVBLK Vbp;
|
||||||
bool Init;
|
bool Init;
|
||||||
bool Done;
|
bool Done;
|
||||||
ULONG Rc;
|
ULONG Rc;
|
||||||
int N; // Row number
|
int N; // Row number
|
||||||
}; // end of class TDBWMI
|
}; // end of class TDBWMI
|
||||||
|
|
||||||
@@ -129,76 +128,24 @@ class WMICOL : public COLBLK {
|
|||||||
|
|
||||||
// Members
|
// Members
|
||||||
PTDBWMI Tdbp; // Points to WMI table block
|
PTDBWMI Tdbp; // Points to WMI table block
|
||||||
VARIANT Prop; // Property value
|
VARIANT Prop; // Property value
|
||||||
CIMTYPE Ctype; // CIM Type
|
CIMTYPE Ctype; // CIM Type
|
||||||
HRESULT Res;
|
HRESULT Res;
|
||||||
}; // end of class WMICOL
|
}; // 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 {
|
class TDBWCL : public TDBCAT {
|
||||||
friend class WCLCOL;
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TDBWCL(PWMIDEF tdp);
|
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:
|
protected:
|
||||||
// Specific routines
|
// Specific routines
|
||||||
bool Initialize(PGLOBAL g);
|
virtual PQRYRES GetResult(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
IWbemServices *Svc; // IWbemServices pointer
|
char *Nsp; // Name space
|
||||||
IWbemClassObject *ClsObj;
|
char *Cls; // Class
|
||||||
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;
|
|
||||||
}; // end of class TDBWCL
|
}; // 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
|
|
||||||
|
@@ -15,9 +15,12 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
#include "colblk.h"
|
||||||
|
|
||||||
//pedef class INDEXDEF *PIXDEF;
|
//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) */
|
/* 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 bool IsReadOnly(void) {return Read_Only;}
|
||||||
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
|
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
|
||||||
virtual int GetProgCur(void) {return GetRecpos();}
|
virtual int GetProgCur(void) {return GetRecpos();}
|
||||||
virtual PSZ GetFile(PGLOBAL g) {return "Not a file";}
|
virtual PSZ GetFile(PGLOBAL g) {return "Not a file";}
|
||||||
virtual int GetRemote(void) {return 0;}
|
virtual int GetRemote(void) {return 0;}
|
||||||
virtual void SetFile(PGLOBAL g, PSZ fn) {}
|
virtual void SetFile(PGLOBAL g, PSZ fn) {}
|
||||||
virtual void ResetDB(void) {}
|
virtual void ResetDB(void) {}
|
||||||
virtual void ResetSize(void) {MaxSize = -1;}
|
virtual void ResetSize(void) {MaxSize = -1;}
|
||||||
@@ -198,4 +201,66 @@ class DllExport TDBASE : public TDB {
|
|||||||
bool Read_Only; // True for read only tables
|
bool Read_Only; // True for read only tables
|
||||||
}; // end of class TDBASE
|
}; // 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
|
#endif // TABLE_DEFINED
|
||||||
|
Reference in New Issue
Block a user