/************* RelDef CPP Program Source Code File (.CPP) **************/ /* PROGRAM NAME: RELDEF */ /* ------------- */ /* Version 1.7 */ /* */ /* COPYRIGHT: */ /* ---------- */ /* (C) Copyright to the author Olivier BERTRAND 2004-2019 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ /* This program are the DB definition related routines. */ /* */ /***********************************************************************/
/***********************************************************************/ /* OEMColumns: Get table column info for an OEM table. */ /***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
{ typedef PQRYRES(__stdcall* XCOLDEF) (PGLOBAL, void*, char*, char*, bool); constchar* module, * subtype; char c, soname[_MAX_PATH], getname[40] = "Col"; #ifdefined(_WIN32)
HANDLE hdll; /* Handle to the external DLL */ #else// !_WIN32 void* hdll; /* Handle for the loaded shared library */ #endif// !_WIN32
XCOLDEF coldef = NULL;
PQRYRES qrp = NULL;
module = topt->module;
subtype = topt->subtype;
if (!module || !subtype) return NULL;
/*********************************************************************/ /* Ensure that the .dll doesn't have a path. */ /* This is done to ensure that only approved dll from the system */ /* directories are used (to make this even remotely secure). */ /*********************************************************************/ if (check_valid_path(module, strlen(module))) {
safe_strcpy(g->Message, sizeof(g->Message), "Module cannot contain a path"); return NULL;
} elseif (strlen(subtype)+1+3 >= sizeof(getname)) {
safe_strcpy(g->Message, sizeof(g->Message), "Subtype string too long"); return NULL;
} else
PlugSetPath(soname, module, GetPluginDir());
// The exported name is always in uppercase for (int i = 0; ; i++) {
c = subtype[i];
getname[i + 3] = toupper(c); if (!c) break;
} // endfor i
#ifdefined(_WIN32) // Load the Dll implementing the table if (!(hdll = LoadLibrary(soname))) { char buf[256];
DWORD rc = GetLastError();
// Get the function returning an instance of the external DEF class if (!(coldef = (XCOLDEF)GetProcAddress((HINSTANCE)hdll, getname))) {
snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), GetLastError(), getname);
FreeLibrary((HMODULE)hdll); return NULL;
} // endif coldef #else// !_WIN32 constchar* error = NULL;
// Get the function returning an instance of the external DEF class if (!(coldef = (XCOLDEF)dlsym(hdll, getname))) {
error = dlerror();
snprintf(g->Message, sizeof(g->Message), MSG(GET_FUNC_ERR), getname, SVP(error));
dlclose(hdll); return NULL;
} // endif coldef #endif// !_WIN32
// Just in case the external Get function does not set error messages
snprintf(g->Message, sizeof(g->Message), "Error getting column info from %s", subtype);
// Get the table column definition
qrp = coldef(g, topt, tab, db, info);
/* --------------------------- Class RELDEF -------------------------- */
/***********************************************************************/ /* RELDEF Constructor. */ /***********************************************************************/
RELDEF::RELDEF(void)
{
Next = NULL;
To_Cols = NULL;
Name = NULL;
Database = NULL;
Cat = NULL;
Hc = NULL;
} // end of RELDEF constructor
/***********************************************************************/ /* This function return a pointer to the Table Option Struct. */ /***********************************************************************/
PTOS RELDEF::GetTopt(void)
{ return Hc->GetTableOptionStruct();
} // end of GetTopt
/***********************************************************************/ /* This function sets an integer table information. */ /***********************************************************************/ bool RELDEF::SetIntCatInfo(PCSZ what, int n)
{ return Hc->SetIntegerOption(what, n);
} // end of SetIntCatInfo
/***********************************************************************/ /* This function returns integer table information. */ /***********************************************************************/ int RELDEF::GetIntCatInfo(PCSZ what, int idef)
{ int n= Hc->GetIntegerOption(what);
return (n == NO_IVAL) ? idef : n;
} // end of GetIntCatInfo
/***********************************************************************/ /* This function returns Boolean table information. */ /***********************************************************************/ bool RELDEF::GetBoolCatInfo(PCSZ what, bool bdef)
{ bool b= Hc->GetBooleanOption(what, bdef);
return b;
} // end of GetBoolCatInfo
/***********************************************************************/ /* This function returns size catalog information. */ /***********************************************************************/ int RELDEF::GetSizeCatInfo(PCSZ what, PCSZ sdef)
{ char c;
PCSZ s; 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; // fall through case'K':
n *= 1024;
} // endswitch c
return n;
} // end of GetSizeCatInfo
/***********************************************************************/ /* This function sets char table information in buf. */ /***********************************************************************/ int RELDEF::GetCharCatInfo(PCSZ what, PCSZ sdef, char *buf, int size)
{
PCSZ s= Hc->GetStringOption(what);
strncpy(buf, ((s) ? s : sdef), size); return size;
} // end of GetCharCatInfo
/***********************************************************************/ /* To be used by any TDB's. */ /***********************************************************************/ bool RELDEF::Partitioned(void)
{ return Hc->IsPartitioned();
} // end of Partitioned
/***********************************************************************/ /* This function returns string table information. */ /* Default parameter is "*" to get the handler default. */ /***********************************************************************/ char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
{ char *sval = NULL;
PCSZ name, s= Hc->GetStringOption(what, sdef);
if (s) { if (!Hc->IsPartitioned() ||
(stricmp(what, "filename") && stricmp(what, "tabname")
&& stricmp(what, "connect")))
sval= PlugDup(g, s); else
sval= (char*)s;
} elseif (!stricmp(what, "filename")) { // Return default file name
PCSZ ftype= Hc->GetStringOption("Type", "*"); int i, n;
// Do the definition of AM specific fields if (DefineAM(g, am, 0)) returntrue;
// Get The column definitions if (stricmp(am, "OEM") && GetColCatInfo(g) < 0) returntrue;
Hc->tshp = NULL; // TO BE CHECKED returnfalse;
} // end of Define
/***********************************************************************/ /* This function returns the database data path. */ /***********************************************************************/
PCSZ TABDEF::GetPath(void)
{ return (Database) ? Database : (Hc) ? Hc->GetDataPath() : NULL;
} // end of GetPath
/***********************************************************************/ /* This function returns column table information. */ /***********************************************************************/ int TABDEF::GetColCatInfo(PGLOBAL g)
{ char *type = GetStringCatInfo(g, "Type", "*"); char c, fty, eds; int i, n, loff, poff, nof, nlg; void *field = NULL;
RECFM trf;
PCOLDEF cdp, lcdp = NULL, tocols= NULL;
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
memset(pcf, 0, sizeof(COLINFO));
// Get the table format
trf = GetTableFormat(type);
// Take care of the column definitions
i= poff= nof= nlg= 0;
#ifdefined(_WIN32) // Offsets of HTML and DIR tables start from 0, DBF at 1
loff= (trf == RECFM_DBF) ? 1 : (trf == RECFM_XML || trf == RECFM_DIR) ? -1 : 0; #else// !_WIN32 // Offsets of HTML tables start from 0, DIR and DBF at 1
loff = (trf == RECFM_DBF || trf == RECFM_DIR) ? 1 : (trf == RECFM_XML) ? -1 : 0; #endif// !_WIN32
while (true) { // Default Offset depends on table format switch (trf ) { case RECFM_VAR: case RECFM_FIX: case RECFM_BIN: case RECFM_VCT: case RECFM_DBF:
poff= loff + nof; // Default next offset
nlg= MY_MAX(nlg, poff); // Default lrecl break; case RECFM_CSV: case RECFM_FMT:
nlg+= nof; /* falls through */ case RECFM_DIR: case RECFM_XML:
poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1); break; //case RECFM_INI: //case RECFM_MAC: //case RECFM_TBL: //case RECFM_XCL: //case RECFM_OCCUR: //case RECFM_PRX: case RECFM_OEM:
poff = 0; // Offset represents an independent flag break; default: // PLG ODBC JDBC MYSQL WMI...
poff = 0; // NA break;
} // endswitch trf
// do {
field= Hc->GetColumnOption(g, field, pcf); // } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
if (trf == RECFM_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) { // DBF date format defaults to 'YYYMMDD'
pcf->Datefmt= "YYYYMMDD";
pcf->Length= 8;
} // endif trf
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
loff= cdp->GetOffset();
switch (trf ) { case RECFM_VCT:
cdp->SetOffset(0); // Not to have shift /* falls through */ case RECFM_BIN: // BIN/VEC are packed by default if (nof) { // Field width is the internal representation width // that can also depend on the column format
fty = cdp->Decode ? 'C' : 'X';
eds = 0;
n = 0;
if (cdp->Fmt && !cdp->Decode) { for (i = 0; cdp->Fmt[i]; i++) {
c = toupper(cdp->Fmt[i]);
if (isdigit(c))
n = (n * 10 + (c - '0')); elseif (c == 'L' || c == 'B' || c == 'H')
eds = c; else
fty = c;
} // endfor i
} // endif Fmt
if (n)
nof = n; elseswitch (fty) { case'X': if (eds && IsTypeChar(cdp->Buf_Type))
nof = sizeof(longlong); else
nof= cdp->Clen;
// Degree is the the number of defined columns (informational) if (i != GetDegree())
SetDegree(i);
if (GetDefType() == TYPE_AM_DOS) { int ending, recln= 0;
ending = Hc->GetIntegerOption("Ending");
// Calculate the default record size switch (trf ) { case RECFM_FIX: case RECFM_BIN:
recln= nlg + ending; // + length of line ending break; case RECFM_VCT:
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 RECFM_VAR: case RECFM_DBF:
recln= nlg; break; case RECFM_CSV: case RECFM_FMT: // 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 default: break;
} // endswitch trf
// lrecl must be at least recln to avoid buffer overflow if (trace(1))
htrc("Lrecl: Calculated=%d defined=%d\n",
recln, Hc->GetIntegerOption("Lrecl"));
// Attach the column definition to the tabdef
SetCols(tocols); return poff;
} // end of GetColCatInfo
/***********************************************************************/ /* SetIndexInfo: retrieve index description from the table structure. */ /***********************************************************************/ void TABDEF::SetIndexInfo(void)
{ // Attach new index(es)
SetIndx(Hc->GetIndexInfo());
} // end of SetIndexInfo
/* --------------------------- Class OEMDEF -------------------------- */
/*********************************************************************/ /* Ensure that the module name doesn't have a path. */ /* This is done to ensure that only approved libs from the system */ /* directories are used (to make this even remotely secure). */ /*********************************************************************/ if (check_valid_path(Module, strlen(Module))) {
safe_strcpy(g->Message, sizeof(g->Message), "Module cannot contain a path"); return NULL;
} elseif (strlen(Subtype)+1+3 >= sizeof(getname)) {
safe_strcpy(g->Message, sizeof(g->Message), "Subtype string too long"); return NULL;
} else // PlugSetPath(soname, Module, GetPluginDir()); // Crashes on Fedora
snprintf(soname, sizeof(soname), "%s%s", GetPluginDir(), Module);
#ifdefined(_WIN32) // Is the DLL already loaded? if (!Hdll && !(Hdll = GetModuleHandle(soname))) // No, load the Dll implementing the function if (!(Hdll = LoadLibrary(soname))) { char buf[256];
DWORD rc = GetLastError();
// The exported name is always in uppercase for (int i = 0; ; i++) {
c = Subtype[i];
getname[i + 3] = toupper(c); if (!c) break;
} // endfor i
// Get the function returning an instance of the external DEF class if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) { char buf[256];
DWORD rc = GetLastError();
// The exported name is always in uppercase for (int i = 0; ; i++) {
c = Subtype[i];
getname[i + 3] = toupper(c); if (!c) break;
} // endfor i
// Get the function returning an instance of the external DEF class if (!(getdef = (XGETDEF)dlsym(Hdll, getname))) {
error = dlerror();
snprintf(g->Message, sizeof(g->Message), MSG(GET_FUNC_ERR), getname, SVP(error));
dlclose(Hdll); return NULL;
} // endif getdef #endif// !_WIN32
// Just in case the external Get function does not set error messages
snprintf(g->Message, sizeof(g->Message), MSG(DEF_ALLOC_ERROR), Subtype);
// Get the table definition block if (!(xdefp = getdef(g, NULL))) return NULL;
// Have the external class do its complete definition if (!cat->Cbuf) { // Suballocate a temporary buffer for the entire column section
cat->Cblen = GetSizeCatInfo("Colsize", "8K");
cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen);
} // endif Cbuf
// Ok, return external block return xdefp;
} // end of GetXdef
#if0 /***********************************************************************/ /* DeleteTableFile: Delete an OEM table file if applicable. */ /***********************************************************************/ bool OEMDEF::DeleteTableFile(PGLOBAL g)
{ if (!Pxdef)
Pxdef = GetXdef(g);
return (Pxdef) ? Pxdef->DeleteTableFile(g) : true;
} // end of DeleteTableFile #endif// 0
// If define block not here yet, get it now if (!Pxdef && !(Pxdef = GetXdef(g))) returntrue; // Error
// Here "OEM" should be replace by a more useful value return Pxdef->Define(g, Cat, Name, Schema, Subtype);
} // end of DefineAM
/***********************************************************************/ /* GetTable: makes a new Table Description Block. */ /***********************************************************************/
PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
{
PTDB tdbp = NULL;
// If define block not here yet, get it now if (!Pxdef && !(Pxdef = GetXdef(g))) return NULL; // Error
/*********************************************************************/ /* Allocate a TDB of the proper type. */ /* Column blocks will be allocated only when needed. */ /*********************************************************************/ if (!(tdbp = Pxdef->GetTable(g, mode))) return NULL; elseif (Multiple && tdbp->GetFtype() == RECFM_OEM)
tdbp = new(g) TDBMUL(tdbp); // No block optimization yet
#if0 /*********************************************************************/ /* The OEM table is based on a file type (currently DOS+ only) */ /*********************************************************************/
assert (rfm == RECFM_VAR || rfm == RECFM_FIX ||
rfm == RECFM_BIN || rfm == RECFM_VCT);
/***********************************************************************/ /* Define: initialize a column definition from a COLINFO structure. */ /***********************************************************************/ int COLDEF::Define(PGLOBAL g, void *, PCOLINFO cfp, int poff)
{
Name = (PSZ)PlugDup(g, cfp->Name);
if (cfp->Remark && *cfp->Remark)
Desc = (PSZ)PlugDup(g, cfp->Remark);
if (cfp->Datefmt)
Decode = (PSZ)PlugDup(g, cfp->Datefmt);
} else
Offset = poff;
if (cfp->Fieldfmt)
Fmt = (PSZ)PlugDup(g, cfp->Fieldfmt);
Flags = cfp->Flags; return (Flags & (U_VIRTUAL|U_SPECIAL)) ? 0 : Long;
} // end of Define
/* ------------------------- End of RelDef --------------------------- */
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.26Bemerkung:
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.