diff options
Diffstat (limited to 'storage/connect/reldef.cpp')
-rw-r--r-- | storage/connect/reldef.cpp | 957 |
1 files changed, 957 insertions, 0 deletions
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp new file mode 100644 index 00000000..9af9faa3 --- /dev/null +++ b/storage/connect/reldef.cpp @@ -0,0 +1,957 @@ +/************* 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. */ +/* */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant MariaDB header file. */ +/***********************************************************************/ +#include "my_global.h" +#if defined(_WIN32) +#include <sqlext.h> +#else +//#include <dlfcn.h> // dlopen(), dlclose(), dlsym() ... +#include "osutil.h" +//#include "sqlext.h" +#endif +#include "handler.h" + +/***********************************************************************/ +/* Include application header files */ +/* */ +/* global.h is header containing all global declarations. */ +/* plgdbsem.h is header containing DB application declarations. */ +/* catalog.h is header containing DB description declarations. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "reldef.h" +#include "colblk.h" +#include "tabcol.h" +#include "filamap.h" +#include "filamfix.h" +#if defined(VCT_SUPPORT) +#include "filamvct.h" +#endif // VCT_SUPPORT +#if defined(GZ_SUPPORT) +#include "filamgz.h" +#endif // GZ_SUPPORT +#include "tabdos.h" +#include "valblk.h" +#include "tabmul.h" +#include "ha_connect.h" +#include "mycat.h" + +#if !defined(_WIN32) +extern handlerton *connect_hton; +#endif // !_WIN32 + +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +USETEMP UseTemp(void); +char *GetPluginDir(void); +PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info); + +/***********************************************************************/ +/* 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); + const char* module, * subtype; + char c, soname[_MAX_PATH], getname[40] = "Col"; +#if defined(_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; + } + else if (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 + +#if defined(_WIN32) + // Load the Dll implementing the table + if (!(hdll = LoadLibrary(soname))) { + char buf[256]; + DWORD rc = GetLastError(); + + snprintf(g->Message, sizeof(g->Message), MSG(DLL_LOAD_ERROR), rc, soname); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)buf, sizeof(buf), NULL); + safe_strcat(g->Message, sizeof(g->Message), ": "); + safe_strcat(g->Message, sizeof(g->Message), buf); + return NULL; + } // endif hDll + +// 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 + const char* error = NULL; + + // Load the desired shared library + if (!(hdll = dlopen(soname, RTLD_LAZY))) { + error = dlerror(); + snprintf(g->Message, sizeof(g->Message), MSG(SHARED_LIB_ERR), soname, SVP(error)); + return NULL; + } // endif Hdll + +// 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); + +#if defined(_WIN32) + FreeLibrary((HMODULE)hdll); +#else // !_WIN32 + dlclose(hdll); +#endif // !_WIN32 + + return qrp; +} // end of OEMColumns + +/* --------------------------- 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; + + } else if (!stricmp(what, "filename")) { + // Return default file name + PCSZ ftype= Hc->GetStringOption("Type", "*"); + int i, n; + + if (IsFileType(GetTypeID(ftype))) { + name= Hc->GetPartName(); + sval= (char*)PlugSubAlloc(g, NULL, strlen(name) + 12); + snprintf(sval, strlen(name) + 12, "%s.", name); + n= strlen(sval); + + // Fold ftype to lower case + for (i= 0; i < 12; i++) + if (!ftype[i]) { + sval[n+i]= 0; + break; + } else + sval[n+i]= tolower(ftype[i]); + + } // endif FileType + + } // endif s + + return sval; + } // end of GetStringCatInfo + +/* --------------------------- Class TABDEF -------------------------- */ + +/***********************************************************************/ +/* TABDEF Constructor. */ +/***********************************************************************/ +TABDEF::TABDEF(void) + { + Schema = NULL; + Desc = NULL; + Recfm = RECFM_DFLT; + Catfunc = FNC_NO; + Card = 0; + Elemt = 0; + Sort = 0; + Multiple = 0; + Degree = 0; + Pseudo = 0; + Read_Only = false; + m_data_charset = NULL; + csname = NULL; + } // end of TABDEF constructor + +/***********************************************************************/ +/* Return the table format. */ +/***********************************************************************/ +RECFM TABDEF::GetTableFormat(const char* type) +{ + RECFM recfm = Recfm; + + if (Catfunc != FNC_NO) + recfm = RECFM_NAF; + else if (recfm == RECFM_DFLT) + // Default format depends on the table type + switch (GetTypeID(type)) { + case TAB_DOS: recfm = RECFM_VAR; break; + case TAB_CSV: recfm = RECFM_CSV; break; + case TAB_FMT: recfm = RECFM_FMT; break; + case TAB_FIX: recfm = RECFM_FIX; break; + case TAB_BIN: recfm = RECFM_BIN; break; + case TAB_VEC: recfm = RECFM_VCT; break; + case TAB_DBF: recfm = RECFM_DBF; break; + case TAB_XML: recfm = RECFM_XML; break; + case TAB_DIR: recfm = RECFM_DIR; break; + default: recfm = RECFM_NAF; break; + } // endswitch type + + return recfm; +} // end of GetTableFormat + +/***********************************************************************/ +/* Define: initialize the table definition block from XDB file. */ +/***********************************************************************/ +bool TABDEF::Define(PGLOBAL g, PCATLG cat, + LPCSTR name, LPCSTR schema, LPCSTR am) +{ + Hc = ((MYCAT*)cat)->GetHandler(); + Name = (PSZ)name; + Schema = (PSZ)Hc->GetDBName(schema); + Cat = cat; + Catfunc = GetFuncID(GetStringCatInfo(g, "Catfunc", NULL)); + Elemt = GetIntCatInfo("Elements", 0); + Multiple = GetIntCatInfo("Multiple", 0); + Degree = GetIntCatInfo("Degree", 0); + Read_Only = GetBoolCatInfo("ReadOnly", false); + const char *data_charset_name= GetStringCatInfo(g, "Data_charset", NULL); + m_data_charset= data_charset_name ? + get_charset_by_csname(data_charset_name, MY_CS_PRIMARY, + MYF(MY_UTF8_IS_UTF8MB3)): + NULL; + csname = GetStringCatInfo(g, "Table_charset", NULL); + + // Do the definition of AM specific fields + if (DefineAM(g, am, 0)) + return true; + + // Get The column definitions + if (stricmp(am, "OEM") && GetColCatInfo(g) < 0) + return true; + + Hc->tshp = NULL; // TO BE CHECKED + return false; +} // 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; + +#if defined(_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 independant 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')); + else if (c == 'L' || c == 'B' || c == 'H') + eds = c; + else + fty = c; + + } // endfor i + + } // endif Fmt + + if (n) + nof = n; + else switch (fty) { + case 'X': + if (eds && IsTypeChar(cdp->Buf_Type)) + nof = sizeof(longlong); + else + nof= cdp->Clen; + + break; + case 'C': break; + case 'R': + case 'F': nof = sizeof(float); break; + case 'I': nof = sizeof(int); break; + case 'D': nof = sizeof(double); break; + case 'S': nof = sizeof(short); break; + case 'T': nof = sizeof(char); break; + case 'G': nof = sizeof(longlong); break; + default: /* Wrong format */ + snprintf(g->Message, sizeof(g->Message), "Invalid format %c", fty); + return -1; + } // endswitch fty + + } // endif nof + + default: + break; + } // endswitch trf + + if (lcdp) + lcdp->SetNext(cdp); + else + tocols= cdp; + + lcdp= cdp; + i++; + } // endwhile + + // 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")); + + recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl")); + Hc->SetIntegerOption("Lrecl", recln); + ((PDOSDEF)this)->SetLrecl(recln); + + if (trace(1)) + htrc("Lrecl set to %d\n", recln); + + } // endif TYPE + + // 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 -------------------------- */ + +/***********************************************************************/ +/* GetXdef: get the external TABDEF from OEM module. */ +/***********************************************************************/ +PTABDEF OEMDEF::GetXdef(PGLOBAL g) + { + typedef PTABDEF (__stdcall *XGETDEF) (PGLOBAL, void *); + char c, soname[_MAX_PATH], getname[40] = "Get"; + PTABDEF xdefp; + XGETDEF getdef = NULL; + PCATLG cat = Cat; + + /*********************************************************************/ + /* 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; + } else +// PlugSetPath(soname, Module, GetPluginDir()); // Crashes on Fedora + snprintf(soname, sizeof(soname), "%s%s", GetPluginDir(), Module); + +#if defined(_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(); + + snprintf(g->Message, sizeof(g->Message), MSG(DLL_LOAD_ERROR), rc, soname); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)buf, sizeof(buf), NULL); + safe_strcat(g->Message, sizeof(g->Message), ": "); + safe_strcat(g->Message, sizeof(g->Message), buf); + return NULL; + } // endif hDll + + // 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(); + + snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), rc, getname); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)buf, sizeof(buf), NULL); + safe_strcat(g->Message, sizeof(g->Message), ": "); + safe_strcat(g->Message, sizeof(g->Message), buf); + FreeLibrary((HMODULE)Hdll); + return NULL; + } // endif getdef +#else // !_WIN32 + const char *error = NULL; + +#if 0 // Don't know what all this stuff does + Dl_info dl_info; + + // The OEM lib must retrieve exported CONNECT variables + if (dladdr(&connect_hton, &dl_info)) { + if (dlopen(dl_info.dli_fname, RTLD_NOLOAD | RTLD_NOW | RTLD_GLOBAL) == 0) { + error = dlerror(); + snprintf(g->Message, sizeof(g->Message), "dlopen failed: %s, OEM not supported", SVP(error)); + return NULL; + } // endif dlopen + + } else { + error = dlerror(); + snprintf(g->Message, sizeof(g->Message), "dladdr failed: %s, OEM not supported", SVP(error)); + return NULL; + } // endif dladdr +#endif // 0 + + // Load the desired shared library + if (!Hdll && !(Hdll = dlopen(soname, RTLD_LAZY))) { + error = dlerror(); + snprintf(g->Message, sizeof(g->Message), MSG(SHARED_LIB_ERR), soname, SVP(error)); + return NULL; + } // endif Hdll + + // 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 + +#if 0 +/***********************************************************************/ +/* 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 + +/***********************************************************************/ +/* Define: initialize the table definition block from XDB file. */ +/***********************************************************************/ +bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int) + { + Module = GetStringCatInfo(g, "Module", ""); + Subtype = GetStringCatInfo(g, "Subtype", Module); + + if (!*Module) + Module = Subtype; + + char *desc = (char*)PlugSubAlloc(g, NULL, strlen(Module) + + strlen(Subtype) + 3); + sprintf(desc, "%s(%s)", Module, Subtype); + Desc = desc; + + // If define block not here yet, get it now + if (!Pxdef && !(Pxdef = GetXdef(g))) + return true; // 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; + else if (Multiple && tdbp->GetFtype() == RECFM_OEM) + tdbp = new(g) TDBMUL(tdbp); // No block optimization yet + +#if 0 + /*********************************************************************/ + /* 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); + + PTXF txfp = NULL; + PDOSDEF defp = (PDOSDEF)Pxdef; + bool map = defp->Mapped && mode != MODE_INSERT && + !(UseTemp() == TMP_FORCE && + (mode == MODE_UPDATE || mode == MODE_DELETE)); + int cmpr = defp->Compressed; + + /*********************************************************************/ + /* Allocate table and file processing class of the proper type. */ + /* Column blocks will be allocated only when needed. */ + /*********************************************************************/ + if (!((PTDBDOS)tdbp)->GetTxfp()) { + if (cmpr) { +#if defined(GZ_SUPPORT) + if (cmpr == 1) + txfp = new(g) GZFAM(defp); + else + txfp = new(g) ZLBFAM(defp); +#else // !GZ_SUPPORT + safe_strcpy(g->Message, sizeof(g->Message), "Compress not supported"); + return NULL; +#endif // !GZ_SUPPORT + } else if (rfm == RECFM_VAR) { + if (map) + txfp = new(g) MAPFAM(defp); + else + txfp = new(g) DOSFAM(defp); + + } else if (rfm == RECFM_FIX || rfm == RECFM_BIN) { + if (map) + txfp = new(g) MPXFAM(defp); + else + txfp = new(g) FIXFAM(defp); + } else if (rfm == RECFM_VCT) { +#if defined(VCT_SUPPORT) + assert(Pxdef->GetDefType() == TYPE_AM_VCT); + + if (map) + txfp = new(g) VCMFAM((PVCTDEF)defp); + else + txfp = new(g) VCTFAM((PVCTDEF)defp); +#else // !VCT_SUPPORT + safe_strcpy(g->Message, sizeof(g->Message), "VCT no more supported"); + return NULL; +#endif // !VCT_SUPPORT + } // endif's + + ((PTDBDOS)tdbp)->SetTxfp(txfp); + } // endif Txfp + + if (Multiple) + tdbp = new(g) TDBMUL(tdbp); +#endif // 0 + return tdbp; + } // end of GetTable + +/* --------------------------- Class COLCRT -------------------------- */ + +/***********************************************************************/ +/* COLCRT Constructors. */ +/***********************************************************************/ +COLCRT::COLCRT(PSZ name) + { + Next = NULL; + Name = name; + Desc = NULL; + Decode = NULL; + Fmt = NULL; + Offset = -1; + Long = -1; + Precision = -1; + Freq = -1; + Key = -1; + Scale = -1; + Opt = -1; + DataType = '*'; + } // end of COLCRT constructor for table creation + +COLCRT::COLCRT(void) + { + Next = NULL; + Name = NULL; + Desc = NULL; + Decode = NULL; + Fmt = NULL; + Offset = 0; + Long = 0; + Precision = 0; + Freq = 0; + Key = 0; + Scale = 0; + Opt = 0; + DataType = '*'; + } // end of COLCRT constructor for table & view definition + +/* --------------------------- Class COLDEF -------------------------- */ + +/***********************************************************************/ +/* COLDEF Constructor. */ +/***********************************************************************/ +COLDEF::COLDEF(void) : COLCRT() + { + To_Min = NULL; + To_Max = NULL; + To_Pos = NULL; + Xdb2 = FALSE; + To_Bmap = NULL; + To_Dval = NULL; + Ndv = 0; + Nbm = 0; + Buf_Type = TYPE_ERROR; + Clen = 0; + Poff = 0; + memset(&F, 0, sizeof(FORMAT)); + Flags = 0; + } // end of COLDEF constructor + +/***********************************************************************/ +/* 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->Flags & U_SPECIAL)) { + Poff = poff; + Buf_Type = cfp->Type; + + if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) < 0) { + snprintf(g->Message, sizeof(g->Message), MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name); + return -1; + } // endswitch + + safe_strcpy(F.Type, sizeof(F.Type), GetFormatType(Buf_Type)); + F.Length = cfp->Length; + F.Prec = cfp->Scale; + Offset = (cfp->Offset < 0) ? poff : cfp->Offset; + Precision = cfp->Precision; + Scale = cfp->Scale; + Long = cfp->Length; + Opt = cfp->Opt; + Key = cfp->Key; + Freq = cfp->Freq; + + 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 --------------------------- */ |