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