Commit 38edf74a authored by Olivier Bertrand's avatar Olivier Bertrand

1) Fix bug on strange sprintf

2) Fix bug on bad sprintf
3) Fix bug on cast from pointer to int

4) Begin implementing the "info" tables.
Already existing were the ODBC sata source table and the
WMI column info table.

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

The ODBC column info table.

Modified:
ha_connect.cc  (4)
odbconn.cpp    (4)
tabodbc.h      (4)
tabodbc.cpp    (4)
tabsys.h       (3)
rcmsg.c        (4)
tabfmt.cpp     (2)
tabtbl.cpp     (1)
resource.h     (4)
mycat.h        (4)
parent 60c4cab3
......@@ -157,9 +157,10 @@ void XmlCleanupParserLib(void);
PQRYRES DBFColumns(PGLOBAL g, char *fn, BOOL info);
PQRYRES CSVColumns(PGLOBAL g, char *fn, char sep, char q, int hdr, int mxr);
#if defined(ODBC_SUPPORT)
PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn);
PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn, bool info);
#endif // ODBC_SUPPORT
#if defined(MYSQL_SUPPORT)
PQRYRES ODBCDataSources(PGLOBAL g, bool info = true);
PQRYRES MyColumns(PGLOBAL g, char *host, char *db, char *user, char *pwd,
char *table, char *colpat, int port, bool key);
#endif // MYSQL_SUPPORT
......@@ -233,6 +234,7 @@ struct ha_table_option_struct {
const char *qchar;
const char *module;
const char *subtype;
const char *info;
const char *oplist;
int lrecl;
int elements;
......@@ -263,6 +265,7 @@ ha_create_table_option connect_table_option_list[]=
HA_TOPTION_STRING("QCHAR", qchar),
HA_TOPTION_STRING("MODULE", module),
HA_TOPTION_STRING("SUBTYPE", subtype),
HA_TOPTION_STRING("INFO", info),
HA_TOPTION_STRING("OPTION_LIST", oplist),
HA_TOPTION_NUMBER("LRECL", lrecl, 0, 0, INT_MAX32, 1),
HA_TOPTION_NUMBER("BLOCK_SIZE", elements, 0, 0, INT_MAX32, 1),
......@@ -808,6 +811,8 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
opval= (char*)options->module;
else if (!stricmp(opname, "Subtype"))
opval= (char*)options->subtype;
else if (!stricmp(opname, "Info"))
opval= (char*)options->info;
if (!opval && options->oplist)
opval= GetListOption(opname, options->oplist);
......@@ -3306,6 +3311,8 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
tab= pov->value.str;
} else if (!stricmp(pov->name.str, "db_name")) {
db= pov->value.str;
} else if (!stricmp(pov->name.str, "info")) {
inf= pov->value.str;
} else if (!stricmp(pov->name.str, "sep_char")) {
sep= pov->value.str;
spc= (!strcmp(sep, "\\t")) ? '\t' : *sep;
......@@ -3334,12 +3341,12 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
switch (ttp) {
#if defined(ODBC_SUPPORT)
case 'O': // ODBC
info= !!strchr("1yYoO", *inf);
info= inf && !!strchr("1yYoO", *inf);
if (!(dsn= create_info->connect_string.str) && !info)
sprintf(g->Message, "Missing %s connection string", typn);
else
ok= !info;
ok= true;
break;
#endif // ODBC_SUPPORT
......@@ -3386,7 +3393,11 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
break;
#if defined(ODBC_SUPPORT)
case 'O':
qrp= MyODBCCols(g, tab, dsn);
if (dsn)
qrp= MyODBCCols(g, tab, dsn, info);
else
qrp= ODBCDataSources(g);
break;
#endif // ODBC_SUPPORT
#if defined(MYSQL_SUPPORT)
......@@ -3409,50 +3420,56 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
return true;
} // endif qrp
for (i= 0; !b && i < qrp->Nblin; i++) {
crp= qrp->Colresp; // Column Name
cnm= encode(g, crp->Kdata->GetCharValue(i));
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
crp= crp->Next; // Data Type
type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true);
crp= crp->Next; // Type Name
crp= crp->Next; // Precision (length)
len= crp->Kdata->GetIntValue(i);
length= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(length, "%d", len);
crp= crp->Next; // Length
crp= crp->Next; // Scale (precision)
if ((dec= crp->Kdata->GetIntValue(i))) {
decimals= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(decimals, "%d", dec);
} else
if (info) {
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
cnm= encode(g, crp->Name);
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
type= PLGtoMYSQL(crp->Type, true);
len= crp->Length;
length= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(length, "%d", len);
decimals= NULL;
if ((crp= crp->Next) && // Remark (comment)
(rem= crp->Kdata->GetCharValue(i)))
comment= thd->make_lex_string(NULL, rem, strlen(rem), true);
else
comment= thd->make_lex_string(NULL, "", 0, true);
// Now add the field
// b= add_field_to_list(thd, &name, type, length, decimals,
// 0, NULL, NULL, comment, NULL, NULL, NULL, 0, NULL, NULL);
b= add_fields(thd, alt_info, name, type, length, decimals,
// Now add the field
b= add_fields(thd, alt_info, name, type, length, decimals,
0, comment, NULL, NULL, NULL);
} // endfor i
} // endfor crp
} else
for (i= 0; !b && i < qrp->Nblin; i++) {
crp= qrp->Colresp; // Column Name
cnm= encode(g, crp->Kdata->GetCharValue(i));
name= thd->make_lex_string(NULL, cnm, strlen(cnm), true);
crp= crp->Next; // Data Type
type= PLGtoMYSQL(crp->Kdata->GetIntValue(i), true);
crp= crp->Next; // Type Name
crp= crp->Next; // Precision (length)
len= crp->Kdata->GetIntValue(i);
length= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(length, "%d", len);
crp= crp->Next; // Length
crp= crp->Next; // Scale (precision)
if ((dec= crp->Kdata->GetIntValue(i))) {
decimals= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(decimals, "%d", dec);
} else
decimals= NULL;
if ((crp= crp->Next) && // Remark (comment)
(rem= crp->Kdata->GetCharValue(i)))
comment= thd->make_lex_string(NULL, rem, strlen(rem), true);
else
comment= thd->make_lex_string(NULL, "", 0, true);
// Now add the field
b= add_fields(thd, alt_info, name, type, length, decimals,
0, comment, NULL, NULL, NULL);
} // endfor i
return b;
} else if (info) { // ODBC Data Sources
comment= thd->make_lex_string(NULL, "", 0, true);
name= thd->make_lex_string(NULL, "Name", 4, true);
b= add_fields(thd, alt_info, name, MYSQL_TYPE_VARCHAR, "256", 0,
0, comment, NULL, NULL, NULL);
name= thd->make_lex_string(NULL, "Description", 11, true);
b= add_fields(thd, alt_info, name, MYSQL_TYPE_VARCHAR, "256", 0,
0, comment, NULL, NULL, NULL);
return b;
} // endif info
} // endif ok
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
return true;
......
......@@ -99,9 +99,9 @@ extern int xtrace;
/* General DB routines. */
/**************************************************************************/
//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, ...);
/**************************************************************************/
......@@ -149,9 +149,9 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
// 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)
//#elif defined(WIN32)
// Get header from ressource file
LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
#else // !WIN32
GetRcString(ids + crp->Ncol, cname, sizeof(cname));
#endif // !WIN32
......
......@@ -232,8 +232,8 @@ void ResetNullValues(CATPARM *cap)
/* of an ODBC table that will be retrieved by GetData commands. */
/* Note: The first two columns (Qualifier, Owner) are ignored. */
/***********************************************************************/
PQRYRES ODBCColumns(PGLOBAL g, ODBConn *op, char *dsn, char *table,
char *colpat)
PQRYRES ODBCColumns(PGLOBAL g, ODBConn *ocp, char *dsn, char *table,
char *colpat)
{
static int dbtype[] = {DB_CHAR, DB_CHAR,
DB_CHAR, DB_SHORT, DB_CHAR,
......@@ -248,30 +248,25 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *op, char *dsn, char *table,
int maxres;
PQRYRES qrp;
CATPARM *cap;
ODBConn *ocp = op;
if (!op) {
/**********************************************************************/
/* Open the connection with the ODBC data source. */
/**********************************************************************/
ocp = new(g) ODBConn(g, NULL);
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;
} // endif op
/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
maxres = (n) ? (int)n : 250;
n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
length[0] = (n) ? (n + 1) : 128;
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
length[1] = (n) ? (n + 1) : 128;
n = ocp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[2] = (n) ? (n + 1) : 128;
if (ocp) {
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
maxres = (n) ? (int)n : 250;
n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
length[0] = (n) ? (n + 1) : 128;
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
length[1] = (n) ? (n + 1) : 128;
n = ocp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[2] = (n) ? (n + 1) : 128;
} else { // Info table
maxres = 0;
length[0] = 128;
length[1] = 128;
length[2] = 128;
} // endif ocp
#ifdef DEBTRACE
htrc("ODBCColumns: max=%d len=%d,%d,%d\n",
......@@ -284,6 +279,9 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *op, char *dsn, char *table,
qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS + 1,
dbtype, buftyp, length);
if (!ocp) // Info table
return qrp;
#ifdef DEBTRACE
htrc("Getting col results ncol=%d\n", qrp->Nbcol);
#endif
......@@ -304,12 +302,6 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *op, char *dsn, char *table,
} else
qrp = NULL;
/************************************************************************/
/* Close any local connection. */
/************************************************************************/
if (!op)
ocp->Close();
/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
......@@ -319,31 +311,39 @@ PQRYRES ODBCColumns(PGLOBAL g, ODBConn *op, char *dsn, char *table,
/**************************************************************************/
/* MyODBCCols: returns column info as required by ha_connect::pre_create. */
/**************************************************************************/
PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn)
PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn, bool info)
{
int type, len, prec;
PCOLRES crpt, crpl, crpp;
PQRYRES qrp;
ODBConn *ocp = new(g) ODBConn(g, NULL);
ODBConn *ocp;
/**********************************************************************/
/* Open the connection with the ODBC data source. */
/**********************************************************************/
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;
if (!info) {
ocp = new(g) ODBConn(g, NULL);
if (ocp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;
} else
ocp = NULL;
/**********************************************************************/
/* Get the information about the ODBC table columns. */
/**********************************************************************/
if ((qrp = ODBCColumns(g, ocp, dsn, tab, NULL)))
if ((qrp = ODBCColumns(g, ocp, dsn, tab, NULL)) && ocp)
dsn = ocp->GetConnect(); // Complete connect string
else
return NULL;
/************************************************************************/
/* Close the local connection. */
/************************************************************************/
ocp->Close();
if (ocp)
ocp->Close();
if (!qrp)
return NULL; // Error in ODBCColumns
/************************************************************************/
/* Keep only the info used by ha_connect::pre_create. */
......@@ -378,23 +378,30 @@ PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn)
/*************************************************************************/
/* ODBCDataSources: constructs the result blocks containing all ODBC */
/* data sources available on the local host. */
/* Called with info=true to have result column names. */
/*************************************************************************/
PQRYRES ODBCDataSources(PGLOBAL g)
PQRYRES ODBCDataSources(PGLOBAL g, bool info)
{
static int dbtype[] = {DB_CHAR, DB_CHAR};
static int buftyp[] = {TYPE_STRING, TYPE_STRING};
static unsigned int length[] = {0, 256};
int n, ncol = 2;
int n = 0, ncol = 2;
int maxres;
PQRYRES qrp;
ODBConn *ocp = new(g) ODBConn(g, NULL);
ODBConn *ocp;
/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
maxres = 512; // This is completely arbitrary
n = ocp->GetMaxValue(SQL_MAX_DSN_LENGTH);
length[0] = (n) ? (n + 1) : 256;
if (!info) {
ocp = new(g) ODBConn(g, NULL);
n = ocp->GetMaxValue(SQL_MAX_DSN_LENGTH);
length[0] = (n) ? (n + 1) : 256;
maxres = 512; // Estimated max number of data sources
} else {
length[0] = 256;
maxres = 0;
} // endif info
#ifdef DEBTRACE
htrc("ODBCDataSources: max=%d len=%d\n", maxres, length[0]);
......@@ -403,14 +410,12 @@ PQRYRES ODBCDataSources(PGLOBAL g)
/************************************************************************/
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, 0, dbtype, buftyp, length);
qrp->Colresp->Name = "Name";
qrp->Colresp->Next->Name = "Description";
qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC, dbtype, buftyp, length);
/************************************************************************/
/* Now get the results into blocks. */
/************************************************************************/
if (ocp->GetDataSources(qrp))
if (!info && ocp->GetDataSources(qrp))
qrp = NULL;
/************************************************************************/
......
......@@ -15,11 +15,9 @@
#include <stdio.h>
#include "resource.h"
int GetRcString(int id, char *buf, int bufsize)
char *GetMsgid(int id)
{
char *p = NULL, msg[32];
//printf("In GetRcString id=%d\n", id);
char *p = NULL;
switch (id) {
case IDS_00: p = "%s"; break;
......@@ -111,6 +109,8 @@ int GetRcString(int id, char *buf, int bufsize)
case IDS_SPC_06: p = "Longueur"; break;
case IDS_SPC_07: p = "Echelle"; break;
case IDS_SPC_08: p = "Pseudo_Colonne"; break;
case IDS_DSC_01: p = "Nom"; break;
case IDS_DSC_02: p = "Description"; break;
#else // English
case IDS_01: p = "%s: error allocating communication buffer of %d bytes"; break;
case IDS_02: p = "%s: error allocating parser memory for %d columns"; break;
......@@ -199,11 +199,22 @@ int GetRcString(int id, char *buf, int bufsize)
case IDS_SPC_06: p = "Length"; break;
case IDS_SPC_07: p = "Scale"; break;
case IDS_SPC_08: p = "Pseudo_Column"; break;
case IDS_DSC_01: p = "Name"; break;
case IDS_DSC_02: p = "Description"; break;
#endif // English
default:
sprintf(msg, "ID=%d unknown", id);
p = msg;
} // endswitch(id)
return p;
} // end of GetMsgid
int GetRcString(int id, char *buf, int bufsize)
{
char *p = NULL, msg[32];
if (!(p = GetMsgid(id))) {
sprintf(msg, "ID=%d unknown", id);
p = msg;
} // endif p
return sprintf(buf, "%.*s", bufsize-1, p);
} // end of GetRcString
......@@ -118,11 +118,11 @@
#define IDS_PLG_07 1286
#define IDS_PLG_08 1287
#define IDS_PLG_09 1288
#define IDS_DSC 1295
#define IDS_DSRC 1295
#define IDS_DSC_01 1296
#define IDS_DSC_02 1297
#define IDS_DSC_03 1298
#define IDS_DSC_04 1299
//#define IDS_DSC_03 1298
//#define IDS_DSC_04 1299
// Next default values for new objects
//
......
......@@ -1365,7 +1365,8 @@ void CSVCOL::WriteColumn(PGLOBAL g)
htrc("new length(%p)=%d\n", p, strlen(p));
if ((signed)strlen(p) > flen) {
sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen);
sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen,
tdbp->RowNumber(g), tdbp->GetFile(g));
longjmp(g->jumper[g->jump_level], 34);
} // endif
......
/************* Tabodbc C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABODBC */
/* ------------- */
/* Version 2.4 */
/* Version 2.5 */
/* */
/* COPYRIGHT: */
/* ---------- */
......@@ -64,7 +64,6 @@
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
//#include "sqry.h"
#include "xtable.h"
#include "tabodbc.h"
#include "tabmul.h"
......@@ -74,7 +73,9 @@
#include "sql_string.h"
PQRYRES ODBCDataSources(PGLOBAL g);
extern "C" char *GetMsgid(int id);
PQRYRES ODBCDataSources(PGLOBAL g, bool info = false);
PQRYRES MyODBCCols(PGLOBAL g, char *tab, char *dsn, bool info);
/***********************************************************************/
/* DB static variables. */
......@@ -89,9 +90,8 @@ extern int num_read, num_there, num_eq[2]; // Statistics
/***********************************************************************/
ODBCDEF::ODBCDEF(void)
{
Connect = Tabname = Tabowner = Tabqual = Qchar = NULL;
Connect = Tabname = Tabowner = Tabqual = Qchar = Info = NULL;
Catver = Options = 0;
Info = false;
} // end of ODBCDEF constructor
/***********************************************************************/
......@@ -109,11 +109,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabowner = Cat->GetStringCatInfo(g, Name, "Owner", "");
Tabqual = Cat->GetStringCatInfo(g, Name, "Qualifier", "");
Qchar = Cat->GetStringCatInfo(g, Name, "Qchar", "");
Info = Cat->GetStringCatInfo(g, Name, "Info", NULL);
Catver = Cat->GetIntCatInfo(Name, "Catver", 2);
Options = Cat->GetIntCatInfo(Name, "Options", dop);
//Options = Cat->GetIntCatInfo(Name, "Options", 0);
Pseudo = 2; // FILID is Ok but not ROWID
Info = Cat->GetBoolCatInfo(Name, "Info", false);
return false;
} // end of DefineAM
......@@ -128,7 +128,7 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
/* Allocate a TDB of the proper type. */
/* Column blocks will be allocated only when needed. */
/*********************************************************************/
if (!Info) {
if (!Info || !strchr("1yYoO", *Info)) {
tdbp = new(g) TDBODBC(this);
if (Multiple == 1)
......@@ -136,8 +136,10 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
else if (Multiple == 2)
strcpy(g->Message, MSG(NO_ODBC_MUL));
} else
tdbp = new(g) TDBOIF(this);
} else if (*Connect)
tdbp = new(g) TDBOCL(this);
else
tdbp = new(g) TDBSRC(this);
return tdbp;
} // end of GetTable
......@@ -905,6 +907,8 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
TDBOIF::TDBOIF(PODEF tdp) : TDBASE(tdp)
{
Qrp = NULL;
ID = 0;
NC = 0;
Init = false;
N = -1;
} // end of TDBOIF constructor
......@@ -926,32 +930,13 @@ PCOL TDBOIF::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
Columns = colp;
} // endif cprec
if (!colp->Flag) {
if (!stricmp(colp->Name, "Name"))
colp->Flag = 1;
else if (!stricmp(colp->Name, "Description"))
colp->Flag = 2;
} // endif Flag
for (int i = 1; !colp->Flag && i <= NC; i++)
if (!stricmp(colp->Name, GetMsgid(ID + i)))
colp->Flag = i;
return colp;
} // end of MakeCol
/***********************************************************************/
/* Initialize: Get the list of ODBC data sources. */
/***********************************************************************/
bool TDBOIF::Initialize(PGLOBAL g)
{
if (Init)
return false;
if (!(Qrp = ODBCDataSources(g)))
return true;
Init = true;
return false;
} // end of Initialize
/***********************************************************************/
/* OIF: Get the number of properties. */
/***********************************************************************/
......@@ -1003,19 +988,22 @@ bool TDBOIF::OpenDB(PGLOBAL g)
bool TDBOIF::InitCol(PGLOBAL g)
{
POIFCOL colp;
PCOLRES crp;
for (colp = (POIFCOL)Columns; colp; colp = (POIFCOL)colp->GetNext())
switch (colp->Flag) {
case 1:
colp->Crp = Qrp->Colresp;
break;
case 2:
colp->Crp = Qrp->Colresp->Next;
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;
default:
strcpy(g->Message, "Invalid column name or flag");
return true;
} // endswitch Flag
} // 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
......@@ -1073,7 +1061,52 @@ OIFCOL::OIFCOL(PCOLDEF cdp, PTDB tdbp, int n)
void OIFCOL::ReadColumn(PGLOBAL g)
{
// Get the value of the Name or Description property
Value->SetValue_psz(Crp->Kdata->GetCharValue(Tdbp->N));
Value->SetValue_pvblk(Crp->Kdata, Tdbp->N);
} // end of ReadColumn
/* ---------------------------TDBSRC class --------------------------- */
/***********************************************************************/
/* Initialize: Get the list of ODBC data sources. */
/***********************************************************************/
bool TDBSRC::Initialize(PGLOBAL g)
{
if (Init)
return false;
if (!(Qrp = ODBCDataSources(g)))
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, Tabn, Dsn, false)))
return true;
Init = true;
return false;
} // end of Initialize
/* ------------------------ End of Tabodbc --------------------------- */
......@@ -6,12 +6,14 @@
/* This file contains the TDBODBC classes declares. */
/***********************************************************************/
#include "colblk.h"
#include "resource.h"
typedef class ODBCDEF *PODEF;
typedef class TDBODBC *PTDBODBC;
typedef class ODBCCOL *PODBCCOL;
typedef class TDBOIF *PTDBOIF;
typedef class OIFCOL *POIFCOL;
typedef class TDBSRC *PTDBSRC;
/***********************************************************************/
/* ODBC table. */
......@@ -42,9 +44,9 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Tabowner; /* External table owner */
PSZ Tabqual; /* External table qualifier */
PSZ Qchar; /* Identifier quoting character */
PSZ Info; /* Information value */
int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */
bool Info; /* true if getting data sources */
}; // end of ODBCDEF
#if !defined(NODBC)
......@@ -99,9 +101,9 @@ class TDBODBC : public TDBASE {
ODBConn *Ocp; // Points to an ODBC connection class
ODBCCOL *Cnp; // Points to count(*) column
char *Connect; // Points to connection string
char *TableName; // Points to EOM table name
char *Owner; // Points to EOM table Owner
char *Qualifier; // Points to EOM table Qualifier
char *TableName; // Points to ODBC table name
char *Owner; // Points to ODBC table Owner
char *Qualifier; // Points to ODBC table Qualifier
char *Query; // Points to SQL statement
char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause
......@@ -162,7 +164,7 @@ class ODBCCOL : public COLBLK {
}; // end of class ODBCCOL
/***********************************************************************/
/* This is the class declaration for the ODBC info table. */
/* This is the base class declaration for the ODBC info tables. */
/***********************************************************************/
class TDBOIF : public TDBASE {
friend class OIFCOL;
......@@ -189,11 +191,13 @@ class TDBOIF : public TDBASE {
protected:
// Specific routines
bool Initialize(PGLOBAL g);
virtual bool Initialize(PGLOBAL g) = 0;
bool InitCol(PGLOBAL g);
// Members
PQRYRES Qrp;
PQRYRES Qrp; // Result set
int ID; // Base of Column names
int NC; // Number of valid flags
int N; // Row number
bool Init;
}; // end of class TDBOIF
......@@ -221,5 +225,36 @@ class OIFCOL : public COLBLK {
PCOLRES Crp; // The column data array
int Flag;
}; // end of class OIFCOL
/***********************************************************************/
/* This is the class declaration for the Data Sources info table. */
/***********************************************************************/
class TDBSRC : public TDBOIF {
public:
// Constructor
TDBSRC(PODEF tdp) : TDBOIF(tdp) {ID = IDS_DSRC; NC = 2;}
protected:
// Specific routines
virtual bool Initialize(PGLOBAL g);
}; // end of class TDBSRC
/***********************************************************************/
/* This is the class declaration for the columns info 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
#endif // !NODBC
......@@ -61,7 +61,7 @@ class TDBINI : public TDBASE {
// Methods
virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void) {return (int)Section;}
virtual int GetRecpos(void) {return N;}
virtual int GetProgCur(void) {return N;}
virtual int GetAffectedRows(void) {return 0;}
virtual PSZ GetFile(PGLOBAL g) {return Ifile;}
......
......@@ -216,7 +216,7 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
/***********************************************************************/
PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
{
char *db, key[128];
char *db, key[256];
uint k, flags;
PTDB tdbp = NULL;
TABLE_LIST table_list;
......@@ -236,9 +236,11 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
table_list.init_one_table(db, strlen(db),
tblp->Name, strlen(tblp->Name),
NULL, TL_IGNORE);
k = sprintf(key, "%s\0%s\0", db, tblp->Name);
k = sprintf(key, "%s", db);
k += sprintf(key + ++k, "%s", tblp->Name);
key[++k] = 0;
if (!(s = alloc_table_share(&table_list, key, k))) {
if (!(s = alloc_table_share(&table_list, key, ++k))) {
strcpy(g->Message, "Error allocating share\n");
return NULL;
} // endif s
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment