int TDBWMI::GetMaxSize(PGLOBAL g) { if (MaxSize < 0) { /*******************************************************************/ /* Loop enumerating to get the count. This is prone to last a */ /* very long time for some classes such as DataFile, this is why */ /* we just return an estimated value that will be ajusted later. */ /*******************************************************************/ MaxSize = Ems; #if 0 if (Initialize(g)) return -1; else if (GetWMIInfo(g)) return -1; else MaxSize = 0; PDBUSER dup = PlgGetUser(g); while (Enumerator) { Res = Enumerator->Next(WBEM_INFINITE, 1, &ClsObj, &Rc); if (Rc == 0) break; MaxSize++; } // endwile Enumerator Res = Enumerator->Reset(); #endif // 0 } // endif MaxSize return MaxSize; } // end of GetMaxSize
bool TDBCSV::IsUsingTemp(PGLOBAL g) { USETEMP usetemp = PlgGetUser(g)->UseTemp; return (usetemp == TMP_YES || usetemp == TMP_FORCE || (usetemp == TMP_AUTO && Mode == MODE_UPDATE)); } // end of IsUsingTemp
bool DBFFAM::OpenTableFile(PGLOBAL g) { char opmode[4], filename[_MAX_PATH]; //int ftype = Tdbp->GetFtype(); MODE mode = Tdbp->GetMode(); PDBUSER dbuserp = PlgGetUser(g); switch (mode) { case MODE_READ: strcpy(opmode, "rb"); break; case MODE_DELETE: if (!Tdbp->GetNext()) { // Store the number of deleted lines DelRows = -1; // Means all lines deleted // DelRows = Cardinality(g); no good because of soft deleted lines // This will erase the entire file strcpy(opmode, "w"); Tdbp->ResetSize(); Records = 0; break; } // endif // Selective delete, pass thru case MODE_UPDATE: UseTemp = Tdbp->IsUsingTemp(g); strcpy(opmode, (UseTemp) ? "rb" : "r+b"); break; case MODE_INSERT: // Must be in text mode to remove an eventual EOF character strcpy(opmode, "a+"); break; default: sprintf(g->Message, MSG(BAD_OPEN_MODE), mode); return true; } // endswitch Mode // Now open the file stream PlugSetPath(filename, To_File, Tdbp->GetPath()); if (!(Stream = PlugOpenFile(g, filename, opmode))) { if (trace) htrc("%s\n", g->Message); return (mode == MODE_READ && errno == ENOENT) ? PushWarning(g, Tdbp) : true; } // endif Stream if (trace) htrc("File %s is open in mode %s\n", filename, opmode); To_Fb = dbuserp->Openlist; // Keep track of File block /*********************************************************************/ /* Allocate the line buffer. For mode Delete a bigger buffer has to */ /* be allocated because is it also used to move lines into the file.*/ /*********************************************************************/ return AllocateBuffer(g); } // end of OpenTableFile
PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) { PTDBASE tdbp; if (Catfunc != FNC_COL) { USETEMP tmp = PlgGetUser(g)->UseTemp; bool map = Mapped && mode != MODE_INSERT && !(tmp != TMP_NO && mode == MODE_UPDATE) && !(tmp == TMP_FORCE && (mode == MODE_UPDATE || mode == MODE_DELETE)); PTXF txfp; /*******************************************************************/ /* Allocate a file processing class of the proper type. */ /*******************************************************************/ if (map) { // Should be now compatible with UNIX txfp = new(g) MAPFAM(this); } else if (Compressed) { #if defined(ZIP_SUPPORT) if (Compressed == 1) txfp = new(g) ZIPFAM(this); else { strcpy(g->Message, "Compress 2 not supported yet"); return NULL; } // endelse #else // !ZIP_SUPPORT strcpy(g->Message, "Compress not supported"); return NULL; #endif // !ZIP_SUPPORT } else txfp = new(g) DOSFAM(this); /*******************************************************************/ /* Allocate a TDB of the proper type. */ /* Column blocks will be allocated only when needed. */ /*******************************************************************/ if (!Fmtd) tdbp = new(g) TDBCSV(this, txfp); else tdbp = new(g) TDBFMT(this, txfp); if (Multiple) tdbp = new(g) TDBMUL(tdbp); } else tdbp = new(g)TDBCCL(this); return tdbp; } // end of GetTable
PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode) { /*********************************************************************/ /* Allocate a TDB of the proper type. */ /* Column blocks will be allocated only when needed. */ /*********************************************************************/ // Mapping not used for insert (except for true VEC not split tables) // or when UseTemp is forced bool map = Mapped && (Estimate || mode != MODE_INSERT) && !(PlgGetUser(g)->UseTemp == TMP_FORCE && (mode == MODE_UPDATE || mode == MODE_DELETE)); PTXF txfp; PTDB tdbp; if (Multiple) { strcpy(g->Message, MSG(NO_MUL_VCT)); return NULL; } // endif Multiple if (Split) { if (map) txfp = new(g) VMPFAM(this); else txfp = new(g) VECFAM(this); } else if (Huge) txfp = new(g) BGVFAM(this); else if (map) txfp = new(g) VCMFAM(this); else txfp = new(g) VCTFAM(this); tdbp = new(g) TDBVCT(this, txfp); /*********************************************************************/ /* For block tables, get eventually saved optimization values. */ /*********************************************************************/ if (mode != MODE_INSERT) if (tdbp->GetBlockValues(g)) PushWarning(g, (PTDBASE)tdbp); // return NULL; // causes a crash when deleting index return tdbp; } // end of GetTable
bool DOSFAM::OpenTempFile(PGLOBAL g) { char tempname[_MAX_PATH]; bool rc = false; /*********************************************************************/ /* Open the temporary file, Spos is at the beginning of file. */ /*********************************************************************/ PlugSetPath(tempname, To_File, Tdbp->GetPath()); strcat(PlugRemoveType(tempname, tempname), ".t"); if (!(T_Stream = PlugOpenFile(g, tempname, "wb"))) { if (trace) htrc("%s\n", g->Message); rc = true; } else To_Fbt = PlgGetUser(g)->Openlist; return rc; } // end of OpenTempFile
int DOSFAM::RenameTempFile(PGLOBAL g) { char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH]; int rc; if (!To_Fbt) return RC_INFO; // Nothing to do ??? // This loop is necessary because, in case of join, // To_File can have been open several times. for (PFBLOCK fb = PlgGetUser(g)->Openlist; fb; fb = fb->Next) if (fb == To_Fb || fb == To_Fbt) rc = PlugCloseFile(g, fb); tempname = (char*)To_Fbt->Fname; PlugSetPath(filename, To_File, Tdbp->GetPath()); strcat(PlugRemoveType(filetemp, filename), ".ttt"); remove(filetemp); // May still be there from previous error if (rename(filename, filetemp)) { // Save file for security sprintf(g->Message, MSG(RENAME_ERROR), filename, filetemp, strerror(errno)); rc = RC_FX; } else if (rename(tempname, filename)) { sprintf(g->Message, MSG(RENAME_ERROR), tempname, filename, strerror(errno)); rc = rename(filetemp, filename); // Restore saved file rc = RC_FX; } else if (remove(filetemp)) { sprintf(g->Message, MSG(REMOVE_ERROR), filetemp, strerror(errno)); rc = RC_INFO; // Acceptable } else rc = RC_OK; return rc; } // end of RenameTempFile
bool DOSFAM::OpenTableFile(PGLOBAL g) { char opmode[4], filename[_MAX_PATH]; //int ftype = Tdbp->GetFtype(); MODE mode = Tdbp->Mode; PDBUSER dbuserp = PlgGetUser(g); // This is required when using Unix files under Windows Bin = (Ending == 1); switch (mode) { case MODE_READ: strcpy(opmode, "r"); break; case MODE_DELETE: if (!Tdbp->Next) { // Store the number of deleted lines DelRows = Cardinality(g); if (Blocked) { // Cardinality must return 0 Block = 0; Last = Nrec; } // endif blocked // This will erase the entire file strcpy(opmode, "w"); Tdbp->ResetSize(); break; } // endif // Selective delete, pass thru Bin = true; case MODE_UPDATE: if ((UseTemp = Tdbp->IsUsingTemp(g))) { strcpy(opmode, "r"); Bin = true; } else strcpy(opmode, "r+"); break; case MODE_INSERT: strcpy(opmode, "a+"); break; default: sprintf(g->Message, MSG(BAD_OPEN_MODE), mode); return true; } // endswitch Mode // For blocked I/O or for moving lines, open the table in binary strcat(opmode, (Blocked || Bin) ? "b" : "t"); // Now open the file stream PlugSetPath(filename, To_File, Tdbp->GetPath()); if (!(Stream = PlugOpenFile(g, filename, opmode))) { if (trace) htrc("%s\n", g->Message); return (mode == MODE_READ && errno == ENOENT) ? PushWarning(g, Tdbp) : true; } // endif Stream if (trace) htrc("File %s open Stream=%p mode=%s\n", filename, Stream, opmode); To_Fb = dbuserp->Openlist; // Keep track of File block /*********************************************************************/ /* Allocate the line buffer. For mode Delete a bigger buffer has to */ /* be allocated because is it also used to move lines into the file.*/ /*********************************************************************/ return AllocateBuffer(g); } // end of OpenTableFile
PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db, const char *user, const char *pwd, const char *table, const char *colpat, int port, bool info) { int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING}; XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA, FLD_CHARSET}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0}; char *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16]; int i, n, nf, ncol = sizeof(buftyp) / sizeof(int); int len, type, prec, rc, k = 0; PQRYRES qrp; PCOLRES crp; MYSQLC myc; if (!port) port = mysqld_port; if (!info) { /********************************************************************/ /* Open the connection with the MySQL server. */ /********************************************************************/ if (myc.Open(g, host, db, user, pwd, port)) return NULL; /********************************************************************/ /* Do an evaluation of the result size. */ /********************************************************************/ STRING cmd(g, 64, "SHOW FULL COLUMNS FROM "); bool b = cmd.Append((PSZ)table); b |= cmd.Append(" FROM "); b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName)); if (colpat) { b |= cmd.Append(" LIKE "); b |= cmd.Append((PSZ)colpat); } // endif colpat if (b) { strcpy(g->Message, "Out of memory"); return NULL; } // endif b if (trace) htrc("MyColumns: cmd='%s'\n", cmd.GetStr()); if ((n = myc.GetResultSize(g, cmd.GetStr())) < 0) { myc.Close(); return NULL; } // endif n /********************************************************************/ /* Get the size of the name and default columns. */ /********************************************************************/ length[0] = myc.GetFieldLength(0); // length[10] = myc.GetFieldLength(5); } 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 4: crp->Name = "Length"; break; case 5: crp->Name = "Key"; break; case 10: crp->Name = "Date_fmt"; break; case 11: crp->Name = "Default"; break; case 12: crp->Name = "Extra"; break; case 13: crp->Name = "Collation"; break; } // endswitch i if (info) return qrp; /**********************************************************************/ /* Now get the results into blocks. */ /**********************************************************************/ for (i = 0; i < n; /*i++*/) { if ((rc = myc.Fetch(g, -1)) == RC_FX) { myc.Close(); return NULL; } else if (rc == RC_EF) break; // Get column name colname = myc.GetCharField(0); crp = qrp->Colresp; // Column_Name crp->Kdata->SetValue(colname, i); // Get type, type name, precision, unsigned and zerofill chset = myc.GetCharField(2); fld = myc.GetCharField(1); prec = 0; len = 0; v = (chset && !strcmp(chset, "binary")) ? 'B' : 0; *uns = 0; *zero = 0; switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) { case 3: nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero); break; case 2: nf = sscanf(fld, "%[^(](%d) %s %s", buf, &len, uns, zero) + 1; break; case 1: nf = sscanf(fld, "%s %s %s", buf, uns, zero) + 2; break; default: sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld); myc.Close(); return NULL; } // endswitch nf if ((type = MYSQLtoPLG(buf, &v)) == TYPE_ERROR) { if (v == 'K') { // Skip this column sprintf(g->Message, "Column %s skipped (unsupported type %s)", colname, buf); PushWarning(g, thd); continue; } // endif v sprintf(g->Message, "Column %s unsupported type %s", colname, buf); myc.Close(); return NULL; } else if (type == TYPE_STRING) { if (v == 'X') { len = GetConvSize(); sprintf(g->Message, "Column %s converted to varchar(%d)", colname, len); PushWarning(g, thd); v = 'V'; } else len = MY_MIN(len, 4096); } // endif type qrp->Nblin++; crp = crp->Next; // Data_Type crp->Kdata->SetValue(type, i); switch (nf) { case 5: crp->Nulls[i] = 'Z'; break; case 4: crp->Nulls[i] = 'U'; break; default: crp->Nulls[i] = v; break; } // endswitch nf crp = crp->Next; // Type_Name crp->Kdata->SetValue(buf, i); if (type == TYPE_DATE) { // When creating tables we do need info about date columns fmt = MyDateFmt(buf); len = strlen(fmt); } else fmt = NULL; crp = crp->Next; // Precision crp->Kdata->SetValue(len, i); crp = crp->Next; // key (was Length) fld = myc.GetCharField(4); crp->Kdata->SetValue(fld, i); crp = crp->Next; // Scale crp->Kdata->SetValue(prec, i); crp = crp->Next; // Radix crp->Kdata->SetValue(0, i); crp = crp->Next; // Nullable fld = myc.GetCharField(3); crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i); crp = crp->Next; // Remark fld = myc.GetCharField(8); crp->Kdata->SetValue(fld, i); crp = crp->Next; // Date format // crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i); crp->Kdata->SetValue(fmt, i); crp = crp->Next; // New (default) fld = myc.GetCharField(5); crp->Kdata->SetValue(fld, i); crp = crp->Next; // New (extra) fld = myc.GetCharField(6); crp->Kdata->SetValue(fld, i); crp = crp->Next; // New (charset) fld = chset; crp->Kdata->SetValue(fld, i); i++; // Can be skipped } // endfor i #if 0 if (k > 1) { // Multicolumn primary key PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata; for (i = 0; i < n; i++) if (vbp->GetIntValue(i)) vbp->SetValue(k, i); } // endif k #endif // 0 /**********************************************************************/ /* Close MySQL connection. */ /**********************************************************************/ myc.Close(); /**********************************************************************/ /* Return the result pointer for use by GetData routines. */ /**********************************************************************/ return qrp; } // end of MyColumns
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"); 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_BIN) { 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