mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Commit merged file (on Linux)
modified: storage/connect/ha_connect.cc storage/connect/myconn.cpp storage/connect/odbccat.h storage/connect/odbconn.cpp storage/connect/odbconn.h storage/connect/tabmul.cpp storage/connect/tabmysql.cpp storage/connect/tabodbc.cpp storage/connect/tabodbc.h - Fix typo error in TDBDIR::CloseDB modified: storage/connect/tabmul.cpp - Fix format in TDBXDBC::MakeCMD (was not accepted on Linux) modified: storage/connect/tabodbc.cpp
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/************* Tabodbc C++ Program Source Code File (.CPP) *************/
|
||||
/* PROGRAM NAME: TABODBC */
|
||||
/* ------------- */
|
||||
/* Version 2.5 */
|
||||
/* Version 2.6 */
|
||||
/* */
|
||||
/* COPYRIGHT: */
|
||||
/* ---------- */
|
||||
@@ -90,8 +90,9 @@ extern int num_read, num_there, num_eq[2]; // Statistics
|
||||
/***********************************************************************/
|
||||
ODBCDEF::ODBCDEF(void)
|
||||
{
|
||||
Connect = Tabname = Tabowner = Tabqual = Qchar = NULL;
|
||||
Catver = Options = 0;
|
||||
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = NULL;
|
||||
Catver = Options = 0;
|
||||
Xsrc = false;
|
||||
} // end of ODBCDEF constructor
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -107,9 +108,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
||||
Tabowner = Cat->GetStringCatInfo(g, "Owner", "");
|
||||
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", "");
|
||||
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||
Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
|
||||
Catver = Cat->GetIntCatInfo("Catver", 2);
|
||||
Options = Cat->GetIntCatInfo("Options", dop);
|
||||
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
||||
Pseudo = 2; // FILID is Ok but not ROWID
|
||||
return false;
|
||||
} // end of DefineAM
|
||||
@@ -125,7 +128,9 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
|
||||
/* Allocate a TDB of the proper type. */
|
||||
/* Column blocks will be allocated only when needed. */
|
||||
/*********************************************************************/
|
||||
switch (Catfunc) {
|
||||
if (Xsrc)
|
||||
tdbp = new(g) TDBXDBC(this);
|
||||
else switch (Catfunc) {
|
||||
case FNC_COL:
|
||||
tdbp = new(g) TDBOCL(this);
|
||||
break;
|
||||
@@ -161,19 +166,21 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
||||
Cnp = NULL;
|
||||
|
||||
if (tdp) {
|
||||
Connect = tdp->GetConnect();
|
||||
TableName = tdp->GetTabname();
|
||||
Owner = tdp->GetTabowner();
|
||||
Qualifier = tdp->GetTabqual();
|
||||
Connect = tdp->Connect;
|
||||
TableName = tdp->Tabname;
|
||||
Owner = tdp->Tabowner;
|
||||
Qualifier = tdp->Tabqual;
|
||||
Srcdef = tdp->Srcdef;
|
||||
Quote = tdp->GetQchar();
|
||||
Options = tdp->GetOptions();
|
||||
Options = tdp->Options;
|
||||
Rows = tdp->GetElemt();
|
||||
Catver = tdp->GetCatver();
|
||||
Catver = tdp->Catver;
|
||||
} else {
|
||||
Connect = NULL;
|
||||
TableName = NULL;
|
||||
Owner = NULL;
|
||||
Qualifier = NULL;
|
||||
Srcdef = NULL;
|
||||
Quote = NULL;
|
||||
Options = 0;
|
||||
Rows = 0;
|
||||
@@ -201,6 +208,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
|
||||
TableName = tdbp->TableName;
|
||||
Owner = tdbp->Owner;
|
||||
Qualifier = tdbp->Qualifier;
|
||||
Srcdef = tdbp->Srcdef;
|
||||
Quote = tdbp->Quote;
|
||||
Query = tdbp->Query;
|
||||
Count = tdbp->Count;
|
||||
@@ -299,7 +307,6 @@ void TDBODBC::SetFile(PGLOBAL g, PSZ fn)
|
||||
DBQ = fn;
|
||||
} // end of SetFile
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* Convert an UTF-8 string to latin characters. */
|
||||
/******************************************************************/
|
||||
@@ -314,7 +321,6 @@ int TDBODBC::Decode(char *txt, char *buf, size_t n)
|
||||
return 0;
|
||||
} // end of Decode
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* MakeSQL: make the SQL statement use with ODBC connection. */
|
||||
/* Note: when implementing EOM filtering, column only used in local */
|
||||
@@ -329,6 +335,9 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
||||
PTABLE tablep = To_Table;
|
||||
PCOL colp;
|
||||
|
||||
if (Srcdef)
|
||||
return Srcdef;
|
||||
|
||||
if (!cnt) {
|
||||
// Normal SQL statement to retrieve results
|
||||
for (colp = Columns; colp; colp = colp->GetNext())
|
||||
@@ -430,6 +439,83 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
||||
return sql;
|
||||
} // end of MakeSQL
|
||||
|
||||
/***********************************************************************/
|
||||
/* MakeInsert: make the Insert statement used with ODBC connection. */
|
||||
/***********************************************************************/
|
||||
bool TDBODBC::MakeInsert(PGLOBAL g)
|
||||
{
|
||||
char *colist, *valist;
|
||||
// char *tk = "`";
|
||||
int len = 0;
|
||||
bool b = FALSE;
|
||||
PCOL colp;
|
||||
|
||||
if (Query)
|
||||
return false; // already done
|
||||
|
||||
for (colp = Columns; colp; colp = colp->GetNext())
|
||||
if (colp->IsSpecial()) {
|
||||
strcpy(g->Message, MSG(NO_ODBC_SPECOL));
|
||||
return true;
|
||||
} else {
|
||||
len += (strlen(colp->GetName()) + 4);
|
||||
((PODBCCOL)colp)->Rank = ++Nparm;
|
||||
} // endif colp
|
||||
|
||||
colist = (char*)PlugSubAlloc(g, NULL, len);
|
||||
*colist = '\0';
|
||||
valist = (char*)PlugSubAlloc(g, NULL, 2 * Nparm);
|
||||
*valist = '\0';
|
||||
|
||||
for (colp = Columns; colp; colp = colp->GetNext()) {
|
||||
if (b) {
|
||||
strcat(colist, ", ");
|
||||
strcat(valist, ",");
|
||||
} else
|
||||
b = true;
|
||||
|
||||
if (Quote)
|
||||
strcat(strcat(strcat(colist, Quote), colp->GetName()), Quote);
|
||||
else
|
||||
strcat(colist, colp->GetName());
|
||||
|
||||
strcat(valist, "?"); // Parameter marker
|
||||
} // endfor colp
|
||||
|
||||
// Below 32 is enough to contain the fixed part of the query
|
||||
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
|
||||
Query = (char*)PlugSubAlloc(g, NULL, len);
|
||||
strcpy(Query, "INSERT INTO ");
|
||||
|
||||
if (Quote)
|
||||
strcat(strcat(strcat(Query, Quote), TableName), Quote);
|
||||
else
|
||||
strcat(Query, TableName);
|
||||
|
||||
strcat(strcat(strcat(Query, " ("), colist), ") VALUES (");
|
||||
strcat(strcat(Query, valist), ")");
|
||||
|
||||
return false;
|
||||
} // end of MakeInsert
|
||||
|
||||
/***********************************************************************/
|
||||
/* ODBC Bind Parameter function. */
|
||||
/***********************************************************************/
|
||||
bool TDBODBC::BindParameters(PGLOBAL g)
|
||||
{
|
||||
PODBCCOL colp;
|
||||
|
||||
for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
|
||||
colp->AllocateBuffers(g, 0);
|
||||
|
||||
if (Ocp->BindParam(colp))
|
||||
return true;
|
||||
|
||||
} // endfor colp
|
||||
|
||||
return false;
|
||||
} // end of BindParameters
|
||||
|
||||
/***********************************************************************/
|
||||
/* ResetSize: call by TDBMUL when calculating size estimate. */
|
||||
/***********************************************************************/
|
||||
@@ -448,6 +534,12 @@ void TDBODBC::ResetSize(void)
|
||||
int TDBODBC::GetMaxSize(PGLOBAL g)
|
||||
{
|
||||
if (MaxSize < 0) {
|
||||
if (Srcdef) {
|
||||
// Give a reasonable guess
|
||||
MaxSize = 100;
|
||||
return MaxSize;
|
||||
} // endif Srcdef
|
||||
|
||||
if (!Ocp)
|
||||
Ocp = new(g) ODBConn(g, this);
|
||||
|
||||
@@ -473,12 +565,11 @@ int TDBODBC::GetMaxSize(PGLOBAL g)
|
||||
} // end of GetMaxSize
|
||||
|
||||
/***********************************************************************/
|
||||
/* Return 0 in mode DELETE or UPDATE to tell that it is done. */
|
||||
/* Return max size value. */
|
||||
/***********************************************************************/
|
||||
int TDBODBC::GetProgMax(PGLOBAL g)
|
||||
{
|
||||
return (Mode == MODE_DELETE || Mode == MODE_UPDATE) ? 0
|
||||
: GetMaxSize(g);
|
||||
return GetMaxSize(g);
|
||||
} // end of GetProgMax
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -546,14 +637,24 @@ bool TDBODBC::OpenDB(PGLOBAL g)
|
||||
if (!colp->IsSpecial())
|
||||
colp->AllocateBuffers(g, Rows);
|
||||
|
||||
} else
|
||||
rc = true;
|
||||
} else {
|
||||
Ocp->Close();
|
||||
return true;
|
||||
} // endif Query
|
||||
|
||||
if (!rc)
|
||||
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
|
||||
|
||||
} else if (Mode == MODE_INSERT) {
|
||||
if (!(rc = MakeInsert(g)))
|
||||
if (Nparm != Ocp->PrepareSQL(Query)) {
|
||||
strcpy(g->Message, MSG(PARM_CNT_MISS));
|
||||
rc = true;
|
||||
} else
|
||||
rc = BindParameters(g);
|
||||
|
||||
} else {
|
||||
strcpy(g->Message, "ODBC tables are read only in this version");
|
||||
strcpy(g->Message, "No DELETE/UPDATE of ODBC tablesd");
|
||||
return true;
|
||||
} // endelse
|
||||
|
||||
@@ -592,30 +693,6 @@ int TDBODBC::ReadDB(PGLOBAL g)
|
||||
// Direct access of ODBC tables is not implemented yet
|
||||
strcpy(g->Message, MSG(NO_ODBC_DIRECT));
|
||||
longjmp(g->jumper[g->jump_level], GetAmType());
|
||||
|
||||
#if 0
|
||||
/*******************************************************************/
|
||||
/* Reading is by an index table. */
|
||||
/*******************************************************************/
|
||||
int recpos = To_Kindex->Fetch(g);
|
||||
|
||||
switch (recpos) {
|
||||
case -1: // End of file reached
|
||||
return RC_EF;
|
||||
case -2: // No match for join
|
||||
return RC_NF;
|
||||
case -3: // Same record as current one
|
||||
num_there++;
|
||||
return RC_OK;
|
||||
default:
|
||||
/***************************************************************/
|
||||
/* Set the cursor position according to record to read. */
|
||||
/***************************************************************/
|
||||
//--------------------------------- TODO --------------------------------
|
||||
break;
|
||||
} // endswitch recpos
|
||||
#endif // 0
|
||||
|
||||
} // endif To_Kindex
|
||||
|
||||
/*********************************************************************/
|
||||
@@ -641,8 +718,15 @@ int TDBODBC::ReadDB(PGLOBAL g)
|
||||
/***********************************************************************/
|
||||
int TDBODBC::WriteDB(PGLOBAL g)
|
||||
{
|
||||
strcpy(g->Message, "ODBC tables are read only");
|
||||
return RC_FX;
|
||||
int n = Ocp->ExecuteSQL(false);
|
||||
|
||||
if (n < 0) {
|
||||
AftRows = n;
|
||||
return RC_FX;
|
||||
} else
|
||||
AftRows += n;
|
||||
|
||||
return RC_OK;
|
||||
} // end of WriteDB
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -664,7 +748,8 @@ void TDBODBC::CloseDB(PGLOBAL g)
|
||||
// To_Kindex = NULL;
|
||||
// } // endif
|
||||
|
||||
Ocp->Close();
|
||||
if (Ocp)
|
||||
Ocp->Close();
|
||||
|
||||
if (trace)
|
||||
htrc("ODBC CloseDB: closing %s\n", Name);
|
||||
@@ -892,7 +977,7 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
|
||||
/* Do convert the column value if necessary. */
|
||||
/*********************************************************************/
|
||||
if (Value != To_Val)
|
||||
Value->SetValue_pval(To_Val, false); // Convert the inserted value
|
||||
Value->SetValue_pval(To_Val, FALSE); // Convert the inserted value
|
||||
|
||||
if (Buf_Type == TYPE_DATE) {
|
||||
struct tm tm, *dbtime = ((DTVAL*)Value)->GetGmTime(&tm);
|
||||
@@ -903,8 +988,245 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
|
||||
Sqlbuf->day = dbtime->tm_mday;
|
||||
Sqlbuf->month = dbtime->tm_mon + 1;
|
||||
Sqlbuf->year = dbtime->tm_year + 1900;
|
||||
Sqlbuf->fraction = 0;
|
||||
} // endif Buf_Type
|
||||
|
||||
if (Nullable)
|
||||
*StrLen = (Value->IsNull()) ? SQL_NULL_DATA :
|
||||
(IsTypeNum(Buf_Type)) ? 0 : SQL_NTS;
|
||||
|
||||
} // end of WriteColumn
|
||||
|
||||
/* -------------------------- Class TDBXDBC -------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Implementation of the TDBODBC class. */
|
||||
/***********************************************************************/
|
||||
PTDB TDBXDBC::CopyOne(PTABS t)
|
||||
{
|
||||
PTDB tp;
|
||||
PXSRCCOL cp1, cp2;
|
||||
PGLOBAL g = t->G; // Is this really useful ???
|
||||
|
||||
tp = new(g) TDBXDBC(this);
|
||||
|
||||
for (cp1 = (PXSRCCOL)Columns; cp1; cp1 = (PXSRCCOL)cp1->GetNext()) {
|
||||
cp2 = new(g) XSRCCOL(cp1, tp); // Make a copy
|
||||
NewPointer(t, cp1, cp2);
|
||||
} // endfor cp1
|
||||
|
||||
return tp;
|
||||
} // end of CopyOne
|
||||
|
||||
/***********************************************************************/
|
||||
/* Allocate XSRC column description block. */
|
||||
/***********************************************************************/
|
||||
PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
||||
{
|
||||
PXSRCCOL colp = new(g) XSRCCOL(cdp, this, cprec, n);
|
||||
|
||||
if (!colp->Flag)
|
||||
Cmdcol = colp->GetName();
|
||||
|
||||
return colp;
|
||||
} // end of MakeCol
|
||||
|
||||
/***********************************************************************/
|
||||
/* MakeCMD: make the SQL statement to send to ODBC connection. */
|
||||
/***********************************************************************/
|
||||
char *TDBXDBC::MakeCMD(PGLOBAL g)
|
||||
{
|
||||
char *xcmd = NULL;
|
||||
|
||||
if (To_Filter) {
|
||||
if (Cmdcol) {
|
||||
char col[128], cmd[1024];
|
||||
int n;
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
n = sscanf(To_Filter, "%s = '%1023c", col, cmd);
|
||||
|
||||
if (n == 2 && !stricmp(col, Cmdcol)) {
|
||||
xcmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
|
||||
|
||||
strcpy(xcmd, cmd);
|
||||
xcmd[strlen(xcmd) - 1] = 0;
|
||||
} else
|
||||
strcpy(g->Message, "Invalid command specification filter");
|
||||
|
||||
} else
|
||||
strcpy(g->Message, "No command column in select list");
|
||||
|
||||
} else if (!Srcdef)
|
||||
strcpy(g->Message, "No Srcdef default command");
|
||||
else
|
||||
xcmd = Srcdef;
|
||||
|
||||
return xcmd;
|
||||
} // end of MakeCMD
|
||||
|
||||
#if 0
|
||||
/***********************************************************************/
|
||||
/* ODBC Bind Parameter function. */
|
||||
/***********************************************************************/
|
||||
bool TDBXDBC::BindParameters(PGLOBAL g)
|
||||
{
|
||||
PODBCCOL colp;
|
||||
|
||||
for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
|
||||
colp->AllocateBuffers(g, 0);
|
||||
|
||||
if (Ocp->BindParam(colp))
|
||||
return true;
|
||||
|
||||
} // endfor colp
|
||||
|
||||
return false;
|
||||
} // end of BindParameters
|
||||
#endif // 0
|
||||
|
||||
/***********************************************************************/
|
||||
/* XDBC GetMaxSize: returns table size (always one row). */
|
||||
/***********************************************************************/
|
||||
int TDBXDBC::GetMaxSize(PGLOBAL g)
|
||||
{
|
||||
if (MaxSize < 0)
|
||||
MaxSize = 1;
|
||||
|
||||
return MaxSize;
|
||||
} // end of GetMaxSize
|
||||
|
||||
/***********************************************************************/
|
||||
/* ODBC Access Method opening routine. */
|
||||
/* New method now that this routine is called recursively (last table */
|
||||
/* first in reverse order): index blocks are immediately linked to */
|
||||
/* join block of next table if it exists or else are discarted. */
|
||||
/***********************************************************************/
|
||||
bool TDBXDBC::OpenDB(PGLOBAL g)
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
if (g->Trace)
|
||||
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
|
||||
this, Tdb_No, Use, Mode);
|
||||
|
||||
if (Use == USE_OPEN) {
|
||||
strcpy(g->Message, "Multiple execution is not allowed");
|
||||
return true;
|
||||
} // endif use
|
||||
|
||||
/*********************************************************************/
|
||||
/* Open an ODBC connection for this table. */
|
||||
/* Note: this may not be the proper way to do. Perhaps it is better */
|
||||
/* to test whether a connection is already open for this datasource */
|
||||
/* and if so to allocate just a new result set. But this only for */
|
||||
/* drivers allowing concurency in getting results ??? */
|
||||
/*********************************************************************/
|
||||
if (!Ocp)
|
||||
Ocp = new(g) ODBConn(g, this);
|
||||
else if (Ocp->IsOpen())
|
||||
Ocp->Close();
|
||||
|
||||
if (Ocp->Open(Connect, Options) < 1)
|
||||
return true;
|
||||
|
||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||
|
||||
if (Mode != MODE_READ) {
|
||||
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
|
||||
return true;
|
||||
} // endif Mode
|
||||
|
||||
/*********************************************************************/
|
||||
/* Get the command to execute. */
|
||||
/*********************************************************************/
|
||||
if (!(Query = MakeCMD(g))) {
|
||||
Ocp->Close();
|
||||
return true;
|
||||
} // endif Query
|
||||
|
||||
Rows = 1;
|
||||
|
||||
if (Ocp->PrepareSQL(Query)) {
|
||||
strcpy(g->Message, "Parameters not supported");
|
||||
AftRows = -1;
|
||||
} else
|
||||
AftRows = 0;
|
||||
|
||||
return false;
|
||||
} // end of OpenDB
|
||||
|
||||
/***********************************************************************/
|
||||
/* ReadDB: Data Base read routine for xdbc access method. */
|
||||
/***********************************************************************/
|
||||
int TDBXDBC::ReadDB(PGLOBAL g)
|
||||
{
|
||||
if (trace)
|
||||
htrc("XDBC ReadDB: query=%s\n", SVP(Query));
|
||||
|
||||
if (Rows--) {
|
||||
if (!AftRows)
|
||||
AftRows = Ocp->ExecuteSQL(true);
|
||||
|
||||
} else
|
||||
return RC_EF;
|
||||
|
||||
Fpos++; // Used for progress info
|
||||
return RC_OK;
|
||||
} // end of ReadDB
|
||||
|
||||
/***********************************************************************/
|
||||
/* Data Base delete line routine for ODBC access method. */
|
||||
/***********************************************************************/
|
||||
int TDBXDBC::WriteDB(PGLOBAL g)
|
||||
{
|
||||
strcpy(g->Message, "Execsrc tables are read only");
|
||||
return RC_FX;
|
||||
} // end of DeleteDB
|
||||
|
||||
/* --------------------------- XSRCCOL ------------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* XSRCCOL public constructor. */
|
||||
/***********************************************************************/
|
||||
XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
||||
: ODBCCOL(cdp, tdbp, cprec, i, am)
|
||||
{
|
||||
// Set additional ODBC access method information for column.
|
||||
Flag = cdp->GetOffset();
|
||||
} // end of XSRCCOL constructor
|
||||
|
||||
/***********************************************************************/
|
||||
/* XSRCCOL constructor used for copying columns. */
|
||||
/* tdbp is the pointer to the new table descriptor. */
|
||||
/***********************************************************************/
|
||||
XSRCCOL::XSRCCOL(XSRCCOL *col1, PTDB tdbp) : ODBCCOL(col1, tdbp)
|
||||
{
|
||||
Flag = col1->Flag;
|
||||
} // end of XSRCCOL copy constructor
|
||||
|
||||
/***********************************************************************/
|
||||
/* ReadColumn: set column value according to Flag. */
|
||||
/***********************************************************************/
|
||||
void XSRCCOL::ReadColumn(PGLOBAL g)
|
||||
{
|
||||
PTDBXDBC tdbp = (PTDBXDBC)To_Tdb;
|
||||
|
||||
switch (Flag) {
|
||||
case 0: Value->SetValue_psz(tdbp->Query); break;
|
||||
case 1: Value->SetValue(tdbp->AftRows); break;
|
||||
case 2: Value->SetValue_psz(g->Message); break;
|
||||
default: Value->SetValue_psz("Invalid Flag"); break;
|
||||
} // endswitch Flag
|
||||
|
||||
} // end of ReadColumn
|
||||
|
||||
/***********************************************************************/
|
||||
/* WriteColumn: Should never be called. */
|
||||
/***********************************************************************/
|
||||
void XSRCCOL::WriteColumn(PGLOBAL g)
|
||||
{
|
||||
// Should never be called
|
||||
} // end of WriteColumn
|
||||
|
||||
/* ---------------------------TDBSRC class --------------------------- */
|
||||
|
Reference in New Issue
Block a user