diff options
Diffstat (limited to 'storage/connect/tabxml.cpp')
-rw-r--r-- | storage/connect/tabxml.cpp | 279 |
1 files changed, 153 insertions, 126 deletions
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index 573339bce35..19490d350e8 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -163,8 +163,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) return NULL; tdp->Tabname = tab; + tdp->Tabname = (char*)GetStringTableOption(g, topt, "Tabname", tab); + tdp->Rowname = (char*)GetStringTableOption(g, topt, "Rownode", NULL); tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false); tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); + tdp->Skip = GetBooleanTableOption(g, topt, "Skipnull", false); if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL))) #if defined(__WIN__) @@ -280,7 +283,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) if (!vp->atp) node = vp->nl->GetItem(g, vp->k++, tdp->Usedom ? node : NULL); - strncat(fmt, colname, XLEN(fmt)); + if (!j) + strncat(fmt, colname, XLEN(fmt)); + strncat(fmt, "/", XLEN(fmt)); strncat(xcol->Name, "_", XLEN(xcol->Name)); j++; @@ -302,6 +307,7 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) case RC_INFO: PushWarning(g, txmp); case RC_OK: + xcol->Cbn = !strlen(buf); break; default: goto err; @@ -327,9 +333,9 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) xcp->Len = MY_MAX(xcp->Len, xcol->Len); xcp->Scale = MY_MAX(xcp->Scale, xcol->Scale); - xcp->Cbn |= xcol->Cbn; + xcp->Cbn |= (xcol->Cbn || !xcol->Len); xcp->Found = true; - } else { + } else if(xcol->Len || !tdp->Skip) { // New column xcp = new(g) XMCOL(g, xcol, fmt, i); length[0] = MY_MAX(length[0], strlen(xcol->Name)); @@ -344,7 +350,8 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) n++; } // endif xcp - pxcp = xcp; + if (xcp) + pxcp = xcp; if (vp->atp) vp->atp = vp->atp->GetNext(g); @@ -445,6 +452,7 @@ XMLDEF::XMLDEF(void) Usedom = false; Zipped = false; Mulentries = false; + Skip = false; } // end of XMLDEF constructor /***********************************************************************/ @@ -814,127 +822,141 @@ bool TDBXML::Initialize(PGLOBAL g) } // endif Bufdone #if !defined(UNIX) - if (!Root) try { + if (!Root) try { #else - if (!Root) { + if (!Root) { #endif - char tabpath[64], filename[_MAX_PATH]; - - // We used the file name relative to recorded datapath - PlugSetPath(filename, Xfile, GetPath()); - - // Load or re-use the table file - rc = LoadTableFile(g, filename); - - if (rc == RC_OK) { - // Get root node - if (!(Root = Docp->GetRoot(g))) { - // This should never happen as load should have failed - strcpy(g->Message, MSG(EMPTY_DOC)); - goto error; - } // endif Root - - // If tabname is not an Xpath, - // construct one that will find it anywhere - if (!strchr(Tabname, '/')) - strcat(strcpy(tabpath, "//"), Tabname); - else - strcpy(tabpath, Tabname); - - // Evaluate table xpath - if ((TabNode = Root->SelectSingleNode(g, tabpath))) { - if (TabNode->GetType() != XML_ELEMENT_NODE) { - sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); - goto error; - } // endif Type - - } else if (Mode == MODE_INSERT && XmlDB) { - // We are adding a new table to a multi-table file - - // If XmlDB is not an Xpath, - // construct one that will find it anywhere - if (!strchr(XmlDB, '/')) - strcat(strcpy(tabpath, "//"), XmlDB); - else - strcpy(tabpath, XmlDB); - - if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { - // DB node does not exist yet; we cannot create it - // because we don't know where it should be placed - sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); - goto error; - } // endif DBnode - - if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { - sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); - goto error; - } // endif TabNode - - DBnode->AddText(g, "\n"); - } else - TabNode = Root; // Try this ? - - } else if (rc == RC_NF || rc == RC_EF) { - // The XML file does not exist or is void - if (Mode == MODE_INSERT) { - // New Document - char buf[64]; - - // Create the XML node - if (Docp->NewDoc(g, "1.0")) { - strcpy(g->Message, MSG(NEW_DOC_FAILED)); - goto error; - } // endif NewDoc - - // Now we can link the Xblock - To_Xb = Docp->LinkXblock(g, Mode, rc, filename); - - // Add a CONNECT comment node - strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); - Docp->AddComment(g, buf); - - if (XmlDB) { - // This is a multi-table file - DBnode = Root = Docp->NewRoot(g, XmlDB); - DBnode->AddText(g, "\n"); - TabNode = DBnode->AddChildNode(g, Tabname); - DBnode->AddText(g, "\n"); - } else - TabNode = Root = Docp->NewRoot(g, Tabname); - - if (TabNode == NULL || Root == NULL) { - strcpy(g->Message, MSG(XML_INIT_ERROR)); - goto error; - } else if (SetTabNode(g)) - goto error; - - } else { - sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); - - if (Mode == MODE_READ) { - PushWarning(g, this); - Void = true; - } // endif Mode - - goto error; - } // endif Mode - - } else if (rc == RC_INFO) { - // Loading failed - sprintf(g->Message, MSG(LOADING_FAILED), Xfile); - goto error; - } else // (rc == RC_FX) - goto error; - - // Get row node list - if (Rowname) - Nlist = TabNode->SelectNodes(g, Rowname); - else - Nlist = TabNode->GetChildElements(g); - - Docp->SetNofree(true); // For libxml2 + char tabpath[64], filename[_MAX_PATH]; + + // We used the file name relative to recorded datapath + PlugSetPath(filename, Xfile, GetPath()); + + // Load or re-use the table file + rc = LoadTableFile(g, filename); + + if (rc == RC_OK) { + // Get root node + if (!(Root = Docp->GetRoot(g))) { + // This should never happen as load should have failed + strcpy(g->Message, MSG(EMPTY_DOC)); + goto error; + } // endif Root + + // If tabname is not an Xpath, + // construct one that will find it anywhere + if (!strchr(Tabname, '/')) + strcat(strcpy(tabpath, "//"), Tabname); + else + strcpy(tabpath, Tabname); + + // Evaluate table xpath + if ((TabNode = Root->SelectSingleNode(g, tabpath))) { + if (TabNode->GetType() != XML_ELEMENT_NODE) { + sprintf(g->Message, MSG(BAD_NODE_TYPE), TabNode->GetType()); + goto error; + } // endif Type + + } else if (Mode == MODE_INSERT && XmlDB) { + // We are adding a new table to a multi-table file + + // If XmlDB is not an Xpath, + // construct one that will find it anywhere + if (!strchr(XmlDB, '/')) + strcat(strcpy(tabpath, "//"), XmlDB); + else + strcpy(tabpath, XmlDB); + + if (!(DBnode = Root->SelectSingleNode(g, tabpath))) { + // DB node does not exist yet; we cannot create it + // because we don't know where it should be placed + sprintf(g->Message, MSG(MISSING_NODE), XmlDB, Xfile); + goto error; + } // endif DBnode + + if (!(TabNode = DBnode->AddChildNode(g, Tabname))) { + sprintf(g->Message, MSG(FAIL_ADD_NODE), Tabname); + goto error; + } // endif TabNode + + DBnode->AddText(g, "\n"); + } else { + TabNode = Root; // Try this ? + Tabname = TabNode->GetName(g); + } // endif's + + } else if (rc == RC_NF || rc == RC_EF) { + // The XML file does not exist or is void + if (Mode == MODE_INSERT) { + // New Document + char buf[64]; + + // Create the XML node + if (Docp->NewDoc(g, "1.0")) { + strcpy(g->Message, MSG(NEW_DOC_FAILED)); + goto error; + } // endif NewDoc + + // Now we can link the Xblock + To_Xb = Docp->LinkXblock(g, Mode, rc, filename); + + // Add a CONNECT comment node + strcpy(buf, " Created by the MariaDB CONNECT Storage Engine"); + Docp->AddComment(g, buf); + + if (XmlDB) { + // This is a multi-table file + DBnode = Root = Docp->NewRoot(g, XmlDB); + DBnode->AddText(g, "\n"); + TabNode = DBnode->AddChildNode(g, Tabname); + DBnode->AddText(g, "\n"); + } else + TabNode = Root = Docp->NewRoot(g, Tabname); + + if (TabNode == NULL || Root == NULL) { + strcpy(g->Message, MSG(XML_INIT_ERROR)); + goto error; + } else if (SetTabNode(g)) + goto error; + + } else { + sprintf(g->Message, MSG(FILE_UNFOUND), Xfile); + + if (Mode == MODE_READ) { + PushWarning(g, this); + Void = true; + } // endif Mode + + goto error; + } // endif Mode + + } else if (rc == RC_INFO) { + // Loading failed + sprintf(g->Message, MSG(LOADING_FAILED), Xfile); + goto error; + } else // (rc == RC_FX) + goto error; + + if (!Rowname) { + for (PXNODE n = TabNode->GetChild(g); n; n = n->GetNext(g)) + if (n->GetType() == XML_ELEMENT_NODE) { + Rowname = n->GetName(g); + break; + } // endif Type + + if (!Rowname) + Rowname = TabNode->GetName(g); + } // endif Rowname + + // Get row node list + if (strcmp(Rowname, Tabname)) + Nlist = TabNode->SelectNodes(g, Rowname); + else + Nrow = 1; + + + Docp->SetNofree(true); // For libxml2 #if defined(__WIN__) - } catch(_com_error e) { + } catch (_com_error e) { // We come here if a DOM command threw an error char buf[128]; @@ -1221,10 +1243,14 @@ int TDBXML::ReadDB(PGLOBAL g) htrc("TDBXML ReadDB: Irow=%d RowNode=%p\n", Irow, RowNode); // Get the new row node - if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { - sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); - return RC_FX; - } // endif RowNode + if (Nlist) { + if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) { + sprintf(g->Message, MSG(MISSING_ROWNODE), Irow); + return RC_FX; + } // endif RowNode + + } else + RowNode = TabNode; if (Colname && Coltype == 2) Clist = RowNode->SelectNodes(g, Colname, Clist); @@ -1279,6 +1305,7 @@ int TDBXML::WriteDB(PGLOBAL g) /***********************************************************************/ int TDBXML::DeleteDB(PGLOBAL g, int irc) { + // TODO: Handle null Nlist if (irc == RC_FX) { // Delete all rows for (Irow = 0; Irow < Nrow; Irow++) |