Commit b3f9838f authored by Olivier Bertrand's avatar Olivier Bertrand

Update 10.1 with changes from 10.0

parent 48a77e61
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "tabcol.h" #include "tabcol.h"
#include "catalog.h" #include "catalog.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h"
#define my_strupr(p) my_caseup_str(default_charset_info, (p)); #define my_strupr(p) my_caseup_str(default_charset_info, (p));
#define my_strlwr(p) my_casedn_str(default_charset_info, (p)); #define my_strlwr(p) my_casedn_str(default_charset_info, (p));
......
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
La ressource de manifeste a ‚t‚ mise … jour pour la derniŠre fois … 15:13:07,47 le 21/03/2015
...@@ -275,7 +275,7 @@ PXNODE DOMNODE::GetNext(PGLOBAL g) ...@@ -275,7 +275,7 @@ PXNODE DOMNODE::GetNext(PGLOBAL g)
{ {
if (Nodep->nextSibling == NULL) if (Nodep->nextSibling == NULL)
Next = NULL; Next = NULL;
else if (!Next) else // if (!Next)
Next = new(g) DOMNODE(Doc, Nodep->nextSibling); Next = new(g) DOMNODE(Doc, Nodep->nextSibling);
return Next; return Next;
...@@ -288,7 +288,7 @@ PXNODE DOMNODE::GetChild(PGLOBAL g) ...@@ -288,7 +288,7 @@ PXNODE DOMNODE::GetChild(PGLOBAL g)
{ {
if (Nodep->firstChild == NULL) if (Nodep->firstChild == NULL)
Children = NULL; Children = NULL;
else if (!Children) else // if (!Children)
Children = new(g) DOMNODE(Doc, Nodep->firstChild); Children = new(g) DOMNODE(Doc, Nodep->firstChild);
return Children; return Children;
...@@ -441,15 +441,27 @@ PXNODE DOMNODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np) ...@@ -441,15 +441,27 @@ PXNODE DOMNODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
/******************************************************************/ /******************************************************************/
PXATTR DOMNODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap) PXATTR DOMNODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
{ {
MSXML2::IXMLDOMElementPtr ep = Nodep; MSXML2::IXMLDOMElementPtr ep;
MSXML2::IXMLDOMAttributePtr atp = ep->getAttributeNode(name); MSXML2::IXMLDOMNamedNodeMapPtr nmp;
MSXML2::IXMLDOMAttributePtr atp;
if (name) {
ep = Nodep;
atp = ep->getAttributeNode(name);
nmp = NULL;
} else {
nmp = Nodep->Getattributes();
atp = nmp->Getitem(0);
} // endif name
if (atp) { if (atp) {
if (ap) { if (ap) {
((PDOMATTR)ap)->Atrp = atp; ((PDOMATTR)ap)->Atrp = atp;
((PDOMATTR)ap)->Nmp = nmp;
((PDOMATTR)ap)->K = 0;
return ap; return ap;
} else } else
return new(g) DOMATTR(Doc, atp); return new(g) DOMATTR(Doc, atp, nmp);
} else } else
return NULL; return NULL;
...@@ -617,14 +629,85 @@ bool DOMNODELIST::DropItem(PGLOBAL g, int n) ...@@ -617,14 +629,85 @@ bool DOMNODELIST::DropItem(PGLOBAL g, int n)
/******************************************************************/ /******************************************************************/
/* DOMATTR constructor. */ /* DOMATTR constructor. */
/******************************************************************/ /******************************************************************/
DOMATTR::DOMATTR(PXDOC dp, MSXML2::IXMLDOMAttributePtr ap) DOMATTR::DOMATTR(PXDOC dp, MSXML2::IXMLDOMAttributePtr ap,
MSXML2::IXMLDOMNamedNodeMapPtr nmp)
: XMLATTRIBUTE(dp) : XMLATTRIBUTE(dp)
{ {
Atrp = ap; Atrp = ap;
Nmp = nmp;
Ws = NULL; Ws = NULL;
Len = 0; Len = 0;
K = 0;
} // end of DOMATTR constructor } // end of DOMATTR constructor
/******************************************************************/
/* Return the attribute name. */
/******************************************************************/
char *DOMATTR::GetName(PGLOBAL g)
{
if (!WideCharToMultiByte(CP_ACP, 0, Atrp->nodeName, -1,
Name, sizeof(Name), NULL, NULL)) {
strcpy(g->Message, MSG(NAME_CONV_ERR));
return NULL;
} // endif
return Name;
} // end of GetName
/******************************************************************/
/* Return the next attribute node. */
/* This funtion is implemented as needed by XMLColumns. */
/******************************************************************/
PXATTR DOMATTR::GetNext(PGLOBAL g)
{
if (!Nmp)
return NULL;
if (++K >= Nmp->Getlength()) {
Nmp->reset();
Nmp = NULL;
K = 0;
return NULL;
} // endif K
Atrp = Nmp->Getitem(K);
return this;
} // end of GetNext
/******************************************************************/
/* Return the content of a node and subnodes. */
/******************************************************************/
RCODE DOMATTR::GetText(PGLOBAL g, char *buf, int len)
{
RCODE rc = RC_OK;
if (!WideCharToMultiByte(CP_UTF8, 0, Atrp->text, -1,
buf, len, NULL, NULL)) {
DWORD lsr = GetLastError();
switch (lsr) {
case 0:
case ERROR_INSUFFICIENT_BUFFER: // 122L
sprintf(g->Message, "Truncated %s content", GetName(g));
rc = RC_INFO;
break;
case ERROR_NO_UNICODE_TRANSLATION: // 1113L
sprintf(g->Message, "Invalid character(s) in %s content",
GetName(g));
rc = RC_INFO;
break;
default:
sprintf(g->Message, "System error getting %s content",
GetName(g));
rc = RC_FX;
break;
} // endswitch
} // endif
return rc;
} // end of GetText
/******************************************************************/ /******************************************************************/
/* Set the text content of an attribute. */ /* Set the text content of an attribute. */
/******************************************************************/ /******************************************************************/
......
...@@ -122,15 +122,24 @@ class DOMATTR : public XMLATTRIBUTE { ...@@ -122,15 +122,24 @@ class DOMATTR : public XMLATTRIBUTE {
friend class DOMDOC; friend class DOMDOC;
friend class DOMNODE; friend class DOMNODE;
public: public:
// Properties
virtual char *GetName(PGLOBAL g);
virtual PXATTR GetNext(PGLOBAL);
// Methods // Methods
virtual RCODE GetText(PGLOBAL g, char *bufp, int len);
virtual bool SetText(PGLOBAL g, char *txtp, int len); virtual bool SetText(PGLOBAL g, char *txtp, int len);
protected: protected:
// Constructor // Constructor
DOMATTR(PXDOC dp, MSXML2::IXMLDOMAttributePtr ap); DOMATTR(PXDOC dp, MSXML2::IXMLDOMAttributePtr ap,
MSXML2::IXMLDOMNamedNodeMapPtr nmp = NULL);
// Members // Members
MSXML2::IXMLDOMAttributePtr Atrp; MSXML2::IXMLDOMAttributePtr Atrp;
MSXML2::IXMLDOMNamedNodeMapPtr Nmp;
char Name[64];
WCHAR *Ws; WCHAR *Ws;
int Len; int Len;
long K;
}; // end of class DOMATTR }; // end of class DOMATTR
...@@ -17,6 +17,7 @@ typedef class MAPFAM *PMAPFAM; ...@@ -17,6 +17,7 @@ typedef class MAPFAM *PMAPFAM;
/* This is the variable file access method using file mapping. */ /* This is the variable file access method using file mapping. */
/***********************************************************************/ /***********************************************************************/
class DllExport MAPFAM : public TXTFAM { class DllExport MAPFAM : public TXTFAM {
friend class TDBJSON;
public: public:
// Constructor // Constructor
MAPFAM(PDOSDEF tdp); MAPFAM(PDOSDEF tdp);
......
...@@ -42,6 +42,7 @@ class DllExport TXTFAM : public BLOCK { ...@@ -42,6 +42,7 @@ class DllExport TXTFAM : public BLOCK {
virtual PTXF Duplicate(PGLOBAL g) = 0; virtual PTXF Duplicate(PGLOBAL g) = 0;
virtual bool GetUseTemp(void) {return false;} virtual bool GetUseTemp(void) {return false;}
virtual int GetDelRows(void) {return DelRows;} virtual int GetDelRows(void) {return DelRows;}
PFBLOCK GetTo_Fb(void) {return To_Fb;}
int GetCurBlk(void) {return CurBlk;} int GetCurBlk(void) {return CurBlk;}
void SetTdbp(PTDBDOS tdbp) {Tdbp = tdbp;} void SetTdbp(PTDBDOS tdbp) {Tdbp = tdbp;}
int GetBlock(void) {return Block;} int GetBlock(void) {return Block;}
......
...@@ -145,7 +145,6 @@ ...@@ -145,7 +145,6 @@
#include "connect.h" #include "connect.h"
#include "user_connect.h" #include "user_connect.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h"
#include "myutil.h" #include "myutil.h"
#include "preparse.h" #include "preparse.h"
#include "inihandl.h" #include "inihandl.h"
...@@ -169,7 +168,7 @@ ...@@ -169,7 +168,7 @@
#define JSONMAX 10 // JSON Default max grp size #define JSONMAX 10 // JSON Default max grp size
extern "C" { extern "C" {
char version[]= "Version 1.03.0006 March 16, 2015"; char version[]= "Version 1.03.0006 April 12, 2015";
#if defined(WIN32) #if defined(WIN32)
char compver[]= "Version 1.03.0006 " __DATE__ " " __TIME__; char compver[]= "Version 1.03.0006 " __DATE__ " " __TIME__;
...@@ -211,6 +210,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); ...@@ -211,6 +210,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, char *tab, char *db, bool info); PQRYRES VirColumns(PGLOBAL g, char *tab, char *db, bool info);
PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
int pretty, int lvl, int mxr, bool info); int pretty, int lvl, int mxr, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *dp, char *tab, PTOS topt, bool info);
void PushWarning(PGLOBAL g, THD *thd, int level); void PushWarning(PGLOBAL g, THD *thd, int level);
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const char *db, char *tab, const char *src, int port); const char *db, char *tab, const char *src, int port);
...@@ -5228,6 +5228,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -5228,6 +5228,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
strcpy(g->Message, "Missing OEM module or subtype"); strcpy(g->Message, "Missing OEM module or subtype");
break; break;
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
case TAB_XML:
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
case TAB_JSON: case TAB_JSON:
if (!fn) if (!fn)
sprintf(g->Message, "Missing %s file name", topt->type); sprintf(g->Message, "Missing %s file name", topt->type);
...@@ -5348,6 +5351,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -5348,6 +5351,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case TAB_JSON: case TAB_JSON:
qrp= JSONColumns(g, (char*)db, fn, objn, pty, lrecl, lvl, fnc == FNC_COL); qrp= JSONColumns(g, (char*)db, fn, objn, pty, lrecl, lvl, fnc == FNC_COL);
break; break;
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
case TAB_XML:
qrp= XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL);
break;
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
case TAB_OEM: case TAB_OEM:
qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL); qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
break; break;
...@@ -5386,6 +5394,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -5386,6 +5394,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
} // endfor crp } // endfor crp
} else { } else {
char *schem= NULL;
// Not a catalog table // Not a catalog table
if (!qrp->Nblin) { if (!qrp->Nblin) {
if (tab) if (tab)
...@@ -5469,6 +5479,19 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -5469,6 +5479,19 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
key= crp->Kdata->GetCharValue(i); key= crp->Kdata->GetCharValue(i);
break; break;
case FLD_SCHEM:
#if defined(ODBC_SUPPORT)
if (ttp == TAB_ODBC && crp->Kdata) {
if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) {
sprintf(g->Message,
"Several %s tables found, specify DBNAME", tab);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
goto err;
} else if (!schem)
schem= crp->Kdata->GetCharValue(i);
} // endif ttp
#endif // ODBC_SUPPORT
default: default:
break; // Ignore break; // Ignore
} // endswitch Fld } // endswitch Fld
...@@ -5790,6 +5813,18 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5790,6 +5813,18 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif type } // endif type
if (type == TAB_JSON) {
int pretty= atoi(GetListOption(g, "Pretty", options->oplist, "2"));
if (!options->lrecl && pretty != 2) {
sprintf(g->Message, "LRECL must be specified for pretty=%d", pretty);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
DBUG_RETURN(rc);
} // endif lrecl
} // endif type
// Check column types // Check column types
for (field= table_arg->field; *field; field++) { for (field= table_arg->field; *field; field++) {
fp= *field; fp= *field;
......
...@@ -26,6 +26,11 @@ ...@@ -26,6 +26,11 @@
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
/****************************************************************************/
/* mycat.h contains the TOS, PTOS, ha_table_option_struct declarations. */
/****************************************************************************/
#include "mycat.h"
static char *strz(PGLOBAL g, LEX_STRING &ls); static char *strz(PGLOBAL g, LEX_STRING &ls);
/****************************************************************************/ /****************************************************************************/
...@@ -68,7 +73,6 @@ class XCHK : public BLOCK { ...@@ -68,7 +73,6 @@ class XCHK : public BLOCK {
typedef class XCHK *PCHK; typedef class XCHK *PCHK;
typedef class user_connect *PCONNECT; typedef class user_connect *PCONNECT;
typedef struct ha_table_option_struct TOS, *PTOS;
typedef struct ha_field_option_struct FOS, *PFOS; typedef struct ha_field_option_struct FOS, *PFOS;
typedef struct ha_index_option_struct XOS, *PXOS; typedef struct ha_index_option_struct XOS, *PXOS;
...@@ -80,6 +84,9 @@ extern handlerton *connect_hton; ...@@ -80,6 +84,9 @@ extern handlerton *connect_hton;
These can be specified in the CREATE TABLE: These can be specified in the CREATE TABLE:
CREATE TABLE ( ... ) {...here...} CREATE TABLE ( ... ) {...here...}
*/ */
#if 0 // moved to mycat.h
typedef struct ha_table_option_struct TOS, *PTOS;
struct ha_table_option_struct { struct ha_table_option_struct {
const char *type; const char *type;
const char *filename; const char *filename;
...@@ -111,6 +118,7 @@ struct ha_table_option_struct { ...@@ -111,6 +118,7 @@ struct ha_table_option_struct {
bool readonly; bool readonly;
bool sepindex; bool sepindex;
}; };
#endif // 0
/** /**
structure for CREATE TABLE options (field options) structure for CREATE TABLE options (field options)
......
...@@ -162,9 +162,11 @@ class XML2ATTR : public XMLATTRIBUTE { ...@@ -162,9 +162,11 @@ class XML2ATTR : public XMLATTRIBUTE {
friend class XML2NODE; friend class XML2NODE;
public: public:
// Properties // Properties
//virtual char *GetText(void); virtual char *GetName(PGLOBAL g) {return (char*)Atrp->name;}
virtual PXATTR GetNext(PGLOBAL g);
// Methods // Methods
virtual RCODE GetText(PGLOBAL g, char *bufp, int len);
virtual bool SetText(PGLOBAL g, char *txtp, int len); virtual bool SetText(PGLOBAL g, char *txtp, int len);
protected: protected:
...@@ -812,7 +814,7 @@ PXNODE XML2NODE::GetNext(PGLOBAL g) ...@@ -812,7 +814,7 @@ PXNODE XML2NODE::GetNext(PGLOBAL g)
if (!Nodep->next) if (!Nodep->next)
Next = NULL; Next = NULL;
else if (!Next) else // if (!Next)
Next = new(g) XML2NODE(Doc, Nodep->next); Next = new(g) XML2NODE(Doc, Nodep->next);
return Next; return Next;
...@@ -828,7 +830,7 @@ PXNODE XML2NODE::GetChild(PGLOBAL g) ...@@ -828,7 +830,7 @@ PXNODE XML2NODE::GetChild(PGLOBAL g)
if (!Nodep->children) if (!Nodep->children)
Children = NULL; Children = NULL;
else if (!Children) else // if (!Children)
Children = new(g) XML2NODE(Doc, Nodep->children); Children = new(g) XML2NODE(Doc, Nodep->children);
return Children; return Children;
...@@ -978,10 +980,16 @@ PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np) ...@@ -978,10 +980,16 @@ PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
/******************************************************************/ /******************************************************************/
PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap) PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
{ {
xmlAttrPtr atp;
if (trace) if (trace)
htrc("GetAttribute: %s\n", name); htrc("GetAttribute: %s\n", SVP(name));
if (name)
atp = xmlHasProp(Nodep, BAD_CAST name);
else
atp = Nodep->properties;
xmlAttrPtr atp = xmlHasProp(Nodep, BAD_CAST name);
if (atp) { if (atp) {
if (ap) { if (ap) {
...@@ -1209,6 +1217,52 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np) ...@@ -1209,6 +1217,52 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np)
Parent = np; Parent = np;
} // end of XML2ATTR constructor } // end of XML2ATTR constructor
/******************************************************************/
/* Return the next sibling of the attribute. */
/******************************************************************/
PXATTR XML2ATTR::GetNext(PGLOBAL g)
{
if (trace)
htrc("Attr GetNext\n");
if (!Atrp->next)
return NULL;
else
return new(g) XML2ATTR(Doc, Atrp->next, Atrp->parent);
} // end of GetNext
/******************************************************************/
/* Return the text of an attribute. */
/******************************************************************/
RCODE XML2ATTR::GetText(PGLOBAL g, char *buf, int len)
{
RCODE rc = RC_OK;
xmlChar *txt;
if (trace)
htrc("GetText\n");
if ((txt = xmlGetProp(Atrp->parent, Atrp->name))) {
// Copy the text to the buffer
if (strlen((char*)txt) >= (unsigned)len) {
memcpy(buf, txt, len - 1);
buf[len - 1] = 0;
sprintf(g->Message, "Truncated %s content", Atrp->name);
rc = RC_INFO;
} else
strcpy(buf, (const char*)txt);
xmlFree(txt);
} else
*buf = '\0';
if (trace)
htrc("GetText: %s\n", buf);
return rc;
} // end of GetText
/******************************************************************/ /******************************************************************/
/* Set the content of an attribute. */ /* Set the content of an attribute. */
/******************************************************************/ /******************************************************************/
......
...@@ -74,9 +74,6 @@ ...@@ -74,9 +74,6 @@
#include "tabxcl.h" #include "tabxcl.h"
#include "tabtbl.h" #include "tabtbl.h"
#include "taboccur.h" #include "taboccur.h"
#if defined(XML_SUPPORT)
#include "tabxml.h"
#endif // XML_SUPPORT
#include "tabmul.h" #include "tabmul.h"
#include "tabmysql.h" #include "tabmysql.h"
#if defined(ODBC_SUPPORT) #if defined(ODBC_SUPPORT)
...@@ -89,7 +86,9 @@ ...@@ -89,7 +86,9 @@
#include "tabvir.h" #include "tabvir.h"
#include "tabjson.h" #include "tabjson.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h" #if defined(XML_SUPPORT)
#include "tabxml.h"
#endif // XML_SUPPORT
/***********************************************************************/ /***********************************************************************/
/* Extern static variables. */ /* Extern static variables. */
......
...@@ -24,6 +24,46 @@ ...@@ -24,6 +24,46 @@
#include "block.h" #include "block.h"
#include "catalog.h" #include "catalog.h"
typedef struct ha_table_option_struct TOS, *PTOS;
/**
structure for CREATE TABLE options (table options)
These can be specified in the CREATE TABLE:
CREATE TABLE ( ... ) {...here...}
*/
struct ha_table_option_struct {
const char *type;
const char *filename;
const char *optname;
const char *tabname;
const char *tablist;
const char *dbname;
const char *separator;
//const char *connect;
const char *qchar;
const char *module;
const char *subtype;
const char *catfunc;
const char *srcdef;
const char *colist;
const char *oplist;
const char *data_charset;
ulonglong lrecl;
ulonglong elements;
//ulonglong estimate;
ulonglong multiple;
ulonglong header;
ulonglong quoted;
ulonglong ending;
ulonglong compressed;
bool mapped;
bool huge;
bool split;
bool readonly;
bool sepindex;
};
// Possible value for catalog functions // Possible value for catalog functions
#define FNC_NO (1 << 0) // Not a catalog table #define FNC_NO (1 << 0) // Not a catalog table
#define FNC_COL (1 << 1) // Column catalog function #define FNC_COL (1 << 1) // Column catalog function
......
...@@ -15,7 +15,7 @@ DATEPUB int(4) ...@@ -15,7 +15,7 @@ DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json'; ) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1; SELECT * FROM t1;
ISBN LANG SUBJECT AUTHOR TITLE TRANSLATION TRANSLATOR PUBLISHER DATEPUB ISBN LANG SUBJECT AUTHOR TITLE TRANSLATION TRANSLATOR PUBLISHER DATEPUB
9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999 9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1; DROP TABLE t1;
# #
...@@ -37,7 +37,7 @@ Year int(4) FIELD_FORMAT='DATEPUB' ...@@ -37,7 +37,7 @@ Year int(4) FIELD_FORMAT='DATEPUB'
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json'; ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1; SELECT * FROM t1;
ISBN Language Subject Authors Title Translation Translator Publisher Location Year ISBN Language Subject Authors Title Translation Translator Publisher Location Year
9782212090819 fr applications 2 Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications 2 Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications 1 XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999 9782840825685 fr applications 1 XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1; DROP TABLE t1;
# #
...@@ -60,7 +60,7 @@ Year int(4) FIELD_FORMAT='DATEPUB' ...@@ -60,7 +60,7 @@ Year int(4) FIELD_FORMAT='DATEPUB'
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json'; ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1; SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Jean-Christophe and Franois Bernadac and Knab Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Jean-Christophe and Franois Bernadac and Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999 9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1; DROP TABLE t1;
# #
...@@ -83,14 +83,14 @@ Year int(4) FIELD_FORMAT='DATEPUB' ...@@ -83,14 +83,14 @@ Year int(4) FIELD_FORMAT='DATEPUB'
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json'; ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT * FROM t1; SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Jean-Christophe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Franois Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999 9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
UPDATE t1 SET AuthorFN = 'Philippe' WHERE AuthorLN = 'Knab'; UPDATE t1 SET AuthorFN = 'Philippe' WHERE AuthorLN = 'Knab';
SELECT * FROM t1 WHERE ISBN = '9782212090819'; SELECT * FROM t1 WHERE ISBN = '9782212090819';
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Philippe Bernadac Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Philippe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Franois Knab Construire une application XML NULL NULL Eyrolles Paris 1999
# #
# To add an author a new table must be created # To add an author a new table must be created
# #
...@@ -104,8 +104,8 @@ William J. Pardi ...@@ -104,8 +104,8 @@ William J. Pardi
INSERT INTO t2 VALUES('Charles','Dickens'); INSERT INTO t2 VALUES('Charles','Dickens');
SELECT * FROM t1; SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications Philippe Bernadac Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Philippe Bernadac Construire une application XML NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Franois Knab Construire une application XML Eyrolles Paris 1999 9782212090819 fr applications Franois Knab Construire une application XML NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999 9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
9782840825685 fr applications Charles Dickens XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999 9782840825685 fr applications Charles Dickens XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1; DROP TABLE t1;
......
...@@ -109,6 +109,7 @@ class XMLNODE : public BLOCK { ...@@ -109,6 +109,7 @@ class XMLNODE : public BLOCK {
virtual int GetType(void) = 0; virtual int GetType(void) = 0;
virtual PXNODE GetNext(PGLOBAL) = 0; virtual PXNODE GetNext(PGLOBAL) = 0;
virtual PXNODE GetChild(PGLOBAL) = 0; virtual PXNODE GetChild(PGLOBAL) = 0;
virtual int GetLen(void) {return Len;}
// Methods // Methods
virtual RCODE GetContent(PGLOBAL, char *, int) = 0; virtual RCODE GetContent(PGLOBAL, char *, int) = 0;
...@@ -163,9 +164,11 @@ class XMLNODELIST : public BLOCK { ...@@ -163,9 +164,11 @@ class XMLNODELIST : public BLOCK {
class XMLATTRIBUTE : public BLOCK { class XMLATTRIBUTE : public BLOCK {
public: public:
// Properties // Properties
//virtual char *GetText(void) = 0; virtual char *GetName(PGLOBAL) = 0;
virtual PXATTR GetNext(PGLOBAL) = 0;
// Methods // Methods
virtual RCODE GetText(PGLOBAL, char *, int) = 0;
virtual bool SetText(PGLOBAL, char *, int) = 0; virtual bool SetText(PGLOBAL, char *, int) = 0;
protected: protected:
......
/************* RelDef CPP Program Source Code File (.CPP) **************/ /************* RelDef CPP Program Source Code File (.CPP) **************/
/* PROGRAM NAME: REFDEF */ /* PROGRAM NAME: RELDEF */
/* ------------- */ /* ------------- */
/* Version 1.4 */ /* Version 1.4 */
/* */ /* */
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
/***********************************************************************/ /***********************************************************************/
#include "global.h" #include "global.h"
#include "plgdbsem.h" #include "plgdbsem.h"
#include "mycat.h"
#include "reldef.h" #include "reldef.h"
#include "colblk.h" #include "colblk.h"
#include "filamap.h" #include "filamap.h"
...@@ -73,6 +72,14 @@ RELDEF::RELDEF(void) ...@@ -73,6 +72,14 @@ RELDEF::RELDEF(void)
Hc = NULL; Hc = NULL;
} // end of RELDEF constructor } // end of RELDEF constructor
/***********************************************************************/
/* This function return a pointer to the Table Option Struct. */
/***********************************************************************/
PTOS RELDEF::GetTopt(void)
{
return Hc->GetTableOptionStruct();
} // end of GetTopt
/***********************************************************************/ /***********************************************************************/
/* This function sets an integer table information. */ /* This function sets an integer table information. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "block.h" #include "block.h"
#include "catalog.h" #include "catalog.h"
#include "my_sys.h" #include "my_sys.h"
#include "mycat.h"
typedef class INDEXDEF *PIXDEF; typedef class INDEXDEF *PIXDEF;
typedef class ha_connect *PHC; typedef class ha_connect *PHC;
...@@ -40,6 +41,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block ...@@ -40,6 +41,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
void SetCat(PCATLG cat) { Cat=cat; } void SetCat(PCATLG cat) { Cat=cat; }
// Methods // Methods
PTOS GetTopt(void);
bool GetBoolCatInfo(PSZ what, bool bdef); bool GetBoolCatInfo(PSZ what, bool bdef);
bool SetIntCatInfo(PSZ what, int ival); bool SetIntCatInfo(PSZ what, int ival);
bool Partitioned(void); bool Partitioned(void);
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "global.h" #include "global.h"
#include "plgdbsem.h" #include "plgdbsem.h"
//#include "xtable.h" //#include "xtable.h"
//#include "mycat.h" // for FNC_COL
#include "maputil.h" #include "maputil.h"
#include "filamtxt.h" #include "filamtxt.h"
#include "tabdos.h" #include "tabdos.h"
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
#include "tabmul.h" #include "tabmul.h"
#include "checklvl.h" #include "checklvl.h"
#include "resource.h" #include "resource.h"
#include "mycat.h" #include "mycat.h" // for FNC_COL
/***********************************************************************/ /***********************************************************************/
/* This should be an option. */ /* This should be an option. */
...@@ -45,140 +44,6 @@ ...@@ -45,140 +44,6 @@
/***********************************************************************/ /***********************************************************************/
USETEMP UseTemp(void); USETEMP UseTemp(void);
/***********************************************************************/
/* Make the document tree from a file. */
/***********************************************************************/
PJSON MakeJsonTree(PGLOBAL g, char *fn, char *objn, int pty,
PJAR& doc, DWORD& drc)
{
char *p, *memory, *objpath, *key;
int len, i = 0;
HANDLE hFile;
MEMMAP mm;
PJSON jsp, top;
PJOB objp = NULL;
PJAR arp = NULL;
PJVAL val = NULL;
/*********************************************************************/
/* Create the mapping file object. */
/*********************************************************************/
hFile = CreateFileMap(g, fn, &mm, MODE_READ, false);
if (hFile == INVALID_HANDLE_VALUE) {
drc = GetLastError();
if (!*g->Message)
sprintf(g->Message, MSG(OPEN_MODE_ERROR), "map", (int)drc, fn);
return NULL;
} // endif hFile
/*********************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*********************************************************************/
len = mm.lenL;
memory = (char *)mm.memory;
if (!len) { // Empty file
CloseFileHandle(hFile);
CloseMemMap(memory, len);
drc = ENOENT;
return NULL;
} else if (!memory) {
sprintf(g->Message, MSG(MAP_VIEW_ERROR), fn, drc);
CloseFileHandle(hFile);
return NULL;
} // endif Memory
CloseFileHandle(hFile); // Not used anymore
/*********************************************************************/
/* Parse the json file and allocate its tree structure. */
/*********************************************************************/
g->Message[0] = 0;
jsp = top = ParseJson(g, memory, len, pty);
CloseMemMap(memory, len);
drc = EBADF;
if (!jsp && g->Message[0])
return NULL;
objpath = PlugDup(g, objn); // NULL if !objn
/*********************************************************************/
/* Find the table in the tree structure. */
/*********************************************************************/
for (doc = NULL; jsp && objpath; objpath = p) {
if ((p = strchr(objpath, ':')))
*p++ = 0;
if (*objpath != '[') { // objpass is a key
if (jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Table path does no match json file");
return NULL;
} // endif Type
key = objpath;
objp = jsp->GetObject();
arp = NULL;
val = objp->GetValue(key);
if (!val || !(jsp = val->GetJson())) {
sprintf(g->Message, "Cannot find object key %s", key);
return NULL;
} // endif val
} else if (objpath[strlen(objpath)-1] == ']') {
if (jsp->GetType() != TYPE_JAR) {
strcpy(g->Message, "Table path does no match json file");
return NULL;
} // endif Type
arp = jsp->GetArray();
objp = NULL;
i = atoi(objpath+1) - 1;
val = arp->GetValue(i);
if (!val) {
sprintf(g->Message, "Cannot find array value %d", i);
return NULL;
} // endif val
} else {
sprintf(g->Message, "Invalid Table path %s", objn);
return NULL;
} // endif objpath
jsp = val->GetJson();
} // endfor objpath
if (jsp && jsp->GetType() == TYPE_JAR)
doc = jsp->GetArray();
else {
// The table is void or is just one object or one value
doc = new(g) JARRAY;
if (val) {
doc->AddValue(g, val);
doc->InitArray(g);
} else if (jsp) {
doc->AddValue(g, new(g) JVALUE(jsp));
doc->InitArray(g);
} // endif val
if (objp)
objp->SetValue(g, new(g) JVALUE(doc), key);
else if (arp)
arp->SetValue(g, new(g) JVALUE(doc), i);
else
top = doc;
} // endif jsp
return top;
} // end of MakeJsonTree
typedef struct _jncol { typedef struct _jncol {
struct _jncol *Next; struct _jncol *Next;
char *Name; char *Name;
...@@ -202,11 +67,9 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, ...@@ -202,11 +67,9 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT}; FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0}; static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
char filename[_MAX_PATH], colname[65], fmt[129], *buf; char filename[_MAX_PATH], colname[65], fmt[129];
int i, j, n = 0; int i, j, n = 0;
int ncol = sizeof(buftyp) / sizeof(int); int ncol = sizeof(buftyp) / sizeof(int);
FILE *infile;
DWORD drc;
PVAL valp; PVAL valp;
JCOL jcol; JCOL jcol;
PJCL jcp, fjcp = NULL, pjcp = NULL; PJCL jcp, fjcp = NULL, pjcp = NULL;
...@@ -214,7 +77,9 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, ...@@ -214,7 +77,9 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
PJSON jsp; PJSON jsp;
PJVAL jvp; PJVAL jvp;
PJOB row; PJOB row;
PJAR doc; PJDEF tdp;
TDBJSN *tjnp;
PJTDB tjsp;
PQRYRES qrp; PQRYRES qrp;
PCOLRES crp; PCOLRES crp;
...@@ -237,41 +102,47 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, ...@@ -237,41 +102,47 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
} else } else
PlugSetPath(filename, fn, dp); PlugSetPath(filename, fn, dp);
tdp = new(g) JSONDEF;
tdp->Database = dp;
tdp->Fn = filename;
tdp->Objname = objn;
tdp->Pretty = pretty;
if (pretty == 2) { if (pretty == 2) {
if (!MakeJsonTree(g, filename, objn, pretty, doc, drc)) tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
if (tjsp->MakeDocument(g))
return NULL; return NULL;
jsp = (doc) ? doc->GetValue(0) : NULL; jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL;
} else { } else {
if (!lrecl) { if (!lrecl) {
sprintf(g->Message, "LRECL must be specified for pretty=%d", pretty); sprintf(g->Message, "LRECL must be specified for pretty=%d", pretty);
return NULL; return NULL;
} else if (!(buf = (char*)PlugSubAlloc(g, NULL, lrecl))) { } // endif lrecl
sprintf(g->Message, "Alloc error, lrecl=%d", lrecl);
return NULL;
} // endif buf
if (!(infile = global_fopen(g, MSGID_CANNOT_OPEN, filename, "r"))) tdp->Lrecl = lrecl;
return NULL; tdp->Ending = CRLF;
tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
tjnp->SetMode(MODE_READ);
// Read first record if (tjnp->OpenDB(g))
for (i = 0; i <= pretty; i++)
if (!fgets(buf, lrecl, infile)) {
if (feof(infile)) {
strcpy(g->Message, "Void json table");
return NULL; return NULL;
} // endif fgets
sprintf(g->Message, MSG(READ_ERROR), filename, strerror(0)); switch (tjnp->ReadDB(g)) {
return NULL; case RC_EF:
} // endif fgets strcpy(g->Message, "Void json table");
case RC_FX:
goto err;
default:
jsp = tjnp->GetRow();
} // endswitch ReadDB
jsp = ParseJson(g, buf, strlen(buf), pretty, NULL);
} // endif pretty } // endif pretty
if (!(row = (jsp) ? jsp->GetObject() : NULL)) { if (!(row = (jsp) ? jsp->GetObject() : NULL)) {
strcpy(g->Message, "Can only retrieve columns from object rows"); strcpy(g->Message, "Can only retrieve columns from object rows");
return NULL; goto err;
} // endif row } // endif row
jcol.Next = NULL; jcol.Next = NULL;
...@@ -394,20 +265,18 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, ...@@ -394,20 +265,18 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
if (pretty != 2) { if (pretty != 2) {
// Read next record // Read next record
if (!fgets(buf, lrecl, infile)) { switch (tjnp->ReadDB(g)) {
if (!feof(infile)) { case RC_EF:
sprintf(g->Message, MSG(READ_ERROR), filename, strerror(0));
return NULL;
} else
jsp = NULL;
} else if (pretty == 1 && strlen(buf) == 1 && *buf == ']') {
jsp = NULL; jsp = NULL;
} else break;
jsp = ParseJson(g, buf, strlen(buf), pretty, NULL); case RC_FX:
goto err;
default:
jsp = tjnp->GetRow();
} // endswitch ReadDB
} else } else
jsp = doc->GetValue(i); jsp = tjsp->GetDoc()->GetValue(i);
if (!(row = (jsp) ? jsp->GetObject() : NULL)) if (!(row = (jsp) ? jsp->GetObject() : NULL))
break; break;
...@@ -415,7 +284,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, ...@@ -415,7 +284,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
} // endor i } // endor i
if (pretty != 2) if (pretty != 2)
fclose(infile); tjnp->CloseDB(g);
skipit: skipit:
if (trace) if (trace)
...@@ -471,7 +340,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, ...@@ -471,7 +340,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
err: err:
if (pretty != 2) if (pretty != 2)
fclose(infile); tjnp->CloseDB(g);
return NULL; return NULL;
} // end of JSONColumns } // end of JSONColumns
...@@ -487,6 +356,7 @@ JSONDEF::JSONDEF(void) ...@@ -487,6 +356,7 @@ JSONDEF::JSONDEF(void)
Limit = 1; Limit = 1;
Level = 0; Level = 0;
ReadMode = 0; ReadMode = 0;
Strict = false;
} // end of JSONDEF constructor } // end of JSONDEF constructor
/***********************************************************************/ /***********************************************************************/
...@@ -540,7 +410,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -540,7 +410,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
// Txfp must be set for TDBDOS // Txfp must be set for TDBDOS
tdbp = new(g) TDBJSN(this, txfp); tdbp = new(g) TDBJSN(this, txfp);
} else { } else {
txfp = new(g) DOSFAM(this); txfp = new(g) MAPFAM(this);
tdbp = new(g) TDBJSON(this, txfp); tdbp = new(g) TDBJSON(this, txfp);
} // endif Pretty } // endif Pretty
...@@ -557,30 +427,45 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) ...@@ -557,30 +427,45 @@ 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)
{ {
Top = NULL;
Row = NULL; Row = NULL;
Val = NULL;
Colp = NULL; Colp = NULL;
if (tdp) {
Jmode = tdp->Jmode; Jmode = tdp->Jmode;
Objname = tdp->Objname;
Xcol = tdp->Xcol; Xcol = tdp->Xcol;
Limit = tdp->Limit;
Pretty = tdp->Pretty;
Strict = tdp->Strict;
} else {
Jmode = MODE_OBJECT;
Objname = NULL;
Xcol = NULL;
Limit = 1;
Pretty = 0;
Strict = false;
} // endif tdp
Fpos = -1; Fpos = -1;
//Spos = 0;
N = 0; N = 0;
Limit = tdp->Limit;
NextSame = 0; NextSame = 0;
SameRow = 0; SameRow = 0;
Xval = -1; Xval = -1;
Pretty = tdp->Pretty;
Strict = tdp->Strict;
Comma = false; Comma = false;
} // end of TDBJSN standard constructor } // end of TDBJSN standard constructor
TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp) TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
{ {
Top = tdbp->Top;
Row = tdbp->Row; Row = tdbp->Row;
Val = tdbp->Val;
Colp = tdbp->Colp; Colp = tdbp->Colp;
Jmode = tdbp->Jmode; Jmode = tdbp->Jmode;
Objname = tdbp->Objname;
Xcol = tdbp->Xcol; Xcol = tdbp->Xcol;
Fpos = tdbp->Fpos; Fpos = tdbp->Fpos;
//Spos = tdbp->Spos;
N = tdbp->N; N = tdbp->N;
Limit = tdbp->Limit; Limit = tdbp->Limit;
NextSame = tdbp->NextSame; NextSame = tdbp->NextSame;
...@@ -658,6 +543,34 @@ int TDBJSN::GetMaxSize(PGLOBAL g) ...@@ -658,6 +543,34 @@ int TDBJSN::GetMaxSize(PGLOBAL g)
return MaxSize; return MaxSize;
} // end of GetMaxSize } // end of GetMaxSize
/***********************************************************************/
/* Find the row in the tree structure. */
/***********************************************************************/
PJSON TDBJSN::FindRow(PGLOBAL g)
{
char *p, *objpath;
PJSON jsp = Row;
PJVAL val = NULL;
for (objpath = PlugDup(g, Objname); jsp && objpath; objpath = p) {
if ((p = strchr(objpath, ':')))
*p++ = 0;
if (*objpath != '[') { // objpass is a key
val = (jsp->GetType() == TYPE_JOB) ?
jsp->GetObject()->GetValue(objpath) : NULL;
} else if (objpath[strlen(objpath)-1] == ']') {
val = (jsp->GetType() == TYPE_JAR) ?
jsp->GetArray()->GetValue(atoi(objpath+1) - 1) : NULL;
} else
val = NULL;
jsp = (val) ? val->GetJson() : NULL;
} // endfor objpath
return jsp;
} // end of FindRow
/***********************************************************************/ /***********************************************************************/
/* OpenDB: Data Base open routine for JSN access method. */ /* OpenDB: Data Base open routine for JSN access method. */
/***********************************************************************/ /***********************************************************************/
...@@ -668,7 +581,6 @@ bool TDBJSN::OpenDB(PGLOBAL g) ...@@ -668,7 +581,6 @@ bool TDBJSN::OpenDB(PGLOBAL g)
/* Table already open replace it at its beginning. */ /* Table already open replace it at its beginning. */
/*******************************************************************/ /*******************************************************************/
Fpos= -1; Fpos= -1;
// Spos = 0;
NextSame = 0; NextSame = 0;
SameRow = 0; SameRow = 0;
} else { } else {
...@@ -743,6 +655,7 @@ int TDBJSN::ReadDB(PGLOBAL g) ...@@ -743,6 +655,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
strlen(To_Line), Pretty, &Comma))) { strlen(To_Line), Pretty, &Comma))) {
rc = (Pretty == 1 && !strcmp(To_Line, "]")) ? RC_EF : RC_FX; rc = (Pretty == 1 && !strcmp(To_Line, "]")) ? RC_EF : RC_FX;
} else { } else {
Row = FindRow(g);
SameRow = 0; SameRow = 0;
Fpos++; Fpos++;
rc = RC_OK; rc = RC_OK;
...@@ -751,20 +664,86 @@ int TDBJSN::ReadDB(PGLOBAL g) ...@@ -751,20 +664,86 @@ int TDBJSN::ReadDB(PGLOBAL g)
return rc; return rc;
} // end of ReadDB } // end of ReadDB
/***********************************************************************/
/* Make the top tree from the object path. */
/***********************************************************************/
int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
{
if (Objname) {
if (!Val) {
// Parse and allocate Objname item(s)
char *p;
char *objpath = PlugDup(g, Objname);
int i;
PJOB objp;
PJAR arp;
PJVAL val = NULL;
Top = NULL;
for (; objpath; objpath = p) {
if ((p = strchr(objpath, ':')))
*p++ = 0;
if (*objpath != '[') {
objp = new(g) JOBJECT;
if (!Top)
Top = objp;
if (val)
val->SetValue(objp);
val = new(g) JVALUE;
objp->SetValue(g, val, objpath);
} else if (objpath[strlen(objpath)-1] == ']') {
arp = new(g) JARRAY;
if (!Top)
Top = arp;
if (val)
val->SetValue(arp);
val = new(g) JVALUE;
i = atoi(objpath+1) - 1;
arp->SetValue(g, val, i);
arp->InitArray(g);
} else {
sprintf(g->Message, "Invalid Table path %s", Objname);
return RC_FX;
} // endif objpath
} // endfor p
Val = val;
} // endif Val
Val->SetValue(jsp);
} else
Top = jsp;
return RC_OK;
} // end of MakeTopTree
/***********************************************************************/ /***********************************************************************/
/* PrepareWriting: Prepare the line for WriteDB. */ /* PrepareWriting: Prepare the line for WriteDB. */
/***********************************************************************/ /***********************************************************************/
bool TDBJSN::PrepareWriting(PGLOBAL g) bool TDBJSN::PrepareWriting(PGLOBAL g)
{ {
PSZ s = Serialize(g, Row, NULL, Pretty); PSZ s;
if (s) { if (MakeTopTree(g, Row))
return true;
if ((s = Serialize(g, Top, NULL, Pretty))) {
if (Comma) if (Comma)
strcat(s, ","); strcat(s, ",");
if ((signed)strlen(s) > Lrecl) { if ((signed)strlen(s) > Lrecl) {
sprintf(g->Message, "Line would be truncated (lrecl=%d)", Lrecl); strncpy(To_Line, s, Lrecl);
return true; sprintf(g->Message, "Line truncated (lrecl=%d)", Lrecl);
return PushWarning(g, this);
} else } else
strcpy(To_Line, s); strcpy(To_Line, s);
...@@ -1083,6 +1062,10 @@ void JSONCOL::ReadColumn(PGLOBAL g) ...@@ -1083,6 +1062,10 @@ void JSONCOL::ReadColumn(PGLOBAL g)
if (!Tjp->SameRow || Xnod >= Tjp->SameRow) if (!Tjp->SameRow || Xnod >= Tjp->SameRow)
Value->SetValue_pval(GetColumnValue(g, Tjp->Row, 0)); Value->SetValue_pval(GetColumnValue(g, Tjp->Row, 0));
// Set null when applicable
if (Nullable)
Value->SetNull(Value->IsZero());
} // end of ReadColumn } // end of ReadColumn
/***********************************************************************/ /***********************************************************************/
...@@ -1272,7 +1255,7 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n) ...@@ -1272,7 +1255,7 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
/***********************************************************************/ /***********************************************************************/
PJSON JSONCOL::GetRow(PGLOBAL g) PJSON JSONCOL::GetRow(PGLOBAL g)
{ {
PJVAL val; PJVAL val = NULL;
PJAR arp; PJAR arp;
PJSON nwr, row = Tjp->Row; PJSON nwr, row = Tjp->Row;
...@@ -1438,18 +1421,14 @@ void JSONCOL::WriteColumn(PGLOBAL g) ...@@ -1438,18 +1421,14 @@ void JSONCOL::WriteColumn(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
TDBJSON::TDBJSON(PJDEF tdp, PTXF txfp) : TDBJSN(tdp, txfp) TDBJSON::TDBJSON(PJDEF tdp, PTXF txfp) : TDBJSN(tdp, txfp)
{ {
Top = NULL;
Doc = NULL; Doc = NULL;
Objname = tdp->Objname;
Multiple = tdp->Multiple; Multiple = tdp->Multiple;
Done = Changed = false; Done = Changed = false;
} // end of TDBJSON standard constructor } // end of TDBJSON standard constructor
TDBJSON::TDBJSON(PJTDB tdbp) : TDBJSN(tdbp) TDBJSON::TDBJSON(PJTDB tdbp) : TDBJSN(tdbp)
{ {
Top = tdbp->Top;
Doc = tdbp->Doc; Doc = tdbp->Doc;
Objname = tdbp->Objname;
Multiple = tdbp->Multiple; Multiple = tdbp->Multiple;
Done = tdbp->Done; Done = tdbp->Done;
Changed = tdbp->Changed; Changed = tdbp->Changed;
...@@ -1473,64 +1452,17 @@ PTDB TDBJSON::CopyOne(PTABS t) ...@@ -1473,64 +1452,17 @@ PTDB TDBJSON::CopyOne(PTABS t)
} // end of CopyOne } // end of CopyOne
/***********************************************************************/ /***********************************************************************/
/* Make the document tree from a file. */ /* Make the document tree from the object path. */
/***********************************************************************/ /***********************************************************************/
int TDBJSON::MakeNewDoc(PGLOBAL g) int TDBJSON::MakeNewDoc(PGLOBAL g)
{ {
// Create a void table that will be populated // Create a void table that will be populated
Doc = new(g) JARRAY; Doc = new(g) JARRAY;
if (Objname) { if (MakeTopTree(g, Doc))
// Parse and allocate Objname item(s)
char *p;
char *objpath = (char*)PlugSubAlloc(g, NULL, strlen(Objname)+1);
int i;
PJOB objp;
PJAR arp;
PJVAL val = NULL;
strcpy(objpath, Objname);
Top = NULL;
for (; objpath; objpath = p) {
if ((p = strchr(objpath, ':')))
*p++ = 0;
if (*objpath != '[') {
objp = new(g) JOBJECT;
if (!Top)
Top = objp;
if (val)
val->SetValue(objp);
val = new(g) JVALUE;
objp->SetValue(g, val, objpath);
} else if (objpath[strlen(objpath)-1] == ']') {
arp = new(g) JARRAY;
if (!Top)
Top = arp;
if (val)
val->SetValue(arp);
val = new(g) JVALUE;
i = atoi(objpath+1) - 1;
arp->SetValue(g, val, i);
arp->InitArray(g);
} else {
sprintf(g->Message, "Invalid Table path %s", Objname);
return RC_FX; return RC_FX;
} // endif objpath
} // endfor p
val->SetValue(Doc);
} else
Top = Doc;
Done = true;
return RC_OK; return RC_OK;
} // end of MakeNewDoc } // end of MakeNewDoc
...@@ -1539,36 +1471,9 @@ int TDBJSON::MakeNewDoc(PGLOBAL g) ...@@ -1539,36 +1471,9 @@ int TDBJSON::MakeNewDoc(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBJSON::MakeDocument(PGLOBAL g) int TDBJSON::MakeDocument(PGLOBAL g)
{ {
char filename[_MAX_PATH]; char *p, *memory, *objpath, *key;
int rc = RC_OK;
DWORD drc;
if (Done)
return RC_OK;
// Now open the JSON file
PlugSetPath(filename, Txfp->To_File, GetPath());
/*********************************************************************/
/* Get top of the parsed tree and the inside table document. */
/*********************************************************************/
if (!(Top = MakeJsonTree(g, filename, Objname, Pretty, Doc, drc)))
rc = (drc == ENOENT && Mode == MODE_INSERT) ? MakeNewDoc(g) : RC_FX;
Done = (rc == RC_OK);
return rc;
} // end of MakeDocument
#if 0
/***********************************************************************/
/* Make the document tree from a file. */
/***********************************************************************/
int TDBJSON::MakeDocument(PGLOBAL g)
{
char *p, *memory, *objpath, *key, filename[_MAX_PATH];
int len, i = 0; int len, i = 0;
HANDLE hFile; MODE mode = Mode;
MEMMAP mm;
PJSON jsp; PJSON jsp;
PJOB objp = NULL; PJOB objp = NULL;
PJAR arp = NULL; PJAR arp = NULL;
...@@ -1576,61 +1481,33 @@ int TDBJSON::MakeDocument(PGLOBAL g) ...@@ -1576,61 +1481,33 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if (Done) if (Done)
return RC_OK; return RC_OK;
else
Done = true;
// Now open the JSON file
PlugSetPath(filename, Txfp->To_File, GetPath());
/*********************************************************************/ /*********************************************************************/
/* Create the mapping file object. */ /* Create the mapping file object in mode read. */
/*********************************************************************/ /*********************************************************************/
hFile = CreateFileMap(g, filename, &mm, MODE_READ, false); Mode = MODE_READ;
if (hFile == INVALID_HANDLE_VALUE) { if (!Txfp->OpenTableFile(g)) {
DWORD drc = GetLastError(); PFBLOCK fp = Txfp->GetTo_Fb();
if (drc != ENOENT || Mode != MODE_INSERT) { if (fp) {
if (!(*g->Message)) len = fp->Length;
sprintf(g->Message, MSG(OPEN_MODE_ERROR), memory = fp->Memory;
"map", (int)drc, filename); } else {
Mode = mode; // Restore saved Mode
return RC_FX;
} else
return MakeNewDoc(g);
} // endif hFile
/*********************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*********************************************************************/
len = mm.lenL;
memory = (char *)mm.memory;
if (!len) { // Empty file
CloseFileHandle(hFile);
CloseMemMap(memory, len);
if (Mode == MODE_INSERT)
return MakeNewDoc(g); return MakeNewDoc(g);
} // endif fp
} // endif len } else
if (!memory) {
CloseFileHandle(hFile);
sprintf(g->Message, MSG(MAP_VIEW_ERROR), filename, GetLastError());
return RC_FX; return RC_FX;
} // endif Memory
CloseFileHandle(hFile); // Not used anymore
hFile = INVALID_HANDLE_VALUE; // For Fblock
/*********************************************************************/ /*********************************************************************/
/* Parse the json file and allocate its tree structure. */ /* Parse the json file and allocate its tree structure. */
/*********************************************************************/ /*********************************************************************/
g->Message[0] = 0; g->Message[0] = 0;
jsp = Top = ParseJson(g, memory, len, Pretty); jsp = Top = ParseJson(g, memory, len, Pretty);
CloseMemMap(memory, len); Txfp->CloseTableFile(g, false);
Mode = mode; // Restore saved Mode
if (!jsp && g->Message[0]) if (!jsp && g->Message[0])
return RC_FX; return RC_FX;
...@@ -1707,9 +1584,9 @@ int TDBJSON::MakeDocument(PGLOBAL g) ...@@ -1707,9 +1584,9 @@ int TDBJSON::MakeDocument(PGLOBAL g)
} // endif jsp } // endif jsp
Done = true;
return RC_OK; return RC_OK;
} // end of MakeDocument } // end of MakeDocument
#endif // 0
/***********************************************************************/ /***********************************************************************/
/* JSON Cardinality: returns table size in number of rows. */ /* JSON Cardinality: returns table size in number of rows. */
......
...@@ -35,6 +35,8 @@ class JSONDEF : public DOSDEF { /* Table description */ ...@@ -35,6 +35,8 @@ class JSONDEF : public DOSDEF { /* Table description */
friend class TDBJSON; friend class TDBJSON;
friend class TDBJSN; friend class TDBJSN;
friend class TDBJCL; friend class TDBJCL;
friend PQRYRES JSONColumns(PGLOBAL, char *, const char *, char *,
int, int, int, bool);
public: public:
// Constructor // Constructor
JSONDEF(void); JSONDEF(void);
...@@ -74,6 +76,7 @@ class TDBJSN : public TDBDOS { ...@@ -74,6 +76,7 @@ class TDBJSN : public TDBDOS {
virtual AMT GetAmType(void) {return TYPE_AM_JSN;} virtual AMT GetAmType(void) {return TYPE_AM_JSN;}
virtual bool SkipHeader(PGLOBAL g); virtual bool SkipHeader(PGLOBAL g);
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSN(this);} virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSN(this);}
PJSON GetRow(void) {return Row;}
// Methods // Methods
virtual PTDB CopyOne(PTABS t); virtual PTDB CopyOne(PTABS t);
...@@ -90,10 +93,16 @@ class TDBJSN : public TDBDOS { ...@@ -90,10 +93,16 @@ class TDBJSN : public TDBDOS {
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
protected: protected:
PJSON FindRow(PGLOBAL g);
int MakeTopTree(PGLOBAL g, PJSON jsp);
// Members // Members
PJSON Top; // The top JSON tree
PJSON Row; // The current row PJSON Row; // The current row
PJSON Val; // The value of the current row
PJCOL Colp; // The multiple column PJCOL Colp; // The multiple column
JMODE Jmode; // MODE_OBJECT by default JMODE Jmode; // MODE_OBJECT by default
char *Objname; // The table object name
char *Xcol; // Name of expandable column char *Xcol; // Name of expandable column
int Fpos; // The current row index int Fpos; // The current row index
//int Spos; // DELETE start index //int Spos; // DELETE start index
...@@ -168,6 +177,7 @@ class TDBJSON : public TDBJSN { ...@@ -168,6 +177,7 @@ class TDBJSON : public TDBJSN {
// Implementation // Implementation
virtual AMT GetAmType(void) {return TYPE_AM_JSON;} virtual AMT GetAmType(void) {return TYPE_AM_JSON;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSON(this);} virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSON(this);}
PJAR GetDoc(void) {return Doc;}
// Methods // Methods
virtual PTDB CopyOne(PTABS t); virtual PTDB CopyOne(PTABS t);
...@@ -185,18 +195,16 @@ class TDBJSON : public TDBJSN { ...@@ -185,18 +195,16 @@ class TDBJSON : public TDBJSN {
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc); virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
int MakeDocument(PGLOBAL g);
// Optimization routines // Optimization routines
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add); virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
protected: protected:
int MakeNewDoc(PGLOBAL g); int MakeNewDoc(PGLOBAL g);
int MakeDocument(PGLOBAL g);
// Members // Members
PJSON Top; // The file JSON tree
PJAR Doc; // The document array PJAR Doc; // The document array
char *Objname; // The table object name
int Multiple; // 0: No 1: DIR 2: Section 3: filelist int Multiple; // 0: No 1: DIR 2: Section 3: filelist
bool Done; // True when document parsing is done bool Done; // True when document parsing is done
bool Changed; // After Update, Insert or Delete bool Changed; // After Update, Insert or Delete
......
...@@ -587,6 +587,10 @@ CATCOL::CATCOL(PCOLDEF cdp, PTDB tdbp, int n) ...@@ -587,6 +587,10 @@ CATCOL::CATCOL(PCOLDEF cdp, PTDB tdbp, int n)
void CATCOL::ReadColumn(PGLOBAL g) void CATCOL::ReadColumn(PGLOBAL g)
{ {
// Get the value of the Name or Description property // Get the value of the Name or Description property
if (Crp->Kdata)
Value->SetValue_pvblk(Crp->Kdata, Tdbp->N); Value->SetValue_pvblk(Crp->Kdata, Tdbp->N);
else
Value->Reset();
} // end of ReadColumn } // end of ReadColumn
...@@ -56,7 +56,6 @@ ...@@ -56,7 +56,6 @@
#include "xtable.h" #include "xtable.h"
#include "tabcol.h" #include "tabcol.h"
#include "colblk.h" #include "colblk.h"
#include "mycat.h"
#include "reldef.h" #include "reldef.h"
#include "tabmysql.h" #include "tabmysql.h"
#include "valblk.h" #include "valblk.h"
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "xtable.h" #include "xtable.h"
#include "tabmysql.h" #include "tabmysql.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h"
/***********************************************************************/ /***********************************************************************/
/* Prepare and count columns in the column list. */ /* Prepare and count columns in the column list. */
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include "tabpivot.h" #include "tabpivot.h"
#include "valblk.h" #include "valblk.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h" // For GetHandler
/***********************************************************************/ /***********************************************************************/
/* Make the Pivot table column list. */ /* Make the Pivot table column list. */
......
...@@ -72,7 +72,6 @@ ...@@ -72,7 +72,6 @@
#include "tabtbl.h" #include "tabtbl.h"
#include "tabmysql.h" #include "tabmysql.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h" // For GetHandler
#if defined(WIN32) #if defined(WIN32)
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#include "plgdbsem.h" #include "plgdbsem.h"
#include "plgcnx.h" // For DB types #include "plgcnx.h" // For DB types
#include "myutil.h" #include "myutil.h"
#include "mycat.h"
#include "valblk.h" #include "valblk.h"
#include "resource.h" #include "resource.h"
#include "reldef.h" #include "reldef.h"
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include "xtable.h" #include "xtable.h"
#include "tabmysql.h" #include "tabmysql.h"
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h"
/* -------------- Implementation of the XCOL classes ---------------- */ /* -------------- Implementation of the XCOL classes ---------------- */
......
/************* Tabxml C++ Program Source Code File (.CPP) **************/ /************* Tabxml C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABXML */ /* PROGRAM NAME: TABXML */
/* ------------- */ /* ------------- */
/* Version 2.7 */ /* Version 2.8 */
/* */ /* */
/* Author Olivier BERTRAND 2007 - 2014 */ /* Author Olivier BERTRAND 2007 - 2015 */
/* */ /* */
/* This program are the XML tables classes using MS-DOM or libxml2. */ /* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/ /***********************************************************************/
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "osutil.h" #include "osutil.h"
#define _O_RDONLY O_RDONLY #define _O_RDONLY O_RDONLY
#endif // !WIN32 #endif // !WIN32
#include "resource.h" // for IDS_COLUMNS
#define INCLUDE_TDBXML #define INCLUDE_TDBXML
#define NODE_TYPE_LIST #define NODE_TYPE_LIST
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#include "reldef.h" #include "reldef.h"
#include "xtable.h" #include "xtable.h"
#include "colblk.h" #include "colblk.h"
#include "mycat.h"
#include "xindex.h" #include "xindex.h"
#include "plgxml.h" #include "plgxml.h"
#include "tabxml.h" #include "tabxml.h"
...@@ -57,6 +59,336 @@ extern "C" char version[]; ...@@ -57,6 +59,336 @@ extern "C" char version[];
#define XMLSUP "libxml2" #define XMLSUP "libxml2"
#endif // !WIN32 #endif // !WIN32
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
/***********************************************************************/
/* Class and structure used by XMLColumns. */
/***********************************************************************/
typedef class XMCOL *PXCL;
class XMCOL : public BLOCK {
public:
// Constructors
XMCOL(void) {Next = NULL;
Name[0] = 0;
Fmt = NULL;
Type = 1;
Len = Scale = 0;
Cbn = false;
Found = true;}
XMCOL(PGLOBAL g, PXCL xp, char *fmt, int i) {
Next = NULL;
strcpy(Name, xp->Name);
Fmt = (*fmt) ? PlugDup(g, fmt) : NULL;
Type = xp->Type;
Len = xp->Len;
Scale = xp->Scale;
Cbn = (xp->Cbn || i > 1);
Found = true;}
// Members
PXCL Next;
char Name[64];
char *Fmt;
int Type;
int Len;
int Scale;
bool Cbn;
bool Found;
}; // end of class XMCOL
typedef struct LVL {
PXNODE pn;
PXLIST nl;
PXATTR atp;
bool b;
long k;
int m, n;
} *PLVL;
/***********************************************************************/
/* XMLColumns: construct the result blocks containing the description */
/* of all the columns of a table contained inside an XML file. */
/***********************************************************************/
PQRYRES XMLColumns(PGLOBAL g, char *dp, char *tab, PTOS topt, bool info)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
char *op, colname[65], fmt[129], buf[512];
int i, j, lvl, rc, n = 0;
int ncol = sizeof(buftyp) / sizeof(int);
bool ok = true;
PXCL xcol, xcp, fxcp = NULL, pxcp = NULL;
PLVL *lvlp, vp;
PXNODE node = NULL;
PXMLDEF tdp;
PTDBXML txmp;
PQRYRES qrp;
PCOLRES crp;
if (info) {
length[0] = 128;
length[7] = 256;
goto skipit;
} // endif info
/*********************************************************************/
/* Open the input file. */
/*********************************************************************/
if (!topt->filename) {
strcpy(g->Message, MSG(MISSING_FNAME));
return NULL;
} else
lvl = atoi(GetListOption(g, "Level", topt->oplist, "0"));
if (trace)
htrc("File %s lvl=%d\n", topt->filename, lvl);
tdp = new(g) XMLDEF;
tdp->Database = dp;
tdp->Fn = (char*)topt->filename;
tdp->Tabname = tab;
if (!(op = GetListOption(g, "Xmlsup", topt->oplist, NULL)))
#if defined(WIN32)
tdp->Usedom = true;
#else // !WIN32
tdp->Usedom = false;
#endif // !WIN32
else
tdp->Usedom = (toupper(*op) == 'M' || toupper(*op) == 'D');
txmp = new(g) TDBXML(tdp);
if (txmp->Initialize(g))
return NULL;
xcol = new(g) XMCOL;
colname[64] = 0;
fmt[128] = 0;
lvlp = (PLVL*)PlugSubAlloc(g, NULL, sizeof(PLVL) * (lvl + 1));
for (j = 0; j <= lvl; j++)
lvlp[j] = (PLVL)PlugSubAlloc(g, NULL, sizeof(LVL));
/*********************************************************************/
/* Analyse the XML tree and define columns. */
/*********************************************************************/
for (i = 1; ; i++) {
// Get next row
switch (txmp->ReadDB(g)) {
case RC_EF:
vp = NULL;
break;
case RC_FX:
goto err;
default:
vp = lvlp[0];
vp->pn = txmp->RowNode;
vp->atp = vp->pn->GetAttribute(g, NULL);
vp->nl = vp->pn->GetChildElements(g);
vp->b = true;
vp->k = 0;
vp->m = vp->n = 0;
j = 0;
} // endswitch ReadDB
if (!vp)
break;
while (true) {
if (!vp->atp &&
!(node = (vp->nl) ? vp->nl->GetItem(g, vp->k++, node) : NULL))
if (j) {
vp = lvlp[--j];
if (!tdp->Usedom) // nl was destroyed
vp->nl = vp->pn->GetChildElements(g);
if (!lvlp[j+1]->b) {
vp->k--;
ok = false;
} // endif b
continue;
} else
break;
xcol->Name[vp->n] = 0;
fmt[vp->m] = 0;
more:
if (vp->atp) {
strncpy(colname, vp->atp->GetName(g), sizeof(colname));
strncat(xcol->Name, colname, 64);
rc = vp->atp->GetText(g, buf, sizeof(buf));
strncat(fmt, "@", sizeof(fmt));
if (j)
strncat(fmt, colname, sizeof(fmt));
} else {
if (tdp->Usedom && node->GetType() != 1)
continue;
strncpy(colname, node->GetName(g), sizeof(colname));
strncat(xcol->Name, colname, 64);
if (j)
strncat(fmt, colname, sizeof(fmt));
if (j < lvl && ok) {
vp = lvlp[j+1];
vp->k = 0;
vp->atp = node->GetAttribute(g, NULL);
vp->nl = node->GetChildElements(g);
if (tdp->Usedom && vp->nl->GetLength() == 1) {
node = vp->nl->GetItem(g, 0, node);
vp->b = (node->GetType() == 1); // Must be ab element
} else
vp->b = (vp->nl && vp->nl->GetLength());
if (vp->atp || vp->b) {
if (!vp->atp)
node = vp->nl->GetItem(g, vp->k++, node);
strncat(strncat(fmt, colname, 125), "/", 125);
strncat(xcol->Name, "_", 64);
j++;
vp->n = (int)strlen(xcol->Name);
vp->m = (int)strlen(fmt);
goto more;
} else {
vp = lvlp[j];
if (!tdp->Usedom) // nl was destroyed
vp->nl = vp->pn->GetChildElements(g);
} // endif vp
} else
ok = true;
rc = node->GetContent(g, buf, sizeof(buf));
} // endif atp;
xcol->Len = strlen(buf);
// Check whether this column was already found
for (xcp = fxcp; xcp; xcp = xcp->Next)
if (!strcmp(xcol->Name, xcp->Name))
break;
if (xcp) {
if (xcp->Type != xcol->Type)
xcp->Type = TYPE_STRING;
if (*fmt && (!xcp->Fmt || strlen(xcp->Fmt) < strlen(fmt))) {
xcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} // endif *fmt
xcp->Len = MY_MAX(xcp->Len, xcol->Len);
xcp->Scale = MY_MAX(xcp->Scale, xcol->Scale);
xcp->Cbn |= xcol->Cbn;
xcp->Found = true;
} else {
// New column
xcp = new(g) XMCOL(g, xcol, fmt, i);
length[0] = MY_MAX(length[0], strlen(xcol->Name));
length[7] = MY_MAX(length[7], strlen(fmt));
if (pxcp) {
xcp->Next = pxcp->Next;
pxcp->Next = xcp;
} else
fxcp = xcp;
n++;
} // endif xcp
pxcp = xcp;
// for (j = lvl - 1; j >= 0; j--)
// if (jrp[j] && (jrp[j] = jrp[j]->GetNext()))
// goto more;
if (vp->atp)
vp->atp = vp->atp->GetNext(g);
} // endwhile
// Missing column can be null
for (xcp = fxcp; xcp; xcp = xcp->Next) {
xcp->Cbn |= !xcp->Found;
xcp->Found = false;
} // endfor xcp
} // endor i
txmp->CloseDB(g);
skipit:
if (trace)
htrc("CSVColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, false);
crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
crp->Name = "Nullable";
crp->Next->Name = "Xpath";
if (info || !qrp)
return qrp;
qrp->Nblin = n;
/*********************************************************************/
/* Now get the results into blocks. */
/*********************************************************************/
for (i = 0, xcp = fxcp; xcp; i++, xcp = xcp->Next) {
if (xcp->Type == TYPE_UNKNOWN) // Void column
xcp->Type = TYPE_STRING;
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(xcp->Name, i);
crp = crp->Next; // Data Type
crp->Kdata->SetValue(xcp->Type, i);
crp = crp->Next; // Type Name
crp->Kdata->SetValue(GetTypeName(xcp->Type), i);
crp = crp->Next; // Precision
crp->Kdata->SetValue(xcp->Len, i);
crp = crp->Next; // Length
crp->Kdata->SetValue(xcp->Len, i);
crp = crp->Next; // Scale (precision)
crp->Kdata->SetValue(xcp->Scale, i);
crp = crp->Next; // Nullable
crp->Kdata->SetValue(xcp->Cbn ? 1 : 0, i);
crp = crp->Next; // Field format
if (crp->Kdata)
crp->Kdata->SetValue(xcp->Fmt, i);
} // endfor i
/*********************************************************************/
/* Return the result pointer. */
/*********************************************************************/
return qrp;
err:
txmp->CloseDB(g);
return NULL;
} // end of XMLColumns
/* -------------- Implementation of the XMLDEF class ---------------- */ /* -------------- Implementation of the XMLDEF class ---------------- */
/***********************************************************************/ /***********************************************************************/
...@@ -176,6 +508,9 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -176,6 +508,9 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/ /***********************************************************************/
PTDB XMLDEF::GetTable(PGLOBAL g, MODE m) PTDB XMLDEF::GetTable(PGLOBAL g, MODE m)
{ {
if (Catfunc == FNC_COL)
return new(g) TDBXCT(this);
PTDBASE tdbp = new(g) TDBXML(this); PTDBASE tdbp = new(g) TDBXML(this);
if (Multiple) if (Multiple)
...@@ -229,14 +564,14 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp) ...@@ -229,14 +564,14 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
Xfile = tdp->Fn; Xfile = tdp->Fn;
Enc = tdp->Encoding; Enc = tdp->Encoding;
Tabname = tdp->Tabname; Tabname = tdp->Tabname;
Rowname = (*tdp->Rowname) ? tdp->Rowname : NULL; Rowname = (tdp->Rowname && *tdp->Rowname) ? tdp->Rowname : NULL;
Colname = (*tdp->Colname) ? tdp->Colname : NULL; Colname = (tdp->Colname && *tdp->Colname) ? tdp->Colname : NULL;
Mulnode = (*tdp->Mulnode) ? tdp->Mulnode : NULL; Mulnode = (tdp->Mulnode && *tdp->Mulnode) ? tdp->Mulnode : NULL;
XmlDB = (*tdp->XmlDB) ? tdp->XmlDB : NULL; XmlDB = (tdp->XmlDB && *tdp->XmlDB) ? tdp->XmlDB : NULL;
Nslist = (*tdp->Nslist) ? tdp->Nslist : NULL; Nslist = (tdp->Nslist && *tdp->Nslist) ? tdp->Nslist : NULL;
DefNs = (*tdp->DefNs) ? tdp->DefNs : NULL; DefNs = (tdp->DefNs && *tdp->DefNs) ? tdp->DefNs : NULL;
Attrib = (*tdp->Attrib) ? tdp->Attrib : NULL; Attrib = (tdp->Attrib && *tdp->Attrib) ? tdp->Attrib : NULL;
Hdattr = (*tdp->Hdattr) ? tdp->Hdattr : NULL; Hdattr = (tdp->Hdattr && *tdp->Hdattr) ? tdp->Hdattr : NULL;
Coltype = tdp->Coltype; Coltype = tdp->Coltype;
Limit = tdp->Limit; Limit = tdp->Limit;
Xpand = tdp->Xpand; Xpand = tdp->Xpand;
...@@ -771,7 +1106,6 @@ bool TDBXML::OpenDB(PGLOBAL g) ...@@ -771,7 +1106,6 @@ bool TDBXML::OpenDB(PGLOBAL g)
NewRow = (Mode == MODE_INSERT); NewRow = (Mode == MODE_INSERT);
Nsub = 0; Nsub = 0;
Use = USE_OPEN; // Do it now in case we are recursively called Use = USE_OPEN; // Do it now in case we are recursively called
return false; return false;
} // end of OpenDB } // end of OpenDB
...@@ -1847,4 +2181,24 @@ void XPOSCOL::WriteColumn(PGLOBAL g) ...@@ -1847,4 +2181,24 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
} // end of WriteColumn } // end of WriteColumn
/* ---------------------------TDBXCT class --------------------------- */
/***********************************************************************/
/* TDBXCT class constructor. */
/***********************************************************************/
TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
Dp = tdp->GetPath();
Tabn = tdp->Tabname;
} // end of TDBXCT constructor
/***********************************************************************/
/* GetResult: Get the list the JSON file columns. */
/***********************************************************************/
PQRYRES TDBXCT::GetResult(PGLOBAL g)
{
return XMLColumns(g, Dp, Tabn, Topt, false);
} // end of GetResult
/* ------------------------ End of Tabxml ---------------------------- */ /* ------------------------ End of Tabxml ---------------------------- */
...@@ -16,6 +16,8 @@ typedef class XMLCOL *PXMLCOL; ...@@ -16,6 +16,8 @@ typedef class XMLCOL *PXMLCOL;
/***********************************************************************/ /***********************************************************************/
class DllExport XMLDEF : public TABDEF { /* Logical table description */ class DllExport XMLDEF : public TABDEF { /* Logical table description */
friend class TDBXML; friend class TDBXML;
friend class TDBXCT;
friend PQRYRES XMLColumns(PGLOBAL, char*, char*, PTOS, bool);
public: public:
// Constructor // Constructor
XMLDEF(void); XMLDEF(void);
...@@ -55,6 +57,7 @@ class DllExport TDBXML : public TDBASE { ...@@ -55,6 +57,7 @@ class DllExport TDBXML : public TDBASE {
friend class XMLCOL; friend class XMLCOL;
friend class XMULCOL; friend class XMULCOL;
friend class XPOSCOL; friend class XPOSCOL;
friend PQRYRES XMLColumns(PGLOBAL, char*, char*, PTOS, bool);
public: public:
// Constructor // Constructor
TDBXML(PXMLDEF tdp); TDBXML(PXMLDEF tdp);
...@@ -237,4 +240,24 @@ class XPOSCOL : public XMLCOLX { ...@@ -237,4 +240,24 @@ class XPOSCOL : public XMLCOLX {
virtual void ReadColumn(PGLOBAL g); virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g); virtual void WriteColumn(PGLOBAL g);
}; // end of class XPOSCOL }; // end of class XPOSCOL
/***********************************************************************/
/* This is the class declaration for the XML catalog table. */
/***********************************************************************/
class TDBXCT : public TDBCAT {
public:
// Constructor
TDBXCT(PXMLDEF tdp);
protected:
// Specific routines
virtual PQRYRES GetResult(PGLOBAL g);
// Members
PTOS Topt;
char *Dp;
//const char *Fn;
char *Tabn;
}; // end of class TDBXCT
#endif // INCLUDE_TDBXML #endif // INCLUDE_TDBXML
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