mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
2809803ee2
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)
779 lines
26 KiB
C++
779 lines
26 KiB
C++
/************* TabTbl C++ Program Source Code File (.CPP) **************/
|
|
/* PROGRAM NAME: TABTBL */
|
|
/* ------------- */
|
|
/* Version 1.4 */
|
|
/* */
|
|
/* COPYRIGHT: */
|
|
/* ---------- */
|
|
/* (C) Copyright to PlugDB Software Development 2008-2013 */
|
|
/* Author: Olivier BERTRAND */
|
|
/* */
|
|
/* WHAT THIS PROGRAM DOES: */
|
|
/* ----------------------- */
|
|
/* This program are the TDBTBL class DB routines. */
|
|
/* */
|
|
/* WHAT YOU NEED TO COMPILE THIS PROGRAM: */
|
|
/* -------------------------------------- */
|
|
/* */
|
|
/* REQUIRED FILES: */
|
|
/* --------------- */
|
|
/* TABTBL.CPP - Source code */
|
|
/* PLGDBSEM.H - DB application declaration file */
|
|
/* TABDOS.H - TABDOS classes declaration file */
|
|
/* TABTBL.H - TABTBL classes declaration file */
|
|
/* GLOBAL.H - Global declaration file */
|
|
/* */
|
|
/* REQUIRED LIBRARIES: */
|
|
/* ------------------- */
|
|
/* Large model C library */
|
|
/* */
|
|
/* REQUIRED PROGRAMS: */
|
|
/* ------------------ */
|
|
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
|
|
/* */
|
|
/***********************************************************************/
|
|
|
|
/***********************************************************************/
|
|
/* Include relevant section of system dependant header files. */
|
|
/***********************************************************************/
|
|
//#include "sql_base.h"
|
|
#include "my_global.h"
|
|
#if defined(WIN32)
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#if defined(__BORLANDC__)
|
|
#define __MFC_COMPAT__ // To define min/max as macro
|
|
#endif
|
|
//#include <windows.h>
|
|
#else
|
|
#if defined(UNIX)
|
|
#include <fnmatch.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "osutil.h"
|
|
#else
|
|
//#include <io.h>
|
|
#endif
|
|
//#include <fcntl.h>
|
|
#endif
|
|
|
|
/***********************************************************************/
|
|
/* Include application header files: */
|
|
/***********************************************************************/
|
|
#include "table.h" // MySQL table definitions
|
|
#include "global.h" // global declarations
|
|
#include "plgdbsem.h" // DB application declarations
|
|
#include "reldef.h" // DB definition declares
|
|
//#include "filter.h" // FILTER classes dcls
|
|
#include "filamtxt.h"
|
|
#include "tabcol.h"
|
|
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
|
|
#include "tabtbl.h" // TDBTBL and TBLCOL classes dcls
|
|
#include "ha_connect.h"
|
|
#include "mycat.h" // For GetHandler
|
|
|
|
extern "C" int trace;
|
|
|
|
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags);
|
|
|
|
/* ---------------------------- Class TBLDEF ---------------------------- */
|
|
|
|
/**************************************************************************/
|
|
/* Constructor. */
|
|
/**************************************************************************/
|
|
TBLDEF::TBLDEF(void)
|
|
{
|
|
To_Tables = NULL;
|
|
Ntables = 0;
|
|
Pseudo = 3;
|
|
} // end of TBLDEF constructor
|
|
|
|
/**************************************************************************/
|
|
/* DefineAM: define specific AM block values from XDB file. */
|
|
/**************************************************************************/
|
|
bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|
{
|
|
char *tablist, *dbname;
|
|
|
|
Desc = "Table list table";
|
|
tablist = Cat->GetStringCatInfo(g, Name, "Tablist", "");
|
|
dbname = Cat->GetStringCatInfo(g, Name, "Database", NULL);
|
|
Ntables = 0;
|
|
|
|
if (*tablist) {
|
|
char *p, *pn, *pdb;
|
|
PTBL *ptbl = &To_Tables, tbl;
|
|
|
|
for (pdb = tablist; ;) {
|
|
if ((p = strchr(pdb, ',')))
|
|
*p = 0;
|
|
|
|
// Analyze the table name, it has the format:
|
|
// [dbname.]tabname
|
|
if ((pn = strchr(pdb, '.'))) {
|
|
*pn++ = 0;
|
|
} else {
|
|
pn = pdb;
|
|
pdb = dbname;
|
|
} // endif p
|
|
|
|
// Allocate the TBLIST block for that table
|
|
tbl = (PTBL)PlugSubAlloc(g, NULL, sizeof(TBLIST));
|
|
tbl->Next = NULL;
|
|
tbl->Name = pn;
|
|
tbl->DB = pdb;
|
|
|
|
if (trace)
|
|
htrc("TBL: Name=%s db=%s\n", tbl->Name, SVP(tbl->DB));
|
|
|
|
// Link the blocks
|
|
*ptbl = tbl;
|
|
ptbl = &tbl->Next;
|
|
Ntables++;
|
|
|
|
if (p)
|
|
pdb = pn + strlen(pn) + 1;
|
|
else
|
|
break;
|
|
|
|
} // endfor pdb
|
|
|
|
Maxerr = Cat->GetIntCatInfo(Name, "Maxerr", 0);
|
|
Accept = (Cat->GetBoolCatInfo(Name, "Accept", 0) != 0);
|
|
} // endif fsec || tablist
|
|
|
|
return FALSE;
|
|
} // end of DefineAM
|
|
|
|
/***********************************************************************/
|
|
/* GetTable: makes a new Table Description Block. */
|
|
/***********************************************************************/
|
|
PTDB TBLDEF::GetTable(PGLOBAL g, MODE m)
|
|
{
|
|
PTDB tdbp;
|
|
|
|
/*********************************************************************/
|
|
/* Allocate a TDB of the proper type. */
|
|
/* Column blocks will be allocated only when needed. */
|
|
/*********************************************************************/
|
|
tdbp = new(g) TDBTBL(this);
|
|
|
|
return tdbp;
|
|
} // end of GetTable
|
|
|
|
/* ------------------------- Class TDBTBL ---------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* TDBTBL constructors. */
|
|
/***********************************************************************/
|
|
TDBTBL::TDBTBL(PTBLDEF tdp) : TDBASE(tdp)
|
|
{
|
|
Tablist = NULL;
|
|
CurTable = NULL;
|
|
Tdbp = NULL;
|
|
Accept = tdp->Accept;
|
|
Maxerr = tdp->Maxerr;
|
|
Nbf = 0;
|
|
Rows = 0;
|
|
Crp = 0;
|
|
// NTables = 0;
|
|
// iTable = 0;
|
|
} // end of TDBTBL standard constructor
|
|
|
|
/***********************************************************************/
|
|
/* Allocate TBL column description block. */
|
|
/***********************************************************************/
|
|
PCOL TDBTBL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|
{
|
|
return new(g) TBLCOL(cdp, this, cprec, n);
|
|
} // end of MakeCol
|
|
|
|
/***********************************************************************/
|
|
/* InsertSpecialColumn: Put a special column ahead of the column list.*/
|
|
/***********************************************************************/
|
|
PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
|
|
{
|
|
PCOL colp;
|
|
|
|
if (!scp->IsSpecial())
|
|
return NULL;
|
|
|
|
if (scp->GetAmType() == TYPE_AM_TABID)
|
|
// This special column is handled locally
|
|
colp = new((TIDBLK*)scp) TBTBLK(scp->GetValue());
|
|
else // Other special columns are treated normally
|
|
colp = scp;
|
|
|
|
colp->SetNext(Columns);
|
|
Columns = colp;
|
|
return colp;
|
|
} // end of InsertSpecialColumn
|
|
|
|
/***********************************************************************/
|
|
/* Get the PTDB of a table of the list. */
|
|
/***********************************************************************/
|
|
PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
|
|
{
|
|
char *db, key[256];
|
|
uint k, flags;
|
|
PTDB tdbp = NULL;
|
|
TABLE_LIST table_list;
|
|
TABLE_SHARE *s;
|
|
PCATLG cat = To_Def->GetCat();
|
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
|
THD *thd = (hc->GetTable())->in_use;
|
|
|
|
if (!thd)
|
|
return NULL; // Should not happen anymore
|
|
|
|
if (tblp->DB)
|
|
db = tblp->DB;
|
|
else
|
|
db = (char*)hc->GetDBName(NULL);
|
|
|
|
table_list.init_one_table(db, strlen(db),
|
|
tblp->Name, strlen(tblp->Name),
|
|
NULL, TL_IGNORE);
|
|
k = sprintf(key, "%s", db);
|
|
k += sprintf(key + ++k, "%s", tblp->Name);
|
|
key[++k] = 0;
|
|
|
|
if (!(s = alloc_table_share(&table_list, key, ++k))) {
|
|
strcpy(g->Message, "Error allocating share\n");
|
|
return NULL;
|
|
} // endif s
|
|
|
|
// 1 8 16
|
|
//flags = READ_ALL | DONT_OPEN_TABLES | DONT_OPEN_MASTER_REG;
|
|
//flags = 25;
|
|
flags = 24;
|
|
|
|
if (!open_table_def(thd, s, flags)) {
|
|
hc->tshp = s;
|
|
tdbp = cat->GetTable(g, tabp);
|
|
hc->tshp = NULL;
|
|
} else
|
|
sprintf(g->Message, "Error %d opening share\n", s->error);
|
|
|
|
if (trace && tdbp)
|
|
htrc("Subtable %s in %s\n",
|
|
tblp->Name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
|
|
|
free_table_share(s);
|
|
return tdbp;
|
|
} // end of GetSubTable
|
|
|
|
/***********************************************************************/
|
|
/* Initializes the table table list. */
|
|
/***********************************************************************/
|
|
bool TDBTBL::InitTableList(PGLOBAL g)
|
|
{
|
|
char *colname;
|
|
int n, colpos;
|
|
PTBL tblp;
|
|
PTABLE tabp;
|
|
PTDB tdbp;
|
|
PCOL colp;
|
|
PTBLDEF tdp = (PTBLDEF)To_Def;
|
|
|
|
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
|
|
|
for (n = 0, tblp = tdp->GetTables(); tblp; tblp = tblp->Next) {
|
|
if (TestFil(g, To_Filter, tblp)) {
|
|
// Table or named view
|
|
tabp = new(g) XTAB(tblp->Name);
|
|
tabp->SetQualifier(tblp->DB);
|
|
|
|
// Get the table description block of this table
|
|
if (!(tdbp = GetSubTable(g, tblp, tabp))) {
|
|
if (++Nbf > Maxerr)
|
|
return TRUE; // Error return
|
|
else
|
|
continue; // Skip this table
|
|
|
|
} // endif tdbp
|
|
|
|
// We must allocate subtable columns before GetMaxSize is called
|
|
// because some (PLG, ODBC?) need to have their columns attached.
|
|
// Real initialization will be done later.
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (!cp->IsSpecial()) {
|
|
colname = cp->GetName();
|
|
colpos = ((PTBLCOL)cp)->Colnum;
|
|
|
|
// We try first to get the column by name
|
|
if (!(colp = tdbp->ColDB(g, colname, 0)) && colpos)
|
|
// When unsuccessful, if a column number was specified
|
|
// try to get the column by its position in the table
|
|
colp = tdbp->ColDB(g, NULL, colpos);
|
|
|
|
if (!colp) {
|
|
if (!Accept) {
|
|
sprintf(g->Message, MSG(NO_MATCHING_COL),
|
|
colname, tdbp->GetName());
|
|
return TRUE; // Error return
|
|
} // endif !Accept
|
|
|
|
} else // this is needed in particular by PLG tables
|
|
colp->SetColUse(cp->GetColUse());
|
|
|
|
} // endif !special
|
|
|
|
if (Tablist)
|
|
Tablist->Link(tabp);
|
|
else
|
|
Tablist = tabp;
|
|
|
|
n++;
|
|
} // endif filp
|
|
|
|
} // endfor tblp
|
|
|
|
//NumTables = n;
|
|
To_Filter = NULL; // To avoid doing it several times
|
|
return FALSE;
|
|
} // end of InitTableList
|
|
|
|
/***********************************************************************/
|
|
/* Test the tablename against the pseudo "local" filter. */
|
|
/***********************************************************************/
|
|
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTBL tblp)
|
|
{
|
|
char *fil, op[8], tn[NAME_LEN];
|
|
bool neg;
|
|
|
|
if (!filp)
|
|
return TRUE;
|
|
else if (strstr(filp, " OR ") || strstr(filp, " AND "))
|
|
return TRUE; // Not handled yet
|
|
else
|
|
fil = filp + (*filp == '(' ? 1 : 0);
|
|
|
|
if (sscanf(fil, "TABID %s", op) != 1)
|
|
return TRUE; // ignore invalid filter
|
|
|
|
if ((neg = !strcmp(op, "NOT")))
|
|
strcpy(op, "IN");
|
|
|
|
if (!strcmp(op, "=")) {
|
|
// Temporarily, filter must be "TABID = 'value'" only
|
|
if (sscanf(fil, "TABID = '%[^']'", tn) != 1)
|
|
return TRUE; // ignore invalid filter
|
|
|
|
return !stricmp(tn, tblp->Name);
|
|
} else if (!strcmp(op, "IN")) {
|
|
char *p, *tnl = (char*)PlugSubAlloc(g, NULL, strlen(fil) - 10);
|
|
int n;
|
|
|
|
if (neg)
|
|
n = sscanf(fil, "TABID NOT IN (%[^)])", tnl);
|
|
else
|
|
n = sscanf(fil, "TABID IN (%[^)])", tnl);
|
|
|
|
if (n != 1)
|
|
return TRUE; // ignore invalid filter
|
|
|
|
while (tnl) {
|
|
if ((p = strchr(tnl, ',')))
|
|
*p++ = 0;
|
|
|
|
if (sscanf(tnl, "'%[^']'", tn) != 1)
|
|
return TRUE; // ignore invalid filter
|
|
else if (!stricmp(tn, tblp->Name))
|
|
return !neg; // Found
|
|
|
|
tnl = p;
|
|
} // endwhile
|
|
|
|
return neg; // Not found
|
|
} // endif op
|
|
|
|
return TRUE; // invalid operator
|
|
} // end of TestFil
|
|
|
|
/***********************************************************************/
|
|
/* TBL GetProgMax: get the max value for progress information. */
|
|
/***********************************************************************/
|
|
int TDBTBL::GetProgMax(PGLOBAL g)
|
|
{
|
|
PTABLE tblp;
|
|
int n, pmx = 0;
|
|
|
|
if (!Tablist && InitTableList(g))
|
|
return -1;
|
|
|
|
for (tblp = Tablist; tblp; tblp = tblp->GetNext())
|
|
if ((n = tblp->GetTo_Tdb()->GetProgMax(g)) > 0)
|
|
pmx += n;
|
|
|
|
return pmx;
|
|
} // end of GetProgMax
|
|
|
|
/***********************************************************************/
|
|
/* TBL GetProgCur: get the current value for progress information. */
|
|
/***********************************************************************/
|
|
int TDBTBL::GetProgCur(void)
|
|
{
|
|
return Crp + Tdbp->GetProgCur();
|
|
} // end of GetProgCur
|
|
|
|
#if 0
|
|
/***********************************************************************/
|
|
/* TBL Cardinality: returns table cardinality in number of rows. */
|
|
/* This function can be called with a null argument to test the */
|
|
/* availability of Cardinality implementation (1 yes, 0 no). */
|
|
/* Can be used on Multiple FIX table only. */
|
|
/***********************************************************************/
|
|
int TDBTBL::Cardinality(PGLOBAL g)
|
|
{
|
|
if (!g)
|
|
return Tdbp->Cardinality(g);
|
|
|
|
if (!Tablist && InitTableList(g))
|
|
return -1;
|
|
|
|
int n, card = 0;
|
|
|
|
for (int i = 0; i < NumFiles; i++) {
|
|
Tdbp->SetFile(g, Filenames[i]);
|
|
Tdbp->ResetSize();
|
|
|
|
if ((n = Tdbp->Cardinality(g)) < 0) {
|
|
// strcpy(g->Message, MSG(BAD_CARDINALITY));
|
|
return -1;
|
|
} // endif n
|
|
|
|
card += n;
|
|
} // endfor i
|
|
|
|
return card;
|
|
} // end of Cardinality
|
|
#endif // 0
|
|
|
|
/***********************************************************************/
|
|
/* Sum up the sizes of all sub-tables. */
|
|
/***********************************************************************/
|
|
int TDBTBL::GetMaxSize(PGLOBAL g)
|
|
{
|
|
if (MaxSize < 0) {
|
|
PTABLE tblp;
|
|
int mxsz;
|
|
|
|
if (!Tablist && InitTableList(g))
|
|
return 0; // Cannot be calculated at this stage
|
|
|
|
// if (Use == USE_OPEN) {
|
|
// strcpy(g->Message, MSG(MAXSIZE_ERROR));
|
|
// return -1;
|
|
// } else
|
|
MaxSize = 0;
|
|
|
|
for (tblp = Tablist; tblp; tblp = tblp->GetNext()) {
|
|
if ((mxsz = tblp->GetTo_Tdb()->GetMaxSize(g)) < 0) {
|
|
MaxSize = -1;
|
|
return mxsz;
|
|
} // endif mxsz
|
|
|
|
MaxSize += mxsz;
|
|
} // endfor i
|
|
|
|
} // endif MaxSize
|
|
|
|
return MaxSize;
|
|
} // end of GetMaxSize
|
|
|
|
/***********************************************************************/
|
|
/* Reset read/write position values. */
|
|
/***********************************************************************/
|
|
void TDBTBL::ResetDB(void)
|
|
{
|
|
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
|
if (colp->GetAmType() == TYPE_AM_TABID)
|
|
colp->COLBLK::Reset();
|
|
|
|
for (PTABLE tblp = Tablist; tblp; tblp = tblp->GetNext())
|
|
((PTDBASE)tblp->GetTo_Tdb())->ResetDB();
|
|
|
|
Tdbp = (PTDBASE)Tablist->GetTo_Tdb();
|
|
Crp = 0;
|
|
} // end of ResetDB
|
|
|
|
/***********************************************************************/
|
|
/* Returns RowId if b is false or Rownum if b is true. */
|
|
/***********************************************************************/
|
|
int TDBTBL::RowNumber(PGLOBAL g, bool b)
|
|
{
|
|
return Tdbp->RowNumber(g) + ((b) ? 0 : Rows);
|
|
} // end of RowNumber
|
|
|
|
/***********************************************************************/
|
|
/* TBL Access Method opening routine. */
|
|
/* Open first file, other will be opened sequencially when reading. */
|
|
/***********************************************************************/
|
|
bool TDBTBL::OpenDB(PGLOBAL g)
|
|
{
|
|
if (trace)
|
|
htrc("TBL OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
|
|
this, Tdb_No, Use, To_Key_Col, Mode);
|
|
|
|
if (Use == USE_OPEN) {
|
|
/*******************************************************************/
|
|
/* Table already open, replace it at its beginning. */
|
|
/*******************************************************************/
|
|
ResetDB();
|
|
return Tdbp->OpenDB(g); // Re-open fist table
|
|
} // endif use
|
|
|
|
#if 0
|
|
/*********************************************************************/
|
|
/* Direct access needed for join or sorting. */
|
|
/*********************************************************************/
|
|
if (NeedIndexing(g)) {
|
|
// Direct access of TBL tables is not implemented yet
|
|
strcpy(g->Message, MSG(NO_MUL_DIR_ACC));
|
|
return TRUE;
|
|
} // endif NeedIndexing
|
|
#endif // 0
|
|
|
|
/*********************************************************************/
|
|
/* When GetMaxsize was called, To_Filter was not set yet. */
|
|
/*********************************************************************/
|
|
if (To_Filter && Tablist) {
|
|
Tablist = NULL;
|
|
Nbf = 0;
|
|
} // endif To_Filter
|
|
|
|
/*********************************************************************/
|
|
/* Open the first table of the list. */
|
|
/*********************************************************************/
|
|
if (!Tablist && InitTableList(g)) // done in GetMaxSize
|
|
return TRUE;
|
|
|
|
if ((CurTable = Tablist)) {
|
|
Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
|
|
Tdbp->SetMode(Mode);
|
|
// Tdbp->ResetDB();
|
|
// Tdbp->ResetSize();
|
|
|
|
// Check and initialize the subtable columns
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
|
cp->COLBLK::Reset();
|
|
else if (((PTBLCOL)cp)->Init(g))
|
|
return TRUE;
|
|
|
|
if (trace)
|
|
htrc("Opening subtable %s\n", Tdbp->GetName());
|
|
|
|
// Now we can safely open the table
|
|
if (Tdbp->OpenDB(g))
|
|
return TRUE;
|
|
|
|
} // endif *Tablist
|
|
|
|
Use = USE_OPEN;
|
|
return FALSE;
|
|
} // end of OpenDB
|
|
|
|
/***********************************************************************/
|
|
/* ReadDB: Data Base read routine for MUL access method. */
|
|
/***********************************************************************/
|
|
int TDBTBL::ReadDB(PGLOBAL g)
|
|
{
|
|
int rc;
|
|
|
|
if (!CurTable)
|
|
return RC_EF;
|
|
else if (To_Kindex) {
|
|
/*******************************************************************/
|
|
/* Reading is by an index table. */
|
|
/*******************************************************************/
|
|
strcpy(g->Message, MSG(NO_INDEX_READ));
|
|
rc = RC_FX;
|
|
} else {
|
|
/*******************************************************************/
|
|
/* Now start the reading process. */
|
|
/*******************************************************************/
|
|
retry:
|
|
rc = Tdbp->ReadDB(g);
|
|
|
|
if (rc == RC_EF) {
|
|
// Total number of rows met so far
|
|
Rows += Tdbp->RowNumber(g) - 1;
|
|
Crp += Tdbp->GetProgMax(g);
|
|
|
|
if ((CurTable = CurTable->GetNext())) {
|
|
/***************************************************************/
|
|
/* Continue reading from next table file. */
|
|
/***************************************************************/
|
|
Tdbp->CloseDB(g);
|
|
Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
|
|
|
|
// Check and initialize the subtable columns
|
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
|
cp->COLBLK::Reset();
|
|
else if (((PTBLCOL)cp)->Init(g))
|
|
return RC_FX;
|
|
|
|
if (trace)
|
|
htrc("Opening subtable %s\n", Tdbp->GetName());
|
|
|
|
// Now we can safely open the table
|
|
if (Tdbp->OpenDB(g)) // Open next table
|
|
return RC_FX;
|
|
|
|
goto retry;
|
|
} // endif iFile
|
|
|
|
} else if (rc == RC_FX)
|
|
strcat(strcat(strcat(g->Message, " ("), Tdbp->GetName()), ")");
|
|
|
|
} // endif To_Kindex
|
|
|
|
return rc;
|
|
} // end of ReadDB
|
|
|
|
/***********************************************************************/
|
|
/* Data Base write routine for MUL access method. */
|
|
/***********************************************************************/
|
|
int TDBTBL::WriteDB(PGLOBAL g)
|
|
{
|
|
strcpy(g->Message, MSG(TABMUL_READONLY));
|
|
return RC_FX; // NIY
|
|
} // end of WriteDB
|
|
|
|
/***********************************************************************/
|
|
/* Data Base delete line routine for MUL access method. */
|
|
/***********************************************************************/
|
|
int TDBTBL::DeleteDB(PGLOBAL g, int irc)
|
|
{
|
|
strcpy(g->Message, MSG(TABMUL_READONLY));
|
|
return RC_FX; // NIY
|
|
} // end of DeleteDB
|
|
|
|
/***********************************************************************/
|
|
/* Data Base close routine for MUL access method. */
|
|
/***********************************************************************/
|
|
void TDBTBL::CloseDB(PGLOBAL g)
|
|
{
|
|
if (Tdbp)
|
|
Tdbp->CloseDB(g);
|
|
|
|
} // end of CloseDB
|
|
|
|
/* ---------------------------- TBLCOL ------------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* TBLCOL public constructor. */
|
|
/***********************************************************************/
|
|
TBLCOL::TBLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|
: COLBLK(cdp, tdbp, i)
|
|
{
|
|
if (cprec) {
|
|
Next = cprec->GetNext();
|
|
cprec->SetNext(this);
|
|
} else {
|
|
Next = tdbp->GetColumns();
|
|
tdbp->SetColumns(this);
|
|
} // endif cprec
|
|
|
|
// Set additional Dos access method information for column.
|
|
Long = cdp->GetLong(); // ???
|
|
//strcpy(F_Date, cdp->F_Date);
|
|
Colp = NULL;
|
|
To_Val = NULL;
|
|
Pseudo = FALSE;
|
|
Colnum = cdp->GetOffset(); // If columns are retrieved by number
|
|
|
|
if (trace)
|
|
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
|
|
|
|
} // end of TBLCOL constructor
|
|
|
|
#if 0
|
|
/***********************************************************************/
|
|
/* TBLCOL public constructor. */
|
|
/***********************************************************************/
|
|
TBLCOL::TBLCOL(SPCBLK *scp, PTDB tdbp) : COLBLK(scp->GetName(), tdbp, 0)
|
|
{
|
|
// Set additional TBL access method information for pseudo column.
|
|
Is_Key = Was_Key = scp->IsKey();
|
|
Long = scp->GetLength();
|
|
Buf_Type = scp->GetResultType();
|
|
*Format.Type = (Buf_Type == TYPE_INT) ? 'N' : 'C';
|
|
Format.Length = Long;
|
|
Colp = NULL;
|
|
To_Val = NULL;
|
|
Pseudo = TRUE;
|
|
} // end of TBLCOL constructor
|
|
|
|
/***********************************************************************/
|
|
/* TBLCOL constructor used for copying columns. */
|
|
/* tdbp is the pointer to the new table descriptor. */
|
|
/***********************************************************************/
|
|
TBLCOL::TBLCOL(TBLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
|
|
{
|
|
Long = col1->Long;
|
|
Colp = col1->Colp;
|
|
To_Val = col1->To_Val;
|
|
Pseudo = col1->Pseudo;
|
|
} // end of TBLCOL copy constructor
|
|
#endif
|
|
|
|
/***********************************************************************/
|
|
/* TBLCOL initialization routine. */
|
|
/* Look for the matching column in the current table. */
|
|
/***********************************************************************/
|
|
bool TBLCOL::Init(PGLOBAL g)
|
|
{
|
|
PTDBTBL tdbp = (PTDBTBL)To_Tdb;
|
|
|
|
To_Val = NULL;
|
|
|
|
if (!(Colp = tdbp->Tdbp->ColDB(g, Name, 0)) && Colnum)
|
|
Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum);
|
|
|
|
if (Colp) {
|
|
Colp->InitValue(g); // May not have been done elsewhere
|
|
To_Val = Colp->GetValue();
|
|
} else if (!tdbp->Accept) {
|
|
sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName());
|
|
return TRUE;
|
|
} else
|
|
Value->Reset();
|
|
|
|
return FALSE;
|
|
} // end of Init
|
|
|
|
/***********************************************************************/
|
|
/* ReadColumn: */
|
|
/***********************************************************************/
|
|
void TBLCOL::ReadColumn(PGLOBAL g)
|
|
{
|
|
if (trace)
|
|
htrc("TBL ReadColumn: name=%s\n", Name);
|
|
|
|
if (Colp) {
|
|
Colp->ReadColumn(g);
|
|
Value->SetValue_pval(To_Val);
|
|
} // endif Colp
|
|
|
|
} // end of ReadColumn
|
|
|
|
/* ---------------------------- TBTBLK ------------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* ReadColumn: */
|
|
/***********************************************************************/
|
|
void TBTBLK::ReadColumn(PGLOBAL g)
|
|
{
|
|
if (trace)
|
|
htrc("TBT ReadColumn: name=%s\n", Name);
|
|
|
|
Value->SetValue_psz((char*)((PTDBTBL)To_Tdb)->Tdbp->GetName());
|
|
} // end of ReadColumn
|
|
|
|
/* ------------------------------------------------------------------- */
|