Commit 671d9b6c authored by Olivier Bertrand's avatar Olivier Bertrand

- Fix MDEV-22571 and MDEV-22572. Allow multiple ZIP table

  and enable using special column in them.
  modified:   storage/connect/tabzip.cpp
  modified:   storage/connect/tabzip.h

- Fix some compiler errors
  modified:   storage/connect/tabcmg.cpp
parent 41acc81f
...@@ -355,7 +355,6 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2, ...@@ -355,7 +355,6 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
} // endif mode } // endif mode
rcop = false; rcop = false;
} catch (int n) { } catch (int n) {
if (trace(1)) if (trace(1))
htrc("Exception %d: %s\n", n, g->Message); htrc("Exception %d: %s\n", n, g->Message);
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "global.h" #include "global.h"
#include "plgdbsem.h" #include "plgdbsem.h"
#include "filamdbf.h" #include "filamdbf.h"
#include "filamzip.h"
#include "tabdos.h" #include "tabdos.h"
#include "valblk.h" #include "valblk.h"
#define NO_FUNC #define NO_FUNC
...@@ -139,7 +140,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf) ...@@ -139,7 +140,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf)
if (fread(buf, HEADLEN, 1, file) != 1) { if (fread(buf, HEADLEN, 1, file) != 1) {
strcpy(g->Message, MSG(NO_READ_32)); strcpy(g->Message, MSG(NO_READ_32));
return RC_NF; return RC_NF;
} // endif fread } // endif fread
// Check first byte to be sure of .dbf type // Check first byte to be sure of .dbf type
if ((buf->Version & 0x03) != DBFTYPE) { if ((buf->Version & 0x03) != DBFTYPE) {
...@@ -149,7 +150,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf) ...@@ -149,7 +150,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf)
if ((buf->Version & 0x30) == 0x30) { if ((buf->Version & 0x30) == 0x30) {
strcpy(g->Message, MSG(FOXPRO_FILE)); strcpy(g->Message, MSG(FOXPRO_FILE));
dbc = 264; // FoxPro database container dbc = 264; // FoxPro database container
} // endif Version } // endif Version
} else } else
strcpy(g->Message, MSG(DBASE_FILE)); strcpy(g->Message, MSG(DBASE_FILE));
...@@ -158,12 +159,12 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf) ...@@ -158,12 +159,12 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf)
if (fseek(file, buf->Headlen() - dbc, SEEK_SET) != 0) { if (fseek(file, buf->Headlen() - dbc, SEEK_SET) != 0) {
sprintf(g->Message, MSG(BAD_HEADER), fn); sprintf(g->Message, MSG(BAD_HEADER), fn);
return RC_FX; return RC_FX;
} // endif fseek } // endif fseek
if (fread(&endmark, 2, 1, file) != 1) { if (fread(&endmark, 2, 1, file) != 1) {
strcpy(g->Message, MSG(BAD_HEAD_END)); strcpy(g->Message, MSG(BAD_HEAD_END));
return RC_FX; return RC_FX;
} // endif fread } // endif fread
// Some files have just 1D others have 1D00 following fields // Some files have just 1D others have 1D00 following fields
if (endmark[0] != EOH && endmark[1] != EOH) { if (endmark[0] != EOH && endmark[1] != EOH) {
...@@ -172,7 +173,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf) ...@@ -172,7 +173,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf)
if (rc == RC_OK) if (rc == RC_OK)
return RC_FX; return RC_FX;
} // endif endmark } // endif endmark
// Calculate here the number of fields while we have the dbc info // Calculate here the number of fields while we have the dbc info
buf->SetFields((buf->Headlen() - dbc - 1) / 32); buf->SetFields((buf->Headlen() - dbc - 1) / 32);
...@@ -180,13 +181,58 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf) ...@@ -180,13 +181,58 @@ static int dbfhead(PGLOBAL g, FILE *file, PCSZ fn, DBFHEADER *buf)
return rc; return rc;
} // end of dbfhead } // end of dbfhead
/****************************************************************************/
/* dbfields: Analyze a DBF header and set the table fields number. */
/* Parameters: */
/* PGLOBAL g -- pointer to the CONNECT Global structure */
/* DBFHEADER *hdrp -- pointer to _dbfheader structure */
/* Returns: */
/* RC_OK, RC_INFO, or RC_FX if error. */
/****************************************************************************/
static int dbfields(PGLOBAL g, DBFHEADER* hdrp)
{
char* endmark;
int dbc = 2, rc = RC_OK;
*g->Message = '\0';
// Check first byte to be sure of .dbf type
if ((hdrp->Version & 0x03) != DBFTYPE) {
strcpy(g->Message, MSG(NOT_A_DBF_FILE));
rc = RC_INFO;
if ((hdrp->Version & 0x30) == 0x30) {
strcpy(g->Message, MSG(FOXPRO_FILE));
dbc = 264; // FoxPro database container
} // endif Version
} else
strcpy(g->Message, MSG(DBASE_FILE));
// Check last byte(s) of header
endmark = (char*)hdrp + hdrp->Headlen() - dbc;
// Some headers just have 1D others have 1D00 following fields
if (endmark[0] != EOH && endmark[1] != EOH) {
sprintf(g->Message, MSG(NO_0DH_HEAD), dbc);
if (rc == RC_OK)
return RC_FX;
} // endif endmark
// Calculate here the number of fields while we have the dbc info
hdrp->SetFields((hdrp->Headlen() - dbc - 1) / 32);
return rc;
} // end of dbfields
/* -------------------------- Function DBFColumns ------------------------- */ /* -------------------------- Function DBFColumns ------------------------- */
/****************************************************************************/ /****************************************************************************/
/* DBFColumns: constructs the result blocks containing the description */ /* DBFColumns: constructs the result blocks containing the description */
/* of all the columns of a DBF file that will be retrieved by #GetData. */ /* of all the columns of a DBF file that will be retrieved by #GetData. */
/****************************************************************************/ /****************************************************************************/
PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, PTOS topt, bool info)
{ {
int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT}; TYPE_INT, TYPE_INT, TYPE_SHORT};
...@@ -196,10 +242,12 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -196,10 +242,12 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
char buf[2], filename[_MAX_PATH]; char buf[2], filename[_MAX_PATH];
int ncol = sizeof(buftyp) / sizeof(int); int ncol = sizeof(buftyp) / sizeof(int);
int rc, type, len, field, fields; int rc, type, len, field, fields;
bool bad; bool bad, mul;
DBFHEADER mainhead; PCSZ target, pwd;
DESCRIPTOR thisfield; DBFHEADER mainhead, *hp;
FILE *infile = NULL; DESCRIPTOR thisfield, *tfp;
FILE *infile = NULL;
UNZIPUTL *zutp = NULL;
PQRYRES qrp; PQRYRES qrp;
PCOLRES crp; PCOLRES crp;
...@@ -217,21 +265,55 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -217,21 +265,55 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
/************************************************************************/ /************************************************************************/
PlugSetPath(filename, fn, dp); PlugSetPath(filename, fn, dp);
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb"))) if (topt->zipped) {
return NULL; target = GetStringTableOption(g, topt, "Entry", NULL);
mul = (target && *target) ? strchr(target, '*') || strchr(target, '?')
/************************************************************************/ : false;
/* Get the first 32 bytes of the header. */ mul = GetBooleanTableOption(g, topt, "Mulentries", mul);
/************************************************************************/
if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) { if (mul) {
fclose(infile); strcpy(g->Message, "Cannot find column definition for multiple entries");
return NULL; return NULL;
} // endif dbfhead } // endif Multiple
/************************************************************************/ pwd = GetStringTableOption(g, topt, "Password", NULL);
/* Allocate the structures used to refer to the result set. */ zutp = new(g) UNZIPUTL(target, pwd, mul);
/************************************************************************/
fields = mainhead.Fields(); if (!zutp->OpenTable(g, MODE_READ, filename))
hp = (DBFHEADER*)zutp->memory;
else
return NULL;
/**********************************************************************/
/* Set the table fields number. */
/**********************************************************************/
if ((rc = dbfields(g, hp)) == RC_FX) {
zutp->close();
return NULL;
} // endif dbfields
tfp = (DESCRIPTOR*)hp;
} else {
if (!(infile = global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
return NULL;
else
hp = &mainhead;
/**********************************************************************/
/* Get the first 32 bytes of the header. */
/**********************************************************************/
if ((rc = dbfhead(g, infile, filename, hp)) == RC_FX) {
fclose(infile);
return NULL;
} // endif dbfhead
tfp = &thisfield;
} // endif zipped
/************************************************************************/
/* Get the number of the table fields. */
/************************************************************************/
fields = hp->Fields();
} else } else
fields = 0; fields = 0;
...@@ -241,19 +323,21 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -241,19 +323,21 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
if (info || !qrp) { if (info || !qrp) {
if (infile) if (infile)
fclose(infile); fclose(infile);
else if (zutp)
zutp->close();
return qrp; return qrp;
} // endif info } // endif info
if (trace(1)) { if (trace(1)) {
htrc("Structure of %s\n", filename); htrc("Structure of %s\n", filename);
htrc("headlen=%hd reclen=%hd degree=%d\n", htrc("headlen=%hd reclen=%hd degree=%d\n",
mainhead.Headlen(), mainhead.Reclen(), fields); hp->Headlen(), hp->Reclen(), fields);
htrc("flags(iem)=%d,%d,%d cp=%d\n", mainhead.Incompleteflag, htrc("flags(iem)=%d,%d,%d cp=%d\n", hp->Incompleteflag,
mainhead.Encryptflag, mainhead.Mdxflag, mainhead.Language); hp->Encryptflag, hp->Mdxflag, hp->Language);
htrc("%hd records, last changed %02d/%02d/%d\n", htrc("%hd records, last changed %02d/%02d/%d\n",
mainhead.Records(), mainhead.Filedate[1], mainhead.Filedate[2], hp->Records(), hp->Filedate[1], hp->Filedate[2],
mainhead.Filedate[0] + (mainhead.Filedate[0] <= 30) ? 2000 : 1900); hp->Filedate[0] + (hp->Filedate[0] <= 30) ? 2000 : 1900);
htrc("Field Type Offset Len Dec Set Mdx\n"); htrc("Field Type Offset Len Dec Set Mdx\n");
} // endif trace } // endif trace
...@@ -265,21 +349,24 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -265,21 +349,24 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
for (field = 0; field < fields; field++) { for (field = 0; field < fields; field++) {
bad = FALSE; bad = FALSE;
if (fread(&thisfield, HEADLEN, 1, infile) != 1) { if (topt->zipped) {
tfp = (DESCRIPTOR*)((char*)tfp + HEADLEN);
} else if (fread(tfp, HEADLEN, 1, infile) != 1) {
sprintf(g->Message, MSG(ERR_READING_REC), field+1, fn); sprintf(g->Message, MSG(ERR_READING_REC), field+1, fn);
goto err; goto err;
} else } // endif fread
len = thisfield.Length;
len = tfp->Length;
if (trace(1)) if (trace(1))
htrc("%-11s %c %6ld %3d %2d %3d %3d\n", htrc("%-11s %c %6ld %3d %2d %3d %3d\n",
thisfield.Name, thisfield.Type, thisfield.Offset, len, tfp->Name, tfp->Type, tfp->Offset, len,
thisfield.Decimals, thisfield.Setfield, thisfield.Mdxfield); tfp->Decimals, tfp->Setfield, tfp->Mdxfield);
/************************************************************************/ /************************************************************************/
/* Now get the results into blocks. */ /* Now get the results into blocks. */
/************************************************************************/ /************************************************************************/
switch (thisfield.Type) { switch (tfp->Type) {
case 'C': // Characters case 'C': // Characters
case 'L': // Logical 'T' or 'F' or space case 'L': // Logical 'T' or 'F' or space
type = TYPE_STRING; type = TYPE_STRING;
...@@ -294,7 +381,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -294,7 +381,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
// type = TYPE_INT; // type = TYPE_INT;
// break; // break;
case 'N': case 'N':
type = (thisfield.Decimals) ? TYPE_DOUBLE type = (tfp->Decimals) ? TYPE_DOUBLE
: (len > 10) ? TYPE_BIGINT : TYPE_INT; : (len > 10) ? TYPE_BIGINT : TYPE_INT;
break; break;
case 'F': // Float case 'F': // Float
...@@ -306,8 +393,8 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -306,8 +393,8 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
break; break;
default: default:
if (!info) { if (!info) {
sprintf(g->Message, MSG(BAD_DBF_TYPE), thisfield.Type sprintf(g->Message, MSG(BAD_DBF_TYPE), tfp->Type
, thisfield.Name); , tfp->Name);
goto err; goto err;
} // endif info } // endif info
...@@ -316,27 +403,31 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -316,27 +403,31 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
} // endswitch Type } // endswitch Type
crp = qrp->Colresp; // Column Name crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(thisfield.Name, field); crp->Kdata->SetValue(tfp->Name, field);
crp = crp->Next; // Data Type crp = crp->Next; // Data Type
crp->Kdata->SetValue((int)type, field); crp->Kdata->SetValue((int)type, field);
crp = crp->Next; // Type Name crp = crp->Next; // Type Name
if (bad) { if (bad) {
buf[0] = thisfield.Type; buf[0] = tfp->Type;
crp->Kdata->SetValue(buf, field); crp->Kdata->SetValue(buf, field);
} else } else
crp->Kdata->SetValue(GetTypeName(type), field); crp->Kdata->SetValue(GetTypeName(type), field);
crp = crp->Next; // Precision crp = crp->Next; // Precision
crp->Kdata->SetValue((int)thisfield.Length, field); crp->Kdata->SetValue((int)tfp->Length, field);
crp = crp->Next; // Length crp = crp->Next; // Length
crp->Kdata->SetValue((int)thisfield.Length, field); crp->Kdata->SetValue((int)tfp->Length, field);
crp = crp->Next; // Scale (precision) crp = crp->Next; // Scale (precision)
crp->Kdata->SetValue((int)thisfield.Decimals, field); crp->Kdata->SetValue((int)tfp->Decimals, field);
} // endfor field } // endfor field
qrp->Nblin = field; qrp->Nblin = field;
fclose(infile);
if (infile)
fclose(infile);
else if (zutp)
zutp->close();
#if 0 #if 0
if (info) { if (info) {
...@@ -347,9 +438,9 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -347,9 +438,9 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
sprintf(buf, sprintf(buf,
"Ver=%02x ncol=%hu nlin=%u lrecl=%hu headlen=%hu date=%02d/%02d/%02d", "Ver=%02x ncol=%hu nlin=%u lrecl=%hu headlen=%hu date=%02d/%02d/%02d",
mainhead.Version, fields, mainhead.Records, mainhead.Reclen, hp->Version, fields, hp->Records, hp->Reclen,
mainhead.Headlen, mainhead.Filedate[0], mainhead.Filedate[1], hp->Headlen, hp->Filedate[0], hp->Filedate[1],
mainhead.Filedate[2]); hp->Filedate[2]);
strcat(g->Message, buf); strcat(g->Message, buf);
} // endif info } // endif info
...@@ -360,9 +451,13 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info) ...@@ -360,9 +451,13 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info)
/**************************************************************************/ /**************************************************************************/
return qrp; return qrp;
err: err:
fclose(infile); if (infile)
return NULL; fclose(infile);
else if (zutp)
zutp->close();
return NULL;
} // end of DBFColumns } // end of DBFColumns
/* ---------------------------- Class DBFBASE ----------------------------- */ /* ---------------------------- Class DBFBASE ----------------------------- */
......
...@@ -19,7 +19,7 @@ typedef class DBMFAM *PDBMFAM; ...@@ -19,7 +19,7 @@ typedef class DBMFAM *PDBMFAM;
/****************************************************************************/ /****************************************************************************/
/* Functions used externally. */ /* Functions used externally. */
/****************************************************************************/ /****************************************************************************/
PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, bool info); PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, PTOS tiop, bool info);
/****************************************************************************/ /****************************************************************************/
/* This is the base class for dBASE file access methods. */ /* This is the base class for dBASE file access methods. */
......
/*********** File AM Zip C++ Program Source Code File (.CPP) ***********/ /*********** File AM Zip C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: FILAMZIP */ /* PROGRAM NAME: FILAMZIP */
/* ------------- */ /* ------------- */
/* Version 1.3 */ /* Version 1.4 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ /* (C) Copyright to the author Olivier BERTRAND 2016-2020 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -45,6 +45,62 @@ ...@@ -45,6 +45,62 @@
#define WRITEBUFFERSIZE (16384) #define WRITEBUFFERSIZE (16384)
/****************************************************************************/
/* Definitions used for DBF tables. */
/****************************************************************************/
#define HEADLEN 32 /* sizeof ( mainhead or thisfield ) */
//efine MEMOLEN 10 /* length of memo field in .dbf */
#define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */
#define EOH 0x0D /* end-of-header marker in .dbf file */
/****************************************************************************/
/* First 32 bytes of a DBF table. */
/* Note: some reserved fields are used here to store info (Fields) */
/****************************************************************************/
typedef struct _dbfheader {
uchar Version; /* Version information flags */
char Filedate[3]; /* date, YYMMDD, binary. YY=year-1900 */
private:
/* The following four members are stored in little-endian format on disk */
char m_RecordsBuf[4]; /* records in the file */
char m_HeadlenBuf[2]; /* bytes in the header */
char m_ReclenBuf[2]; /* bytes in a record */
char m_FieldsBuf[2]; /* Reserved but used to store fields */
public:
char Incompleteflag; /* 01 if incomplete, else 00 */
char Encryptflag; /* 01 if encrypted, else 00 */
char Reserved2[12]; /* for LAN use */
char Mdxflag; /* 01 if production .mdx, else 00 */
char Language; /* Codepage */
char Reserved3[2];
uint Records(void) const { return uint4korr(m_RecordsBuf); }
ushort Headlen(void) const { return uint2korr(m_HeadlenBuf); }
ushort Reclen(void) const { return uint2korr(m_ReclenBuf); }
ushort Fields(void) const { return uint2korr(m_FieldsBuf); }
void SetHeadlen(ushort num) { int2store(m_HeadlenBuf, num); }
void SetReclen(ushort num) { int2store(m_ReclenBuf, num); }
void SetFields(ushort num) { int2store(m_FieldsBuf, num); }
} DBFHEADER;
/****************************************************************************/
/* Column field descriptor of a .dbf file. */
/****************************************************************************/
typedef struct _descriptor {
char Name[11]; /* field name, in capitals, null filled*/
char Type; /* field type, C, D, F, L, M or N */
uint Offset; /* used in memvars, not in files. */
uchar Length; /* field length */
uchar Decimals; /* number of decimal places */
short Reserved4;
char Workarea; /* ??? */
char Reserved5[2];
char Setfield; /* ??? */
char Reserved6[7];
char Mdxfield; /* 01 if tag field in production .mdx */
} DESCRIPTOR;
bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul); bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul);
/***********************************************************************/ /***********************************************************************/
...@@ -214,10 +270,21 @@ bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul ...@@ -214,10 +270,21 @@ bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul
buf = (char*)PlugSubAlloc(g, NULL, WRITEBUFFERSIZE); buf = (char*)PlugSubAlloc(g, NULL, WRITEBUFFERSIZE);
if (mul) if (!mul) {
err = ZipFiles(g, zutp, fn, buf); PCSZ entp;
else
err = ZipFile(g, zutp, fn, entry, buf); if (!entry) { // entry defaults to the file name
char* p = strrchr((char*)fn, '/');
#if defined(__WIN__)
if (!p) p = strrchr((char*)fn, '\\');
#endif // __WIN__
entp = (p) ? p + 1 : entry;
} else
entp = entry;
err = ZipFile(g, zutp, fn, entp, buf);
} else
err = ZipFiles(g, zutp, fn, buf);
zutp->close(); zutp->close();
return err; return err;
...@@ -232,6 +299,7 @@ ZIPUTIL::ZIPUTIL(PCSZ tgt) ...@@ -232,6 +299,7 @@ ZIPUTIL::ZIPUTIL(PCSZ tgt)
{ {
zipfile = NULL; zipfile = NULL;
target = tgt; target = tgt;
pwd = NULL;
fp = NULL; fp = NULL;
entryopen = false; entryopen = false;
} // end of ZIPUTIL standard constructor } // end of ZIPUTIL standard constructor
...@@ -241,6 +309,7 @@ ZIPUTIL::ZIPUTIL(ZIPUTIL *zutp) ...@@ -241,6 +309,7 @@ ZIPUTIL::ZIPUTIL(ZIPUTIL *zutp)
{ {
zipfile = zutp->zipfile; zipfile = zutp->zipfile;
target = zutp->target; target = zutp->target;
pwd = zutp->pwd;
fp = zutp->fp; fp = zutp->fp;
entryopen = zutp->entryopen; entryopen = zutp->entryopen;
} // end of UNZIPUTL copy constructor } // end of UNZIPUTL copy constructor
...@@ -385,11 +454,11 @@ void ZIPUTIL::closeEntry() ...@@ -385,11 +454,11 @@ void ZIPUTIL::closeEntry()
/***********************************************************************/ /***********************************************************************/
/* Constructors. */ /* Constructors. */
/***********************************************************************/ /***********************************************************************/
UNZIPUTL::UNZIPUTL(PCSZ tgt, bool mul) UNZIPUTL::UNZIPUTL(PCSZ tgt, PCSZ pw, bool mul)
{ {
zipfile = NULL; zipfile = NULL;
target = tgt; target = tgt;
pwd = NULL; pwd = pw;
fp = NULL; fp = NULL;
memory = NULL; memory = NULL;
size = 0; size = 0;
...@@ -959,7 +1028,7 @@ int UZXFAM::Cardinality(PGLOBAL g) ...@@ -959,7 +1028,7 @@ int UZXFAM::Cardinality(PGLOBAL g)
} // end of Cardinality } // end of Cardinality
/***********************************************************************/ /***********************************************************************/
/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ /* OpenTableFile: Open a FIX/UNIX table file from a ZIP file. */
/***********************************************************************/ /***********************************************************************/
bool UZXFAM::OpenTableFile(PGLOBAL g) bool UZXFAM::OpenTableFile(PGLOBAL g)
{ {
...@@ -1015,6 +1084,197 @@ int UZXFAM::GetNext(PGLOBAL g) ...@@ -1015,6 +1084,197 @@ int UZXFAM::GetNext(PGLOBAL g)
return RC_OK; return RC_OK;
} // end of GetNext } // end of GetNext
/* -------------------------- class UZDFAM --------------------------- */
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
UZDFAM::UZDFAM(PDOSDEF tdp) : DBMFAM(tdp)
{
zutp = NULL;
tdfp = tdp;
//target = tdp->GetEntry();
//mul = tdp->GetMul();
//Lrecl = tdp->GetLrecl();
} // end of UZXFAM standard constructor
UZDFAM::UZDFAM(PUZDFAM txfp) : DBMFAM(txfp)
{
zutp = txfp->zutp;
tdfp = txfp->tdfp;
//target = txfp->target;
//mul = txfp->mul;
//Lrecl = txfp->Lrecl;
} // end of UZXFAM copy constructor
#if 0
/****************************************************************************/
/* dbfhead: Routine to analyze a DBF header. */
/* Parameters: */
/* PGLOBAL g -- pointer to the CONNECT Global structure */
/* DBFHEADER *hdrp -- pointer to _dbfheader structure */
/* Returns: */
/* RC_OK, RC_NF, RC_INFO, or RC_FX if error. */
/* Side effects: */
/* Set the fields number in the header. */
/****************************************************************************/
int UZDFAM::dbfhead(PGLOBAL g, void* buf)
{
char *endmark;
int dbc = 2, rc = RC_OK;
DBFHEADER* hdrp = (DBFHEADER*)buf;
*g->Message = '\0';
// Check first byte to be sure of .dbf type
if ((hdrp->Version & 0x03) != DBFTYPE) {
strcpy(g->Message, MSG(NOT_A_DBF_FILE));
rc = RC_INFO;
if ((hdrp->Version & 0x30) == 0x30) {
strcpy(g->Message, MSG(FOXPRO_FILE));
dbc = 264; // FoxPro database container
} // endif Version
} else
strcpy(g->Message, MSG(DBASE_FILE));
// Check last byte(s) of header
endmark = (char*)hdrp + hdrp->Headlen() - dbc;
// Some headers just have 1D others have 1D00 following fields
if (endmark[0] != EOH && endmark[1] != EOH) {
sprintf(g->Message, MSG(NO_0DH_HEAD), dbc);
if (rc == RC_OK)
return RC_FX;
} // endif endmark
// Calculate here the number of fields while we have the dbc info
hdrp->SetFields((hdrp->Headlen() - dbc - 1) / 32);
return rc;
} // end of dbfhead
/****************************************************************************/
/* ScanHeader: scan the DBF file header for number of records, record size,*/
/* and header length. Set Records, check that Reclen is equal to lrecl and */
/* return the header length or 0 in case of error. */
/****************************************************************************/
int UZDFAM::ScanHeader(PGLOBAL g, int* rln)
{
int rc;
DBFHEADER header;
/************************************************************************/
/* Get the first 32 bytes of the header. */
/************************************************************************/
rc = dbfhead(g, &header);
if (rc == RC_FX)
return -1;
*rln = (int)header.Reclen();
Records = (int)header.Records();
return (int)header.Headlen();
} // end of ScanHeader
#endif // 0
/***********************************************************************/
/* ZIP GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
int UZDFAM::GetFileLength(PGLOBAL g)
{
int len;
if (!zutp && OpenTableFile(g))
return 0;
if (zutp->entryopen)
len = zutp->size;
else
len = 0;
return len;
} // end of GetFileLength
/***********************************************************************/
/* ZIP Cardinality: return the number of rows if possible. */
/***********************************************************************/
int UZDFAM::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
int card = -1;
int len = GetFileLength(g);
card = Records;
// Set number of blocks for later use
Block = (card > 0) ? (card + Nrec - 1) / Nrec : 0;
return card;
} // end of Cardinality
/***********************************************************************/
/* OpenTableFile: Open a DBF table file from a ZIP file. */
/***********************************************************************/
bool UZDFAM::OpenTableFile(PGLOBAL g)
{
// May have been already opened in GetFileLength
if (!zutp || !zutp->zipfile) {
char filename[_MAX_PATH];
MODE mode = Tdbp->GetMode();
/*********************************************************************/
/* Allocate the ZIP utility class. */
/*********************************************************************/
if (!zutp)
zutp = new(g)UNZIPUTL(tdfp);
// We used the file name relative to recorded datapath
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!zutp->OpenTable(g, mode, filename)) {
// The pseudo "buffer" is here the entire real buffer
Memory = zutp->memory;
Top = Memory + zutp->size;
To_Fb = zutp->fp; // Useful when closing
return AllocateBuffer(g);
} else
return true;
} else
Reset();
return false;
} // end of OpenTableFile
/***********************************************************************/
/* GetNext: go to next entry. */
/***********************************************************************/
int UZDFAM::GetNext(PGLOBAL g)
{
int rc = zutp->nextEntry(g);
if (rc != RC_OK)
return rc;
int len = zutp->size;
#if 0
if (len % Lrecl) {
sprintf(g->Message, MSG(NOT_FIXED_LEN), zutp->fn, len, Lrecl);
return RC_FX;
} // endif size
#endif // 0
Memory = zutp->memory;
Top = Memory + len;
Rewind();
return RC_OK;
} // end of GetNext
/* -------------------------- class ZIPFAM --------------------------- */ /* -------------------------- class ZIPFAM --------------------------- */
/***********************************************************************/ /***********************************************************************/
...@@ -1045,7 +1305,7 @@ bool ZIPFAM::OpenTableFile(PGLOBAL g) ...@@ -1045,7 +1305,7 @@ bool ZIPFAM::OpenTableFile(PGLOBAL g)
strcpy(g->Message, "No insert into existing zip file"); strcpy(g->Message, "No insert into existing zip file");
return true; return true;
} else if (append && len > 0) { } else if (append && len > 0) {
UNZIPUTL *zutp = new(g) UNZIPUTL(target, false); UNZIPUTL *zutp = new(g) UNZIPUTL(target, NULL, false);
if (!zutp->IsInsertOk(g, filename)) { if (!zutp->IsInsertOk(g, filename)) {
strcpy(g->Message, "No insert into existing entry"); strcpy(g->Message, "No insert into existing entry");
...@@ -1129,7 +1389,7 @@ bool ZPXFAM::OpenTableFile(PGLOBAL g) ...@@ -1129,7 +1389,7 @@ bool ZPXFAM::OpenTableFile(PGLOBAL g)
strcpy(g->Message, "No insert into existing zip file"); strcpy(g->Message, "No insert into existing zip file");
return true; return true;
} else if (append && len > 0) { } else if (append && len > 0) {
UNZIPUTL *zutp = new(g) UNZIPUTL(target, false); UNZIPUTL *zutp = new(g) UNZIPUTL(target, NULL, false);
if (!zutp->IsInsertOk(g, filename)) { if (!zutp->IsInsertOk(g, filename)) {
strcpy(g->Message, "No insert into existing entry"); strcpy(g->Message, "No insert into existing entry");
......
/************** filamzip H Declares Source Code File (.H) **************/ /************** filamzip H Declares Source Code File (.H) **************/
/* Name: filamzip.h Version 1.2 */ /* Name: filamzip.h Version 1.3 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ /* (C) Copyright to the author Olivier BERTRAND 2016-2020 */
/* */ /* */
/* This file contains the ZIP file access method classes declares. */ /* This file contains the ZIP file access method classes declares. */
/***********************************************************************/ /***********************************************************************/
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "block.h" #include "block.h"
#include "filamap.h" #include "filamap.h"
#include "filamfix.h" #include "filamfix.h"
#include "filamdbf.h"
#include "zip.h" #include "zip.h"
#include "unzip.h" #include "unzip.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
typedef class UNZFAM *PUNZFAM; typedef class UNZFAM *PUNZFAM;
typedef class UZXFAM *PUZXFAM; typedef class UZXFAM *PUZXFAM;
typedef class UZDFAM* PUZDFAM;
typedef class ZIPFAM *PZIPFAM; typedef class ZIPFAM *PZIPFAM;
typedef class ZPXFAM *PZPXFAM; typedef class ZPXFAM *PZPXFAM;
...@@ -53,7 +55,7 @@ class DllExport ZIPUTIL : public BLOCK { ...@@ -53,7 +55,7 @@ class DllExport ZIPUTIL : public BLOCK {
class DllExport UNZIPUTL : public BLOCK { class DllExport UNZIPUTL : public BLOCK {
public: public:
// Constructor // Constructor
UNZIPUTL(PCSZ tgt, bool mul); UNZIPUTL(PCSZ tgt, PCSZ pw, bool mul);
UNZIPUTL(PDOSDEF tdp); UNZIPUTL(PDOSDEF tdp);
// Implementation // Implementation
...@@ -143,6 +145,36 @@ class DllExport UZXFAM : public MPXFAM { ...@@ -143,6 +145,36 @@ class DllExport UZXFAM : public MPXFAM {
PDOSDEF tdfp; PDOSDEF tdfp;
}; // end of UZXFAM }; // end of UZXFAM
/***********************************************************************/
/* This is the fixed unzip file access method. */
/***********************************************************************/
class DllExport UZDFAM : public DBMFAM {
//friend class UNZFAM;
public:
// Constructors
UZDFAM(PDOSDEF tdp);
UZDFAM(PUZDFAM txfp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_ZIP; }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)UZDFAM(this); }
// Methods
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
virtual bool OpenTableFile(PGLOBAL g);
virtual int GetNext(PGLOBAL g);
//virtual int ReadBuffer(PGLOBAL g);
protected:
int dbfhead(PGLOBAL g, void* buf);
int ScanHeader(PGLOBAL g, int* rln);
// Members
UNZIPUTL* zutp;
PDOSDEF tdfp;
}; // end of UZDFAM
/***********************************************************************/ /***********************************************************************/
/* This is the zip file access method. */ /* This is the zip file access method. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -4507,12 +4507,12 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick) ...@@ -4507,12 +4507,12 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
case TAB_DIR: case TAB_DIR:
case TAB_ZIP: case TAB_ZIP:
case TAB_OEM: case TAB_OEM:
if (table && table->pos_in_table_list) // if SELECT if (table && table->pos_in_table_list) { // if SELECT
{ #if MYSQL_VERSION_ID > 100200
//Switch_to_definer_security_ctx backup_ctx(thd, table->pos_in_table_list); Switch_to_definer_security_ctx backup_ctx(thd, table->pos_in_table_list);
#endif // VERSION_ID > 100200
return check_global_access(thd, FILE_ACL); return check_global_access(thd, FILE_ACL);
} } else
else
return check_global_access(thd, FILE_ACL); return check_global_access(thd, FILE_ACL);
case TAB_ODBC: case TAB_ODBC:
case TAB_JDBC: case TAB_JDBC:
...@@ -4528,7 +4528,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick) ...@@ -4528,7 +4528,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
case TAB_VIR: case TAB_VIR:
// This is temporary until a solution is found // This is temporary until a solution is found
return false; return false;
} // endswitch type } // endswitch type
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0)); my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
return true; return true;
...@@ -5882,7 +5882,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5882,7 +5882,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} else switch (ttp) { } else switch (ttp) {
case TAB_DBF: case TAB_DBF:
qrp= DBFColumns(g, dpath, fn, fnc == FNC_COL); qrp= DBFColumns(g, dpath, fn, topt, fnc == FNC_COL);
break; break;
#if defined(ODBC_SUPPORT) #if defined(ODBC_SUPPORT)
case TAB_ODBC: case TAB_ODBC:
...@@ -6733,11 +6733,6 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -6733,11 +6733,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
PCSZ m= GetListOption(g, "Mulentries", options->oplist, "NO"); PCSZ m= GetListOption(g, "Mulentries", options->oplist, "NO");
bool mul= *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON"); bool mul= *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON");
if (!entry && !mul) {
my_message(ER_UNKNOWN_ERROR, "Missing entry name", MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif entry
strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/"); strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
PlugSetPath(zbuf, options->filename, dbpath); PlugSetPath(zbuf, options->filename, dbpath);
PlugSetPath(buf, fn, dbpath); PlugSetPath(buf, fn, dbpath);
......
...@@ -380,7 +380,6 @@ MGODEF::MGODEF(void) ...@@ -380,7 +380,6 @@ MGODEF::MGODEF(void)
Uri = NULL; Uri = NULL;
Colist = NULL; Colist = NULL;
Filter = NULL; Filter = NULL;
Level = 0;
Base = 0; Base = 0;
Version = 0; Version = 0;
Pipe = false; Pipe = false;
......
...@@ -82,7 +82,6 @@ class DllExport MGODEF : public EXTDEF { /* Table description */ ...@@ -82,7 +82,6 @@ class DllExport MGODEF : public EXTDEF { /* Table description */
PSZ Wrapname; /* Java wrapper name */ PSZ Wrapname; /* Java wrapper name */
PCSZ Colist; /* Options list */ PCSZ Colist; /* Options list */
PCSZ Filter; /* Filtering query */ PCSZ Filter; /* Filtering query */
int Level; /* Used for catalog table */
int Base; /* The array index base */ int Base; /* The array index base */
int Version; /* The Java driver version */ int Version; /* The Java driver version */
bool Pipe; /* True is Colist is a pipeline */ bool Pipe; /* True is Colist is a pipeline */
......
...@@ -49,7 +49,7 @@ bool XMLDOCUMENT::InitZip(PGLOBAL g, PCSZ entry) ...@@ -49,7 +49,7 @@ bool XMLDOCUMENT::InitZip(PGLOBAL g, PCSZ entry)
{ {
#if defined(ZIP_SUPPORT) #if defined(ZIP_SUPPORT)
bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false; bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false;
zip = new(g) UNZIPUTL(entry, mul); zip = new(g) UNZIPUTL(entry, NULL, mul);
return zip == NULL; return zip == NULL;
#else // !ZIP_SUPPORT #else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "tabmul.h" #include "tabmul.h"
#include "filter.h" #include "filter.h"
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info);
/* -------------------------- Class CMGDISC -------------------------- */ /* -------------------------- Class CMGDISC -------------------------- */
/***********************************************************************/ /***********************************************************************/
......
/************* TabDos C++ Program Source Code File (.CPP) **************/ /************* TabDos C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABDOS */ /* PROGRAM NAME: TABDOS */
/* ------------- */ /* ------------- */
/* Version 4.9.4 */ /* Version 4.9.5 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 1998-2019 */ /* (C) Copyright to the author Olivier BERTRAND 1998-2020 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -359,7 +359,26 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) ...@@ -359,7 +359,26 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
/* Allocate table and file processing class of the proper type. */ /* Allocate table and file processing class of the proper type. */
/* Column blocks will be allocated only when needed. */ /* Column blocks will be allocated only when needed. */
/*********************************************************************/ /*********************************************************************/
if (Zipped) { if (Recfm == RECFM_DBF) {
if (Catfunc == FNC_NO) {
if (Zipped) {
if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) {
txfp = new(g) UZDFAM(this);
} else {
strcpy(g->Message, "Zipped DBF tables are read only");
return NULL;
} // endif's mode
} else if (map)
txfp = new(g) DBMFAM(this);
else
txfp = new(g) DBFFAM(this);
tdbp = new(g) TDBFIX(this, txfp);
} else
tdbp = new(g) TDBDCL(this); // Catfunc should be 'C'
} else if (Zipped) {
#if defined(ZIP_SUPPORT) #if defined(ZIP_SUPPORT)
if (Recfm == RECFM_VAR) { if (Recfm == RECFM_VAR) {
if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) { if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) {
...@@ -389,17 +408,6 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) ...@@ -389,17 +408,6 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL; return NULL;
#endif // !ZIP_SUPPORT #endif // !ZIP_SUPPORT
} else if (Recfm == RECFM_DBF) {
if (Catfunc == FNC_NO) {
if (map)
txfp = new(g) DBMFAM(this);
else
txfp = new(g) DBFFAM(this);
tdbp = new(g) TDBFIX(this, txfp);
} else // Catfunc should be 'C'
tdbp = new(g) TDBDCL(this);
} else if (Recfm != RECFM_VAR && Compressed < 2) { } else if (Recfm != RECFM_VAR && Compressed < 2) {
if (Huge) if (Huge)
txfp = new(g) BGXFAM(this); txfp = new(g) BGXFAM(this);
......
...@@ -30,6 +30,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */ ...@@ -30,6 +30,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
friend class DBFBASE; friend class DBFBASE;
friend class UNZIPUTL; friend class UNZIPUTL;
friend class JSONCOL; friend class JSONCOL;
friend class TDBDCL;
public: public:
// Constructor // Constructor
DOSDEF(void); DOSDEF(void);
......
...@@ -98,18 +98,20 @@ class DllExport BINCOL : public DOSCOL { ...@@ -98,18 +98,20 @@ class DllExport BINCOL : public DOSCOL {
/* This is the class declaration for the DBF columns catalog table. */ /* This is the class declaration for the DBF columns catalog table. */
/***********************************************************************/ /***********************************************************************/
class TDBDCL : public TDBCAT { class TDBDCL : public TDBCAT {
public: public:
// Constructor // Constructor
TDBDCL(PDOSDEF tdp) : TDBCAT(tdp) {Fn = tdp->GetFn();} TDBDCL(PDOSDEF tdp) : TDBCAT(tdp)
{Fn = tdp->GetFn(); Topt = tdp->GetTopt();}
protected: protected:
// Specific routines // Specific routines
virtual PQRYRES GetResult(PGLOBAL g) virtual PQRYRES GetResult(PGLOBAL g)
{return DBFColumns(g, ((PTABDEF)To_Def)->GetPath(), Fn, false);} {return DBFColumns(g, ((PTABDEF)To_Def)->GetPath(), Fn, Topt, false);}
// Members // Members
PCSZ Fn; // The DBF file (path) name PCSZ Fn; // The DBF file (path) name
}; // end of class TDBOCL PTOS Topt;
}; // end of class TDBOCL
#endif // __TABFIX__ #endif // __TABFIX__
...@@ -739,6 +739,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -739,6 +739,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
/***********************************************************************/ /***********************************************************************/
TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp) TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
{ {
G = NULL;
Top = NULL; Top = NULL;
Row = NULL; Row = NULL;
Val = NULL; Val = NULL;
......
...@@ -104,7 +104,6 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */ ...@@ -104,7 +104,6 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */
PCSZ Xcol; /* Name of expandable column */ PCSZ Xcol; /* Name of expandable column */
int Limit; /* Limit of multiple values */ int Limit; /* Limit of multiple values */
int Pretty; /* Depends on file structure */ int Pretty; /* Depends on file structure */
int Level; /* Used for catalog table */
int Base; /* The array index base */ int Base; /* The array index base */
bool Strict; /* Strict syntax checking */ bool Strict; /* Strict syntax checking */
char Sep; /* The Jpath separator */ char Sep; /* The Jpath separator */
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "filamzip.h" #include "filamzip.h"
#include "resource.h" // for IDS_COLUMNS #include "resource.h" // for IDS_COLUMNS
#include "tabdos.h" #include "tabdos.h"
#include "tabmul.h"
#include "tabzip.h" #include "tabzip.h"
/* -------------------------- Class ZIPDEF --------------------------- */ /* -------------------------- Class ZIPDEF --------------------------- */
...@@ -41,7 +42,14 @@ bool ZIPDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -41,7 +42,14 @@ bool ZIPDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/ /***********************************************************************/
PTDB ZIPDEF::GetTable(PGLOBAL g, MODE m) PTDB ZIPDEF::GetTable(PGLOBAL g, MODE m)
{ {
return new(g) TDBZIP(this); PTDB tdbp = NULL;
tdbp = new(g) TDBZIP(this);
if (Multiple)
tdbp = new(g) TDBMUL(tdbp);
return tdbp;
} // end of GetTable } // end of GetTable
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
...@@ -108,7 +116,7 @@ int TDBZIP::Cardinality(PGLOBAL g) ...@@ -108,7 +116,7 @@ int TDBZIP::Cardinality(PGLOBAL g)
Cardinal = (err == UNZ_OK) ? (int)ginfo.number_entry : 0; Cardinal = (err == UNZ_OK) ? (int)ginfo.number_entry : 0;
} else } else
Cardinal = 0; Cardinal = 10; // Dummy for multiple tables
} // endif Cardinal } // endif Cardinal
...@@ -187,6 +195,7 @@ int TDBZIP::DeleteDB(PGLOBAL g, int irc) ...@@ -187,6 +195,7 @@ int TDBZIP::DeleteDB(PGLOBAL g, int irc)
void TDBZIP::CloseDB(PGLOBAL g) void TDBZIP::CloseDB(PGLOBAL g)
{ {
close(); close();
nexterr = UNZ_OK; // For multiple tables
Use = USE_READY; // Just to be clean Use = USE_READY; // Just to be clean
} // end of CloseDB } // end of CloseDB
......
...@@ -48,6 +48,8 @@ class DllExport TDBZIP : public TDBASE { ...@@ -48,6 +48,8 @@ class DllExport TDBZIP : public TDBASE {
// Implementation // Implementation
virtual AMT GetAmType(void) {return TYPE_AM_ZIP;} virtual AMT GetAmType(void) {return TYPE_AM_ZIP;}
virtual PCSZ GetFile(PGLOBAL) {return zfn;}
virtual void SetFile(PGLOBAL, PCSZ fn) {zfn = fn;}
// Methods // Methods
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment