Commit e6b563f8 authored by Olivier Bertrand's avatar Olivier Bertrand

Fix some XML table type bugs:

- in DOMNODELIST::DropItem
  if (Listp == NULL || Listp->length <= n)
    return true;
is wrong, should be:
  if (Listp == NULL || Listp->length < n)
    return true;
- Crash in discovery with libxml2 in XMLColumns because:
            if (!tdp->Usedom)    // nl was destroyed
              vp->nl = vp->pn->GetChildElements(g);
is executed with vp->pn uninitialized. Fixed by adding:
          vp->pn = node;
line 264.
-In discovery with libxml2 some columns are not found.
Because list was not recovered properly, nodes being modified and not reallocated.
Fixed lines 214 and 277.
  modified:   storage/connect/domdoc.cpp
  modified:   storage/connect/tabxml.cpp

Add support for zipped table files
  modified:   storage/connect/domdoc.cpp
  modified:   storage/connect/domdoc.h
  modified:   storage/connect/filamap.cpp
  modified:   storage/connect/filamap.h
  modified:   storage/connect/filamzip.cpp
  modified:   storage/connect/filamzip.h
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/libdoc.cpp
  modified:   storage/connect/plgdbutl.cpp
  modified:   storage/connect/plgxml.cpp
  modified:   storage/connect/plgxml.h
  modified:   storage/connect/tabdos.cpp
  modified:   storage/connect/tabdos.h
  modified:   storage/connect/tabfmt.cpp
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabxml.cpp
parent 95230650
......@@ -89,30 +89,43 @@ DOMDOC::DOMDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
/******************************************************************/
/* Initialize XML parser and check library compatibility. */
/******************************************************************/
bool DOMDOC::Initialize(PGLOBAL g)
{
if (TestHr(g, CoInitialize(NULL)))
bool DOMDOC::Initialize(PGLOBAL g, char *entry, bool zipped)
{
if (zipped && InitZip(g, entry))
return true;
if (TestHr(g, CoInitialize(NULL)))
return true;
if (TestHr(g, Docp.CreateInstance("msxml2.domdocument")))
return true;
return MakeNSlist(g);
} // end of Initialize
} // end of Initialize
/******************************************************************/
/* Parse the XML file and construct node tree in memory. */
/******************************************************************/
bool DOMDOC::ParseFile(char *fn)
{
// Load the document
bool DOMDOC::ParseFile(PGLOBAL g, char *fn)
{
bool b;
Docp->async = false;
if (!(bool)Docp->load((_bstr_t)fn))
if (zip) {
// Parse an in memory document
char *xdoc = GetMemDoc(g, fn);
b = (xdoc) ? (bool)Docp->loadXML((_bstr_t)xdoc) : false;
} else
// Load the document
b = (bool)Docp->load((_bstr_t)fn);
if (!b)
return true;
return false;
} // end of ParseFile
} // end of ParseFile
/******************************************************************/
/* Create or reuse an Xblock for this document. */
......@@ -239,6 +252,7 @@ int DOMDOC::DumpDoc(PGLOBAL g, char *ofn)
void DOMDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
{
CloseXMLFile(g, xp, false);
CloseZip();
} // end of Close
/* ----------------------- class DOMNODE ------------------------ */
......@@ -616,13 +630,13 @@ PXNODE DOMNODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
/* Reset the pointer on the deleted item. */
/******************************************************************/
bool DOMNODELIST::DropItem(PGLOBAL g, int n)
{
if (Listp == NULL || Listp->length <= n)
return true;
{
if (Listp == NULL || Listp->length < n)
return true;
//Listp->item[n] = NULL; La proprit n'a pas de mthode 'set'
return false;
} // end of DeleteItem
} // end of DeleteItem
/* ----------------------- class DOMATTR ------------------------ */
......
......@@ -37,8 +37,8 @@ class DOMDOC : public XMLDOCUMENT {
virtual void SetNofree(bool b) {} // Only libxml2
// Methods
virtual bool Initialize(PGLOBAL g);
virtual bool ParseFile(char *fn);
virtual bool Initialize(PGLOBAL g, char *entry, bool zipped);
virtual bool ParseFile(PGLOBAL g, char *fn);
virtual bool NewDoc(PGLOBAL g, char *ver);
virtual void AddComment(PGLOBAL g, char *com);
virtual PXNODE GetRoot(PGLOBAL g);
......
......@@ -319,11 +319,13 @@ int MAPFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
int MAPFAM::ReadBuffer(PGLOBAL g)
{
int len;
int rc, len;
// Are we at the end of the memory
if (Mempos >= Top)
return RC_EF;
if (Mempos >= Top)
if ((rc = GetNext(g)) != RC_OK)
return rc;
if (!Placed) {
/*******************************************************************/
......@@ -341,8 +343,10 @@ int MAPFAM::ReadBuffer(PGLOBAL g)
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
if ((rc = GetNext(g)) != RC_OK)
return rc;
case RC_NF:
// Skip this record
if ((rc = SkipRecord(g, false)) != RC_OK)
return rc;
......@@ -569,7 +573,7 @@ int MBKFAM::GetRowID(void)
/***********************************************************************/
int MBKFAM::ReadBuffer(PGLOBAL g)
{
int len;
int rc, len;
/*********************************************************************/
/* Sequential block reading when Placed is not true. */
......@@ -577,8 +581,10 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
if (Placed) {
Placed = false;
} else if (Mempos >= Top) { // Are we at the end of the memory
return RC_EF;
} else if (++CurNum < Nrec) {
if ((rc = GetNext(g)) != RC_OK)
return rc;
} else if (++CurNum < Nrec) {
Fpos = Mempos;
} else {
/*******************************************************************/
......@@ -588,7 +594,8 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
next:
if (++CurBlk >= Block)
return RC_EF;
if ((rc = GetNext(g)) != RC_OK)
return rc;
/*******************************************************************/
/* Before reading a new block, check whether block optimization */
......@@ -596,8 +603,11 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
if ((rc = GetNext(g)) != RC_OK)
return rc;
break;
case RC_NF:
goto next;
} // endswitch rc
......@@ -697,14 +707,18 @@ int MPXFAM::InitDelete(PGLOBAL, int fpos, int)
/***********************************************************************/
int MPXFAM::ReadBuffer(PGLOBAL g)
{
int rc;
/*********************************************************************/
/* Sequential block reading when Placed is not true. */
/*********************************************************************/
if (Placed) {
Placed = false;
} else if (Mempos >= Top) { // Are we at the end of the memory
return RC_EF;
} else if (++CurNum < Nrec) {
if ((rc = GetNext(g)) != RC_OK)
return rc;
} else if (++CurNum < Nrec) {
Fpos = Mempos;
} else {
/*******************************************************************/
......@@ -714,7 +728,7 @@ int MPXFAM::ReadBuffer(PGLOBAL g)
next:
if (++CurBlk >= Block)
return RC_EF;
return GetNext(g);
/*******************************************************************/
/* Before reading a new block, check whether block optimization */
......@@ -722,8 +736,11 @@ int MPXFAM::ReadBuffer(PGLOBAL g)
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
if ((rc = GetNext(g)) != RC_OK)
return rc;
break;
case RC_NF:
goto next;
} // endswitch rc
......
......@@ -41,7 +41,8 @@ class DllExport MAPFAM : public TXTFAM {
virtual int SkipRecord(PGLOBAL g, bool header);
virtual bool OpenTableFile(PGLOBAL g);
virtual bool DeferReading(void) {return false;}
virtual int ReadBuffer(PGLOBAL g);
virtual int GetNext(PGLOBAL g) {return RC_EF;}
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g, bool abort);
......
This diff is collapsed.
......@@ -17,67 +17,101 @@
typedef class ZIPFAM *PZIPFAM;
typedef class ZPXFAM *PZPXFAM;
/***********************************************************************/
/* This is the ZIP utility fonctions class. */
/***********************************************************************/
class DllExport ZIPUTIL : public BLOCK {
public:
// Constructor
ZIPUTIL(PSZ tgt, bool mul);
//ZIPUTIL(ZIPUTIL *zutp);
// Implementation
//PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZIPFAM(this); }
// Methods
virtual bool OpenTable(PGLOBAL g, MODE mode, char *fn);
bool open(PGLOBAL g, char *fn);
bool openEntry(PGLOBAL g);
void close(void);
void closeEntry(void);
bool WildMatch(PSZ pat, PSZ str);
int findEntry(PGLOBAL g, bool next);
int nextEntry(PGLOBAL g);
// Members
unzFile zipfile; // The ZIP container file
PSZ target; // The target file name
unz_file_info finfo; // The current file info
PFBLOCK fp;
char *memory;
uint size;
int multiple; // Multiple targets
bool entryopen; // True when open current entry
char fn[FILENAME_MAX]; // The current entry file name
char mapCaseTable[256];
}; // end of ZIPFAM
/***********************************************************************/
/* This is the ZIP file access method. */
/***********************************************************************/
class DllExport ZIPFAM : public MAPFAM {
friend class ZPXFAM;
public:
// Constructor
// Constructors
ZIPFAM(PDOSDEF tdp);
ZIPFAM(PZIPFAM txfp);
ZIPFAM(PDOSDEF tdp, PZPXFAM txfp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_ZIP;}
virtual PTXF Duplicate(PGLOBAL g) {return (PTXF) new(g) ZIPFAM(this);}
virtual AMT GetAmType(void) { return TYPE_AM_ZIP; }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZIPFAM(this); }
// Methods
virtual int Cardinality(PGLOBAL g);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g) {return (g) ? 10 : 1;}
//virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
virtual bool OpenTableFile(PGLOBAL g);
virtual bool DeferReading(void) {return false;}
virtual int ReadBuffer(PGLOBAL g);
virtual bool DeferReading(void) { return false; }
virtual int GetNext(PGLOBAL g);
//virtual int ReadBuffer(PGLOBAL g);
//virtual int WriteBuffer(PGLOBAL g);
//virtual int DeleteRecords(PGLOBAL g, int irc);
//virtual void CloseTableFile(PGLOBAL g, bool abort);
void close(void);
protected:
bool open(PGLOBAL g, const char *filename);
bool openEntry(PGLOBAL g);
void closeEntry(void);
bool WildMatch(PSZ pat, PSZ str);
int findEntry(PGLOBAL g, bool next);
// Members
unzFile zipfile; // The ZIP container file
//PSZ zfn; // The ZIP file name
PSZ target; // The target file name
unz_file_info finfo; // The current file info
//char fn[FILENAME_MAX]; // The current file name
bool entryopen; // True when open current entry
int multiple; // Multiple targets
char mapCaseTable[256];
ZIPUTIL *zutp;
PSZ target;
bool mul;
}; // end of ZIPFAM
/***********************************************************************/
/* This is the fixed ZIP file access method. */
/***********************************************************************/
class DllExport ZPXFAM : public ZIPFAM {
class DllExport ZPXFAM : public MPXFAM {
friend class ZIPFAM;
public:
// Constructor
// Constructors
ZPXFAM(PDOSDEF tdp);
ZPXFAM(PZPXFAM txfp);
// Implementation
virtual PTXF Duplicate(PGLOBAL g) {return (PTXF) new(g) ZPXFAM(this);}
virtual AMT GetAmType(void) { return TYPE_AM_ZIP; }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZPXFAM(this); }
// Methods
virtual int ReadBuffer(PGLOBAL g);
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:
// Members
int Lrecl;
ZIPUTIL *zutp;
PSZ target;
bool mul;
}; // end of ZPXFAM
#endif // __FILAMZIP_H
......@@ -1242,8 +1242,10 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
if (opval && (!stricmp(opname, "connect")
|| !stricmp(opname, "tabname")
|| !stricmp(opname, "filename")))
opval = GetRealString(opval);
|| !stricmp(opname, "filename")
|| !stricmp(opname, "optname")
|| !stricmp(opname, "entry")))
opval = GetRealString(opval);
if (!opval) {
if (sdef && !strcmp(sdef, "*")) {
......
/******************************************************************/
/* Implementation of XML document processing using libxml2 */
/* Author: Olivier Bertrand 2007-2015 */
/* Author: Olivier Bertrand 2007-2016 */
/******************************************************************/
#include "my_global.h"
#include <string.h>
......@@ -68,8 +68,8 @@ class LIBXMLDOC : public XMLDOCUMENT {
virtual void SetNofree(bool b) {Nofreelist = b;}
// Methods
virtual bool Initialize(PGLOBAL g);
virtual bool ParseFile(char *fn);
virtual bool Initialize(PGLOBAL g, char *entry, bool zipped);
virtual bool ParseFile(PGLOBAL g, char *fn);
virtual bool NewDoc(PGLOBAL g, char *ver);
virtual void AddComment(PGLOBAL g, char *com);
virtual PXNODE GetRoot(PGLOBAL g);
......@@ -373,22 +373,33 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
/******************************************************************/
/* Initialize XML parser and check library compatibility. */
/******************************************************************/
bool LIBXMLDOC::Initialize(PGLOBAL g)
{
bool LIBXMLDOC::Initialize(PGLOBAL g, char *entry, bool zipped)
{
if (zipped && InitZip(g, entry))
return true;
int n = xmlKeepBlanksDefault(1);
return MakeNSlist(g);
} // end of Initialize
} // end of Initialize
/******************************************************************/
/* Parse the XML file and construct node tree in memory. */
/******************************************************************/
bool LIBXMLDOC::ParseFile(char *fn)
bool LIBXMLDOC::ParseFile(PGLOBAL g, char *fn)
{
if (trace)
htrc("ParseFile\n");
if ((Docp = xmlParseFile(fn))) {
if (Docp->encoding)
if (zip) {
// Parse an in memory document
char *xdoc = GetMemDoc(g, fn);
Docp = (xdoc) ? xmlParseDoc((const xmlChar *)xdoc) : NULL;
} else
Docp = xmlParseFile(fn);
if (Docp) {
if (Docp->encoding)
Encoding = (char*)Docp->encoding;
return false;
......@@ -609,6 +620,7 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
} // endif xp
CloseXML2File(g, xp, false);
CloseZip();
} // end of Close
/******************************************************************/
......
......@@ -939,7 +939,7 @@ int PlugCloseFile(PGLOBAL g __attribute__((unused)), PFBLOCK fp, bool all)
#endif // LIBXML2_SUPPORT
#ifdef ZIP_SUPPORT
case TYPE_FB_ZIP:
((PZIPFAM)fp->File)->close();
((ZIPUTIL*)fp->File)->close();
fp->Memory = NULL;
fp->Mode = MODE_ANY;
fp->Count = 0;
......
......@@ -30,19 +30,51 @@ PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf,
/* XMLDOCUMENT constructor. */
/******************************************************************/
XMLDOCUMENT::XMLDOCUMENT(char *nsl, char *nsdf, char *enc)
{
Namespaces = NULL;
{
#if defined(ZIP_SUPPORT)
zip = NULL;
#else // !ZIP_SUPPORT
zip = false;
#endif // !ZIP_SUPPORT
Namespaces = NULL;
Encoding = enc;
Nslist = nsl;
DefNs = nsdf;
} // end of XMLDOCUMENT constructor
} // end of XMLDOCUMENT constructor
/******************************************************************/
/* Initialize zipped file processing. */
/******************************************************************/
bool XMLDOCUMENT::InitZip(PGLOBAL g, char *entry)
{
#if defined(ZIP_SUPPORT)
bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false;
zip = new(g) ZIPUTIL(entry, mul);
return zip == NULL;
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return true;
#endif // !ZIP_SUPPORT
} // end of InitZip
/******************************************************************/
/* Make the namespace structure list. */
/******************************************************************/
char* XMLDOCUMENT::GetMemDoc(PGLOBAL g, char *fn)
{
#if defined(ZIP_SUPPORT)
return (zip->OpenTable(g, MODE_ANY, fn)) ? NULL : zip->memory;
#else // !ZIP_SUPPORT
return NULL;
#endif // !ZIP_SUPPORT
} // end of GetMemDoc
/******************************************************************/
/* Make the namespace structure list. */
/******************************************************************/
bool XMLDOCUMENT::MakeNSlist(PGLOBAL g)
{
char *prefix, *href, *next = Nslist;
{
char *prefix, *href, *next = Nslist;
PNS nsp, *ppns = &Namespaces;
while (next) {
......@@ -83,6 +115,19 @@ bool XMLDOCUMENT::MakeNSlist(PGLOBAL g)
return false;
} // end of MakeNSlist
/******************************************************************/
/* Close ZIP file. */
/******************************************************************/
void XMLDOCUMENT::CloseZip(void)
{
#if defined(ZIP_SUPPORT)
if (zip) {
zip->close();
zip = NULL;
} // endif zip
#endif // ZIP_SUPPORT
} // end of CloseZip
/******************************************************************/
/* XMLNODE constructor. */
/******************************************************************/
......
#if defined(ZIP_SUPPORT)
#include "filamzip.h"
#endif // ZIP_SUPPORT
/******************************************************************/
/* Dual XML implementation base classes defines. */
/******************************************************************/
......@@ -72,8 +76,8 @@ class XMLDOCUMENT : public BLOCK {
virtual void SetNofree(bool b) = 0;
// Methods
virtual bool Initialize(PGLOBAL) = 0;
virtual bool ParseFile(char *) = 0;
virtual bool Initialize(PGLOBAL, char *, bool) = 0;
virtual bool ParseFile(PGLOBAL, char *) = 0;
virtual bool NewDoc(PGLOBAL, char *) = 0;
virtual void AddComment(PGLOBAL, char *) = 0;
virtual PXNODE GetRoot(PGLOBAL) = 0;
......@@ -91,8 +95,16 @@ class XMLDOCUMENT : public BLOCK {
// Utility
bool MakeNSlist(PGLOBAL g);
bool InitZip(PGLOBAL g, char *entry);
char *GetMemDoc(PGLOBAL g, char *fn);
void CloseZip(void);
// Members
#if defined(ZIP_SUPPORT)
ZIPUTIL *zip; /* Used for zipped file */
#else // !ZIP_SUPPORT
bool zip; /* Always false */
#endif // !ZIP_SUPPORT
PNS Namespaces; /* To the namespaces */
char *Encoding; /* The document encoding */
char *Nslist; /* Namespace list */
......
......@@ -101,6 +101,7 @@ DOSDEF::DOSDEF(void)
Recfm = RECFM_VAR;
Mapped = false;
Zipped = false;
Mulentries = false;
Padded = false;
Huge = false;
Accept = false;
......@@ -131,12 +132,13 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
: (am && (*am == 'B' || *am == 'b')) ? "B"
: (am && !stricmp(am, "DBF")) ? "D" : "V";
if (*dfm != 'D')
Zipped = GetBoolCatInfo("Zipped", false);
if ((Zipped = GetBoolCatInfo("Zipped", false)))
Mulentries = ((Entry = GetStringCatInfo(g, "Entry", NULL)))
? strchr(Entry, '*') || strchr(Entry, '?')
: GetBoolCatInfo("Mulentries", false);
Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
Ofn = GetStringCatInfo(g, "Optname", Fn);
Entry = GetStringCatInfo(g, "Entry", NULL);
GetCharCatInfo("Recfm", (PSZ)dfm, buf, sizeof(buf));
Recfm = (toupper(*buf) == 'F') ? RECFM_FIX :
(toupper(*buf) == 'B') ? RECFM_BIN :
......@@ -344,14 +346,16 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
/*********************************************************************/
if (Zipped) {
#if defined(ZIP_SUPPORT)
if (Recfm == RECFM_VAR)
txfp = new(g) ZIPFAM(this);
else
txfp = new(g) ZPXFAM(this);
if (Recfm == RECFM_VAR) {
txfp = new(g)ZIPFAM(this);
tdbp = new(g)TDBDOS(this, txfp);
} else {
txfp = new(g)ZPXFAM(this);
tdbp = new(g)TDBFIX(this, txfp);
} // endif Recfm
tdbp = new(g) TDBDOS(this, txfp);
#else // !ZIP_SUPPORT
strcpy(g->Message, "ZIP not supported");
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
} else if (Recfm == RECFM_DBF) {
......@@ -559,7 +563,7 @@ int TDBDOS::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
Txfp->Reset();
((PZLBFAM)Txfp)->SetOptimized(false);
#endif // GZ_SUPPORT
} else if (Txfp->GetAmType() == TYPE_AM_BLK)
} else if (Txfp->GetAmType() == TYPE_AM_BLK)
Txfp = new(g) DOSFAM((PDOSDEF)To_Def);
Txfp->SetTdbp(this);
......@@ -630,7 +634,12 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
defp->SetOptimized(0);
// Estimate the number of needed blocks
block = (int)((MaxSize + (int)nrec - 1) / (int)nrec);
if ((block = (int)((MaxSize + (int)nrec - 1) / (int)nrec)) < 2) {
// This may be wrong to do in some cases
defp->RemoveOptValues(g);
strcpy(g->Message, MSG(TABLE_NOT_OPT));
return RC_INFO; // Not to be optimized
} // endif block
// We have to use local variables because Txfp->CurBlk is set
// to Rows+1 by unblocked variable length table access methods.
......@@ -973,13 +982,14 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
PCOLDEF cdp;
PDOSDEF defp = (PDOSDEF)To_Def;
PCATLG cat = defp->GetCat();
PDBUSER dup = PlgGetUser(g);
#if 0
if (Mode == MODE_INSERT && Txfp->GetAmType() == TYPE_AM_DOS)
return false;
#endif // __WIN__
if (defp->Optimized)
if (defp->Optimized || !(dup->Check & CHK_OPT))
return false; // Already done or to be redone
if (Ftype == RECFM_VAR || defp->Compressed == 2) {
......
......@@ -28,7 +28,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
friend class TDBFIX;
friend class TXTFAM;
friend class DBFBASE;
friend class ZIPFAM;
friend class ZIPUTIL;
public:
// Constructor
DOSDEF(void);
......@@ -41,7 +41,9 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
virtual bool IsHuge(void) {return Huge;}
PSZ GetFn(void) {return Fn;}
PSZ GetOfn(void) {return Ofn;}
void SetBlock(int block) {Block = block;}
PSZ GetEntry(void) {return Entry;}
bool GetMul(void) {return Mulentries;}
void SetBlock(int block) {Block = block;}
int GetBlock(void) {return Block;}
int GetLast(void) {return Last;}
void SetLast(int last) {Last = last;}
......@@ -58,9 +60,9 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int *GetTo_Pos(void) {return To_Pos;}
// Methods
virtual int Indexable(void)
{return (!Multiple && !Zipped && Compressed != 1) ? 1 : 0;}
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual int Indexable(void)
{return (!Multiple && !Mulentries && Compressed != 1) ? 1 : 0;}
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
bool InvalidateIndex(PGLOBAL g);
......@@ -78,6 +80,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
RECFM Recfm; /* 0:VAR, 1:FIX, 2:BIN, 3:VCT, 6:DBF */
bool Mapped; /* 0: disk file, 1: memory mapped file */
bool Zipped; /* true for zipped table file */
bool Mulentries; /* true for multiple entries */
bool Padded; /* true for padded table file */
bool Huge; /* true for files larger than 2GB */
bool Accept; /* true if wrong lines are accepted */
......
......@@ -177,9 +177,14 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info)
htrc("File %s Sep=%c Qot=%c Header=%d maxerr=%d\n",
SVP(tdp->Fn), tdp->Sep, tdp->Qot, tdp->Header, tdp->Maxerr);
if (tdp->Zipped)
tdbp = new(g) TDBCSV(tdp, new(g) ZIPFAM(tdp));
else
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
tdbp = new(g)TDBCSV(tdp, new(g)ZIPFAM(tdp));
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
} else
tdbp = new(g) TDBCSV(tdp, new(g) DOSFAM(tdp));
tdbp->SetMode(MODE_READ);
......
......@@ -127,9 +127,14 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
if (tdp->Pretty == 2) {
if (tdp->Zipped)
tjsp = new(g) TDBJSON(tdp, new(g) ZIPFAM(tdp));
else
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
tjsp = new(g) TDBJSON(tdp, new(g) ZIPFAM(tdp));
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
} else
tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
if (tjsp->MakeDocument(g))
......@@ -144,9 +149,14 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
if (tdp->Zipped)
tjnp = new(g) TDBJSN(tdp, new(g) ZIPFAM(tdp));
else
if (tdp->Zipped) {
#if defined(ZIP_SUPPORT)
tjnp = new(g)TDBJSN(tdp, new(g)ZIPFAM(tdp));
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
} else
tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
tjnp->SetMode(MODE_READ);
......@@ -467,9 +477,14 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
((TDBJSN*)tdbp)->G = g;
#endif
} else {
if (Zipped)
txfp = new(g) ZIPFAM(this);
else
if (Zipped) {
#if defined(ZIP_SUPPORT)
txfp = new(g)ZIPFAM(this);
#else // !ZIP_SUPPORT
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif // !ZIP_SUPPORT
} else
txfp = new(g) MAPFAM(this);
tdbp = new(g) TDBJSON(this, txfp);
......
/************* Tabxml C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABXML */
/* ------------- */
/* Version 2.8 */
/* Version 2.9 */
/* */
/* Author Olivier BERTRAND 2007 - 2015 */
/* Author Olivier BERTRAND 2007 - 2016 */
/* */
/* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/
......@@ -159,6 +159,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
tdp->Fn = fn;
tdp->Database = SetPath(g, db);
tdp->Tabname = tab;
tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL)))
#if defined(__WIN__)
......@@ -209,7 +211,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
while (true) {
if (!vp->atp &&
!(node = (vp->nl) ? vp->nl->GetItem(g, vp->k++, node) : NULL))
!(node = (vp->nl) ? vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL)
: NULL))
if (j) {
vp = lvlp[--j];
......@@ -259,7 +262,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (j < lvl && ok) {
vp = lvlp[j+1];
vp->k = 0;
vp->atp = node->GetAttribute(g, NULL);
vp->pn = node;
vp->atp = node->GetAttribute(g, NULL);
vp->nl = node->GetChildElements(g);
if (tdp->Usedom && vp->nl->GetLength() == 1) {
......@@ -270,7 +274,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (vp->atp || vp->b) {
if (!vp->atp)
node = vp->nl->GetItem(g, vp->k++, node);
node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL);
strncat(fmt, colname, XLEN(fmt));
strncat(fmt, "/", XLEN(fmt));
......@@ -429,11 +433,14 @@ XMLDEF::XMLDEF(void)
DefNs = NULL;
Attrib = NULL;
Hdattr = NULL;
Entry = NULL;
Coltype = 1;
Limit = 0;
Header = 0;
Xpand = false;
Usedom = false;
Zipped = false;
Mulentries = false;
} // end of XMLDEF constructor
/***********************************************************************/
......@@ -512,7 +519,14 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Get eventual table node attribute
Attrib = GetStringCatInfo(g, "Attribute", NULL);
Hdattr = GetStringCatInfo(g, "HeadAttr", NULL);
return false;
// Specific for zipped files
if ((Zipped = GetBoolCatInfo("Zipped", false)))
Mulentries = ((Entry = GetStringCatInfo(g, "Entry", NULL)))
? strchr(Entry, '*') || strchr(Entry, '?')
: GetBoolCatInfo("Mulentries", false);
return false;
} // end of DefineAM
/***********************************************************************/
......@@ -552,6 +566,7 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
Xfile = tdp->Fn;
Enc = tdp->Encoding;
Tabname = tdp->Tabname;
#if 0 // why all these?
Rowname = (tdp->Rowname) ? tdp->Rowname : NULL;
Colname = (tdp->Colname) ? tdp->Colname : NULL;
Mulnode = (tdp->Mulnode) ? tdp->Mulnode : NULL;
......@@ -560,10 +575,22 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
DefNs = (tdp->DefNs) ? tdp->DefNs : NULL;
Attrib = (tdp->Attrib) ? tdp->Attrib : NULL;
Hdattr = (tdp->Hdattr) ? tdp->Hdattr : NULL;
Coltype = tdp->Coltype;
#endif // 0
Rowname = tdp->Rowname;
Colname = tdp->Colname;
Mulnode = tdp->Mulnode;
XmlDB = tdp->XmlDB;
Nslist = tdp->Nslist;
DefNs = tdp->DefNs;
Attrib = tdp->Attrib;
Hdattr = tdp->Hdattr;
Entry = tdp->Entry;
Coltype = tdp->Coltype;
Limit = tdp->Limit;
Xpand = tdp->Xpand;
Changed = false;
Zipped = tdp->Zipped;
Mulentries = tdp->Mulentries;
Changed = false;
Checked = false;
NextSame = false;
NewRow = false;
......@@ -605,10 +632,13 @@ TDBXML::TDBXML(PTDBXML tdbp) : TDBASE(tdbp)
DefNs = tdbp->DefNs;
Attrib = tdbp->Attrib;
Hdattr = tdbp->Hdattr;
Coltype = tdbp->Coltype;
Entry = tdbp->Entry;
Coltype = tdbp->Coltype;
Limit = tdbp->Limit;
Xpand = tdbp->Xpand;
Changed = tdbp->Changed;
Zipped = tdbp->Zipped;
Mulentries = tdbp->Mulentries;
Changed = tdbp->Changed;
Checked = tdbp->Checked;
NextSame = tdbp->NextSame;
NewRow = tdbp->NewRow;
......@@ -686,7 +716,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
/*********************************************************************/
/* Firstly we check whether this file have been already loaded. */
/*********************************************************************/
if (Mode == MODE_READ || Mode == MODE_ANY)
if ((Mode == MODE_READ || Mode == MODE_ANY) && !Zipped)
for (fp = dup->Openlist; fp; fp = fp->Next)
if (fp->Type == type && fp->Length && fp->Count)
if (!stricmp(fp->Fname, filename))
......@@ -708,7 +738,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
return RC_FX;
// Initialize the implementation
if (Docp->Initialize(g)) {
if (Docp->Initialize(g, Entry, Zipped)) {
sprintf(g->Message, MSG(INIT_FAILED), (Usedom) ? "DOM" : "libxml2");
return RC_FX;
} // endif init
......@@ -717,7 +747,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
htrc("TDBXML: parsing %s rc=%d\n", filename, rc);
// Parse the XML file
if (Docp->ParseFile(filename)) {
if (Docp->ParseFile(g, filename)) {
// Does the file exist?
int h= global_open(g, MSGID_NONE, filename, _O_RDONLY);
......
/*************** Tabxml H Declares Source Code File (.H) ***************/
/* Name: TABXML.H Version 1.6 */
/* Name: TABXML.H Version 1.7 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2007-2015 */
/* (C) Copyright to the author Olivier BERTRAND 2007-2016 */
/* */
/* This file contains the XML table classes declares. */
/***********************************************************************/
......@@ -42,12 +42,15 @@ class DllExport XMLDEF : public TABDEF { /* Logical table description */
char *DefNs; /* Dummy name of default namespace */
char *Attrib; /* Table node attributes */
char *Hdattr; /* Header node attributes */
int Coltype; /* Default column type */
char *Entry; /* Zip entry name or pattern */
int Coltype; /* Default column type */
int Limit; /* Limit of multiple values */
int Header; /* n first rows are header rows */
bool Xpand; /* Put multiple tags in several rows */
bool Usedom; /* True: DOM, False: libxml2 */
}; // end of XMLDEF
bool Zipped; /* True: Zipped XML file(s) */
bool Mulentries; /* True: multiple entries in zip file*/
}; // end of XMLDEF
#if defined(INCLUDE_TDBXML)
/***********************************************************************/
......@@ -122,7 +125,9 @@ class DllExport TDBXML : public TDBASE {
bool Bufdone; // True when column buffers allocated
bool Nodedone; // True when column nodes allocated
bool Void; // True if the file does not exist
char *Xfile; // The XML file
bool Zipped; // True if Zipped XML file(s)
bool Mulentries; // True if multiple entries in zip file
char *Xfile; // The XML file
char *Enc; // New XML table file encoding
char *Tabname; // Name of Table node
char *Rowname; // Name of first level nodes
......@@ -133,7 +138,8 @@ class DllExport TDBXML : public TDBASE {
char *DefNs; // Dummy name of default namespace
char *Attrib; // Table node attribut(s)
char *Hdattr; // Header node attribut(s)
int Coltype; // Default column type
char *Entry; // Zip entry name or pattern
int Coltype; // Default column type
int Limit; // Limit of multiple values
int Header; // n first rows are header rows
int Multiple; // If multiple files
......
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