diff options
Diffstat (limited to 'storage/connect/table.cpp')
-rw-r--r-- | storage/connect/table.cpp | 805 |
1 files changed, 805 insertions, 0 deletions
diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp new file mode 100644 index 00000000..b0b5b86c --- /dev/null +++ b/storage/connect/table.cpp @@ -0,0 +1,805 @@ +/************** Table C++ Functions Source Code File (.CPP) ************/ +/* Name: TABLE.CPP Version 2.8 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */ +/* */ +/* This file contains the TBX, TDB and OPJOIN classes functions. */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant MariaDB header file. */ +/***********************************************************************/ +#include "my_global.h" +#include "sql_string.h" + +/***********************************************************************/ +/* Include required application header files */ +/* global.h is header containing all global Plug declarations. */ +/* plgdbsem.h is header containing the DB applic. declarations. */ +/* xobject.h is header containing XOBJECT derived classes declares. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "xtable.h" +#include "tabcol.h" +#include "filamtxt.h" +#include "tabdos.h" +//#include "catalog.h" +#include "reldef.h" + +int TDB::Tnum = 0; + +/***********************************************************************/ +/* Utility routines. */ +/***********************************************************************/ +void NewPointer(PTABS, void *, void *); +void AddPointer(PTABS, void *); + +/* ---------------------------- class TDB ---------------------------- */ + +/***********************************************************************/ +/* TDB public constructors. */ +/***********************************************************************/ +TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum) +{ + To_Def = tdp; + Use = USE_NO; + To_Orig = NULL; + To_Filter = NULL; + To_CondFil = NULL; + Cond = NULL; + Next = NULL; + Name = (tdp) ? tdp->GetName() : NULL; + To_Table = NULL; + Columns = NULL; + To_SetCols = NULL; + Degree = (tdp) ? tdp->GetDegree() : 0; + Mode = MODE_ANY; + Cardinal = -1; + MaxSize = -1; + Read_Only = (tdp) ? tdp->IsReadOnly() : false; + m_data_charset = (tdp) ? tdp->data_charset() : NULL; + csname = (tdp) ? tdp->csname : NULL; +} // end of TDB standard constructor + +TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum) +{ + To_Def = tdbp->To_Def; + Use = tdbp->Use; + To_Orig = tdbp; + To_Filter = NULL; + To_CondFil = NULL; + Cond = NULL; + Next = NULL; + Name = tdbp->Name; + To_Table = tdbp->To_Table; + Columns = NULL; + To_SetCols = tdbp->To_SetCols; // ??? + Degree = tdbp->Degree; + Mode = tdbp->Mode; + Cardinal = tdbp->Cardinal; + MaxSize = tdbp->MaxSize; + Read_Only = tdbp->IsReadOnly(); + m_data_charset = tdbp->data_charset(); + csname = tdbp->csname; +} // end of TDB copy constructor + +// 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)) + return true; // Special column to ignore while inserting + + return false; // 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; + + if (trace(1)) + htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n", + GetAmType(), SVP(name), Name, num); + + 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 + else if (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; + else if (!(cdp->Flags & U_SPECIAL)) + colp = MakeCol(g, cdp, cprec, i); + else if (Mode != MODE_INSERT) + colp = InsertSpcBlk(g, cdp); + + if (trace(1)) + htrc("colp=%p\n", colp); + + if (name || num) + break; + else if (colp && !colp->IsSpecial()) + cprec = colp; + + } // endif Name + + return (colp); +} // end of ColDB + +/***********************************************************************/ +/* 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); + + if (!stricmp(name, "FILEID") || !stricmp(name, "FDISK") || + !stricmp(name, "FPATH") || !stricmp(name, "FNAME") || + !stricmp(name, "FTYPE") || !stricmp(name, "SERVID")) { + if (!To_Def || !(To_Def->GetPseudo() & 2)) { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_SPEC_COLUMN)); + return NULL; + } // endif Pseudo + + if (!stricmp(name, "FILEID")) + colp = new(g)FIDBLK(cp, OP_XX); + else if (!stricmp(name, "FDISK")) + colp = new(g)FIDBLK(cp, OP_FDISK); + else if (!stricmp(name, "FPATH")) + colp = new(g)FIDBLK(cp, OP_FPATH); + else if (!stricmp(name, "FNAME")) + colp = new(g)FIDBLK(cp, OP_FNAME); + else if (!stricmp(name, "FTYPE")) + colp = new(g)FIDBLK(cp, OP_FTYPE); + else + colp = new(g)SIDBLK(cp); + + } else if (!stricmp(name, "TABID")) { + colp = new(g)TIDBLK(cp); + } else if (!stricmp(name, "PARTID")) { + colp = new(g)PRTBLK(cp); + //} else if (!stricmp(name, "CONID")) { + // colp = new(g) CIDBLK(cp); + } else if (!stricmp(name, "ROWID")) { + colp = new(g)RIDBLK(cp, false); + } else if (!stricmp(name, "ROWNUM")) { + colp = new(g)RIDBLK(cp, true); + } else { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_SPECIAL_COL), name); + return NULL; + } // endif's name + + if (!(colp = InsertSpecialColumn(colp))) { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_SPECIAL_COL), name); + return NULL; + } // endif Insert + + return (colp); +} // end of InsertSpcBlk + +/***********************************************************************/ +/* 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())); + return 0; + } // end of RowNumber + +PTDB TDB::Copy(PTABS t) + { + PTDB tp, tdb1, tdb2 = NULL, outp = NULL; +//PGLOBAL g = t->G; // Is this really useful ??? + + for (tdb1 = this; tdb1; tdb1 = tdb1->Next) { + tp = tdb1->Clone(t); + + if (!outp) + outp = tp; + else + tdb2->Next = tp; + + tdb2 = tp; + NewPointer(t, tdb1, tdb2); + } // endfor tdb1 + + return outp; + } // end of Copy + +/***********************************************************************/ +/* SetRecpos: Replace the table at the specified position. */ +/***********************************************************************/ +bool TDB::SetRecpos(PGLOBAL g, int) +{ + strcpy(g->Message, MSG(SETRECPOS_NIY)); + return true; +} // end of SetRecpos + +void TDB::Printf(PGLOBAL g, FILE *f, uint n) + { + PCOL cp; + char m[64]; + + memset(m, ' ', n); // Make margin string + m[n] = '\0'; + + for (PTDB tp = this; tp; tp = tp->Next) { + fprintf(f, "%sTDB (%p) %s no=%d use=%d type=%d\n", m, + tp, tp->Name, tp->Tdb_No, tp->Use, tp->GetAmType()); + + tp->PrintAM(f, m); + fprintf(f, "%s Columns (deg=%d):\n", m, tp->Degree); + + for (cp = tp->Columns; cp; cp = cp->GetNext()) + cp->Printf(g, f, n); + + } /* endfor tp */ + + } // end of Printf + +void TDB::Prints(PGLOBAL, char *ps, uint) + { + sprintf(ps, "R%d.%s", Tdb_No, Name); + } // end of Prints + +/* -------------------------- class TDBASE --------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBASE class. This is the base class to all */ +/* classes for tables that can be joined together. */ +/***********************************************************************/ +TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp) + { +//To_Def = tdp; + To_Link = NULL; + To_Key_Col = NULL; + To_Kindex = NULL; + To_Xdp = NULL; +//To_SetCols = NULL; + Ftype = RECFM_NAF; +//MaxSize = -1; + Knum = 0; +//Read_Only = (tdp) ? tdp->IsReadOnly() : false; +//m_data_charset= (tdp) ? tdp->data_charset() : NULL; +//csname = (tdp) ? tdp->csname : NULL; + } // end of TDBASE constructor + +TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp) + { +//To_Def = tdbp->To_Def; + To_Link = tdbp->To_Link; + To_Key_Col = tdbp->To_Key_Col; + To_Kindex = tdbp->To_Kindex; + To_Xdp = tdbp->To_Xdp; +//To_SetCols = tdbp->To_SetCols; // ??? + Ftype = tdbp->Ftype; +//MaxSize = tdbp->MaxSize; + Knum = tdbp->Knum; +//Read_Only = tdbp->Read_Only; +//m_data_charset= tdbp->m_data_charset; +//csname = tdbp->csname; + } // end of TDBASE copy constructor + +/***********************************************************************/ +/* 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 + +#if 0 +/***********************************************************************/ +/* 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)) + return true; // Special column to ignore while inserting + + return false; // 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; + + if (trace(1)) + htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n", + GetAmType(), SVP(name), Name, num); + + 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 + else if (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; + else if (!(cdp->Flags & U_SPECIAL)) + colp = MakeCol(g, cdp, cprec, i); + else if (Mode != MODE_INSERT) + colp = InsertSpcBlk(g, cdp); + + if (trace(1)) + htrc("colp=%p\n", colp); + + if (name || num) + break; + else if (colp && !colp->IsSpecial()) + cprec = colp; + + } // endif Name + + return (colp); + } // end of ColDB + +/***********************************************************************/ +/* 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); + + if (!stricmp(name, "FILEID") || !stricmp(name, "FDISK") || + !stricmp(name, "FPATH") || !stricmp(name, "FNAME") || + !stricmp(name, "FTYPE") || !stricmp(name, "SERVID")) { + if (!To_Def || !(To_Def->GetPseudo() & 2)) { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_SPEC_COLUMN)); + return NULL; + } // endif Pseudo + + if (!stricmp(name, "FILEID")) + colp = new(g) FIDBLK(cp, OP_XX); + else if (!stricmp(name, "FDISK")) + colp = new(g) FIDBLK(cp, OP_FDISK); + else if (!stricmp(name, "FPATH")) + colp = new(g) FIDBLK(cp, OP_FPATH); + else if (!stricmp(name, "FNAME")) + colp = new(g) FIDBLK(cp, OP_FNAME); + else if (!stricmp(name, "FTYPE")) + colp = new(g) FIDBLK(cp, OP_FTYPE); + else + colp = new(g) SIDBLK(cp); + + } else if (!stricmp(name, "TABID")) { + colp = new(g) TIDBLK(cp); + } else if (!stricmp(name, "PARTID")) { + colp = new(g) PRTBLK(cp); +//} else if (!stricmp(name, "CONID")) { +// colp = new(g) CIDBLK(cp); + } else if (!stricmp(name, "ROWID")) { + colp = new(g) RIDBLK(cp, false); + } else if (!stricmp(name, "ROWNUM")) { + colp = new(g) RIDBLK(cp, true); + } else { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_SPECIAL_COL), name); + return NULL; + } // endif's name + + if (!(colp = InsertSpecialColumn(colp))) { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_SPECIAL_COL), name); + return NULL; + } // endif Insert + + 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 + +#if 0 +/***********************************************************************/ +/* SetRecpos: Replace the table at the specified position. */ +/***********************************************************************/ +bool TDBASE::SetRecpos(PGLOBAL g, int) + { + strcpy(g->Message, MSG(SETRECPOS_NIY)); + return true; + } // 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 + +#if 0 +/***********************************************************************/ +/* 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 + +/***********************************************************************/ +/* Allocate CAT column description block. */ +/***********************************************************************/ +PCOL TDBCAT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) + { + PCATCOL colp; + + colp = (PCATCOL)new(g) CATCOL(cdp, this, n); + + if (cprec) { + colp->SetNext(cprec->GetNext()); + cprec->SetNext(colp); + } else { + colp->SetNext(Columns); + Columns = colp; + } // endif cprec + + return colp; + } // end of MakeCol + +/***********************************************************************/ +/* Initialize: Get the result query block. */ +/***********************************************************************/ +bool TDBCAT::Initialize(PGLOBAL g) + { + if (Init) + return false; + + if (!(Qrp = GetResult(g))) + return true; + + 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; + return false; + } // 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 + + return MaxSize; + } // end of GetMaxSize + +/***********************************************************************/ +/* CAT Access Method opening routine. */ +/***********************************************************************/ +bool TDBCAT::OpenDB(PGLOBAL g) + { + if (Use == USE_OPEN) { + /*******************************************************************/ + /* Table already open. */ + /*******************************************************************/ + N = -1; + return false; + } // endif use + + if (Mode != MODE_READ) { + /*******************************************************************/ + /* ODBC Info tables cannot be modified. */ + /*******************************************************************/ + strcpy(g->Message, "CAT tables are read only"); + return true; + } // endif Mode + + /*********************************************************************/ + /* Initialize the ODBC processing. */ + /*********************************************************************/ + if (Initialize(g)) + return true; + + Use = USE_OPEN; + return InitCol(g); + } // end of OpenDB + +/***********************************************************************/ +/* Initialize columns. */ +/***********************************************************************/ +bool TDBCAT::InitCol(PGLOBAL g) + { + PCATCOL colp; + PCOLRES crp; + + 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); + return true; + } else if (crp->Fld == FLD_SCALE || crp->Fld == FLD_RADIX) + colp->Value->SetNullable(true); + + } // endfor colp + + return false; + } // end of InitCol + +/***********************************************************************/ +/* SetRecpos: Replace the table at the specified position. */ +/***********************************************************************/ +bool TDBCAT::SetRecpos(PGLOBAL, int recpos) + { + N = recpos - 1; + return false; + } // 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 functions ---------------------------- + +/***********************************************************************/ +/* 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(); + + Value->SetNull(b); + } // end of ReadColumn + |