mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
38edf74a3c
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)
657 lines
22 KiB
C++
657 lines
22 KiB
C++
/* Copyright (C) Olivier Bertrand 2004 - 2012
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
/*************** Mycat CC Program Source Code File (.CC) ***************/
|
|
/* PROGRAM NAME: MYCAT */
|
|
/* ------------- */
|
|
/* Version 1.3 */
|
|
/* */
|
|
/* Author: Olivier Bertrand 2012 - 2013 */
|
|
/* */
|
|
/* WHAT THIS PROGRAM DOES: */
|
|
/* ----------------------- */
|
|
/* This program are the DB description related routines. */
|
|
/***********************************************************************/
|
|
|
|
/***********************************************************************/
|
|
/* Include relevant MariaDB header file. */
|
|
/***********************************************************************/
|
|
#if defined(WIN32)
|
|
//#include <windows.h>
|
|
//#include <sqlext.h>
|
|
#elif defined(UNIX)
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#endif
|
|
#define DONT_DEFINE_VOID
|
|
//#include <mysql/plugin.h>
|
|
#include "handler.h"
|
|
#undef OFFSET
|
|
|
|
/***********************************************************************/
|
|
/* Include application header files */
|
|
/* */
|
|
/* global.h is header containing all global declarations. */
|
|
/* plgdbsem.h is header containing DB application declarations. */
|
|
/* tabdos.h is header containing TDBDOS classes declarations. */
|
|
/* MYCAT.h is header containing DB description declarations. */
|
|
/***********************************************************************/
|
|
#if defined(UNIX)
|
|
#include "osutil.h"
|
|
#endif // UNIX
|
|
#include "global.h"
|
|
#include "plgdbsem.h"
|
|
#include "reldef.h"
|
|
#include "tabcol.h"
|
|
#include "xtable.h"
|
|
#include "filamtxt.h"
|
|
#include "tabdos.h"
|
|
#include "tabfmt.h"
|
|
#include "tabvct.h"
|
|
#include "tabsys.h"
|
|
#if defined(WIN32)
|
|
#include "tabmac.h"
|
|
#include "tabwmi.h"
|
|
#endif // WIN32
|
|
#include "tabtbl.h"
|
|
#if defined(XML_SUPPORT)
|
|
#include "tabxml.h"
|
|
#endif // XML_SUPPORT
|
|
#include "tabmul.h"
|
|
#if defined(MYSQL_SUPPORT)
|
|
#include "tabmysql.h"
|
|
#endif // MYSQL_SUPPORT
|
|
#if defined(ODBC_SUPPORT)
|
|
#define NODBC
|
|
#include "tabodbc.h"
|
|
#endif // ODBC_SUPPORT
|
|
#if defined(PIVOT_SUPPORT)
|
|
#include "tabpivot.h"
|
|
#endif // PIVOT_SUPPORT
|
|
#include "ha_connect.h"
|
|
#include "mycat.h"
|
|
|
|
/**************************************************************************/
|
|
/* Extern static variables. */
|
|
/**************************************************************************/
|
|
#if defined(WIN32)
|
|
extern "C" HINSTANCE s_hModule; // Saved module handle
|
|
#endif // !WIN32
|
|
|
|
extern int xtrace;
|
|
|
|
/**************************************************************************/
|
|
/* General DB routines. */
|
|
/**************************************************************************/
|
|
//bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR);
|
|
//#if !defined(WIN32)
|
|
extern "C" int GetRcString(int id, char *buf, int bufsize);
|
|
//#endif // !WIN32
|
|
//void ptrc(char const *fmt, ...);
|
|
|
|
/**************************************************************************/
|
|
/* Allocate the result structure that will contain result data. */
|
|
/**************************************************************************/
|
|
PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
|
|
int *dbtype, int *buftyp, unsigned int *length,
|
|
bool blank = false, bool nonull = false)
|
|
{
|
|
char cname[NAM_LEN+1];
|
|
int i;
|
|
PCOLRES *pcrp, crp;
|
|
PQRYRES qrp;
|
|
|
|
/************************************************************************/
|
|
/* Allocate the structure used to contain the result set. */
|
|
/************************************************************************/
|
|
qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
|
|
pcrp = &qrp->Colresp;
|
|
qrp->Continued = false;
|
|
qrp->Truncated = false;
|
|
qrp->Info = false;
|
|
qrp->Suball = true;
|
|
qrp->Maxres = maxres;
|
|
qrp->Maxsize = 0;
|
|
qrp->Nblin = 0;
|
|
qrp->Nbcol = 0; // will be ncol
|
|
qrp->Cursor = 0;
|
|
qrp->BadLines = 0;
|
|
|
|
for (i = 0; i < ncol; i++) {
|
|
*pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
|
|
crp = *pcrp;
|
|
pcrp = &crp->Next;
|
|
crp->Colp = NULL;
|
|
crp->Ncol = ++qrp->Nbcol;
|
|
crp->Type = buftyp[i];
|
|
crp->Length = length[i];
|
|
crp->Clen = GetTypeSize(crp->Type, length[i]);
|
|
crp->Prec = 0;
|
|
crp->DBtype = dbtype[i];
|
|
|
|
if (ids > 0) {
|
|
#if defined(XMSG)
|
|
// Get header from message file
|
|
strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
|
|
cname[NAM_LEN] = 0; // for truncated long names
|
|
//#elif defined(WIN32)
|
|
// Get header from ressource file
|
|
// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
|
|
#else // !WIN32
|
|
GetRcString(ids + crp->Ncol, cname, sizeof(cname));
|
|
#endif // !WIN32
|
|
crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1);
|
|
strcpy(crp->Name, cname);
|
|
} else
|
|
crp->Name = NULL; // Will be set by caller
|
|
|
|
// Allocate the Value Block that will contain data
|
|
if (crp->Length || nonull)
|
|
crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
|
|
crp->Length, 0, true, blank);
|
|
else
|
|
crp->Kdata = NULL;
|
|
|
|
if (g->Trace)
|
|
htrc("Column(%d) %s type=%d len=%d value=%p\n",
|
|
crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
|
|
|
|
} // endfor i
|
|
|
|
*pcrp = NULL;
|
|
|
|
return qrp;
|
|
} // end of PlgAllocResult
|
|
|
|
/***********************************************************************/
|
|
/* Get a unique char identifier for types. The letter used are: */
|
|
/* ABCDEF..I.KLM.O..R.T.VWXY.. */
|
|
/***********************************************************************/
|
|
char GetTypeID(char *type)
|
|
{
|
|
return (!type) ? 'D' // DOS (default)
|
|
: (!stricmp(type, "FMT")) ? 'T' // CSV
|
|
: (!stricmp(type, "DIR")) ? 'R' // diR
|
|
: (!stricmp(type, "DBF")) ? 'A' // dbAse
|
|
: (!stricmp(type, "SYS")) ? 'I' // INI
|
|
: (!stricmp(type, "TBL")) ? 'L' // tbL
|
|
: (!stricmp(type, "MYSQL")) ? 'Y' // mYsql
|
|
: (!stricmp(type, "OEM")) ? 'E' : toupper(*type);
|
|
} // end of GetTypeID
|
|
|
|
/* ------------------------- Class CATALOG --------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* CATALOG Constructor. */
|
|
/***********************************************************************/
|
|
CATALOG::CATALOG(void)
|
|
{
|
|
To_Desc= NULL;
|
|
//*DescFile= '\0';
|
|
#if defined(WIN32)
|
|
DataPath= ".\\";
|
|
#else // !WIN32
|
|
DataPath= "./";
|
|
#endif // !WIN32
|
|
Descp= NULL;
|
|
//memset(&DescArea, 0, sizeof(AREADEF));
|
|
memset(&Ctb, 0, sizeof(CURTAB));
|
|
Cbuf= NULL;
|
|
Cblen= 0;
|
|
DefHuge= false;
|
|
} // end of CATALOG constructor
|
|
|
|
/* -------------------------- Class MYCAT ---------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* MYCAT Constructor. */
|
|
/***********************************************************************/
|
|
MYCAT::MYCAT(PHC hc) : CATALOG()
|
|
{
|
|
Hc= hc;
|
|
To_Desc= NULL;
|
|
DefHuge= false;
|
|
SepIndex= true; // Temporay until we can store offet and size
|
|
} // end of MYCAT constructor
|
|
|
|
/***********************************************************************/
|
|
/* When using volatile storage, reset values pointing to Sarea. */
|
|
/***********************************************************************/
|
|
void MYCAT::Reset(void)
|
|
{
|
|
To_Desc= NULL;
|
|
} // end of Reset
|
|
|
|
/***********************************************************************/
|
|
/* This function sets the current database path. */
|
|
/***********************************************************************/
|
|
void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path)
|
|
{
|
|
if (path) {
|
|
size_t len= strlen(path) + (*path != '.' ? 4 : 1);
|
|
char *buf= (char*)PlugSubAlloc(g, NULL, len);
|
|
|
|
if (*path != '.') {
|
|
#if defined(WIN32)
|
|
char *s= "\\";
|
|
#else // !WIN32
|
|
char *s= "/";
|
|
#endif // !WIN32
|
|
strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
|
|
} else
|
|
strcpy(buf, path);
|
|
|
|
*datapath= buf;
|
|
} // endif path
|
|
|
|
} // end of SetDataPath
|
|
|
|
/***********************************************************************/
|
|
/* This function sets an integer MYCAT information. */
|
|
/***********************************************************************/
|
|
bool MYCAT::SetIntCatInfo(LPCSTR name, PSZ what, int n)
|
|
{
|
|
return Hc->SetIntegerOption(what, n);
|
|
} // end of SetIntCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* This function returns integer MYCAT information. */
|
|
/***********************************************************************/
|
|
int MYCAT::GetIntCatInfo(LPCSTR name, PSZ what, int idef)
|
|
{
|
|
int n= Hc->GetIntegerOption(what);
|
|
|
|
return (n == NO_IVAL) ? idef : n;
|
|
} // end of GetIntCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* This function returns Boolean MYCAT information. */
|
|
/***********************************************************************/
|
|
bool MYCAT::GetBoolCatInfo(LPCSTR name, PSZ what, bool bdef)
|
|
{
|
|
bool b= Hc->GetBooleanOption(what, bdef);
|
|
|
|
return b;
|
|
} // end of GetBoolCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* This function returns size catalog information. */
|
|
/***********************************************************************/
|
|
int MYCAT::GetSizeCatInfo(LPCSTR name, PSZ what, PSZ sdef)
|
|
{
|
|
char * s, c;
|
|
int i, n= 0;
|
|
|
|
if (!(s= Hc->GetStringOption(what)))
|
|
s= sdef;
|
|
|
|
if ((i= sscanf(s, " %d %c ", &n, &c)) == 2)
|
|
switch (toupper(c)) {
|
|
case 'M':
|
|
n *= 1024;
|
|
case 'K':
|
|
n *= 1024;
|
|
} // endswitch c
|
|
|
|
return n;
|
|
} // end of GetSizeCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* This function sets char MYCAT information in buf. */
|
|
/***********************************************************************/
|
|
int MYCAT::GetCharCatInfo(LPCSTR name, PSZ what,
|
|
PSZ sdef, char *buf, int size)
|
|
{
|
|
char *s= Hc->GetStringOption(what);
|
|
|
|
strncpy(buf, ((s) ? s : sdef), size);
|
|
return size;
|
|
} // end of GetCharCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* This function returns string MYCAT information. */
|
|
/* Default parameter is "*" to get the handler default. */
|
|
/***********************************************************************/
|
|
char *MYCAT::GetStringCatInfo(PGLOBAL g, PSZ name, PSZ what, PSZ sdef)
|
|
{
|
|
char *sval, *s= Hc->GetStringOption(what, sdef);
|
|
|
|
if (s) {
|
|
sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + 1);
|
|
strcpy(sval, s);
|
|
} else
|
|
sval = NULL;
|
|
|
|
return sval;
|
|
} // end of GetStringCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* This function returns column MYCAT information. */
|
|
/***********************************************************************/
|
|
int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
|
|
{
|
|
char *type= GetStringCatInfo(g, NULL, "Type", "DOS");
|
|
int i, loff, poff, nof, nlg;
|
|
void *field= NULL;
|
|
PCOLDEF cdp, lcdp= NULL, tocols= NULL;
|
|
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
|
|
|
// Get a unique char identifier for type
|
|
char tc= GetTypeID(type);
|
|
|
|
// Take care of the column definitions
|
|
i= poff= nof= nlg= 0;
|
|
|
|
// Offsets of HTML and DIR tables start from 0, DBF at 1
|
|
loff= (tc == 'A') ? 1 : (tc == 'X' || tc == 'R') ? -1 : 0;
|
|
|
|
while (true) {
|
|
// Default Offset depends on table type
|
|
switch (tc) {
|
|
case 'D': // DOS
|
|
case 'F': // FIX
|
|
case 'B': // BIN
|
|
case 'V': // VEC
|
|
case 'A': // DBF
|
|
poff= loff + nof; // Default next offset
|
|
nlg= max(nlg, poff); // Default lrecl
|
|
break;
|
|
case 'C': // CSV
|
|
case 'T': // FMT
|
|
nlg+= nof;
|
|
case 'R': // DIR
|
|
case 'X': // XML
|
|
poff= loff + 1;
|
|
break;
|
|
case 'I': // INI
|
|
case 'M': // MAC
|
|
case 'L': // TBL
|
|
case 'E': // OEM
|
|
poff = 0; // Offset represents an independant flag
|
|
break;
|
|
default: // VCT PLG ODBC MYSQL WMI...
|
|
poff = 0; // NA
|
|
break;
|
|
} // endswitch tc
|
|
|
|
do {
|
|
field= Hc->GetColumnOption(field, pcf);
|
|
} while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
|
|
|
|
if (tc == 'A' && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
|
|
// DBF date format defaults to 'YYYMMDD'
|
|
pcf->Datefmt= "YYYYMMDD";
|
|
pcf->Length= 8;
|
|
} // endif tc
|
|
|
|
if (!field)
|
|
break;
|
|
|
|
// Allocate the column description block
|
|
cdp= new(g) COLDEF;
|
|
|
|
if ((nof= cdp->Define(g, NULL, pcf, poff)) < 0)
|
|
return -1; // Error, probably unhandled type
|
|
else if (nof)
|
|
loff= cdp->GetOffset();
|
|
|
|
switch (tc) {
|
|
case 'V':
|
|
cdp->SetOffset(0); // Not to have shift
|
|
case 'B':
|
|
// BIN/VEC are packed by default
|
|
if (nof)
|
|
// Field width is the internal representation width
|
|
// that can also depend on the column format
|
|
switch (cdp->Fmt ? *cdp->Fmt : 'X') {
|
|
case 'C': break;
|
|
case 'R':
|
|
case 'F':
|
|
case 'L':
|
|
case 'I': nof= 4; break;
|
|
case 'D': nof= 8; break;
|
|
case 'S': nof= 2; break;
|
|
case 'T': nof= 1; break;
|
|
default: nof= cdp->Clen;
|
|
} // endswitch Fmt
|
|
|
|
break;
|
|
} // endswitch tc
|
|
|
|
if (lcdp)
|
|
lcdp->SetNext(cdp);
|
|
else
|
|
tocols= cdp;
|
|
|
|
lcdp= cdp;
|
|
i++;
|
|
} // endwhile
|
|
|
|
// Degree is the the number of defined columns (informational)
|
|
if (i != defp->GetDegree())
|
|
defp->SetDegree(i);
|
|
|
|
if (defp->GetDefType() == TYPE_AM_DOS) {
|
|
int ending, recln= 0;
|
|
PDOSDEF ddp= (PDOSDEF)defp;
|
|
|
|
// Was commented because sometimes ending is 0 even when
|
|
// not specified (for instance if quoted is specified)
|
|
// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
|
|
if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
|
|
#if defined(WIN32)
|
|
ending= 2;
|
|
#else
|
|
ending= 1;
|
|
#endif
|
|
Hc->SetIntegerOption("Ending", ending);
|
|
} // endif ending
|
|
|
|
// Calculate the default record size
|
|
switch (tc) {
|
|
case 'F':
|
|
recln= nlg + ending; // + length of line ending
|
|
break;
|
|
case 'B':
|
|
case 'V':
|
|
recln= nlg;
|
|
|
|
// if ((k= (pak < 0) ? 8 : pak) > 1)
|
|
// See above for detailed comment
|
|
// Round up lrecl to multiple of 8 or pak
|
|
// recln= ((recln + k - 1) / k) * k;
|
|
|
|
break;
|
|
case 'D':
|
|
case 'A':
|
|
recln= nlg;
|
|
break;
|
|
case 'T':
|
|
case 'C':
|
|
// The number of separators (assuming an extra one can exist)
|
|
// recln= poff * ((qotd) ? 3 : 1); to be investigated
|
|
recln= nlg + poff * 3; // To be safe
|
|
break;
|
|
} // endswitch tc
|
|
|
|
// lrecl must be at least recln to avoid buffer overflow
|
|
recln= max(recln, Hc->GetIntegerOption("Lrecl"));
|
|
Hc->SetIntegerOption("Lrecl", recln);
|
|
ddp->SetLrecl(recln);
|
|
} // endif Lrecl
|
|
|
|
// Attach the column definition to the tabdef
|
|
defp->SetCols(tocols);
|
|
return poff;
|
|
} // end of GetColCatInfo
|
|
|
|
/***********************************************************************/
|
|
/* GetIndexInfo: retrieve index description from the table structure. */
|
|
/***********************************************************************/
|
|
bool MYCAT::GetIndexInfo(PGLOBAL g, PTABDEF defp)
|
|
{
|
|
PIXDEF xdp, pxd= NULL, toidx= NULL;
|
|
|
|
// Now take care of the index definitions
|
|
for (int n= 0; ; n++) {
|
|
if (xtrace)
|
|
printf("Getting index %d info\n", n + 1);
|
|
|
|
if (!(xdp= Hc->GetIndexInfo(n)))
|
|
break;
|
|
|
|
if (pxd)
|
|
pxd->SetNext(xdp);
|
|
else
|
|
toidx= xdp;
|
|
|
|
pxd= xdp;
|
|
} // endfor n
|
|
|
|
// All is correct, attach new index(es)
|
|
defp->SetIndx(toidx);
|
|
return false;
|
|
} // end of GetIndexInfo
|
|
|
|
/***********************************************************************/
|
|
/* GetTableDesc: retrieve a table descriptor. */
|
|
/* Look for a table descriptor matching the name and type. If found */
|
|
/* in storage, return a pointer to it, else look in the XDB file. If */
|
|
/* found, make and add the descriptor and return a pointer to it. */
|
|
/***********************************************************************/
|
|
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name,
|
|
LPCSTR am, PRELDEF *prp)
|
|
{
|
|
LPCSTR type;
|
|
|
|
if (xtrace)
|
|
printf("GetTableDesc: name=%s am=%s\n", name, SVP(am));
|
|
|
|
// Firstly check whether this table descriptor is in memory
|
|
if (To_Desc)
|
|
return To_Desc;
|
|
|
|
// Here get the type of this table
|
|
if (!(type= Hc->GetStringOption("Type")))
|
|
type= "DOS";
|
|
|
|
return MakeTableDesc(g, name, type);
|
|
} // end of GetTableDesc
|
|
|
|
/***********************************************************************/
|
|
/* MakeTableDesc: make a table/view description. */
|
|
/* Note: caller must check if name already exists before calling it. */
|
|
/***********************************************************************/
|
|
PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
|
|
{
|
|
char tc;
|
|
PRELDEF tdp= NULL;
|
|
|
|
if (xtrace)
|
|
printf("MakeTableDesc: name=%s am=%s\n", name, SVP(am));
|
|
|
|
/*********************************************************************/
|
|
/* Get a unique char identifier for types. The letter used are: */
|
|
/* ABCDEF..IJKLM.OPQRSTUVWXYZ and Allocate table definition class */
|
|
/*********************************************************************/
|
|
tc= GetTypeID((char*)am);
|
|
|
|
switch (tc) {
|
|
case 'F':
|
|
case 'B':
|
|
case 'A':
|
|
case 'D': tdp= new(g) DOSDEF; break;
|
|
case 'T':
|
|
case 'C': tdp= new(g) CSVDEF; break;
|
|
case 'I': tdp= new(g) INIDEF; break;
|
|
case 'R': tdp= new(g) DIRDEF; break;
|
|
#if defined(XML_SUPPORT)
|
|
case 'X': tdp= new(g) XMLDEF; break;
|
|
#endif // XML_SUPPORT
|
|
case 'V': tdp= new(g) VCTDEF; break;
|
|
#if defined(ODBC_SUPPORT)
|
|
case 'O': tdp= new(g) ODBCDEF; break;
|
|
#endif // ODBC_SUPPORT
|
|
#if defined(WIN32)
|
|
case 'M': tdp= new(g) MACDEF; break;
|
|
case 'W': tdp= new(g) WMIDEF; break;
|
|
#endif // WIN32
|
|
case 'E': tdp= new(g) OEMDEF; break;
|
|
case 'L': tdp= new(g) TBLDEF; break;
|
|
#if defined(MYSQL_SUPPORT)
|
|
case 'Y': tdp= new(g) MYSQLDEF; break;
|
|
#endif // MYSQL_SUPPORT
|
|
#if defined(PIVOT_SUPPORT)
|
|
case 'P': tdp= new(g) PIVOTDEF; break;
|
|
#endif // PIVOT_SUPPORT
|
|
default:
|
|
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
|
|
} // endswitch
|
|
|
|
// Do make the table/view definition from XDB file information
|
|
if (tdp && tdp->Define(g, this, name, am))
|
|
tdp= NULL;
|
|
|
|
return tdp;
|
|
} // end of MakeTableDesc
|
|
|
|
/***********************************************************************/
|
|
/* Initialize a Table Description Block construction. */
|
|
/***********************************************************************/
|
|
PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode)
|
|
{
|
|
PRELDEF tdp;
|
|
PTDB tdbp= NULL;
|
|
LPCSTR name= tablep->GetName();
|
|
|
|
if (xtrace)
|
|
printf("GetTableDB: name=%s\n", name);
|
|
|
|
// Look for the description of the requested table
|
|
tdp= GetTableDesc(g, name, NULL);
|
|
|
|
if (tdp) {
|
|
if (xtrace)
|
|
printf("tdb=%p type=%s\n", tdp, tdp->GetType());
|
|
|
|
if (tablep->GetQualifier())
|
|
SetPath(g, &tdp->Database, tablep->GetQualifier());
|
|
|
|
tdbp= tdp->GetTable(g, mode);
|
|
} // endif tdp
|
|
|
|
if (tdbp) {
|
|
if (xtrace)
|
|
printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
|
|
tdbp->GetAmType());
|
|
tablep->SetTo_Tdb(tdbp);
|
|
tdbp->SetTable(tablep);
|
|
} // endif tdbp
|
|
|
|
return (tdbp);
|
|
} // end of GetTable
|
|
|
|
/***********************************************************************/
|
|
/* ClearDB: Terminates Database usage. */
|
|
/***********************************************************************/
|
|
void MYCAT::ClearDB(PGLOBAL g)
|
|
{
|
|
To_Desc= NULL;
|
|
} // end of ClearDB
|
|
|
|
/* ------------------------ End of MYCAT --------------------------- */
|