mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
cd9e1938ef
parameter to all catalog info functions. modified: storage/connect/catalog.h storage/connect/filamvct.cpp storage/connect/filamzip.cpp storage/connect/ha_connect.cc storage/connect/mycat.cc storage/connect/mycat.h storage/connect/reldef.cpp storage/connect/reldef.h storage/connect/tabdos.cpp storage/connect/tabfmt.cpp storage/connect/tabmul.cpp storage/connect/tabmysql.cpp storage/connect/tabodbc.cpp storage/connect/tabsys.cpp storage/connect/tabtbl.cpp storage/connect/tabvct.cpp storage/connect/tabwmi.cpp storage/connect/tabxml.cpp storage/connect/xindex.cpp
821 lines
29 KiB
C++
821 lines
29 KiB
C++
/*********** File AM Zip C++ Program Source Code File (.CPP) ***********/
|
|
/* PROGRAM NAME: FILAMZIP */
|
|
/* ------------- */
|
|
/* Version 1.4 */
|
|
/* */
|
|
/* COPYRIGHT: */
|
|
/* ---------- */
|
|
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
|
|
/* */
|
|
/* WHAT THIS PROGRAM DOES: */
|
|
/* ----------------------- */
|
|
/* This program are the ZLIB compressed files classes. */
|
|
/* */
|
|
/***********************************************************************/
|
|
|
|
/***********************************************************************/
|
|
/* Include relevant MariaDB header file. */
|
|
/***********************************************************************/
|
|
#include "my_global.h"
|
|
#if defined(WIN32)
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#if defined(__BORLANDC__)
|
|
#define __MFC_COMPAT__ // To define min/max as macro
|
|
#endif
|
|
//#include <windows.h>
|
|
#else // !WIN32
|
|
#if defined(UNIX)
|
|
#include <errno.h>
|
|
#else // !UNIX
|
|
#include <io.h>
|
|
#endif
|
|
#include <fcntl.h>
|
|
#endif // !WIN32
|
|
|
|
/***********************************************************************/
|
|
/* Include application header files: */
|
|
/* global.h is header containing all global declarations. */
|
|
/* plgdbsem.h is header containing the DB application declarations. */
|
|
/* tabdos.h is header containing the TABDOS class declarations. */
|
|
/***********************************************************************/
|
|
#include "global.h"
|
|
#include "plgdbsem.h"
|
|
//#include "catalog.h"
|
|
//#include "reldef.h"
|
|
//#include "xobject.h"
|
|
//#include "kindex.h"
|
|
#include "filamtxt.h"
|
|
#include "tabdos.h"
|
|
#if defined(UNIX)
|
|
#include "osutil.h"
|
|
#endif
|
|
|
|
/***********************************************************************/
|
|
/* This define prepares ZLIB function declarations. */
|
|
/***********************************************************************/
|
|
//#define ZLIB_DLL
|
|
|
|
#include "filamzip.h"
|
|
|
|
/***********************************************************************/
|
|
/* DB static variables. */
|
|
/***********************************************************************/
|
|
extern int num_read, num_there, num_eq[]; // Statistics
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* Implementation of the ZIPFAM class. */
|
|
/***********************************************************************/
|
|
ZIPFAM::ZIPFAM(PZIPFAM txfp) : TXTFAM(txfp)
|
|
{
|
|
Zfile = txfp->Zfile;
|
|
Zpos = txfp->Zpos;
|
|
} // end of ZIPFAM copy constructor
|
|
|
|
/***********************************************************************/
|
|
/* Zerror: Error function for gz calls. */
|
|
/* gzerror returns the error message for the last error which occurred*/
|
|
/* on the given compressed file. errnum is set to zlib error number. */
|
|
/* If an error occurred in the file system and not in the compression */
|
|
/* library, errnum is set to Z_ERRNO and the application may consult */
|
|
/* errno to get the exact error code. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::Zerror(PGLOBAL g)
|
|
{
|
|
int errnum;
|
|
|
|
strcpy(g->Message, gzerror(Zfile, &errnum));
|
|
|
|
if (errnum == Z_ERRNO)
|
|
#if defined(WIN32)
|
|
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(NULL));
|
|
#else // !WIN32
|
|
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
|
|
#endif // !WIN32
|
|
|
|
return (errnum == Z_STREAM_END) ? RC_EF : RC_FX;
|
|
} // end of Zerror
|
|
|
|
/***********************************************************************/
|
|
/* Reset: reset position values at the beginning of file. */
|
|
/***********************************************************************/
|
|
void ZIPFAM::Reset(void)
|
|
{
|
|
TXTFAM::Reset();
|
|
//gzrewind(Zfile); // Useful ?????
|
|
Zpos = 0;
|
|
} // end of Reset
|
|
|
|
/***********************************************************************/
|
|
/* ZIP GetFileLength: returns an estimate of what would be the */
|
|
/* uncompressed file size in number of bytes. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::GetFileLength(PGLOBAL g)
|
|
{
|
|
int len = TXTFAM::GetFileLength(g);
|
|
|
|
if (len > 0)
|
|
// Estimate size reduction to a max of 6
|
|
len *= 6;
|
|
|
|
return len;
|
|
} // end of GetFileLength
|
|
|
|
/***********************************************************************/
|
|
/* ZIP Access Method opening routine. */
|
|
/***********************************************************************/
|
|
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
|
|
|
|
/***********************************************************************/
|
|
/* 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. */
|
|
/***********************************************************************/
|
|
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
|
|
|
|
#ifdef DEBTRACE
|
|
htrc("SubAllocating a buffer of %d bytes\n", Buflen);
|
|
#endif
|
|
|
|
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
|
|
|
|
/***********************************************************************/
|
|
/* GetRowID: return the RowID of last read record. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::GetRowID(void)
|
|
{
|
|
return Rows;
|
|
} // end of GetRowID
|
|
|
|
/***********************************************************************/
|
|
/* GetPos: return the position of last read record. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::GetPos(void)
|
|
{
|
|
return (int)Zpos;
|
|
} // end of GetPos
|
|
|
|
/***********************************************************************/
|
|
/* GetNextPos: return the position of next record. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::GetNextPos(void)
|
|
{
|
|
return gztell(Zfile);
|
|
} // end of GetNextPos
|
|
|
|
/***********************************************************************/
|
|
/* SetPos: Replace the table at the specified position. */
|
|
/***********************************************************************/
|
|
bool ZIPFAM::SetPos(PGLOBAL g, int pos)
|
|
{
|
|
sprintf(g->Message, MSG(NO_SETPOS_YET), "ZIP");
|
|
return true;
|
|
#if 0
|
|
Fpos = pos;
|
|
|
|
if (fseek(Stream, Fpos, SEEK_SET)) {
|
|
sprintf(g->Message, MSG(FSETPOS_ERROR), Fpos);
|
|
return true;
|
|
} // endif
|
|
|
|
Placed = true;
|
|
return false;
|
|
#endif // 0
|
|
} // end of SetPos
|
|
|
|
/***********************************************************************/
|
|
/* Record file position in case of UPDATE or DELETE. */
|
|
/***********************************************************************/
|
|
bool ZIPFAM::RecordPos(PGLOBAL g)
|
|
{
|
|
Zpos = gztell(Zfile);
|
|
return false;
|
|
} // end of RecordPos
|
|
|
|
/***********************************************************************/
|
|
/* Skip one record in file. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::SkipRecord(PGLOBAL g, bool header)
|
|
{
|
|
// Skip this record
|
|
if (gzeof(Zfile))
|
|
return RC_EF;
|
|
else if (gzgets(Zfile, To_Buf, Buflen) == Z_NULL)
|
|
return Zerror(g);
|
|
|
|
if (header)
|
|
RecordPos(g);
|
|
|
|
return RC_OK;
|
|
} // end of SkipRecord
|
|
|
|
/***********************************************************************/
|
|
/* ReadBuffer: Read one line from a compressed text file. */
|
|
/***********************************************************************/
|
|
int ZIPFAM::ReadBuffer(PGLOBAL g)
|
|
{
|
|
char *p;
|
|
int rc;
|
|
|
|
if (!Zfile)
|
|
return RC_EF;
|
|
|
|
if (!Placed) {
|
|
/*******************************************************************/
|
|
/* Record file position in case of UPDATE or DELETE. */
|
|
/*******************************************************************/
|
|
if (RecordPos(g))
|
|
return RC_FX;
|
|
|
|
CurBlk = Rows++; // Update RowID
|
|
} else
|
|
Placed = false;
|
|
|
|
if (gzeof(Zfile)) {
|
|
rc = RC_EF;
|
|
} else if (gzgets(Zfile, To_Buf, Buflen) != Z_NULL) {
|
|
p = To_Buf + strlen(To_Buf) - 1;
|
|
|
|
if (*p == '\n')
|
|
*p = '\0'; // Eliminate ending new-line character
|
|
|
|
if (*(--p) == '\r')
|
|
*p = '\0'; // Eliminate eventuel carriage return
|
|
|
|
strcpy(Tdbp->GetLine(), To_Buf);
|
|
IsRead = true;
|
|
rc = RC_OK;
|
|
num_read++;
|
|
} else
|
|
rc = Zerror(g);
|
|
|
|
#ifdef DEBTRACE
|
|
htrc(" Read: '%s' rc=%d\n", To_Buf, rc);
|
|
#endif
|
|
return rc;
|
|
} // end of ReadBuffer
|
|
|
|
/***********************************************************************/
|
|
/* WriteDB: Data Base write routine for ZDOS access method. */
|
|
/* Update is not possible without using a temporary file (NIY). */
|
|
/***********************************************************************/
|
|
int ZIPFAM::WriteBuffer(PGLOBAL g)
|
|
{
|
|
/*********************************************************************/
|
|
/* Prepare the write buffer. */
|
|
/*********************************************************************/
|
|
strcat(strcpy(To_Buf, Tdbp->GetLine()), CrLf);
|
|
|
|
/*********************************************************************/
|
|
/* Now start the writing process. */
|
|
/*********************************************************************/
|
|
if (gzputs(Zfile, To_Buf) < 0)
|
|
return Zerror(g);
|
|
|
|
return RC_OK;
|
|
} // end of WriteBuffer
|
|
|
|
/***********************************************************************/
|
|
/* Data Base delete line routine for ZDOS access method. (NIY) */
|
|
/***********************************************************************/
|
|
int ZIPFAM::DeleteRecords(PGLOBAL g, int irc)
|
|
{
|
|
strcpy(g->Message, MSG(NO_ZIP_DELETE));
|
|
return RC_FX;
|
|
} // end of DeleteRecords
|
|
|
|
/***********************************************************************/
|
|
/* Data Base close routine for DOS access method. */
|
|
/***********************************************************************/
|
|
void ZIPFAM::CloseTableFile(PGLOBAL g)
|
|
{
|
|
int rc = gzclose(Zfile);
|
|
|
|
#ifdef DEBTRACE
|
|
htrc("ZIP CloseDB: closing %s rc=%d\n", To_File, rc);
|
|
#endif
|
|
|
|
Zfile = NULL; // So we can know whether table is open
|
|
//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
|
|
} // end of CloseTableFile
|
|
|
|
/***********************************************************************/
|
|
/* Rewind routine for ZIP access method. */
|
|
/***********************************************************************/
|
|
void ZIPFAM::Rewind(void)
|
|
{
|
|
gzrewind(Zfile);
|
|
} // end of Rewind
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* Constructors. */
|
|
/***********************************************************************/
|
|
ZBKFAM::ZBKFAM(PDOSDEF tdp) : ZIPFAM(tdp)
|
|
{
|
|
Blocked = true;
|
|
Block = tdp->GetBlock();
|
|
Last = tdp->GetLast();
|
|
Nrec = tdp->GetElemt();
|
|
CurLine = NULL;
|
|
NxtLine = NULL;
|
|
Closing = false;
|
|
BlkPos = tdp->GetTo_Pos();
|
|
} // end of ZBKFAM standard constructor
|
|
|
|
ZBKFAM::ZBKFAM(PZBKFAM txfp) : ZIPFAM(txfp)
|
|
{
|
|
CurLine = txfp->CurLine;
|
|
NxtLine = txfp->NxtLine;
|
|
Closing = txfp->Closing;
|
|
} // end of ZBKFAM copy constructor
|
|
|
|
/***********************************************************************/
|
|
/* Use BlockTest to reduce the table estimated size. */
|
|
/***********************************************************************/
|
|
int ZBKFAM::MaxBlkSize(PGLOBAL g, int s)
|
|
{
|
|
int savcur = CurBlk;
|
|
int size;
|
|
|
|
// Roughly estimate the table size as the sum of blocks
|
|
// that can contain good rows
|
|
for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
|
|
size += (CurBlk == Block - 1) ? Last : Nrec;
|
|
|
|
CurBlk = savcur;
|
|
return size;
|
|
} // end of MaxBlkSize
|
|
|
|
/***********************************************************************/
|
|
/* ZBK Cardinality: returns table cardinality in number of rows. */
|
|
/* This function can be called with a null argument to test the */
|
|
/* availability of Cardinality implementation (1 yes, 0 no). */
|
|
/***********************************************************************/
|
|
int ZBKFAM::Cardinality(PGLOBAL g)
|
|
{
|
|
// Should not be called in this version
|
|
return (g) ? -1 : 0;
|
|
//return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
|
|
} // end of Cardinality
|
|
|
|
/***********************************************************************/
|
|
/* 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. */
|
|
/***********************************************************************/
|
|
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
|
|
|
|
/***********************************************************************/
|
|
/* GetRowID: return the RowID of last read record. */
|
|
/***********************************************************************/
|
|
int ZBKFAM::GetRowID(void)
|
|
{
|
|
return CurNum + Nrec * CurBlk + 1;
|
|
} // end of GetRowID
|
|
|
|
/***********************************************************************/
|
|
/* GetPos: return the position of last read record. */
|
|
/***********************************************************************/
|
|
int ZBKFAM::GetPos(void)
|
|
{
|
|
return CurNum + Nrec * CurBlk; // Computed file index
|
|
} // end of GetPos
|
|
|
|
/***********************************************************************/
|
|
/* Record file position in case of UPDATE or DELETE. */
|
|
/* Not used yet for fixed tables. */
|
|
/***********************************************************************/
|
|
bool ZBKFAM::RecordPos(PGLOBAL g)
|
|
{
|
|
//strcpy(g->Message, "RecordPos not implemented for zip blocked tables");
|
|
//return true;
|
|
return RC_OK;
|
|
} // end of RecordPos
|
|
|
|
/***********************************************************************/
|
|
/* Skip one record in file. */
|
|
/***********************************************************************/
|
|
int ZBKFAM::SkipRecord(PGLOBAL g, bool header)
|
|
{
|
|
//strcpy(g->Message, "SkipRecord not implemented for zip blocked tables");
|
|
//return RC_FX;
|
|
return RC_OK;
|
|
} // end of SkipRecord
|
|
|
|
/***********************************************************************/
|
|
/* ReadBuffer: Read one line from a compressed text file. */
|
|
/***********************************************************************/
|
|
int ZBKFAM::ReadBuffer(PGLOBAL g)
|
|
{
|
|
int n, rc = RC_OK;
|
|
|
|
/*********************************************************************/
|
|
/* Sequential reading when Placed is not true. */
|
|
/*********************************************************************/
|
|
if (++CurNum < Rbuf) {
|
|
CurLine = NxtLine;
|
|
|
|
// Get the position of the next line in the buffer
|
|
while (*NxtLine++ != '\n') ;
|
|
|
|
// Set caller line buffer
|
|
n = NxtLine - CurLine - Ending;
|
|
memcpy(Tdbp->GetLine(), CurLine, n);
|
|
Tdbp->GetLine()[n] = '\0';
|
|
return RC_OK;
|
|
} else if (Rbuf < Nrec && CurBlk != -1)
|
|
return RC_EF;
|
|
|
|
/*********************************************************************/
|
|
/* New block. */
|
|
/*********************************************************************/
|
|
CurNum = 0;
|
|
|
|
if (++CurBlk >= Block)
|
|
return RC_EF;
|
|
|
|
BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];
|
|
|
|
if (!(n = gzread(Zfile, To_Buf, BlkLen))) {
|
|
rc = RC_EF;
|
|
} else if (n > 0) {
|
|
// Get the position of the current line
|
|
CurLine = To_Buf;
|
|
|
|
// Now get the position of the next line
|
|
for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
|
|
|
|
// Set caller line buffer
|
|
n = NxtLine - CurLine - Ending;
|
|
memcpy(Tdbp->GetLine(), CurLine, n);
|
|
Tdbp->GetLine()[n] = '\0';
|
|
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
|
|
IsRead = true;
|
|
rc = RC_OK;
|
|
num_read++;
|
|
} else
|
|
rc = Zerror(g);
|
|
|
|
return rc;
|
|
} // end of ReadBuffer
|
|
|
|
/***********************************************************************/
|
|
/* WriteDB: Data Base write routine for ZDOS access method. */
|
|
/* Update is not possible without using a temporary file (NIY). */
|
|
/***********************************************************************/
|
|
int ZBKFAM::WriteBuffer(PGLOBAL g)
|
|
{
|
|
/*********************************************************************/
|
|
/* Prepare the write buffer. */
|
|
/*********************************************************************/
|
|
if (!Closing)
|
|
strcat(strcpy(CurLine, Tdbp->GetLine()), CrLf);
|
|
|
|
/*********************************************************************/
|
|
/* In Insert mode, blocs are added sequentialy to the file end. */
|
|
/* Note: Update mode is not handled for zip files. */
|
|
/*********************************************************************/
|
|
if (++CurNum == Rbuf) {
|
|
/*******************************************************************/
|
|
/* New block, start the writing process. */
|
|
/*******************************************************************/
|
|
BlkLen = CurLine + strlen(CurLine) - To_Buf;
|
|
|
|
if (gzwrite(Zfile, To_Buf, BlkLen) != BlkLen ||
|
|
gzflush(Zfile, Z_FULL_FLUSH)) {
|
|
Closing = true;
|
|
return Zerror(g);
|
|
} // endif gzwrite
|
|
|
|
Rbuf = Nrec;
|
|
CurBlk++;
|
|
CurNum = 0;
|
|
CurLine = To_Buf;
|
|
} else
|
|
CurLine += strlen(CurLine);
|
|
|
|
return RC_OK;
|
|
} // end of WriteBuffer
|
|
|
|
/***********************************************************************/
|
|
/* Data Base delete line routine for ZBK access method. */
|
|
/* Implemented only for total deletion of the table, which is done */
|
|
/* by opening the file in mode "wb". */
|
|
/***********************************************************************/
|
|
int ZBKFAM::DeleteRecords(PGLOBAL g, int irc)
|
|
{
|
|
if (irc == RC_EF) {
|
|
LPCSTR name = Tdbp->GetName();
|
|
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
|
|
PCATLG cat = PlgGetCatalog(g);
|
|
|
|
defp->SetBlock(0);
|
|
defp->SetLast(Nrec);
|
|
|
|
if (!cat->SetIntCatInfo("Blocks", 0) ||
|
|
!cat->SetIntCatInfo("Last", 0)) {
|
|
sprintf(g->Message, MSG(UPDATE_ERROR), "Header");
|
|
return RC_FX;
|
|
} else
|
|
return RC_OK;
|
|
|
|
} else
|
|
return irc;
|
|
|
|
} // end of DeleteRecords
|
|
|
|
/***********************************************************************/
|
|
/* Data Base close routine for ZBK access method. */
|
|
/***********************************************************************/
|
|
void ZBKFAM::CloseTableFile(PGLOBAL g)
|
|
{
|
|
int rc = RC_OK;
|
|
|
|
if (Tdbp->GetMode() == MODE_INSERT) {
|
|
PCATLG cat = PlgGetCatalog(g);
|
|
LPCSTR name = Tdbp->GetName();
|
|
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
|
|
|
|
if (CurNum && !Closing) {
|
|
// Some more inserted lines remain to be written
|
|
Last = (Nrec - Rbuf) + CurNum;
|
|
Block = CurBlk + 1;
|
|
Rbuf = CurNum--;
|
|
Closing = true;
|
|
rc = WriteBuffer(g);
|
|
} else if (Rbuf == Nrec) {
|
|
Last = Nrec;
|
|
Block = CurBlk;
|
|
} // endif CurNum
|
|
|
|
if (rc != RC_FX) {
|
|
defp->SetBlock(Block);
|
|
defp->SetLast(Last);
|
|
cat->SetIntCatInfo("Blocks", Block);
|
|
cat->SetIntCatInfo("Last", Last);
|
|
} // endif
|
|
|
|
gzclose(Zfile);
|
|
} else if (Tdbp->GetMode() == MODE_DELETE) {
|
|
rc = DeleteRecords(g, RC_EF);
|
|
gzclose(Zfile);
|
|
} else
|
|
rc = gzclose(Zfile);
|
|
|
|
#ifdef DEBTRACE
|
|
htrc("ZIP CloseDB: closing %s rc=%d\n", To_File, rc);
|
|
#endif
|
|
|
|
Zfile = NULL; // So we can know whether table is open
|
|
//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
|
|
} // end of CloseTableFile
|
|
|
|
/***********************************************************************/
|
|
/* Rewind routine for ZBK access method. */
|
|
/***********************************************************************/
|
|
void ZBKFAM::Rewind(void)
|
|
{
|
|
gzrewind(Zfile);
|
|
CurBlk = -1;
|
|
CurNum = Rbuf;
|
|
} // end of Rewind
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/***********************************************************************/
|
|
/* Constructors. */
|
|
/***********************************************************************/
|
|
ZIXFAM::ZIXFAM(PDOSDEF tdp) : ZBKFAM(tdp)
|
|
{
|
|
//Block = tdp->GetBlock();
|
|
//Last = tdp->GetLast();
|
|
Nrec = (tdp->GetElemt()) ? tdp->GetElemt() : DOS_BUFF_LEN;
|
|
Blksize = Nrec * Lrecl;
|
|
} // end of ZIXFAM standard constructor
|
|
|
|
/***********************************************************************/
|
|
/* ZIX Cardinality: returns table cardinality in number of rows. */
|
|
/* This function can be called with a null argument to test the */
|
|
/* availability of Cardinality implementation (1 yes, 0 no). */
|
|
/***********************************************************************/
|
|
int ZIXFAM::Cardinality(PGLOBAL g)
|
|
{
|
|
if (Last)
|
|
return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
|
|
else // Last and Block not defined, cannot do it yet
|
|
return 0;
|
|
|
|
} // end of Cardinality
|
|
|
|
/***********************************************************************/
|
|
/* 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. */
|
|
/***********************************************************************/
|
|
bool ZIXFAM::AllocateBuffer(PGLOBAL g)
|
|
{
|
|
Buflen = Blksize;
|
|
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
|
|
|
|
if (Tdbp->GetMode() == MODE_INSERT) {
|
|
/*******************************************************************/
|
|
/* For Insert the buffer must be prepared. */
|
|
/*******************************************************************/
|
|
memset(To_Buf, ' ', Buflen);
|
|
|
|
if (Tdbp->GetFtype() < 2)
|
|
// if not binary, the file is physically a text file
|
|
for (int len = Lrecl; len <= Buflen; len += Lrecl) {
|
|
#if defined(WIN32)
|
|
To_Buf[len - 2] = '\r';
|
|
#endif // WIN32
|
|
To_Buf[len - 1] = '\n';
|
|
} // endfor len
|
|
|
|
// 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
|
|
|
|
/***********************************************************************/
|
|
/* ReadBuffer: Read one line from a compressed text file. */
|
|
/***********************************************************************/
|
|
int ZIXFAM::ReadBuffer(PGLOBAL g)
|
|
{
|
|
int n, rc = RC_OK;
|
|
|
|
/*********************************************************************/
|
|
/* Sequential reading when Placed is not true. */
|
|
/*********************************************************************/
|
|
if (++CurNum < Rbuf) {
|
|
Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
|
|
return RC_OK;
|
|
} else if (Rbuf < Nrec && CurBlk != -1)
|
|
return RC_EF;
|
|
|
|
/*********************************************************************/
|
|
/* New block. */
|
|
/*********************************************************************/
|
|
CurNum = 0;
|
|
Tdbp->SetLine(To_Buf);
|
|
|
|
//if (++CurBlk >= Block)
|
|
// return RC_EF;
|
|
|
|
if (!(n = gzread(Zfile, To_Buf, Buflen))) {
|
|
rc = RC_EF;
|
|
} else if (n > 0) {
|
|
Rbuf = n / Lrecl;
|
|
IsRead = true;
|
|
rc = RC_OK;
|
|
num_read++;
|
|
} else
|
|
rc = Zerror(g);
|
|
|
|
return rc;
|
|
} // end of ReadBuffer
|
|
|
|
/***********************************************************************/
|
|
/* WriteDB: Data Base write routine for ZDOS access method. */
|
|
/* Update is not possible without using a temporary file (NIY). */
|
|
/***********************************************************************/
|
|
int ZIXFAM::WriteBuffer(PGLOBAL g)
|
|
{
|
|
/*********************************************************************/
|
|
/* In Insert mode, blocs are added sequentialy to the file end. */
|
|
/* Note: Update mode is not handled for zip files. */
|
|
/*********************************************************************/
|
|
if (++CurNum == Rbuf) {
|
|
/*******************************************************************/
|
|
/* New block, start the writing process. */
|
|
/*******************************************************************/
|
|
BlkLen = Rbuf * Lrecl;
|
|
|
|
if (gzwrite(Zfile, To_Buf, BlkLen) != BlkLen ||
|
|
gzflush(Zfile, Z_FULL_FLUSH)) {
|
|
Closing = true;
|
|
return Zerror(g);
|
|
} // endif gzwrite
|
|
|
|
Rbuf = Nrec;
|
|
CurBlk++;
|
|
CurNum = 0;
|
|
Tdbp->SetLine(To_Buf);
|
|
} else
|
|
Tdbp->IncLine(Lrecl); // Used by FIXCOL functions
|
|
|
|
return RC_OK;
|
|
} // end of WriteBuffer
|
|
|
|
/* ------------------------ End of ZipFam ---------------------------- */
|