bool BLKFAM::AllocateBuffer(PGLOBAL g) { int len; MODE mode = Tdbp->GetMode(); // For variable length files, Lrecl does not include CRLF len = Lrecl + ((Tdbp->GetFtype()) ? 0 : Ending); Buflen = len * Nrec; CurLine = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen); if (UseTemp || mode == MODE_DELETE) { if (mode == MODE_UPDATE) OutBuf = (char*)PlugSubAlloc(g, NULL, len + 1); Dbflen = Buflen; DelBuf = PlugSubAlloc(g, NULL, Dbflen); } else if (mode == MODE_INSERT) Rbuf = Nrec; // To be used by WriteDB return false; } // end of AllocateBuffer
char *PRXCOL::Decode(PGLOBAL g, const char *cnm) { char *buf= (char*)PlugSubAlloc(g, NULL, strlen(cnm) + 1); uint dummy_errors; uint32 len= copy_and_convert(buf, strlen(cnm) + 1, &my_charset_latin1, cnm, strlen(cnm), &my_charset_utf8_general_ci, &dummy_errors); buf[len]= '\0'; return buf; } // end of Decode
bool CHRBLK::Init(PGLOBAL g, bool check) { Valp = (char*)PlugSubAlloc(g, NULL, Long + 1); Valp[Long] = '\0'; if (!Blkp) if (AllocBuff(g, Nval * Long)) return true; Check = check; Global = g; return false; } // end of Init
char *TDBINI::GetSeclist(PGLOBAL g) { if (trace) htrc("GetSeclist: Seclist=%p\n", Seclist); if (!Seclist) { // Result will be retrieved from the INI file Seclist = (char*)PlugSubAlloc(g, NULL, Seclen); GetPrivateProfileSectionNames(Seclist, Seclen, Ifile); } // endif Seclist return Seclist; } // end of GetSeclist
char *PlugDup(PGLOBAL g, const char *str) { char *buf; size_t len; if (str && (len = strlen(str))) { buf = (char*)PlugSubAlloc(g, NULL, len + 1); strcpy(buf, str); } else buf = NULL; return(buf); } /* end of PlugDup */
bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Module = Cat->GetStringCatInfo(g, "Module", ""); Subtype = Cat->GetStringCatInfo(g, "Subtype", Module); if (!*Module) Module = Subtype; Desc = (char*)PlugSubAlloc(g, NULL, strlen(Module) + strlen(Subtype) + 3); sprintf(Desc, "%s(%s)", Module, Subtype); return false; } // end of DefineAM
void STRBLK::SetValue(PSZ p, int n) { if (p) { if (!Sorted || !n || !Strp[n-1] || strcmp(p, Strp[n-1])) { Strp[n] = (PSZ)PlugSubAlloc(Global, NULL, strlen(p) + 1); strcpy(Strp[n], p); } else Strp[n] = Strp[n-1]; } else Strp[n] = NULL; } // end of SetValue
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i) { if (args->args[i]) { int n = args->lengths[i]; PSZ s = (PSZ)PlugSubAlloc(g, NULL, n + 1); memcpy(s, args->args[i], n); s[n] = 0; return s; } else return NULL; } // end of MakePSZ
char *PlugReadMessage(PGLOBAL g, int mid, char *m) { char msgfile[_MAX_PATH], msgid[32], buff[256]; char *msg; FILE *mfile = NULL; GetPrivateProfileString("Message", msglang, "Message\\english.msg", msgfile, _MAX_PATH, plgini); if (!(mfile = fopen(msgfile, "rt"))) { sprintf(stmsg, "Fail to open message file %s for %s", msgfile, msglang); goto err; } // endif mfile for (;;) if (!fgets(buff, 256, mfile)) { sprintf(stmsg, "Cannot get message %d %s", mid, SVP(m)); goto fin; } else if (atoi(buff) == mid) break; if (sscanf(buff, " %*d %s \"%[^\"]", msgid, stmsg) < 2) { // Old message file if (!sscanf(buff, " %*d \"%[^\"]", stmsg)) { sprintf(stmsg, "Bad message file for %d %s", mid, SVP(m)); goto fin; } else m = NULL; } // endif sscanf if (m && strcmp(m, msgid)) { // Message file is out of date strcpy(stmsg, m); goto fin; } // endif m fin: fclose(mfile); err: if (g) { // Called by STEP msg = (char *)PlugSubAlloc(g, NULL, strlen(stmsg) + 1); strcpy(msg, stmsg); } else // Called by MSG or PlgGetErrorMsg msg = stmsg; return msg; } // end of PlugReadMessage
PSZ ARRAY::MakeArrayList(PGLOBAL g) { char *p, *tp; int i; size_t z, len = 2; if (Type == TYPE_LIST) return "(?" "?" "?)"; // To be implemented z = MY_MAX(24, GetTypeSize(Type, Len) + 4); tp = (char*)PlugSubAlloc(g, NULL, z); for (i = 0; i < Nval; i++) { Value->SetValue_pvblk(Vblp, i); Value->Print(g, tp, z); len += strlen(tp); } // enfor i if (trace) htrc("Arraylist: len=%d\n", len); p = (char *)PlugSubAlloc(g, NULL, len); strcpy(p, "("); for (i = 0; i < Nval;) { Value->SetValue_pvblk(Vblp, i); Value->Print(g, tp, z); strcat(p, tp); strcat(p, (++i == Nval) ? ")" : ","); } // enfor i if (trace) htrc("Arraylist: newlen=%d\n", strlen(p)); return p; } // end of MakeArrayList
void STRBLK::SetValue(char *sp, uint len, int n) { PSZ p; if (sp) { if (!Sorted || !n || !Strp[n-1] || strlen(Strp[n-1]) != len || strncmp(sp, Strp[n-1], len)) { p = (PSZ)PlugSubAlloc(Global, NULL, len + 1); memcpy(p, sp, len); p[len] = 0; } else p = Strp[n-1]; } else p = NULL; Strp[n] = p; } // end of SetValue
void TDBWMI::DoubleSlash(PGLOBAL g) { if (To_CondFil && strchr(To_CondFil->Body, '\\')) { char *body = To_CondFil->Body; char *buf = (char*)PlugSubAlloc(g, NULL, strlen(body) * 2); int i = 0, k = 0; do { if (body[i] == '\\') buf[k++] = '\\'; buf[k++] = body[i]; } while (body[i++]); To_CondFil->Body = buf; } // endif To_CondFil } // end of DoubleSlash
bool ZBKFAM::AllocateBuffer(PGLOBAL g) { Buflen = Nrec * (Lrecl + 2); CurLine = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen); if (Tdbp->GetMode() == MODE_INSERT) { // Set values so Block and Last can be recalculated if (Last == Nrec) { CurBlk = Block; Rbuf = Nrec; // To be used by WriteDB } else { // The last block must be completed CurBlk = Block - 1; Rbuf = Nrec - Last; // To be used by WriteDB } // endif Last } // endif Insert return false; } // end of AllocateBuffer
bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { Nspace = GetStringCatInfo(g, "Namespace", "Root\\CimV2"); Wclass = GetStringCatInfo(g, "Class", (!stricmp(Nspace, "root\\cimv2") ? "ComputerSystemProduct" : !stricmp(Nspace, "root\\cli") ? "Msft_CliAlias" : "")); if (!*Wclass) { sprintf(g->Message, "Missing class name for %s", Nspace); return true; } else if (!strchr(Wclass, '_')) { char *p = (char*)PlugSubAlloc(g, NULL, strlen(Wclass) + 7); Wclass = strcat(strcpy(p, "Win32_"), Wclass); } // endif Wclass if (Catfunc == FNC_NO) Ems = GetIntCatInfo("Estimate", 100); return false; } // end of DefineAM
bool TDBTBM::OpenTables(PGLOBAL g) { int k; THD *thd = current_thd; PTABLE tabp, *ptabp = &Tablist; PTBMT tp, *ptp = &Tmp; // Allocates the TBMT blocks for the tables for (tabp = Tablist; tabp; tabp = tabp->Next) if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL) { // Remove remote table from the local list *ptabp = tabp->Next; // Make the remote table block tp = (PTBMT)PlugSubAlloc(g, NULL, sizeof(TBMT)); memset(tp, 0, sizeof(TBMT)); tp->G = g; tp->Tap = tabp; tp->Thd = thd; // Create the thread that will do the table opening. pthread_attr_init(&tp->attr); // pthread_attr_setdetachstate(&tp->attr, PTHREAD_CREATE_JOINABLE); if ((k = pthread_create(&tp->Tid, &tp->attr, ThreadOpen, tp))) { sprintf(g->Message, "pthread_create error %d", k); Nbc++; continue; } // endif k // Add it to the remote list *ptp = tp; ptp = &tp->Next; Nrc++; // Number of remote connections } else { ptabp = &tabp->Next; Nlc++; // Number of local connections } // endif Type return false; } // end of OpenTables
bool INIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { char buf[8]; Fn = GetStringCatInfo(g, "Filename", NULL); GetCharCatInfo("Layout", "C", buf, sizeof(buf)); Layout = toupper(*buf); if (Fn) { char *p = (char*)PlugSubAlloc(g, NULL, _MAX_PATH); PlugSetPath(p, Fn, GetPath()); Fn = p; } else { strcpy(g->Message, MSG(MISSING_FNAME)); return true; } // endif Fn Ln = GetSizeCatInfo("Secsize", "8K"); Desc = Fn; return false; } // end of DefineAM
bool ZIPFAM::AllocateBuffer(PGLOBAL g) { MODE mode = Tdbp->GetMode(); Buflen = Lrecl + 2; // Lrecl does not include CRLF //Buflen *= ((Mode == MODE_DELETE) ? DOS_BUFF_LEN : 1); NIY if (trace) htrc("SubAllocating a buffer of %d bytes\n", Buflen); To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen); if (mode == MODE_INSERT) { /*******************************************************************/ /* For Insert buffer must be prepared. */ /*******************************************************************/ memset(To_Buf, ' ', Buflen); To_Buf[Buflen - 2] = '\n'; To_Buf[Buflen - 1] = '\0'; } // endif Insert return false; } // end of AllocateBuffer
bool TDBOCCUR::ViewColumnList(PGLOBAL g) { char *pn; int i; PCOL colp, cp; PTDBMY tdbp; if (!Tdbp->IsView()) return false; if (Tdbp->GetAmType() != TYPE_AM_MYSQL) { strcpy(g->Message, "View is not MySQL"); return true; } else tdbp = (PTDBMY)Tdbp; for (cp = Columns; cp; cp = cp->GetNext()) if (cp->GetAmType() == TYPE_AM_PRX) { if ((colp = tdbp->MakeFieldColumn(g, cp->GetName()))) { ((PPRXCOL)cp)->Colp = colp; ((PPRXCOL)cp)->To_Val = colp->GetValue(); } else return true; } // endif Type Col = (PCOL*)PlugSubAlloc(g, NULL, Mult * sizeof(PCOL)); for (i = 0, pn = Colist; i < Mult; i++, pn += (strlen(pn) + 1)) if (!(Col[i] = tdbp->MakeFieldColumn(g, pn))) { // Column not found in table sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname); return true; } // endif Col return false; } // end of ViewColumnList
bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) { int poff = 0; Name = (PSZ)PlugSubAlloc(g, NULL, strlen(name) + 1); strcpy(Name, name); Cat = cat; Catfunc = GetFuncID(Cat->GetStringCatInfo(g, "Catfunc", NULL)); Elemt = cat->GetIntCatInfo("Elements", 0); Multiple = cat->GetIntCatInfo("Multiple", 0); Degree = cat->GetIntCatInfo("Degree", 0); Read_Only = cat->GetBoolCatInfo("ReadOnly", false); const char *data_charset_name= cat->GetStringCatInfo(g, "Data_charset", NULL); m_data_charset= data_charset_name ? get_charset_by_csname(data_charset_name, MY_CS_PRIMARY, 0): NULL; // 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
bool MAPFAM::OpenTableFile(PGLOBAL g) { char filename[_MAX_PATH]; int len; MODE mode = Tdbp->GetMode(); PFBLOCK fp; PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr; #if defined(_DEBUG) // Insert mode is no more handled using file mapping assert(mode != MODE_INSERT); #endif // _DEBUG /*********************************************************************/ /* We used the file name relative to recorded datapath. */ /*********************************************************************/ PlugSetPath(filename, To_File, Tdbp->GetPath()); /*********************************************************************/ /* Under Win32 the whole file will be mapped so we can use it as */ /* if it were entirely read into virtual memory. */ /* Firstly we check whether this file have been already mapped. */ /*********************************************************************/ if (mode == MODE_READ) { for (fp = dbuserp->Openlist; fp; fp = fp->Next) if (fp->Type == TYPE_FB_MAP && !stricmp(fp->Fname, filename) && fp->Count && fp->Mode == mode) break; if (trace) htrc("Mapping file, fp=%p\n", fp); } else fp = NULL; if (fp) { /*******************************************************************/ /* File already mapped. Just increment use count and get pointer. */ /*******************************************************************/ fp->Count++; Memory = fp->Memory; len = fp->Length; } else { /*******************************************************************/ /* If required, delete the whole file if no filtering is implied. */ /*******************************************************************/ bool del; HANDLE hFile; MEMMAP mm; del = mode == MODE_DELETE && !Tdbp->GetNext(); if (del) DelRows = Cardinality(g); /*******************************************************************/ /* Create the mapping file object. */ /*******************************************************************/ hFile = CreateFileMap(g, filename, &mm, mode, del); if (hFile == INVALID_HANDLE_VALUE) { DWORD rc = GetLastError(); if (!(*g->Message)) sprintf(g->Message, MSG(OPEN_MODE_ERROR), "map", (int) rc, filename); if (trace) htrc("CreateFileMap: %s\n", g->Message); return (mode == MODE_READ && rc == ENOENT) ? PushWarning(g, Tdbp) : true; } // endif hFile /*******************************************************************/ /* Get the file size (assuming file is smaller than 4 GB) */ /*******************************************************************/ len = mm.lenL; Memory = (char *)mm.memory; if (!len) { // Empty or deleted file CloseFileHandle(hFile); Tdbp->ResetSize(); return false; } // endif len if (!Memory) { CloseFileHandle(hFile); sprintf(g->Message, MSG(MAP_VIEW_ERROR), filename, GetLastError()); return true; } // endif Memory #if defined(WIN32) if (mode != MODE_DELETE) { #else // !WIN32 if (mode == MODE_READ) { #endif // !WIN32 CloseFileHandle(hFile); // Not used anymore hFile = INVALID_HANDLE_VALUE; // For Fblock } // endif Mode /*******************************************************************/ /* Link a Fblock. This make possible to reuse already opened maps */ /* and also to automatically unmap them in case of error g->jump. */ /* Note: block can already exist for previously closed file. */ /*******************************************************************/ fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK)); fp->Type = TYPE_FB_MAP; fp->Fname = (char*)PlugSubAlloc(g, NULL, strlen(filename) + 1); strcpy((char*)fp->Fname, filename); fp->Next = dbuserp->Openlist; dbuserp->Openlist = fp; fp->Count = 1; fp->Length = len; fp->Memory = Memory; fp->Mode = mode; fp->File = NULL; fp->Handle = hFile; // Used for Delete } // endif fp To_Fb = fp; // Useful when closing /*********************************************************************/ /* The pseudo "buffer" is here the entire file mapping view. */ /*********************************************************************/ Fpos = Mempos = Memory; Top = Memory + len; if (trace) htrc("fp=%p count=%d MapView=%p len=%d Top=%p\n", fp, fp->Count, Memory, len, Top); return AllocateBuffer(g); // Useful for DBF files } // end of OpenTableFile /***********************************************************************/ /* GetRowID: return the RowID of last read record. */ /***********************************************************************/ int MAPFAM::GetRowID(void) { return Rows; } // end of GetRowID /***********************************************************************/ /* GetPos: return the position of last read record. */ /***********************************************************************/ int MAPFAM::GetPos(void) { return Fpos - Memory; } // end of GetPos /***********************************************************************/ /* GetNextPos: return the position of next record. */ /***********************************************************************/ int MAPFAM::GetNextPos(void) { return Mempos - Memory; } // end of GetNextPos /***********************************************************************/ /* SetPos: Replace the table at the specified position. */ /***********************************************************************/ bool MAPFAM::SetPos(PGLOBAL g, int pos) { Fpos = Mempos = Memory + pos; if (Mempos >= Top || Mempos < Memory) { strcpy(g->Message, MSG(INV_MAP_POS)); return true; } // endif Mempos Placed = true; return false; } // end of SetPos
bool TDBPIVOT::GetSourceTable(PGLOBAL g) { if (Tdbp) return false; // Already done if (!Tabsrc && Tabname) { // Get the table description block of this table if (!(Tdbp = GetSubTable(g, ((PPIVOTDEF)To_Def)->Tablep, true))) return true; if (!GBdone) { char *colist; PCOLDEF cdp; if (FindDefaultColumns(g)) return true; // Locate the suballocated colist (size is not known yet) *(colist = (char*)PlugSubAlloc(g, NULL, 0)) = 0; // Make the column list for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) if (!cdp->GetOffset()) strcat(strcat(colist, cdp->GetName()), ", "); // Add the Pivot column at the end of the list strcat(colist, Picol); // Now we know how much was suballocated PlugSubAlloc(g, NULL, strlen(colist) + 1); // Locate the source string (size is not known yet) Tabsrc = (char*)PlugSubAlloc(g, NULL, 0); // Start making the definition strcat(strcat(strcpy(Tabsrc, "SELECT "), colist), ", "); // Make it suitable for Pivot by doing the group by strcat(strcat(Tabsrc, Function), "("); strcat(strcat(strcat(Tabsrc, Fncol), ") "), Fncol); strcat(strcat(Tabsrc, " FROM "), Tabname); strcat(strcat(Tabsrc, " GROUP BY "), colist); if (Tdbp->IsView()) // Until MariaDB bug is fixed strcat(strcat(Tabsrc, " ORDER BY "), colist); // Now we know how much was suballocated PlugSubAlloc(g, NULL, strlen(Tabsrc) + 1); } // endif !GBdone } else if (!Tabsrc) { strcpy(g->Message, MSG(SRC_TABLE_UNDEF)); return true; } // endif if (Tabsrc) { // Get the new table description block of this source table PTABLE tablep = new(g) XTAB("whatever", Tabsrc); tablep->SetQualifier(Database); if (!(Tdbp = GetSubTable(g, tablep, true))) return true; } // endif Tabsrc return false; } // end of GetSourceTable
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) { char *p, *query, *colname, *skc, buf[64]; int rc, ndif, nblin, w = 0; bool b = false; PVAL valp; PQRYRES qrp; PCOLRES *pcrp, crp, fncrp = NULL; // Save stack and allocation environment and prepare error return if (g->jump_level == MAX_JUMP) { strcpy(g->Message, MSG(TOO_MANY_JUMPS)); return NULL; } // endif jump_level if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) { goto err; } // endif rc // Are there columns to skip? if (Skcol) { uint n = strlen(Skcol); skc = (char*)PlugSubAlloc(g, NULL, n + 2); strcpy(skc, Skcol); skc[n + 1] = 0; // Replace ; by nulls in skc for (p = strchr(skc, ';'); p; p = strchr(p, ';')) *p++ = 0; } else skc = NULL; if (!Tabsrc && Tabname) { // Locate the query query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26); sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname); } else if (!Tabsrc) { strcpy(g->Message, MSG(SRC_TABLE_UNDEF)); return NULL; } else query = Tabsrc; // Open a MySQL connection for this table if (Myc.Open(g, Host, Database, User, Pwd, Port)) return NULL; else b = true; // Send the source command to MySQL if (Myc.ExecSQL(g, query, &w) == RC_FX) goto err; // We must have a storage query to get pivot column values if (!(Qryp = Myc.GetResult(g, true))) goto err; if (!Fncol) { for (crp = Qryp->Colresp; crp; crp = crp->Next) if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc)) Fncol = crp->Name; if (!Fncol) { strcpy(g->Message, MSG(NO_DEF_FNCCOL)); goto err; } // endif Fncol } // endif Fncol if (!Picol) { // Find default Picol as the last one not equal to Fncol for (crp = Qryp->Colresp; crp; crp = crp->Next) if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc)) Picol = crp->Name; if (!Picol) { strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); goto err; } // endif Picol } // endif picol // Prepare the column list for (pcrp = &Qryp->Colresp; crp = *pcrp; ) if (SkipColumn(crp, skc)) { // Ignore this column *pcrp = crp->Next; } else if (!stricmp(Picol, crp->Name)) { if (crp->Nulls) { sprintf(g->Message, "Pivot column %s cannot be nullable", Picol); goto err; } // endif Nulls Rblkp = crp->Kdata; *pcrp = crp->Next; } else if (!stricmp(Fncol, crp->Name)) { fncrp = crp; *pcrp = crp->Next; } else pcrp = &crp->Next; if (!Rblkp) { strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); goto err; } else if (!fncrp) { strcpy(g->Message, MSG(NO_DEF_FNCCOL)); goto err; } // endif if (Tabsrc) { Myc.Close(); b = false; // Before calling sort, initialize all nblin = Qryp->Nblin; Index.Size = nblin * sizeof(int); Index.Sub = TRUE; // Should be small enough if (!PlgDBalloc(g, NULL, Index)) return NULL; Offset.Size = (nblin + 1) * sizeof(int); Offset.Sub = TRUE; // Should be small enough if (!PlgDBalloc(g, NULL, Offset)) return NULL; ndif = Qsort(g, nblin); if (ndif < 0) // error return NULL; } else { // The query was limited, we must get pivot column values query = (char*)PlugSubAlloc(g, NULL, 0); sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname); PlugSubAlloc(g, NULL, strlen(query) + 1); Myc.FreeResult(); // Send the source command to MySQL if (Myc.ExecSQL(g, query, &w) == RC_FX) goto err; // We must have a storage query to get pivot column values if (!(qrp = Myc.GetResult(g, true))) goto err; Myc.Close(); b = false; // Get the column list crp = qrp->Colresp; Rblkp = crp->Kdata; ndif = qrp->Nblin; } // endif Tabsrc // Allocate the Value used to retieve column names if (!(valp = AllocateValue(g, Rblkp->GetType(), Rblkp->GetVlen(), Rblkp->GetPrec()))) return NULL; // Now make the functional columns for (int i = 0; i < ndif; i++) { if (i) { crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); memcpy(crp, fncrp, sizeof(COLRES)); } else crp = fncrp; // Get the value that will be the generated column name if (Tabsrc) valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]); else valp->SetValue_pvblk(Rblkp, i); colname = valp->GetCharString(buf); crp->Name = (char*)PlugSubAlloc(g, NULL, strlen(colname) + 1); strcpy(crp->Name, colname); crp->Flag = 1; // Add this column *pcrp = crp; crp->Next = NULL; pcrp = &crp->Next; } // endfor i // We added ndif columns and removed 2 (picol and fncol) Qryp->Nbcol += (ndif - 2); return Qryp; err: if (b) Myc.Close(); return NULL; } // end of MakePivotColumns
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, const char *name, bool& info) { int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING, TYPE_STRING, TYPE_STRING}; XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_REM, FLD_NO, FLD_CHARSET}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32}; char *fld, *colname, *chset, *fmt, v; int i, n, ncol = sizeof(buftyp) / sizeof(int); int prec, len, type, scale; int zconv = GetConvSize(); bool mysql; TABLE_SHARE *s = NULL; Field* *field; Field *fp; PQRYRES qrp; PCOLRES crp; if (!info) { if (!(s = GetTableShare(g, thd, db, name, mysql))) { return NULL; } else if (s->is_view) { strcpy(g->Message, "Use MYSQL type to see columns from a view"); info = true; // To tell caller name is a view free_table_share(s); return NULL; } else n = s->fieldnames.count; } else { n = 0; length[0] = 128; } // endif info /**********************************************************************/ /* Allocate the structures used to refer to the result set. */ /**********************************************************************/ if (!(qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, buftyp, fldtyp, length, false, true))) return NULL; // Some columns must be renamed for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) switch (++i) { case 2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break; case 10: crp->Name = "Date_fmt"; break; case 11: crp->Name = "Collation"; break; } // endswitch i if (info) return qrp; /**********************************************************************/ /* Now get the results into blocks. */ /**********************************************************************/ for (i = 0, field= s->field; *field; field++) { fp= *field; // Get column name crp = qrp->Colresp; // Column_Name colname = (char *)fp->field_name; crp->Kdata->SetValue(colname, i); chset = (char *)fp->charset()->name; v = (!strcmp(chset, "binary")) ? 'B' : 0; if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) { if (v == 'K') { // Skip this column sprintf(g->Message, "Column %s skipped (unsupported type)", colname); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); continue; } // endif v sprintf(g->Message, "Column %s unsupported type", colname); qrp = NULL; break; } // endif type if (v == 'X') { len = zconv; sprintf(g->Message, "Column %s converted to varchar(%d)", colname, len); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); } // endif v crp = crp->Next; // Data_Type crp->Kdata->SetValue(type, i); if (fp->flags & ZEROFILL_FLAG) crp->Nulls[i] = 'Z'; else if (fp->flags & UNSIGNED_FLAG) crp->Nulls[i] = 'U'; else // X means TEXT field crp->Nulls[i] = (v == 'X') ? 'V' : v; crp = crp->Next; // Type_Name crp->Kdata->SetValue(GetTypeName(type), i); fmt = NULL; if (type == TYPE_DATE) { // When creating tables we do need info about date columns if (mysql) { fmt = MyDateFmt(fp->type()); prec = len = strlen(fmt); } else { fmt = (char*)fp->option_struct->dateformat; prec = len = fp->field_length; } // endif mysql } else if (v != 'X') { if (type == TYPE_DECIM) prec = ((Field_new_decimal*)fp)->precision; else prec = fp->field_length; // prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length; len = fp->char_length(); } else prec = len = zconv; crp = crp->Next; // Precision crp->Kdata->SetValue(prec, i); crp = crp->Next; // Length crp->Kdata->SetValue(len, i); crp = crp->Next; // Scale scale = (type == TYPE_DOUBLE || type == TYPE_DECIM) ? fp->decimals() : 0; crp->Kdata->SetValue(scale, i); crp = crp->Next; // Radix crp->Kdata->SetValue(0, i); crp = crp->Next; // Nullable crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i); crp = crp->Next; // Remark // For Valgrind if (fp->comment.length > 0 && (fld = fp->comment.str)) crp->Kdata->SetValue(fld, fp->comment.length, i); else crp->Kdata->Reset(i); crp = crp->Next; // New (date format) crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i); crp = crp->Next; // New (charset) fld = (char *)fp->charset()->name; crp->Kdata->SetValue(fld, i); // Add this item qrp->Nblin++; i++; // Can be skipped } // endfor field /**********************************************************************/ /* Return the result pointer for use by GetData routines. */ /**********************************************************************/ if (s) free_table_share(s); return qrp; } // end of TabColumns
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, const char *ocr, const char *rank) { char *pn, *colist; int i, k, m, n = 0, c = 0; bool rk, b = false; PCOLRES crp, rcrp, *pcrp; if (!col || !*col) { strcpy(g->Message, "Missing colist"); return true; } // endif col // Prepare the column list colist = PlugDup(g, col); m = PrepareColist(colist); if ((rk = (rank && *rank))) for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1)) n = MY_MAX(n, (signed)strlen(pn)); // Default occur column name is the 1st colist column name if (!ocr || !*ocr) ocr = colist; /**********************************************************************/ /* Replace the columns of the colist by the rank and occur columns. */ /**********************************************************************/ for (i = 0, pcrp = &qrp->Colresp; crp = *pcrp; ) { for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1)) if (!stricmp(pn, crp->Name)) break; if (k < m) { // This column belongs to colist c++; if (!b) { if (rk) { // Add the rank column here rcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); memset(rcrp, 0, sizeof(COLRES)); rcrp->Next = crp; rcrp->Name = (char*)rank; rcrp->Type = TYPE_STRING; rcrp->Length = n; rcrp->Ncol = ++i; *pcrp = rcrp; } // endif rk // First remaining listed column, will be the occur column crp->Name = (char*)ocr; b = true; } else { *pcrp = crp->Next; // Remove this column continue; } // endif b } // endif k crp->Ncol = ++i; pcrp = &crp->Next; } // endfor pcrp // Check whether all columns of the list where found if (c < m) { strcpy(g->Message, "Some colist columns are not in the source table"); return true; } // endif crp /**********************************************************************/ /* Set the number of columns of the table. */ /**********************************************************************/ qrp->Nblin = i; return false; } // end of OcrSrcCols
PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname) { IWbemLocator *loc; char *p; HRESULT res; PWMIUT wp = (PWMIUT)PlugSubAlloc(g, NULL, sizeof(WMIUTIL)); if (trace) htrc("WMIColumns class %s space %s\n", SVP(classname), SVP(nsp)); /*********************************************************************/ /* Set default values for the namespace and class name. */ /*********************************************************************/ if (!nsp) nsp = "root\\cimv2"; if (!classname) { if (!stricmp(nsp, "root\\cimv2")) classname = "ComputerSystemProduct"; else if (!stricmp(nsp, "root\\cli")) classname = "Msft_CliAlias"; else { strcpy(g->Message, "Missing class name"); return NULL; } // endif classname } // endif classname /*********************************************************************/ /* Initialize WMI. */ /*********************************************************************/ //res = CoInitializeEx(NULL, COINIT_MULTITHREADED); res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(res)) { sprintf(g->Message, "Failed to initialize COM library. " "Error code = %p", res); return NULL; } // endif res #if 0 // irrelevant for a DLL res = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (res != RPC_E_TOO_LATE && FAILED(res)) { sprintf(g->Message, "Failed to initialize security. " "Error code = %p", res); CoUninitialize(); return NULL; } // endif Res #endif // 0 res = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**) &loc); if (FAILED(res)) { sprintf(g->Message, "Failed to create Locator. " "Error code = %p", res); CoUninitialize(); return NULL; } // endif res res = loc->ConnectServer(_bstr_t(nsp), NULL, NULL, NULL, 0, NULL, NULL, &wp->Svc); if (FAILED(res)) { sprintf(g->Message, "Could not connect. Error code = %p", res); loc->Release(); CoUninitialize(); return NULL; } // endif res loc->Release(); if (trace) htrc("Successfully connected to namespace.\n"); /*********************************************************************/ /* Perform a full class object retrieval. */ /*********************************************************************/ p = (char*)PlugSubAlloc(g, NULL, strlen(classname) + 7); if (strchr(classname, '_')) strcpy(p, classname); else strcat(strcpy(p, "Win32_"), classname); res = wp->Svc->GetObject(bstr_t(p), 0, 0, &wp->Cobj, 0); if (FAILED(res)) { sprintf(g->Message, "failed GetObject %s in %s\n", classname, nsp); wp->Svc->Release(); wp->Svc = NULL; // MUST be set to NULL (why?) return NULL; } // endif res return wp; } // end of InitWMI
void INICOL::AllocBuf(PGLOBAL g) { if (!Valbuf) Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1); } // end of AllocBuf
MULAR::MULAR(PGLOBAL g, int n) : CSORT(FALSE) { Narray = n; Pars = (PARRAY*)PlugSubAlloc(g, NULL, n * sizeof(PARRAY)); } // end of MULAR constructor
bool TDBFMT::OpenDB(PGLOBAL g) { Linenum = 0; if (Mode == MODE_INSERT || Mode == MODE_UPDATE) { sprintf(g->Message, MSG(FMT_WRITE_NIY), "FMT"); return true; // NIY } // endif Mode if (Use != USE_OPEN && Columns) { // Make the formats used to read records PSZ pfm; int i, n; PCSVCOL colp; PCOLDEF cdp; PDOSDEF tdp = (PDOSDEF)To_Def; for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next) if (!colp->IsSpecial() && !colp->IsVirtual()) // a true column Fields = MY_MAX(Fields, (int)colp->Fldnum); if (Columns) Fields++; // Fldnum was 0 based To_Fld = PlugSubAlloc(g, NULL, Lrecl + 1); FldFormat = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields); memset(FldFormat, 0, sizeof(PSZ) * Fields); FmtTest = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields); memset(FmtTest, 0, sizeof(int) * Fields); // Get the column formats for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) if (!cdp->IsVirtual() && (i = cdp->GetOffset() - 1) < Fields) { if (!(pfm = cdp->GetFmt())) { sprintf(g->Message, MSG(NO_FLD_FORMAT), i + 1, Name); return true; } // endif pfm // Roughly check the Fmt format if ((n = strlen(pfm) - 2) < 4) { sprintf(g->Message, MSG(BAD_FLD_FORMAT), i + 1, Name); return true; } // endif n FldFormat[i] = (PSZ)PlugSubAlloc(g, NULL, n + 5); strcpy(FldFormat[i], pfm); if (!strcmp(pfm + n, "%m")) { // This is a field that can be missing. Flag it so it can // be handled with special processing. FldFormat[i][n+1] = 'n'; // To have sscanf normal processing FmtTest[i] = 2; } else if (i+1 < Fields && strcmp(pfm + n, "%n")) { // There are trailing characters after the field contents // add a marker for the next field start position. strcat(FldFormat[i], "%n"); FmtTest[i] = 1; } // endif's } // endif i } // endif Use return TDBCSV::OpenDB(g); } // end of OpenDB
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, int hdr, int mxr, bool info) { static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_LENGTH, FLD_SCALE}; static unsigned int length[] = {6, 6, 8, 10, 10, 6}; char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096]; int i, imax, hmax, n, nerr, phase, blank, digit, dec, type; int ncol = sizeof(buftyp) / sizeof(int); int num_read = 0, num_max = 10000000; // Statistics int len[MAXCOL], typ[MAXCOL], prc[MAXCOL]; FILE *infile; PQRYRES qrp; PCOLRES crp; if (info) { imax = hmax = 0; length[0] = 128; goto skipit; } // endif info // num_max = atoi(p+1); // Max num of record to test #if defined(WIN32) if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6)) dechar = '.'; else dechar = ','; #else // !WIN32 dechar = '.'; #endif // !WIN32 if (trace) htrc("File %s sep=%c q=%c hdr=%d mxr=%d\n", SVP(fn), sep, q, hdr, mxr); if (!fn) { strcpy(g->Message, MSG(MISSING_FNAME)); return NULL; } // endif fn imax = hmax = nerr = 0; mxr = MY_MAX(0, mxr); for (i = 0; i < MAXCOL; i++) { colname[i] = NULL; len[i] = 0; typ[i] = TYPE_UNKNOWN; prc[i] = 0; } // endfor i /*********************************************************************/ /* Open the input file. */ /*********************************************************************/ PlugSetPath(filename, fn, PlgGetDataPath(g)); if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r"))) return NULL; if (hdr) { /*******************************************************************/ /* Make the column names from the first line. */ /*******************************************************************/ phase = 0; if (fgets(buf, sizeof(buf), infile)) { n = strlen(buf) + 1; buf[n - 2] = '\0'; #if defined(UNIX) // The file can be imported from Windows if (buf[n - 3] == '\r') buf[n - 3] = 0; #endif // UNIX p = (char*)PlugSubAlloc(g, NULL, n); memcpy(p, buf, n); //skip leading blanks for (; *p == ' '; p++) ; if (q && *p == q) { // Header is quoted p++; phase = 1; } // endif q colname[0] = p; } else { sprintf(g->Message, MSG(FILE_IS_EMPTY), fn); goto err; } // endif's for (i = 1; *p; p++) if (phase == 1 && *p == q) { *p = '\0'; phase = 0; } else if (*p == sep && !phase) { *p = '\0'; //skip leading blanks for (; *(p+1) == ' '; p++) ; if (q && *(p+1) == q) { // Header is quoted p++; phase = 1; } // endif q colname[i++] = p + 1; } // endif sep num_read++; imax = hmax = i; for (i = 0; i < hmax; i++) length[0] = MY_MAX(length[0], strlen(colname[i])); } // endif hdr for (num_read++; num_read <= num_max; num_read++) { /*******************************************************************/ /* Now start the reading process. Read one line. */ /*******************************************************************/ if (fgets(buf, sizeof(buf), infile)) { n = strlen(buf); buf[n - 1] = '\0'; #if defined(UNIX) // The file can be imported from Windows if (buf[n - 2] == '\r') buf[n - 2] = 0; #endif // UNIX } else if (feof(infile)) { sprintf(g->Message, MSG(EOF_AFTER_LINE), num_read -1); break; } else { sprintf(g->Message, MSG(ERR_READING_REC), num_read, fn); goto err; } // endif's /*******************************************************************/ /* Make the test for field lengths. */ /*******************************************************************/ i = n = phase = blank = digit = dec = 0; for (p = buf; *p; p++) if (*p == sep) { if (phase != 1) { if (i == MAXCOL - 1) { sprintf(g->Message, MSG(TOO_MANY_FIELDS), num_read, fn); goto err; } // endif i if (n) { len[i] = MY_MAX(len[i], n); type = (digit || (dec && n == 1)) ? TYPE_STRING : (dec) ? TYPE_DOUBLE : TYPE_INT; typ[i] = MY_MIN(type, typ[i]); prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]); } // endif n i++; n = phase = blank = digit = dec = 0; } else // phase == 1 n++; } else if (*p == ' ') { if (phase < 2) n++; if (blank) digit = 1; } else if (*p == q) { if (phase == 0) { if (blank) if (++nerr > mxr) { sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read); goto err; } else goto skip; n = 0; phase = digit = 1; } else if (phase == 1) { if (*(p+1) == q) { // This is currently not implemented for CSV tables // if (++nerr > mxr) { // sprintf(g->Message, MSG(QUOTE_IN_QUOTE), num_read); // goto err; // } else // goto skip; p++; n++; } else phase = 2; } else if (++nerr > mxr) { // phase == 2 sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read); goto err; } else goto skip; } else { if (phase == 2) if (++nerr > mxr) { sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read); goto err; } else goto skip; // isdigit cannot be used here because of debug assert if (!strchr("0123456789", *p)) { if (!digit && *p == dechar) dec = 1; // Decimal point found else if (blank || !(*p == '-' || *p == '+')) digit = 1; } else if (dec) dec++; // More decimals n++; blank = 1; } // endif's *p if (phase == 1) if (++nerr > mxr) { sprintf(g->Message, MSG(UNBALANCE_QUOTE), num_read); goto err; } else goto skip; if (n) { len[i] = MY_MAX(len[i], n); type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING : (dec) ? TYPE_DOUBLE : TYPE_INT; typ[i] = MY_MIN(type, typ[i]); prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]); } // endif n imax = MY_MAX(imax, i+1); skip: ; // Skip erroneous line } // endfor num_read if (trace) { htrc("imax=%d Lengths:", imax); for (i = 0; i < imax; i++) htrc(" %d", len[i]); htrc("\n"); } // endif trace fclose(infile); skipit: if (trace) htrc("CSVColumns: imax=%d hmax=%d len=%d\n", imax, hmax, length[0]); /*********************************************************************/ /* Allocate the structures used to refer to the result set. */ /*********************************************************************/ qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3, buftyp, fldtyp, length, false, false); if (info || !qrp) return qrp; qrp->Nblin = imax; /*********************************************************************/ /* Now get the results into blocks. */ /*********************************************************************/ for (i = 0; i < imax; i++) { if (i >= hmax) { sprintf(buf, "COL%.3d", i+1); p = buf; } else p = colname[i]; if (typ[i] == TYPE_UNKNOWN) // Void column typ[i] = TYPE_STRING; crp = qrp->Colresp; // Column Name crp->Kdata->SetValue(p, i); crp = crp->Next; // Data Type crp->Kdata->SetValue(typ[i], i); crp = crp->Next; // Type Name crp->Kdata->SetValue(GetTypeName(typ[i]), i); crp = crp->Next; // Precision crp->Kdata->SetValue(len[i], i); crp = crp->Next; // Length crp->Kdata->SetValue(len[i], i); crp = crp->Next; // Scale (precision) crp->Kdata->SetValue(prc[i], i); } // endfor i /*********************************************************************/ /* Return the result pointer for use by GetData routines. */ /*********************************************************************/ return qrp; err: fclose(infile); return NULL; } // end of CSVCColumns
bool TDBCSV::OpenDB(PGLOBAL g) { bool rc = false; PCOLDEF cdp; PDOSDEF tdp = (PDOSDEF)To_Def; if (Use != USE_OPEN && (Columns || Mode == MODE_UPDATE)) { // Allocate the storage used to read (or write) records int i, len; PCSVCOL colp; if (!Fields) // May have been set in TABFMT::OpenDB if (Mode != MODE_UPDATE && Mode != MODE_INSERT) { for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next) if (!colp->IsSpecial() && !colp->IsVirtual()) Fields = MY_MAX(Fields, (int)colp->Fldnum); if (Columns) Fields++; // Fldnum was 0 based } else for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) if (!cdp->IsVirtual()) Fields++; Offset = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields); Fldlen = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields); if (Mode == MODE_INSERT || Mode == MODE_UPDATE) { Field = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields); Fldtyp = (bool*)PlugSubAlloc(g, NULL, sizeof(bool) * Fields); } // endif Mode for (i = 0; i < Fields; i++) { Offset[i] = 0; Fldlen[i] = 0; if (Field) { Field[i] = NULL; Fldtyp[i] = false; } // endif Field } // endfor i if (Field) // Prepare writing fields if (Mode != MODE_UPDATE) { for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next) if (!colp->IsSpecial() && !colp->IsVirtual()) { i = colp->Fldnum; len = colp->GetLength(); Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1); Field[i][len] = '\0'; Fldlen[i] = len; Fldtyp[i] = IsTypeNum(colp->GetResultType()); } // endif colp } else // MODE_UPDATE for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) if (!cdp->IsVirtual()) { i = cdp->GetOffset() - 1; len = cdp->GetLength(); Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1); Field[i][len] = '\0'; Fldlen[i] = len; Fldtyp[i] = IsTypeNum(cdp->GetType()); } // endif cdp } // endif Use if (Header) { // Check that the Lrecl is at least equal to the header line length int headlen = 0; PCOLDEF cdp; PDOSDEF tdp = (PDOSDEF)To_Def; for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) headlen += strlen(cdp->GetName()) + 3; // 3 if names are quoted if (headlen > Lrecl) { Lrecl = headlen; Txfp->Lrecl = headlen; } // endif headlen } // endif Header Nerr = 0; rc = TDBDOS::OpenDB(g); if (!rc && Mode == MODE_UPDATE && To_Kindex) // Because KINDEX::Init is executed in mode READ, we must restore // the Fldlen array that was modified when reading the table file. for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) Fldlen[cdp->GetOffset() - 1] = cdp->GetLength(); return rc; } // end of OpenDB