/************* RelDef CPP Program Source Code File (.CPP) **************/ /* PROGRAM NAME: REFDEF */ /* ------------- */ /* Version 1.3 */ /* */ /* COPYRIGHT: */ /* ---------- */ /* (C) Copyright to the author Olivier BERTRAND 2004-2012 */ /* */ /* 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 #else #include // dlopen(), dlclose(), dlsym() ... #include "osutil.h" //#include "sqlext.h" #endif /***********************************************************************/ /* 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 "filamap.h" #include "filamfix.h" #include "filamvct.h" #if defined(ZIP_SUPPORT) #include "filamzip.h" #endif // ZIP_SUPPORT #include "tabdos.h" #include "valblk.h" #include "tabmul.h" /***********************************************************************/ /* External static variables. */ /***********************************************************************/ //extern "C" char plgini[]; /* --------------------------- Class RELDEF -------------------------- */ /***********************************************************************/ /* RELDEF Constructor. */ /***********************************************************************/ RELDEF::RELDEF(void) { Next = NULL; To_Cols = NULL; Name = NULL; Database = NULL; Cat = NULL; } // end of RELDEF constructor /* --------------------------- Class TABDEF -------------------------- */ /***********************************************************************/ /* TABDEF Constructor. */ /***********************************************************************/ TABDEF::TABDEF(void) { Owner = NULL; Desc = NULL; Card = 0; Elemt = 0; Sort = 0; Multiple = 0; Degree = 0; Pseudo = 0; Read_Only = false; } // end of TABDEF constructor /***********************************************************************/ /* Define: initialize the table definition block from XDB file. */ /***********************************************************************/ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) { char buf[8]; int poff = 0; void *memp = cat->Descp; Name = (PSZ)PlugSubAlloc(g, memp, strlen(name) + 1); strcpy(Name, name); Cat = cat; Elemt = cat->GetIntCatInfo(name, "Elements", 0); Multiple = cat->GetIntCatInfo(name, "Multiple", 0); Degree = cat->GetIntCatInfo(name, "Degree", 0); cat->GetCharCatInfo(name, "ReadOnly", "No", buf, sizeof(buf)); Read_Only = (toupper(*buf) == 'Y'); // Get The column definitions if ((poff = cat->GetColCatInfo(g, this)) < 0) return true; // Do the definition of AM specific fields return DefineAM(g, am, poff); } // end of Define /* --------------------------- Class OEMDEF -------------------------- */ /***********************************************************************/ /* GetXdef: get the external TABDEF from OEM module. */ /***********************************************************************/ PTABDEF OEMDEF::GetXdef(PGLOBAL g) { typedef PTABDEF (__stdcall *XGETDEF) (PGLOBAL, void *); char c, getname[40] = "Get"; PTABDEF xdefp; XGETDEF getdef = NULL; PCATLG cat = Cat; void *memp = cat->Descp; #if defined(WIN32) // Is the DLL already loaded? if (!Hdll && !(Hdll = GetModuleHandle(Module))) // No, load the Dll implementing the function if (!(Hdll = LoadLibrary(Module))) { char buf[256]; DWORD rc = GetLastError(); sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, Module); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, (LPTSTR)buf, sizeof(buf), NULL); strcat(strcat(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))) { sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname); FreeLibrary((HMODULE)Hdll); return NULL; } // endif getdef #else // !WIN32 const char *error = NULL; // Is the library already loaded? // if (!Hdll && !(Hdll = ???)) // Load the desired shared library if (!(Hdll = dlopen(Module, RTLD_LAZY))) { error = dlerror(); sprintf(g->Message, MSG(SHARED_LIB_ERR), Module, 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(); sprintf(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 sprintf(g->Message, MSG(DEF_ALLOC_ERROR), Subtype); // Get the table definition block if (!(xdefp = getdef(g, memp))) return NULL; // Have the external class do its complete definition if (!cat->Cbuf) { // Suballocate a temporary buffer for the entire column section cat->Cblen = cat->GetSizeCatInfo("Database", "Colsize", "8K"); cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen); } // endif Cbuf // Here "OEM" should be replace by a more useful value if (xdefp->Define(g, cat, Name, "OEM")) return NULL; // Ok, return external block return xdefp; } // end of GetXdef /***********************************************************************/ /* 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 /***********************************************************************/ /* Define: initialize the table definition block from XDB file. */ /***********************************************************************/ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { void *memp = Cat->Descp; Module = Cat->GetStringCatInfo(g, Name, "Module", ""); Subtype = Cat->GetStringCatInfo(g, Name, "Subtype", Module); if (!*Module) Module = Subtype; Desc = (char*)PlugSubAlloc(g, memp, strlen(Module) + strlen(Subtype) + 3); sprintf(Desc, "%s(%s)", Module, Subtype); return false; } // end of DefineAM /***********************************************************************/ /* GetTable: makes a new Table Description Block. */ /***********************************************************************/ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) { RECFM rfm; PTDBASE 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 = (PTDBASE)Pxdef->GetTable(g, mode))) return NULL; else rfm = tdbp->GetFtype(); if (rfm == RECFM_NAF) return tdbp; else if (rfm == RECFM_OEM) { if (Multiple) tdbp = new(g) TDBMUL(tdbp); // No block optimization yet return tdbp; } // endif OEM /*********************************************************************/ /* 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 && !(PlgGetUser(g)->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(ZIP_SUPPORT) if (cmpr == 1) txfp = new(g) ZIPFAM(defp); else { strcpy(g->Message, "Compress 2 not supported yet"); // txfp = new(g) ZLBFAM(defp); return NULL; } // endelse #else // !ZIP_SUPPORT strcpy(g->Message, "Compress not supported"); return NULL; #endif // !ZIP_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_FIX) { if (map) txfp = new(g) MPXFAM(defp); else txfp = new(g) FIXFAM(defp); } else if (rfm == RECFM_VCT) { assert (Pxdef->GetDefType() == TYPE_AM_VCT); if (map) txfp = new(g) VCMFAM((PVCTDEF)defp); else txfp = new(g) VCTFAM((PVCTDEF)defp); } // endif's ((PTDBDOS)tdbp)->SetTxfp(txfp); } // endif Txfp if (Multiple) tdbp = new(g) TDBMUL(tdbp); 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; //Freq = -1; Key = -1; Prec = -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; //Freq = 0; Key = 0; Prec = 0; Opt = 0; DataType = '*'; } // end of COLCRT constructor for table & view definition /* --------------------------- Class COLDEF -------------------------- */ /***********************************************************************/ /* COLDEF Constructor. */ /***********************************************************************/ COLDEF::COLDEF(void) : COLCRT() { 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 *memp, PCOLINFO cfp, int poff) { Name = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Name) + 1); strcpy(Name, cfp->Name); Poff = poff; Buf_Type = cfp->Type; if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) <= 0) { sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name); return -1; } // endswitch strcpy(F.Type, GetFormatType(Buf_Type)); F.Length = cfp->Length; F.Prec = cfp->Prec; Offset = (cfp->Offset < 0) ? poff : cfp->Offset; Long = cfp->Length; Opt = cfp->Opt; Key = cfp->Key; //Freq = cfp->Freq; if (cfp->Remark && *cfp->Remark) { Desc = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Remark) + 1); strcpy(Desc, cfp->Remark); } // endif Remark if (cfp->Datefmt) { Decode = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Datefmt) + 1); strcpy(Decode, cfp->Datefmt); } // endif Datefmt if (cfp->Fieldfmt) { Fmt = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Fieldfmt) + 1); strcpy(Fmt, cfp->Fieldfmt); } // endif Fieldfmt Flags = cfp->Flags; return (Flags & U_VIRTUAL) ? 0 : Long; } // end of Define /* ------------------------- End of RelDef --------------------------- */