summaryrefslogtreecommitdiff
path: root/storage/connect/mycat.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mnogosearch.org>2013-02-07 13:34:27 +0400
committerAlexander Barkov <bar@mnogosearch.org>2013-02-07 13:34:27 +0400
commit30c4b0ebc24fe0106e146b1f6577a4150e71e258 (patch)
tree592673d8c2f5b418833c3ee5fcfeb9dbf4ba1681 /storage/connect/mycat.cc
parent60c4cab3bd00621cc03afb1be6de01c8fab0c5f0 (diff)
downloadmariadb-git-30c4b0ebc24fe0106e146b1f6577a4150e71e258.tar.gz
- Fixing TAB to 2 spaces
- Fixing line endings from "\r\n" to "\n"
Diffstat (limited to 'storage/connect/mycat.cc')
-rw-r--r--storage/connect/mycat.cc1314
1 files changed, 657 insertions, 657 deletions
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 073c16f18ec..706f41780fe 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -1,657 +1,657 @@
-/* Copyright (C) Olivier Bertrand 2004 - 2012
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*************** Mycat CC Program Source Code File (.CC) ***************/
-/* PROGRAM NAME: MYCAT */
-/* ------------- */
-/* Version 1.3 */
-/* */
-/* Author: Olivier Bertrand 2012 - 2013 */
-/* */
-/* WHAT THIS PROGRAM DOES: */
-/* ----------------------- */
-/* This program are the DB description related routines. */
-/***********************************************************************/
-
-/***********************************************************************/
-/* Include relevant MariaDB header file. */
-/***********************************************************************/
-#if defined(WIN32)
-//#include <windows.h>
-//#include <sqlext.h>
-#elif defined(UNIX)
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#endif
-#define DONT_DEFINE_VOID
-//#include <mysql/plugin.h>
-#include "handler.h"
-#undef OFFSET
-
-/***********************************************************************/
-/* Include application header files */
-/* */
-/* global.h is header containing all global declarations. */
-/* plgdbsem.h is header containing DB application declarations. */
-/* tabdos.h is header containing TDBDOS classes declarations. */
-/* MYCAT.h is header containing DB description declarations. */
-/***********************************************************************/
-#if defined(UNIX)
-#include "osutil.h"
-#endif // UNIX
-#include "global.h"
-#include "plgdbsem.h"
-#include "reldef.h"
-#include "tabcol.h"
-#include "xtable.h"
-#include "filamtxt.h"
-#include "tabdos.h"
-#include "tabfmt.h"
-#include "tabvct.h"
-#include "tabsys.h"
-#if defined(WIN32)
-#include "tabmac.h"
-#include "tabwmi.h"
-#endif // WIN32
-#include "tabtbl.h"
-#if defined(XML_SUPPORT)
-#include "tabxml.h"
-#endif // XML_SUPPORT
-#include "tabmul.h"
-#if defined(MYSQL_SUPPORT)
-#include "tabmysql.h"
-#endif // MYSQL_SUPPORT
-#if defined(ODBC_SUPPORT)
-#define NODBC
-#include "tabodbc.h"
-#endif // ODBC_SUPPORT
-#if defined(PIVOT_SUPPORT)
-#include "tabpivot.h"
-#endif // PIVOT_SUPPORT
-#include "ha_connect.h"
-#include "mycat.h"
-
-/**************************************************************************/
-/* Extern static variables. */
-/**************************************************************************/
-#if defined(WIN32)
-extern "C" HINSTANCE s_hModule; // Saved module handle
-#endif // !WIN32
-
-extern int xtrace;
-
-/**************************************************************************/
-/* General DB routines. */
-/**************************************************************************/
-//bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR);
-#if !defined(WIN32)
-extern "C" int GetRcString(int id, char *buf, int bufsize);
-#endif // !WIN32
-//void ptrc(char const *fmt, ...);
-
-/**************************************************************************/
-/* Allocate the result structure that will contain result data. */
-/**************************************************************************/
-PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
- int *dbtype, int *buftyp, unsigned int *length,
- bool blank = false, bool nonull = false)
- {
- char cname[NAM_LEN+1];
- int i;
- PCOLRES *pcrp, crp;
- PQRYRES qrp;
-
- /************************************************************************/
- /* Allocate the structure used to contain the result set. */
- /************************************************************************/
- qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
- pcrp = &qrp->Colresp;
- qrp->Continued = false;
- qrp->Truncated = false;
- qrp->Info = false;
- qrp->Suball = true;
- qrp->Maxres = maxres;
- qrp->Maxsize = 0;
- qrp->Nblin = 0;
- qrp->Nbcol = 0; // will be ncol
- qrp->Cursor = 0;
- qrp->BadLines = 0;
-
- for (i = 0; i < ncol; i++) {
- *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
- crp = *pcrp;
- pcrp = &crp->Next;
- crp->Colp = NULL;
- crp->Ncol = ++qrp->Nbcol;
- crp->Type = buftyp[i];
- crp->Length = length[i];
- crp->Clen = GetTypeSize(crp->Type, length[i]);
- crp->Prec = 0;
- crp->DBtype = dbtype[i];
-
- if (ids > 0) {
-#if defined(XMSG)
- // Get header from message file
- strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
- cname[NAM_LEN] = 0; // for truncated long names
-#elif defined(WIN32)
- // Get header from ressource file
- LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
-#else // !WIN32
- GetRcString(ids + crp->Ncol, cname, sizeof(cname));
-#endif // !WIN32
- crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1);
- strcpy(crp->Name, cname);
- } else
- crp->Name = NULL; // Will be set by caller
-
- // Allocate the Value Block that will contain data
- if (crp->Length || nonull)
- crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
- crp->Length, 0, true, blank);
- else
- crp->Kdata = NULL;
-
- if (g->Trace)
- htrc("Column(%d) %s type=%d len=%d value=%p\n",
- crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
-
- } // endfor i
-
- *pcrp = NULL;
-
- return qrp;
- } // end of PlgAllocResult
-
-/***********************************************************************/
-/* Get a unique char identifier for types. The letter used are: */
-/* ABCDEF..I.KLM.O..R.T.VWXY.. */
-/***********************************************************************/
-char GetTypeID(char *type)
- {
- return (!type) ? 'D' // DOS (default)
- : (!stricmp(type, "FMT")) ? 'T' // CSV
- : (!stricmp(type, "DIR")) ? 'R' // diR
- : (!stricmp(type, "DBF")) ? 'A' // dbAse
- : (!stricmp(type, "SYS")) ? 'I' // INI
- : (!stricmp(type, "TBL")) ? 'L' // tbL
- : (!stricmp(type, "MYSQL")) ? 'Y' // mYsql
- : (!stricmp(type, "OEM")) ? 'E' : toupper(*type);
- } // end of GetTypeID
-
-/* ------------------------- Class CATALOG --------------------------- */
-
-/***********************************************************************/
-/* CATALOG Constructor. */
-/***********************************************************************/
-CATALOG::CATALOG(void)
- {
- To_Desc= NULL;
-//*DescFile= '\0';
-#if defined(WIN32)
- DataPath= ".\\";
-#else // !WIN32
- DataPath= "./";
-#endif // !WIN32
- Descp= NULL;
-//memset(&DescArea, 0, sizeof(AREADEF));
- memset(&Ctb, 0, sizeof(CURTAB));
- Cbuf= NULL;
- Cblen= 0;
- DefHuge= false;
- } // end of CATALOG constructor
-
-/* -------------------------- Class MYCAT ---------------------------- */
-
-/***********************************************************************/
-/* MYCAT Constructor. */
-/***********************************************************************/
-MYCAT::MYCAT(PHC hc) : CATALOG()
- {
- Hc= hc;
- To_Desc= NULL;
- DefHuge= false;
- SepIndex= true; // Temporay until we can store offet and size
- } // end of MYCAT constructor
-
-/***********************************************************************/
-/* When using volatile storage, reset values pointing to Sarea. */
-/***********************************************************************/
-void MYCAT::Reset(void)
- {
- To_Desc= NULL;
- } // end of Reset
-
-/***********************************************************************/
-/* This function sets the current database path. */
-/***********************************************************************/
-void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path)
- {
- if (path) {
- size_t len= strlen(path) + (*path != '.' ? 4 : 1);
- char *buf= (char*)PlugSubAlloc(g, NULL, len);
-
- if (*path != '.') {
-#if defined(WIN32)
- char *s= "\\";
-#else // !WIN32
- char *s= "/";
-#endif // !WIN32
- strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
- } else
- strcpy(buf, path);
-
- *datapath= buf;
- } // endif path
-
- } // end of SetDataPath
-
-/***********************************************************************/
-/* This function sets an integer MYCAT information. */
-/***********************************************************************/
-bool MYCAT::SetIntCatInfo(LPCSTR name, PSZ what, int n)
- {
- return Hc->SetIntegerOption(what, n);
- } // end of SetIntCatInfo
-
-/***********************************************************************/
-/* This function returns integer MYCAT information. */
-/***********************************************************************/
-int MYCAT::GetIntCatInfo(LPCSTR name, PSZ what, int idef)
- {
- int n= Hc->GetIntegerOption(what);
-
- return (n == NO_IVAL) ? idef : n;
- } // end of GetIntCatInfo
-
-/***********************************************************************/
-/* This function returns Boolean MYCAT information. */
-/***********************************************************************/
-bool MYCAT::GetBoolCatInfo(LPCSTR name, PSZ what, bool bdef)
- {
- bool b= Hc->GetBooleanOption(what, bdef);
-
- return b;
- } // end of GetBoolCatInfo
-
-/***********************************************************************/
-/* This function returns size catalog information. */
-/***********************************************************************/
-int MYCAT::GetSizeCatInfo(LPCSTR name, PSZ what, PSZ sdef)
- {
- char * s, c;
- int i, n= 0;
-
- if (!(s= Hc->GetStringOption(what)))
- s= sdef;
-
- if ((i= sscanf(s, " %d %c ", &n, &c)) == 2)
- switch (toupper(c)) {
- case 'M':
- n *= 1024;
- case 'K':
- n *= 1024;
- } // endswitch c
-
- return n;
-} // end of GetSizeCatInfo
-
-/***********************************************************************/
-/* This function sets char MYCAT information in buf. */
-/***********************************************************************/
-int MYCAT::GetCharCatInfo(LPCSTR name, PSZ what,
- PSZ sdef, char *buf, int size)
- {
- char *s= Hc->GetStringOption(what);
-
- strncpy(buf, ((s) ? s : sdef), size);
- return size;
- } // end of GetCharCatInfo
-
-/***********************************************************************/
-/* This function returns string MYCAT information. */
-/* Default parameter is "*" to get the handler default. */
-/***********************************************************************/
-char *MYCAT::GetStringCatInfo(PGLOBAL g, PSZ name, PSZ what, PSZ sdef)
- {
- char *sval, *s= Hc->GetStringOption(what, sdef);
-
- if (s) {
- sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + 1);
- strcpy(sval, s);
- } else
- sval = NULL;
-
- return sval;
- } // end of GetStringCatInfo
-
-/***********************************************************************/
-/* This function returns column MYCAT information. */
-/***********************************************************************/
-int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
- {
- char *type= GetStringCatInfo(g, NULL, "Type", "DOS");
- int i, loff, poff, nof, nlg;
- void *field= NULL;
- PCOLDEF cdp, lcdp= NULL, tocols= NULL;
- PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
-
- // Get a unique char identifier for type
- char tc= GetTypeID(type);
-
- // Take care of the column definitions
- i= poff= nof= nlg= 0;
-
- // Offsets of HTML and DIR tables start from 0, DBF at 1
- loff= (tc == 'A') ? 1 : (tc == 'X' || tc == 'R') ? -1 : 0;
-
- while (true) {
- // Default Offset depends on table type
- switch (tc) {
- case 'D': // DOS
- case 'F': // FIX
- case 'B': // BIN
- case 'V': // VEC
- case 'A': // DBF
- poff= loff + nof; // Default next offset
- nlg= max(nlg, poff); // Default lrecl
- break;
- case 'C': // CSV
- case 'T': // FMT
- nlg+= nof;
- case 'R': // DIR
- case 'X': // XML
- poff= loff + 1;
- break;
- case 'I': // INI
- case 'M': // MAC
- case 'L': // TBL
- case 'E': // OEM
- poff = 0; // Offset represents an independant flag
- break;
- default: // VCT PLG ODBC MYSQL WMI...
- poff = 0; // NA
- break;
- } // endswitch tc
-
- do {
- field= Hc->GetColumnOption(field, pcf);
- } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
-
- if (tc == 'A' && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
- // DBF date format defaults to 'YYYMMDD'
- pcf->Datefmt= "YYYYMMDD";
- pcf->Length= 8;
- } // endif tc
-
- if (!field)
- break;
-
- // Allocate the column description block
- cdp= new(g) COLDEF;
-
- if ((nof= cdp->Define(g, NULL, pcf, poff)) < 0)
- return -1; // Error, probably unhandled type
- else if (nof)
- loff= cdp->GetOffset();
-
- switch (tc) {
- case 'V':
- cdp->SetOffset(0); // Not to have shift
- case 'B':
- // BIN/VEC are packed by default
- if (nof)
- // Field width is the internal representation width
- // that can also depend on the column format
- switch (cdp->Fmt ? *cdp->Fmt : 'X') {
- case 'C': break;
- case 'R':
- case 'F':
- case 'L':
- case 'I': nof= 4; break;
- case 'D': nof= 8; break;
- case 'S': nof= 2; break;
- case 'T': nof= 1; break;
- default: nof= cdp->Clen;
- } // endswitch Fmt
-
- break;
- } // endswitch tc
-
- if (lcdp)
- lcdp->SetNext(cdp);
- else
- tocols= cdp;
-
- lcdp= cdp;
- i++;
- } // endwhile
-
- // Degree is the the number of defined columns (informational)
- if (i != defp->GetDegree())
- defp->SetDegree(i);
-
- if (defp->GetDefType() == TYPE_AM_DOS) {
- int ending, recln= 0;
- PDOSDEF ddp= (PDOSDEF)defp;
-
- // Was commented because sometimes ending is 0 even when
- // not specified (for instance if quoted is specified)
-// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
- if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
-#if defined(WIN32)
- ending= 2;
-#else
- ending= 1;
-#endif
- Hc->SetIntegerOption("Ending", ending);
- } // endif ending
-
- // Calculate the default record size
- switch (tc) {
- case 'F':
- recln= nlg + ending; // + length of line ending
- break;
- case 'B':
- case 'V':
- recln= nlg;
-
-// if ((k= (pak < 0) ? 8 : pak) > 1)
- // See above for detailed comment
- // Round up lrecl to multiple of 8 or pak
-// recln= ((recln + k - 1) / k) * k;
-
- break;
- case 'D':
- case 'A':
- recln= nlg;
- break;
- case 'T':
- case 'C':
- // The number of separators (assuming an extra one can exist)
-// recln= poff * ((qotd) ? 3 : 1); to be investigated
- recln= nlg + poff * 3; // To be safe
- break;
- } // endswitch tc
-
- // lrecl must be at least recln to avoid buffer overflow
- recln= max(recln, Hc->GetIntegerOption("Lrecl"));
- Hc->SetIntegerOption("Lrecl", recln);
- ddp->SetLrecl(recln);
- } // endif Lrecl
-
- // Attach the column definition to the tabdef
- defp->SetCols(tocols);
- return poff;
- } // end of GetColCatInfo
-
-/***********************************************************************/
-/* GetIndexInfo: retrieve index description from the table structure. */
-/***********************************************************************/
-bool MYCAT::GetIndexInfo(PGLOBAL g, PTABDEF defp)
- {
- PIXDEF xdp, pxd= NULL, toidx= NULL;
-
- // Now take care of the index definitions
- for (int n= 0; ; n++) {
- if (xtrace)
- printf("Getting index %d info\n", n + 1);
-
- if (!(xdp= Hc->GetIndexInfo(n)))
- break;
-
- if (pxd)
- pxd->SetNext(xdp);
- else
- toidx= xdp;
-
- pxd= xdp;
- } // endfor n
-
- // All is correct, attach new index(es)
- defp->SetIndx(toidx);
- return false;
- } // end of GetIndexInfo
-
-/***********************************************************************/
-/* GetTableDesc: retrieve a table descriptor. */
-/* Look for a table descriptor matching the name and type. If found */
-/* in storage, return a pointer to it, else look in the XDB file. If */
-/* found, make and add the descriptor and return a pointer to it. */
-/***********************************************************************/
-PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name,
- LPCSTR am, PRELDEF *prp)
- {
- LPCSTR type;
-
- if (xtrace)
- printf("GetTableDesc: name=%s am=%s\n", name, SVP(am));
-
- // Firstly check whether this table descriptor is in memory
- if (To_Desc)
- return To_Desc;
-
- // Here get the type of this table
- if (!(type= Hc->GetStringOption("Type")))
- type= "DOS";
-
- return MakeTableDesc(g, name, type);
- } // end of GetTableDesc
-
-/***********************************************************************/
-/* MakeTableDesc: make a table/view description. */
-/* Note: caller must check if name already exists before calling it. */
-/***********************************************************************/
-PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
- {
- char tc;
- PRELDEF tdp= NULL;
-
- if (xtrace)
- printf("MakeTableDesc: name=%s am=%s\n", name, SVP(am));
-
- /*********************************************************************/
- /* Get a unique char identifier for types. The letter used are: */
- /* ABCDEF..IJKLM.OPQRSTUVWXYZ and Allocate table definition class */
- /*********************************************************************/
- tc= GetTypeID((char*)am);
-
- switch (tc) {
- case 'F':
- case 'B':
- case 'A':
- case 'D': tdp= new(g) DOSDEF; break;
- case 'T':
- case 'C': tdp= new(g) CSVDEF; break;
- case 'I': tdp= new(g) INIDEF; break;
- case 'R': tdp= new(g) DIRDEF; break;
-#if defined(XML_SUPPORT)
- case 'X': tdp= new(g) XMLDEF; break;
-#endif // XML_SUPPORT
- case 'V': tdp= new(g) VCTDEF; break;
-#if defined(ODBC_SUPPORT)
- case 'O': tdp= new(g) ODBCDEF; break;
-#endif // ODBC_SUPPORT
-#if defined(WIN32)
- case 'M': tdp= new(g) MACDEF; break;
- case 'W': tdp= new(g) WMIDEF; break;
-#endif // WIN32
- case 'E': tdp= new(g) OEMDEF; break;
- case 'L': tdp= new(g) TBLDEF; break;
-#if defined(MYSQL_SUPPORT)
- case 'Y': tdp= new(g) MYSQLDEF; break;
-#endif // MYSQL_SUPPORT
-#if defined(PIVOT_SUPPORT)
- case 'P': tdp= new(g) PIVOTDEF; break;
-#endif // PIVOT_SUPPORT
- default:
- sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
- } // endswitch
-
- // Do make the table/view definition from XDB file information
- if (tdp && tdp->Define(g, this, name, am))
- tdp= NULL;
-
- return tdp;
- } // end of MakeTableDesc
-
-/***********************************************************************/
-/* Initialize a Table Description Block construction. */
-/***********************************************************************/
-PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode)
- {
- PRELDEF tdp;
- PTDB tdbp= NULL;
- LPCSTR name= tablep->GetName();
-
- if (xtrace)
- printf("GetTableDB: name=%s\n", name);
-
- // Look for the description of the requested table
- tdp= GetTableDesc(g, name, NULL);
-
- if (tdp) {
- if (xtrace)
- printf("tdb=%p type=%s\n", tdp, tdp->GetType());
-
- if (tablep->GetQualifier())
- SetPath(g, &tdp->Database, tablep->GetQualifier());
-
- tdbp= tdp->GetTable(g, mode);
- } // endif tdp
-
- if (tdbp) {
- if (xtrace)
- printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
- tdbp->GetAmType());
- tablep->SetTo_Tdb(tdbp);
- tdbp->SetTable(tablep);
- } // endif tdbp
-
- return (tdbp);
- } // end of GetTable
-
-/***********************************************************************/
-/* ClearDB: Terminates Database usage. */
-/***********************************************************************/
-void MYCAT::ClearDB(PGLOBAL g)
- {
- To_Desc= NULL;
- } // end of ClearDB
-
-/* ------------------------ End of MYCAT --------------------------- */
+/* Copyright (C) Olivier Bertrand 2004 - 2012
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*************** Mycat CC Program Source Code File (.CC) ***************/
+/* PROGRAM NAME: MYCAT */
+/* ------------- */
+/* Version 1.3 */
+/* */
+/* Author: Olivier Bertrand 2012 - 2013 */
+/* */
+/* WHAT THIS PROGRAM DOES: */
+/* ----------------------- */
+/* This program are the DB description related routines. */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Include relevant MariaDB header file. */
+/***********************************************************************/
+#if defined(WIN32)
+//#include <windows.h>
+//#include <sqlext.h>
+#elif defined(UNIX)
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#define DONT_DEFINE_VOID
+//#include <mysql/plugin.h>
+#include "handler.h"
+#undef OFFSET
+
+/***********************************************************************/
+/* Include application header files */
+/* */
+/* global.h is header containing all global declarations. */
+/* plgdbsem.h is header containing DB application declarations. */
+/* tabdos.h is header containing TDBDOS classes declarations. */
+/* MYCAT.h is header containing DB description declarations. */
+/***********************************************************************/
+#if defined(UNIX)
+#include "osutil.h"
+#endif // UNIX
+#include "global.h"
+#include "plgdbsem.h"
+#include "reldef.h"
+#include "tabcol.h"
+#include "xtable.h"
+#include "filamtxt.h"
+#include "tabdos.h"
+#include "tabfmt.h"
+#include "tabvct.h"
+#include "tabsys.h"
+#if defined(WIN32)
+#include "tabmac.h"
+#include "tabwmi.h"
+#endif // WIN32
+#include "tabtbl.h"
+#if defined(XML_SUPPORT)
+#include "tabxml.h"
+#endif // XML_SUPPORT
+#include "tabmul.h"
+#if defined(MYSQL_SUPPORT)
+#include "tabmysql.h"
+#endif // MYSQL_SUPPORT
+#if defined(ODBC_SUPPORT)
+#define NODBC
+#include "tabodbc.h"
+#endif // ODBC_SUPPORT
+#if defined(PIVOT_SUPPORT)
+#include "tabpivot.h"
+#endif // PIVOT_SUPPORT
+#include "ha_connect.h"
+#include "mycat.h"
+
+/**************************************************************************/
+/* Extern static variables. */
+/**************************************************************************/
+#if defined(WIN32)
+extern "C" HINSTANCE s_hModule; // Saved module handle
+#endif // !WIN32
+
+extern int xtrace;
+
+/**************************************************************************/
+/* General DB routines. */
+/**************************************************************************/
+//bool PlugCheckPattern(PGLOBAL, LPCSTR, LPCSTR);
+#if !defined(WIN32)
+extern "C" int GetRcString(int id, char *buf, int bufsize);
+#endif // !WIN32
+//void ptrc(char const *fmt, ...);
+
+/**************************************************************************/
+/* Allocate the result structure that will contain result data. */
+/**************************************************************************/
+PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
+ int *dbtype, int *buftyp, unsigned int *length,
+ bool blank = false, bool nonull = false)
+ {
+ char cname[NAM_LEN+1];
+ int i;
+ PCOLRES *pcrp, crp;
+ PQRYRES qrp;
+
+ /************************************************************************/
+ /* Allocate the structure used to contain the result set. */
+ /************************************************************************/
+ qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES));
+ pcrp = &qrp->Colresp;
+ qrp->Continued = false;
+ qrp->Truncated = false;
+ qrp->Info = false;
+ qrp->Suball = true;
+ qrp->Maxres = maxres;
+ qrp->Maxsize = 0;
+ qrp->Nblin = 0;
+ qrp->Nbcol = 0; // will be ncol
+ qrp->Cursor = 0;
+ qrp->BadLines = 0;
+
+ for (i = 0; i < ncol; i++) {
+ *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
+ crp = *pcrp;
+ pcrp = &crp->Next;
+ crp->Colp = NULL;
+ crp->Ncol = ++qrp->Nbcol;
+ crp->Type = buftyp[i];
+ crp->Length = length[i];
+ crp->Clen = GetTypeSize(crp->Type, length[i]);
+ crp->Prec = 0;
+ crp->DBtype = dbtype[i];
+
+ if (ids > 0) {
+#if defined(XMSG)
+ // Get header from message file
+ strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
+ cname[NAM_LEN] = 0; // for truncated long names
+#elif defined(WIN32)
+ // Get header from ressource file
+ LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
+#else // !WIN32
+ GetRcString(ids + crp->Ncol, cname, sizeof(cname));
+#endif // !WIN32
+ crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1);
+ strcpy(crp->Name, cname);
+ } else
+ crp->Name = NULL; // Will be set by caller
+
+ // Allocate the Value Block that will contain data
+ if (crp->Length || nonull)
+ crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
+ crp->Length, 0, true, blank);
+ else
+ crp->Kdata = NULL;
+
+ if (g->Trace)
+ htrc("Column(%d) %s type=%d len=%d value=%p\n",
+ crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata);
+
+ } // endfor i
+
+ *pcrp = NULL;
+
+ return qrp;
+ } // end of PlgAllocResult
+
+/***********************************************************************/
+/* Get a unique char identifier for types. The letter used are: */
+/* ABCDEF..I.KLM.O..R.T.VWXY.. */
+/***********************************************************************/
+char GetTypeID(char *type)
+ {
+ return (!type) ? 'D' // DOS (default)
+ : (!stricmp(type, "FMT")) ? 'T' // CSV
+ : (!stricmp(type, "DIR")) ? 'R' // diR
+ : (!stricmp(type, "DBF")) ? 'A' // dbAse
+ : (!stricmp(type, "SYS")) ? 'I' // INI
+ : (!stricmp(type, "TBL")) ? 'L' // tbL
+ : (!stricmp(type, "MYSQL")) ? 'Y' // mYsql
+ : (!stricmp(type, "OEM")) ? 'E' : toupper(*type);
+ } // end of GetTypeID
+
+/* ------------------------- Class CATALOG --------------------------- */
+
+/***********************************************************************/
+/* CATALOG Constructor. */
+/***********************************************************************/
+CATALOG::CATALOG(void)
+ {
+ To_Desc= NULL;
+//*DescFile= '\0';
+#if defined(WIN32)
+ DataPath= ".\\";
+#else // !WIN32
+ DataPath= "./";
+#endif // !WIN32
+ Descp= NULL;
+//memset(&DescArea, 0, sizeof(AREADEF));
+ memset(&Ctb, 0, sizeof(CURTAB));
+ Cbuf= NULL;
+ Cblen= 0;
+ DefHuge= false;
+ } // end of CATALOG constructor
+
+/* -------------------------- Class MYCAT ---------------------------- */
+
+/***********************************************************************/
+/* MYCAT Constructor. */
+/***********************************************************************/
+MYCAT::MYCAT(PHC hc) : CATALOG()
+ {
+ Hc= hc;
+ To_Desc= NULL;
+ DefHuge= false;
+ SepIndex= true; // Temporay until we can store offet and size
+ } // end of MYCAT constructor
+
+/***********************************************************************/
+/* When using volatile storage, reset values pointing to Sarea. */
+/***********************************************************************/
+void MYCAT::Reset(void)
+ {
+ To_Desc= NULL;
+ } // end of Reset
+
+/***********************************************************************/
+/* This function sets the current database path. */
+/***********************************************************************/
+void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path)
+ {
+ if (path) {
+ size_t len= strlen(path) + (*path != '.' ? 4 : 1);
+ char *buf= (char*)PlugSubAlloc(g, NULL, len);
+
+ if (*path != '.') {
+#if defined(WIN32)
+ char *s= "\\";
+#else // !WIN32
+ char *s= "/";
+#endif // !WIN32
+ strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
+ } else
+ strcpy(buf, path);
+
+ *datapath= buf;
+ } // endif path
+
+ } // end of SetDataPath
+
+/***********************************************************************/
+/* This function sets an integer MYCAT information. */
+/***********************************************************************/
+bool MYCAT::SetIntCatInfo(LPCSTR name, PSZ what, int n)
+ {
+ return Hc->SetIntegerOption(what, n);
+ } // end of SetIntCatInfo
+
+/***********************************************************************/
+/* This function returns integer MYCAT information. */
+/***********************************************************************/
+int MYCAT::GetIntCatInfo(LPCSTR name, PSZ what, int idef)
+ {
+ int n= Hc->GetIntegerOption(what);
+
+ return (n == NO_IVAL) ? idef : n;
+ } // end of GetIntCatInfo
+
+/***********************************************************************/
+/* This function returns Boolean MYCAT information. */
+/***********************************************************************/
+bool MYCAT::GetBoolCatInfo(LPCSTR name, PSZ what, bool bdef)
+ {
+ bool b= Hc->GetBooleanOption(what, bdef);
+
+ return b;
+ } // end of GetBoolCatInfo
+
+/***********************************************************************/
+/* This function returns size catalog information. */
+/***********************************************************************/
+int MYCAT::GetSizeCatInfo(LPCSTR name, PSZ what, PSZ sdef)
+ {
+ char * s, c;
+ int i, n= 0;
+
+ if (!(s= Hc->GetStringOption(what)))
+ s= sdef;
+
+ if ((i= sscanf(s, " %d %c ", &n, &c)) == 2)
+ switch (toupper(c)) {
+ case 'M':
+ n *= 1024;
+ case 'K':
+ n *= 1024;
+ } // endswitch c
+
+ return n;
+} // end of GetSizeCatInfo
+
+/***********************************************************************/
+/* This function sets char MYCAT information in buf. */
+/***********************************************************************/
+int MYCAT::GetCharCatInfo(LPCSTR name, PSZ what,
+ PSZ sdef, char *buf, int size)
+ {
+ char *s= Hc->GetStringOption(what);
+
+ strncpy(buf, ((s) ? s : sdef), size);
+ return size;
+ } // end of GetCharCatInfo
+
+/***********************************************************************/
+/* This function returns string MYCAT information. */
+/* Default parameter is "*" to get the handler default. */
+/***********************************************************************/
+char *MYCAT::GetStringCatInfo(PGLOBAL g, PSZ name, PSZ what, PSZ sdef)
+ {
+ char *sval, *s= Hc->GetStringOption(what, sdef);
+
+ if (s) {
+ sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + 1);
+ strcpy(sval, s);
+ } else
+ sval = NULL;
+
+ return sval;
+ } // end of GetStringCatInfo
+
+/***********************************************************************/
+/* This function returns column MYCAT information. */
+/***********************************************************************/
+int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
+ {
+ char *type= GetStringCatInfo(g, NULL, "Type", "DOS");
+ int i, loff, poff, nof, nlg;
+ void *field= NULL;
+ PCOLDEF cdp, lcdp= NULL, tocols= NULL;
+ PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
+
+ // Get a unique char identifier for type
+ char tc= GetTypeID(type);
+
+ // Take care of the column definitions
+ i= poff= nof= nlg= 0;
+
+ // Offsets of HTML and DIR tables start from 0, DBF at 1
+ loff= (tc == 'A') ? 1 : (tc == 'X' || tc == 'R') ? -1 : 0;
+
+ while (true) {
+ // Default Offset depends on table type
+ switch (tc) {
+ case 'D': // DOS
+ case 'F': // FIX
+ case 'B': // BIN
+ case 'V': // VEC
+ case 'A': // DBF
+ poff= loff + nof; // Default next offset
+ nlg= max(nlg, poff); // Default lrecl
+ break;
+ case 'C': // CSV
+ case 'T': // FMT
+ nlg+= nof;
+ case 'R': // DIR
+ case 'X': // XML
+ poff= loff + 1;
+ break;
+ case 'I': // INI
+ case 'M': // MAC
+ case 'L': // TBL
+ case 'E': // OEM
+ poff = 0; // Offset represents an independant flag
+ break;
+ default: // VCT PLG ODBC MYSQL WMI...
+ poff = 0; // NA
+ break;
+ } // endswitch tc
+
+ do {
+ field= Hc->GetColumnOption(field, pcf);
+ } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
+
+ if (tc == 'A' && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
+ // DBF date format defaults to 'YYYMMDD'
+ pcf->Datefmt= "YYYYMMDD";
+ pcf->Length= 8;
+ } // endif tc
+
+ if (!field)
+ break;
+
+ // Allocate the column description block
+ cdp= new(g) COLDEF;
+
+ if ((nof= cdp->Define(g, NULL, pcf, poff)) < 0)
+ return -1; // Error, probably unhandled type
+ else if (nof)
+ loff= cdp->GetOffset();
+
+ switch (tc) {
+ case 'V':
+ cdp->SetOffset(0); // Not to have shift
+ case 'B':
+ // BIN/VEC are packed by default
+ if (nof)
+ // Field width is the internal representation width
+ // that can also depend on the column format
+ switch (cdp->Fmt ? *cdp->Fmt : 'X') {
+ case 'C': break;
+ case 'R':
+ case 'F':
+ case 'L':
+ case 'I': nof= 4; break;
+ case 'D': nof= 8; break;
+ case 'S': nof= 2; break;
+ case 'T': nof= 1; break;
+ default: nof= cdp->Clen;
+ } // endswitch Fmt
+
+ break;
+ } // endswitch tc
+
+ if (lcdp)
+ lcdp->SetNext(cdp);
+ else
+ tocols= cdp;
+
+ lcdp= cdp;
+ i++;
+ } // endwhile
+
+ // Degree is the the number of defined columns (informational)
+ if (i != defp->GetDegree())
+ defp->SetDegree(i);
+
+ if (defp->GetDefType() == TYPE_AM_DOS) {
+ int ending, recln= 0;
+ PDOSDEF ddp= (PDOSDEF)defp;
+
+ // Was commented because sometimes ending is 0 even when
+ // not specified (for instance if quoted is specified)
+// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
+ if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
+#if defined(WIN32)
+ ending= 2;
+#else
+ ending= 1;
+#endif
+ Hc->SetIntegerOption("Ending", ending);
+ } // endif ending
+
+ // Calculate the default record size
+ switch (tc) {
+ case 'F':
+ recln= nlg + ending; // + length of line ending
+ break;
+ case 'B':
+ case 'V':
+ recln= nlg;
+
+// if ((k= (pak < 0) ? 8 : pak) > 1)
+ // See above for detailed comment
+ // Round up lrecl to multiple of 8 or pak
+// recln= ((recln + k - 1) / k) * k;
+
+ break;
+ case 'D':
+ case 'A':
+ recln= nlg;
+ break;
+ case 'T':
+ case 'C':
+ // The number of separators (assuming an extra one can exist)
+// recln= poff * ((qotd) ? 3 : 1); to be investigated
+ recln= nlg + poff * 3; // To be safe
+ break;
+ } // endswitch tc
+
+ // lrecl must be at least recln to avoid buffer overflow
+ recln= max(recln, Hc->GetIntegerOption("Lrecl"));
+ Hc->SetIntegerOption("Lrecl", recln);
+ ddp->SetLrecl(recln);
+ } // endif Lrecl
+
+ // Attach the column definition to the tabdef
+ defp->SetCols(tocols);
+ return poff;
+ } // end of GetColCatInfo
+
+/***********************************************************************/
+/* GetIndexInfo: retrieve index description from the table structure. */
+/***********************************************************************/
+bool MYCAT::GetIndexInfo(PGLOBAL g, PTABDEF defp)
+ {
+ PIXDEF xdp, pxd= NULL, toidx= NULL;
+
+ // Now take care of the index definitions
+ for (int n= 0; ; n++) {
+ if (xtrace)
+ printf("Getting index %d info\n", n + 1);
+
+ if (!(xdp= Hc->GetIndexInfo(n)))
+ break;
+
+ if (pxd)
+ pxd->SetNext(xdp);
+ else
+ toidx= xdp;
+
+ pxd= xdp;
+ } // endfor n
+
+ // All is correct, attach new index(es)
+ defp->SetIndx(toidx);
+ return false;
+ } // end of GetIndexInfo
+
+/***********************************************************************/
+/* GetTableDesc: retrieve a table descriptor. */
+/* Look for a table descriptor matching the name and type. If found */
+/* in storage, return a pointer to it, else look in the XDB file. If */
+/* found, make and add the descriptor and return a pointer to it. */
+/***********************************************************************/
+PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name,
+ LPCSTR am, PRELDEF *prp)
+ {
+ LPCSTR type;
+
+ if (xtrace)
+ printf("GetTableDesc: name=%s am=%s\n", name, SVP(am));
+
+ // Firstly check whether this table descriptor is in memory
+ if (To_Desc)
+ return To_Desc;
+
+ // Here get the type of this table
+ if (!(type= Hc->GetStringOption("Type")))
+ type= "DOS";
+
+ return MakeTableDesc(g, name, type);
+ } // end of GetTableDesc
+
+/***********************************************************************/
+/* MakeTableDesc: make a table/view description. */
+/* Note: caller must check if name already exists before calling it. */
+/***********************************************************************/
+PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
+ {
+ char tc;
+ PRELDEF tdp= NULL;
+
+ if (xtrace)
+ printf("MakeTableDesc: name=%s am=%s\n", name, SVP(am));
+
+ /*********************************************************************/
+ /* Get a unique char identifier for types. The letter used are: */
+ /* ABCDEF..IJKLM.OPQRSTUVWXYZ and Allocate table definition class */
+ /*********************************************************************/
+ tc= GetTypeID((char*)am);
+
+ switch (tc) {
+ case 'F':
+ case 'B':
+ case 'A':
+ case 'D': tdp= new(g) DOSDEF; break;
+ case 'T':
+ case 'C': tdp= new(g) CSVDEF; break;
+ case 'I': tdp= new(g) INIDEF; break;
+ case 'R': tdp= new(g) DIRDEF; break;
+#if defined(XML_SUPPORT)
+ case 'X': tdp= new(g) XMLDEF; break;
+#endif // XML_SUPPORT
+ case 'V': tdp= new(g) VCTDEF; break;
+#if defined(ODBC_SUPPORT)
+ case 'O': tdp= new(g) ODBCDEF; break;
+#endif // ODBC_SUPPORT
+#if defined(WIN32)
+ case 'M': tdp= new(g) MACDEF; break;
+ case 'W': tdp= new(g) WMIDEF; break;
+#endif // WIN32
+ case 'E': tdp= new(g) OEMDEF; break;
+ case 'L': tdp= new(g) TBLDEF; break;
+#if defined(MYSQL_SUPPORT)
+ case 'Y': tdp= new(g) MYSQLDEF; break;
+#endif // MYSQL_SUPPORT
+#if defined(PIVOT_SUPPORT)
+ case 'P': tdp= new(g) PIVOTDEF; break;
+#endif // PIVOT_SUPPORT
+ default:
+ sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
+ } // endswitch
+
+ // Do make the table/view definition from XDB file information
+ if (tdp && tdp->Define(g, this, name, am))
+ tdp= NULL;
+
+ return tdp;
+ } // end of MakeTableDesc
+
+/***********************************************************************/
+/* Initialize a Table Description Block construction. */
+/***********************************************************************/
+PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode)
+ {
+ PRELDEF tdp;
+ PTDB tdbp= NULL;
+ LPCSTR name= tablep->GetName();
+
+ if (xtrace)
+ printf("GetTableDB: name=%s\n", name);
+
+ // Look for the description of the requested table
+ tdp= GetTableDesc(g, name, NULL);
+
+ if (tdp) {
+ if (xtrace)
+ printf("tdb=%p type=%s\n", tdp, tdp->GetType());
+
+ if (tablep->GetQualifier())
+ SetPath(g, &tdp->Database, tablep->GetQualifier());
+
+ tdbp= tdp->GetTable(g, mode);
+ } // endif tdp
+
+ if (tdbp) {
+ if (xtrace)
+ printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
+ tdbp->GetAmType());
+ tablep->SetTo_Tdb(tdbp);
+ tdbp->SetTable(tablep);
+ } // endif tdbp
+
+ return (tdbp);
+ } // end of GetTable
+
+/***********************************************************************/
+/* ClearDB: Terminates Database usage. */
+/***********************************************************************/
+void MYCAT::ClearDB(PGLOBAL g)
+ {
+ To_Desc= NULL;
+ } // end of ClearDB
+
+/* ------------------------ End of MYCAT --------------------------- */