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
bool TDBCAT::Initialize(PGLOBAL g) { if (Init) return false; if (!(Qrp = GetResult(g))) return true; if (Qrp->Truncated) { sprintf(g->Message, "Result limited to %d lines", Qrp->Maxres); PushWarning(g, this); } // endif Truncated if (Qrp->BadLines) { sprintf(g->Message, "%d bad lines in result", Qrp->BadLines); PushWarning(g, this); } // endif Badlines Init = true; return false; } // end of Initialize
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 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 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
PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) { PTDBASE tdbp; if (Catfunc != FNC_COL) { USETEMP tmp = Use_Temp; 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 txfp = new(g) ZLBFAM(this); #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 /*****************************************************************/ /* For block tables, get eventually saved optimization values. */ /*****************************************************************/ if (tdbp->GetBlockValues(g)) { PushWarning(g, tdbp); // return NULL; // causes a crash when deleting index } else { if (IsOptimized()) { if (map) { txfp = new(g) MBKFAM(this); } else if (Compressed) { #if defined(ZIP_SUPPORT) if (Compressed == 1) txfp = new(g) ZBKFAM(this); else { txfp->SetBlkPos(To_Pos); ((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL); } // endelse #else sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); return NULL; #endif } else txfp = new(g) BLKFAM(this); ((PTDBDOS)tdbp)->SetTxfp(txfp); } // endif Optimized } // endelse } else tdbp = new(g)TDBCCL(this); return tdbp; } // end of GetTable
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
bool ZIPFAM::OpenTableFile(PGLOBAL g) { char opmode[4], filename[_MAX_PATH]; MODE mode = Tdbp->GetMode(); switch (mode) { case MODE_READ: strcpy(opmode, "r"); break; case MODE_UPDATE: /*****************************************************************/ /* Updating ZIP files not implemented yet. */ /*****************************************************************/ strcpy(g->Message, MSG(UPD_ZIP_NOT_IMP)); return true; case MODE_DELETE: if (!Tdbp->GetNext()) { // Store the number of deleted lines DelRows = Cardinality(g); // This will erase the entire file strcpy(opmode, "w"); // Block = 0; // For ZBKFAM // Last = Nrec; // For ZBKFAM Tdbp->ResetSize(); } else { sprintf(g->Message, MSG(NO_PART_DEL), "ZIP"); return true; } // endif filter break; case MODE_INSERT: strcpy(opmode, "a+"); break; default: sprintf(g->Message, MSG(BAD_OPEN_MODE), mode); return true; } // endswitch Mode /*********************************************************************/ /* Open according to logical input/output mode required. */ /* Use specific zlib functions. */ /* Treat files as binary. */ /*********************************************************************/ strcat(opmode, "b"); Zfile = gzopen(PlugSetPath(filename, To_File, Tdbp->GetPath()), opmode); if (Zfile == NULL) { sprintf(g->Message, MSG(GZOPEN_ERROR), opmode, (int)errno, filename); strcat(strcat(g->Message, ": "), strerror(errno)); return (mode == MODE_READ && errno == ENOENT) ? PushWarning(g, Tdbp) : true; } // endif Zfile /*********************************************************************/ /* Something to be done here. >>>>>>>> NOT DONE <<<<<<<< */ /*********************************************************************/ //To_Fb = dbuserp->Openlist; // Keep track of File block /*********************************************************************/ /* Allocate the line buffer. */ /*********************************************************************/ return AllocateBuffer(g); } // end of OpenTableFile