// Methods /***********************************************************************/ /* Return the pointer on the charset of this table. */ /***********************************************************************/
CHARSET_INFO *TDB::data_charset(void)
{ // If no DATA_CHARSET is specified, we assume that character // set of the remote data is the same with CHARACTER SET // definition of the SQL column. return m_data_charset ? m_data_charset : &my_charset_bin;
} // end of data_charset
/***********************************************************************/ /* Return the datapath of the DB this table belongs to. */ /***********************************************************************/
PCSZ TDB::GetPath(void)
{ return To_Def->GetPath();
} // end of GetPath
/***********************************************************************/ /* Return true if name is a special column of this table. */ /***********************************************************************/ bool TDB::IsSpecial(PSZ name)
{ for (PCOLDEF cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) if (!stricmp(cdp->GetName(), name) && (cdp->Flags & U_SPECIAL)) returntrue; // Special column to ignore while inserting
returnfalse; // Not found or not special or not inserting
} // end of IsSpecial
/***********************************************************************/ /* Initialize TDB based column description block construction. */ /* name is used to call columns by name. */ /* num is used by TBL to construct columns by index number. */ /* Note: name=Null and num=0 for constructing all columns (select *) */ /***********************************************************************/
PCOL TDB::ColDB(PGLOBAL g, PSZ name, int num)
{ int i;
PCOLDEF cdp;
PCOL cp, colp = NULL, cprec = NULL;
for (cdp = To_Def->GetCols(), i = 1; cdp; cdp = cdp->GetNext(), i++) if ((!name && !num) ||
(name && !stricmp(cdp->GetName(), name)) || num == i) { /*****************************************************************/ /* Check for existence of desired column. */ /* Also find where to insert the new block. */ /*****************************************************************/ for (cp = Columns; cp; cp = cp->GetNext()) if ((num && cp->GetIndex() == i) ||
(name && !stricmp(cp->GetName(), name))) break; // Found elseif (cp->GetIndex() < i)
cprec = cp;
if (trace(1))
htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);
/*****************************************************************/ /* Now take care of Column Description Block. */ /*****************************************************************/ if (cp)
colp = cp; elseif (!(cdp->Flags & U_SPECIAL))
colp = MakeCol(g, cdp, cprec, i); elseif (Mode != MODE_INSERT)
colp = InsertSpcBlk(g, cdp);
/***********************************************************************/ /* InsertSpecialColumn: Put a special column ahead of the column list.*/ /***********************************************************************/
PCOL TDB::InsertSpecialColumn(PCOL colp)
{ if (!colp->IsSpecial()) return NULL;
colp->SetNext(Columns);
Columns = colp; return colp;
} // end of InsertSpecialColumn
/***********************************************************************/ /* Make a special COLBLK to insert in a table. */ /***********************************************************************/
PCOL TDB::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
{ //char *name = cdp->GetName(); char *name = cdp->GetFmt();
PCOLUMN cp;
PCOL colp;
cp = new(g)COLUMN(cdp->GetName());
if (!To_Table) {
strcpy(g->Message, "Cannot make special column: To_Table is NULL"); return NULL;
} else
cp->SetTo_Table(To_Table);
/***********************************************************************/ /* Marks DOS/MAP table columns used in internal joins. */ /* tdb2 is the top of tree or first tdb in chained tdb's and tdbp */ /* points to the currently marked tdb. */ /* Two questions here: exact meaning of U_J_INT ? */ /* Why is the eventual reference to To_Key_Col not marked U_J_EXT ? */ /***********************************************************************/ void TDB::MarkDB(PGLOBAL, PTDB tdb2)
{ if (trace(1))
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB
/***********************************************************************/ /* RowNumber: returns the current row ordinal number. */ /***********************************************************************/ int TDB::RowNumber(PGLOBAL g, bool)
{
snprintf(g->Message, sizeof(g->Message), MSG(ROWID_NOT_IMPL), GetAmName(g, GetAmType())); return0;
} // end of RowNumber
PTDB TDB::Copy(PTABS t)
{
PTDB tp, tdb1, tdb2 = NULL, outp = NULL; //PGLOBAL g = t->G; // Is this really useful ???
/***********************************************************************/ /* SetRecpos: Replace the table at the specified position. */ /***********************************************************************/ bool TDB::SetRecpos(PGLOBAL g, int)
{
strcpy(g->Message, MSG(SETRECPOS_NIY)); returntrue;
} // end of SetRecpos
/***********************************************************************/ /* Return the pointer on the DB catalog this table belongs to. */ /***********************************************************************/
PCATLG TDBASE::GetCat(void)
{ return (To_Def) ? To_Def->GetCat() : NULL;
} // end of GetCat
#if0 /***********************************************************************/ /* Return the pointer on the charset of this table. */ /***********************************************************************/
CHARSET_INFO *TDBASE::data_charset(void)
{ // If no DATA_CHARSET is specified, we assume that character // set of the remote data is the same with CHARACTER SET // definition of the SQL column. return m_data_charset ? m_data_charset : &my_charset_bin;
} // end of data_charset
/***********************************************************************/ /* Return the datapath of the DB this table belongs to. */ /***********************************************************************/
PSZ TDBASE::GetPath(void)
{ return To_Def->GetPath();
} // end of GetPath
/***********************************************************************/ /* Return true if name is a special column of this table. */ /***********************************************************************/ bool TDBASE::IsSpecial(PSZ name)
{ for (PCOLDEF cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) if (!stricmp(cdp->GetName(), name) && (cdp->Flags & U_SPECIAL)) returntrue; // Special column to ignore while inserting
returnfalse; // Not found or not special or not inserting
} // end of IsSpecial
/***********************************************************************/ /* Initialize TDBASE based column description block construction. */ /* name is used to call columns by name. */ /* num is used by TBL to construct columns by index number. */ /* Note: name=Null and num=0 for constructing all columns (select *) */ /***********************************************************************/
PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
{ int i;
PCOLDEF cdp;
PCOL cp, colp = NULL, cprec = NULL;
for (cdp = To_Def->GetCols(), i = 1; cdp; cdp = cdp->GetNext(), i++) if ((!name && !num) ||
(name && !stricmp(cdp->GetName(), name)) || num == i) { /*****************************************************************/ /* Check for existence of desired column. */ /* Also find where to insert the new block. */ /*****************************************************************/ for (cp = Columns; cp; cp = cp->GetNext()) if ((num && cp->GetIndex() == i) ||
(name && !stricmp(cp->GetName(), name))) break; // Found elseif (cp->GetIndex() < i)
cprec = cp;
if (trace(1))
htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);
/*****************************************************************/ /* Now take care of Column Description Block. */ /*****************************************************************/ if (cp)
colp = cp; elseif (!(cdp->Flags & U_SPECIAL))
colp = MakeCol(g, cdp, cprec, i); elseif (Mode != MODE_INSERT)
colp = InsertSpcBlk(g, cdp);
/***********************************************************************/ /* InsertSpecialColumn: Put a special column ahead of the column list.*/ /***********************************************************************/
PCOL TDBASE::InsertSpecialColumn(PCOL colp)
{ if (!colp->IsSpecial()) return NULL;
colp->SetNext(Columns);
Columns = colp; return colp;
} // end of InsertSpecialColumn
/***********************************************************************/ /* Make a special COLBLK to insert in a table. */ /***********************************************************************/
PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
{ //char *name = cdp->GetName(); char *name = cdp->GetFmt();
PCOLUMN cp;
PCOL colp;
cp= new(g) COLUMN(cdp->GetName());
if (! To_Table) {
strcpy(g->Message, "Cannot make special column: To_Table is NULL"); return NULL;
} else
cp->SetTo_Table(To_Table);
return (colp);
} // end of InsertSpcBlk #endif// 0
/***********************************************************************/ /* ResetTableOpt: Wrong for this table type. */ /***********************************************************************/ int TDBASE::ResetTableOpt(PGLOBAL g, bool, bool)
{
strcpy(g->Message, "This table is not indexable"); return RC_INFO;
} // end of ResetTableOpt
/***********************************************************************/ /* ResetKindex: set or reset the index pointer. */ /***********************************************************************/ void TDBASE::ResetKindex(PGLOBAL g, PKXBASE kxp)
{ if (To_Kindex) { int pos = GetRecpos(); // To be reset in Txfp
for (PCOL colp= Columns; colp; colp= colp->GetNext())
colp->SetKcol(NULL);
To_Kindex->Close(); // Discard old index
SetRecpos(g, pos); // Ignore return value
} // endif To_Kindex
To_Kindex = kxp;
} // end of ResetKindex
#if0 /***********************************************************************/ /* SetRecpos: Replace the table at the specified position. */ /***********************************************************************/ bool TDBASE::SetRecpos(PGLOBAL g, int)
{
strcpy(g->Message, MSG(SETRECPOS_NIY)); returntrue;
} // end of SetRecpos #endif// 0
/***********************************************************************/ /* Methods */ /***********************************************************************/ void TDBASE::PrintAM(FILE *f, char *m)
{
fprintf(f, "%s AM(%d): mode=%d\n", m, GetAmType(), Mode);
} // end of PrintAM
#if0 /***********************************************************************/ /* Marks DOS/MAP table columns used in internal joins. */ /* tdb2 is the top of tree or first tdb in chained tdb's and tdbp */ /* points to the currently marked tdb. */ /* Two questions here: exact meaning of U_J_INT ? */ /* Why is the eventual reference to To_Key_Col not marked U_J_EXT ? */ /***********************************************************************/ void TDBASE::MarkDB(PGLOBAL, PTDB tdb2)
{ if (trace(1))
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB #endif// 0
/* ---------------------------TDBCAT class --------------------------- */
/***********************************************************************/ /* Implementation of the TDBCAT class. */ /***********************************************************************/
TDBCAT::TDBCAT(PTABDEF tdp) : TDBASE(tdp)
{
Qrp = NULL;
Init = false;
N = -1;
} // end of TDBCAT constructor
/***********************************************************************/ /* Initialize: Get the result query block. */ /***********************************************************************/ bool TDBCAT::Initialize(PGLOBAL g)
{ if (Init) returnfalse;
if (!(Qrp = GetResult(g))) returntrue;
if (Qrp->Truncated) {
snprintf(g->Message, sizeof(g->Message), "Result limited to %d lines", Qrp->Maxres);
PushWarning(g, this);
} // endif Truncated
if (Qrp->BadLines) {
snprintf(g->Message, sizeof(g->Message), "%d bad lines in result", Qrp->BadLines);
PushWarning(g, this);
} // endif Badlines
Init = true; returnfalse;
} // end of Initialize
/***********************************************************************/ /* CAT: Get the number of properties. */ /***********************************************************************/ int TDBCAT::GetMaxSize(PGLOBAL g __attribute__((unused)))
{ if (MaxSize < 0) { // if (Initialize(g)) // return -1;
// MaxSize = Qrp->Nblin;
MaxSize = 10; // To make MariaDB happy
} // endif MaxSize
for (colp = (PCATCOL)Columns; colp; colp = (PCATCOL)colp->GetNext()) { for (crp = Qrp->Colresp; crp; crp = crp->Next) if ((colp->Flag && colp->Flag == crp->Fld) ||
(!colp->Flag && !stricmp(colp->Name, crp->Name))) {
colp->Crp = crp; break;
} // endif Flag
if (!colp->Crp /*&& !colp->GetValue()->IsConstant()*/) {
snprintf(g->Message, sizeof(g->Message), "Invalid flag %d for column %s",
colp->Flag, colp->Name); returntrue;
} elseif (crp->Fld == FLD_SCALE || crp->Fld == FLD_RADIX)
colp->Value->SetNullable(true);
} // endfor colp
returnfalse;
} // end of InitCol
/***********************************************************************/ /* SetRecpos: Replace the table at the specified position. */ /***********************************************************************/ bool TDBCAT::SetRecpos(PGLOBAL, int recpos)
{
N = recpos - 1; returnfalse;
} // end of SetRecpos
/***********************************************************************/ /* Data Base read routine for CAT access method. */ /***********************************************************************/ int TDBCAT::ReadDB(PGLOBAL)
{ return (++N < Qrp->Nblin) ? RC_OK : RC_EF;
} // end of ReadDB
/***********************************************************************/ /* WriteDB: Data Base write routine for CAT access methods. */ /***********************************************************************/ int TDBCAT::WriteDB(PGLOBAL g)
{
strcpy(g->Message, "CAT tables are read only"); return RC_FX;
} // end of WriteDB
/***********************************************************************/ /* Data Base delete line routine for CAT access methods. */ /***********************************************************************/ int TDBCAT::DeleteDB(PGLOBAL g, int)
{
strcpy(g->Message, "Delete not enabled for CAT tables"); return RC_FX;
} // end of DeleteDB
/***********************************************************************/ /* Data Base close routine for WMI access method. */ /***********************************************************************/ void TDBCAT::CloseDB(PGLOBAL)
{ // Nothing to do
} // end of CloseDB
/***********************************************************************/ /* CATCOL public constructor. */ /***********************************************************************/
CATCOL::CATCOL(PCOLDEF cdp, PTDB tdbp, int n)
: COLBLK(cdp, tdbp, n)
{
Tdbp = (PTDBCAT)tdbp;
Crp = NULL;
Flag = cdp->GetOffset();
} // end of WMICOL constructor
/***********************************************************************/ /* Read the next Data Source elements. */ /***********************************************************************/ void CATCOL::ReadColumn(PGLOBAL)
{ bool b = (!Crp->Kdata || Crp->Kdata->IsNull(Tdbp->N));
// Get the value of the Name or Description property if (!b)
Value->SetValue_pvblk(Crp->Kdata, Tdbp->N); else
Value->Reset();