Browse Source
- Adding 3 new table types:
- Adding 3 new table types:
PROXY table base on another table. Used by several other types.
XCOL proxy on a table having a colummn containing a list of values
OCCUR proxy on a table having several columns containing the same type
of values that can be put in a unique column and several rows.
TBL Not new but now internally using the PROXY table class.
- Fix 2 bugs in add_field:
Change '=' to ' ' after the COMMENT keyword.
Quote column names between '`' in the SQL string.
- Update xml test result to the CONNECT version
added:
storage/connect/taboccur.cpp
storage/connect/taboccur.h
storage/connect/tabutil.cpp
storage/connect/tabutil.h
storage/connect/tabxcl.cpp
storage/connect/tabxcl.h
modified:
storage/connect/CMakeLists.txt
storage/connect/ha_connect.cc
storage/connect/ha_connect.h
storage/connect/mycat.cc
storage/connect/myconn.cpp
storage/connect/mysql-test/connect/r/xml.result
storage/connect/plgdbsem.h
storage/connect/tabmysql.cpp
storage/connect/tabtbl.cpp
storage/connect/tabtbl.h
storage/connect/valblk.cpp
storage/connect/valblk.h
pull/3/head
18 changed files with 2211 additions and 246 deletions
-
4storage/connect/CMakeLists.txt
-
252storage/connect/ha_connect.cc
-
58storage/connect/ha_connect.h
-
20storage/connect/mycat.cc
-
4storage/connect/myconn.cpp
-
2storage/connect/mysql-test/connect/r/xml.result
-
14storage/connect/plgdbsem.h
-
12storage/connect/tabmysql.cpp
-
375storage/connect/taboccur.cpp
-
145storage/connect/taboccur.h
-
166storage/connect/tabtbl.cpp
-
49storage/connect/tabtbl.h
-
596storage/connect/tabutil.cpp
-
181storage/connect/tabutil.h
-
376storage/connect/tabxcl.cpp
-
133storage/connect/tabxcl.h
-
66storage/connect/valblk.cpp
-
4storage/connect/valblk.h
@ -0,0 +1,375 @@ |
|||
/************ TabOccur CPP Declares Source Code File (.CPP) ************/ |
|||
/* Name: TABOCCUR.CPP Version 1.0 */ |
|||
/* */ |
|||
/* (C) Copyright to the author Olivier BERTRAND 2013 */ |
|||
/* */ |
|||
/* OCCUR: Table that provides a view of a source table where the */ |
|||
/* contain of several columns of the source table is placed in only */ |
|||
/* one column, the OCCUR column, this resulting into several rows. */ |
|||
/***********************************************************************/ |
|||
|
|||
/***********************************************************************/ |
|||
/* Include relevant section of system dependant header files. */ |
|||
/***********************************************************************/ |
|||
#include "my_global.h"
|
|||
#if defined(WIN32)
|
|||
#include <stdlib.h>
|
|||
#include <stdio.h>
|
|||
#if defined(__BORLANDC__)
|
|||
#define __MFC_COMPAT__ // To define min/max as macro
|
|||
#endif
|
|||
//#include <windows.h>
|
|||
#else
|
|||
#if defined(UNIX)
|
|||
#include <fnmatch.h>
|
|||
#include <errno.h>
|
|||
#include <stdlib.h>
|
|||
#include <stdio.h>
|
|||
#include <string.h>
|
|||
#include "osutil.h"
|
|||
#else
|
|||
//#include <io.h>
|
|||
#endif
|
|||
//#include <fcntl.h>
|
|||
#endif
|
|||
|
|||
/***********************************************************************/ |
|||
/* Include application header files: */ |
|||
/***********************************************************************/ |
|||
#include "table.h" // MySQL table definitions
|
|||
#include "global.h"
|
|||
#include "plgdbsem.h"
|
|||
#include "reldef.h"
|
|||
#include "filamtxt.h"
|
|||
#include "tabdos.h"
|
|||
#include "tabcol.h"
|
|||
#include "taboccur.h"
|
|||
#include "xtable.h"
|
|||
#if defined(MYSQL_SUPPORT)
|
|||
#include "tabmysql.h"
|
|||
#endif // MYSQL_SUPPORT
|
|||
#include "ha_connect.h"
|
|||
#include "mycat.h"
|
|||
|
|||
extern "C" int trace; |
|||
|
|||
/* -------------- Implementation of the OCCUR classes ---------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* DefineAM: define specific AM block values from OCCUR table. */ |
|||
/***********************************************************************/ |
|||
bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) |
|||
{ |
|||
//Tabname = Cat->GetStringCatInfo(g, "SrcTable", "");
|
|||
Xcol = Cat->GetStringCatInfo(g, "OccurCol", ""); |
|||
Rcol = Cat->GetStringCatInfo(g, "RankCol", ""); |
|||
Colist = Cat->GetStringCatInfo(g, "Colist", ""); |
|||
return PRXDEF::DefineAM(g, am, poff); |
|||
} // end of DefineAM
|
|||
|
|||
/***********************************************************************/ |
|||
/* GetTable: makes a new TDB of the proper type. */ |
|||
/***********************************************************************/ |
|||
PTDB OCCURDEF::GetTable(PGLOBAL g, MODE m) |
|||
{ |
|||
if (Catfunc != FNC_COL) { |
|||
PTDB tdbp; |
|||
PTDBOCCUR tocp = new(g) TDBOCCUR(this); |
|||
|
|||
// Check that the source table is available
|
|||
if (!tocp || !(tdbp = tocp->GetSubTable(g, Tablep))) |
|||
return NULL; |
|||
|
|||
// Set Tdbp now
|
|||
tocp->SetTdbp((PTDBASE)tdbp); |
|||
|
|||
if (tocp->MakeColumnList(g) < 0) |
|||
return NULL; |
|||
|
|||
return tocp; |
|||
} else |
|||
return new(g) TDBTBC(this); |
|||
|
|||
} // end of GetTable
|
|||
|
|||
/* ------------------------------------------------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* Implementation of the TDBOCCUR class. */ |
|||
/***********************************************************************/ |
|||
TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp) |
|||
{ |
|||
//Tdbp = NULL; // Source table
|
|||
Tabname = tdp->Tablep->GetName(); // Name of source table
|
|||
Colist = tdp->Colist; // List of source columns
|
|||
Xcolumn = tdp->Xcol; // Occur column name
|
|||
Rcolumn = tdp->Rcol; // Rank column name
|
|||
Xcolp = NULL; // To the OCCURCOL column
|
|||
Col = NULL; // To source column blocks array
|
|||
Mult = -1; // Multiplication factor
|
|||
N = 0; // The current table index
|
|||
M = 0; // The occurence rank
|
|||
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
|
|||
} // end of TDBOCCUR constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* Allocate OCCUR/SRC column description block. */ |
|||
/***********************************************************************/ |
|||
PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) |
|||
{ |
|||
PCOL colp = NULL; |
|||
|
|||
if (!stricmp(cdp->GetName(), Rcolumn)) { |
|||
// Allocate a RANK column
|
|||
colp = new(g) RANKCOL(cdp, this, n); |
|||
} else if (!stricmp(cdp->GetName(), Xcolumn)) { |
|||
// Allocate the OCCUR column
|
|||
colp = Xcolp = new(g) OCCURCOL(cdp, this, n); |
|||
} else { |
|||
colp = new(g) PRXCOL(cdp, this, cprec, n); |
|||
|
|||
if (((PPRXCOL)colp)->Init(g)) |
|||
return NULL; |
|||
|
|||
return colp; |
|||
} //endif name
|
|||
|
|||
if (cprec) { |
|||
colp->SetNext(cprec->GetNext()); |
|||
cprec->SetNext(colp); |
|||
} else { |
|||
colp->SetNext(Columns); |
|||
Columns = colp; |
|||
} // endif cprec
|
|||
|
|||
return colp; |
|||
} // end of MakeCol
|
|||
|
|||
/***********************************************************************/ |
|||
/* Allocate OCCUR column description block. */ |
|||
/***********************************************************************/ |
|||
int TDBOCCUR::MakeColumnList(PGLOBAL g) |
|||
{ |
|||
if (Mult < 0) { |
|||
char *p, *pn; |
|||
int i; |
|||
int n = 0; |
|||
|
|||
// Count the number of columns and change separator into null char
|
|||
for (pn = Colist; ; pn += (strlen(pn) + 1)) |
|||
if ((p = strchr(pn, ';'))) { |
|||
*p++ = '\0'; |
|||
n++; |
|||
} else { |
|||
if (*pn) |
|||
n++; |
|||
|
|||
break; |
|||
} // endif p
|
|||
|
|||
Col = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL)); |
|||
|
|||
for (i = 0, pn = Colist; i < n; i++, pn += (strlen(pn) + 1)) { |
|||
if (!(Col[i] = Tdbp->ColDB(g, pn, 0))) { |
|||
// Column not found in table
|
|||
sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname); |
|||
return -1; |
|||
} // endif Col
|
|||
|
|||
if (Col[i]->InitValue(g)) { |
|||
strcpy(g->Message, "OCCUR InitValue failed"); |
|||
return -1; |
|||
} // endif InitValue
|
|||
|
|||
} // endfor i
|
|||
|
|||
// OCCUR column name defaults to the name of the list first column
|
|||
if (!Xcolumn) |
|||
Xcolumn = Colist; |
|||
|
|||
Mult = n; |
|||
} // endif Mult
|
|||
|
|||
return Mult; |
|||
} // end of MakeColumnList
|
|||
|
|||
/***********************************************************************/ |
|||
/* OCCUR GetMaxSize: returns the maximum number of rows in the table. */ |
|||
/***********************************************************************/ |
|||
int TDBOCCUR::GetMaxSize(PGLOBAL g) |
|||
{ |
|||
if (MaxSize < 0) { |
|||
// Mult = MakeColumnList(g);
|
|||
MaxSize = Mult * Tdbp->GetMaxSize(g); |
|||
} // endif MaxSize
|
|||
|
|||
return MaxSize; |
|||
} // end of GetMaxSize
|
|||
|
|||
/***********************************************************************/ |
|||
/* In this sample, ROWID will be the (virtual) row number, */ |
|||
/* while ROWNUM will be the occurence rank in the multiple column. */ |
|||
/***********************************************************************/ |
|||
int TDBOCCUR::RowNumber(PGLOBAL g, bool b) |
|||
{ |
|||
return (b) ? M : N; |
|||
} // end of RowNumber
|
|||
|
|||
/***********************************************************************/ |
|||
/* OCCUR Access Method opening routine. */ |
|||
/***********************************************************************/ |
|||
bool TDBOCCUR::OpenDB(PGLOBAL g) |
|||
{ |
|||
if (Use == USE_OPEN) { |
|||
/*******************************************************************/ |
|||
/* Table already open, just replace it at its beginning. */ |
|||
/*******************************************************************/ |
|||
N = M = 0; |
|||
RowFlag = 0; |
|||
|
|||
if (Xcolp) |
|||
Xcolp->Xreset(); |
|||
|
|||
return Tdbp->OpenDB(g); |
|||
} // endif use
|
|||
|
|||
/*********************************************************************/ |
|||
/* Do it here if not done yet. */ |
|||
/*********************************************************************/ |
|||
// if (MakeColumnList(g) < 0)
|
|||
// return TRUE;
|
|||
|
|||
if (Mode != MODE_READ) { |
|||
/*******************************************************************/ |
|||
/* Currently OCCUR tables cannot be modified. */ |
|||
/*******************************************************************/ |
|||
strcpy(g->Message, "OCCUR tables are read only"); |
|||
return TRUE; |
|||
} // endif Mode
|
|||
|
|||
#if 0
|
|||
/*********************************************************************/ |
|||
/* Be sure OCCUR column exist. */ |
|||
/*********************************************************************/ |
|||
if (!Xcolp) { |
|||
if (!(Xcolp = (POCCURCOL)ColDB(g, Xcolumn, 0))) { |
|||
sprintf(g->Message, "OCCUR column %s definition error", Xcolumn); |
|||
return TRUE; |
|||
} else if (Xcolp->InitValue(g)) { |
|||
strcpy(g->Message, "OCCUR InitValue failed"); |
|||
return TRUE; |
|||
} // endif's Xcolp
|
|||
|
|||
} // endif Xcolp
|
|||
#endif // 0
|
|||
|
|||
if (Xcolp) |
|||
// Lock this column so it is evaluated by its table only
|
|||
Xcolp->AddStatus(BUF_READ); |
|||
|
|||
if (To_Key_Col || To_Kindex) { |
|||
/*******************************************************************/ |
|||
/* Direct access of OCCUR tables is not implemented yet. */ |
|||
/*******************************************************************/ |
|||
strcpy(g->Message, "No direct access to OCCUR tables"); |
|||
return TRUE; |
|||
} // endif To_Key_Col
|
|||
|
|||
/*********************************************************************/ |
|||
/* Do open the source table. */ |
|||
/*********************************************************************/ |
|||
return Tdbp->OpenDB(g); |
|||
} // end of OpenDB
|
|||
|
|||
/***********************************************************************/ |
|||
/* Data Base read routine for OCCUR access method. */ |
|||
/***********************************************************************/ |
|||
int TDBOCCUR::ReadDB(PGLOBAL g) |
|||
{ |
|||
int rc = RC_OK; |
|||
|
|||
/*********************************************************************/ |
|||
/* Now start the multi reading process. */ |
|||
/*********************************************************************/ |
|||
do { |
|||
if (RowFlag != 1) |
|||
if ((rc = Tdbp->ReadDB(g)) != RC_OK) |
|||
break; |
|||
|
|||
if (Xcolp) { |
|||
RowFlag = 0; |
|||
Xcolp->ReadColumn(g); |
|||
M = Xcolp->GetI(); |
|||
} // endif Xcolp
|
|||
|
|||
} while (RowFlag == 2); |
|||
|
|||
N++; |
|||
return rc; |
|||
} // end of ReadDB
|
|||
|
|||
// ------------------------ OCCURCOL functions ----------------------------
|
|||
|
|||
/***********************************************************************/ |
|||
/* OCCURCOL public constructor. */ |
|||
/***********************************************************************/ |
|||
OCCURCOL::OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n) |
|||
: COLBLK(cdp, tdbp, n) |
|||
{ |
|||
// Set additional OCCUR access method information for column.
|
|||
I = 0; |
|||
} // end of OCCURCOL constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* ReadColumn: what this routine does is to access the columns of */ |
|||
/* list, extract their value and convert it to buffer type. */ |
|||
/***********************************************************************/ |
|||
void OCCURCOL::ReadColumn(PGLOBAL g) |
|||
{ |
|||
PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb; |
|||
PCOL *col = tdbp->Col; |
|||
|
|||
for (; I < tdbp->Mult; I++) { |
|||
col[I]->ReadColumn(g); |
|||
|
|||
if (Nullable || !col[I]->GetValue()->IsZero()) |
|||
break; |
|||
|
|||
} // endfor I
|
|||
|
|||
if (I == tdbp->Mult) { |
|||
// No more values, go to next source row
|
|||
tdbp->RowFlag = 2; |
|||
I = 0; |
|||
return; |
|||
} // endif I
|
|||
|
|||
// Set the OCCUR column value from the Ith source column value
|
|||
Value->SetValue_pval(col[I++]->GetValue()); |
|||
tdbp->RowFlag = 1; |
|||
} // end of ReadColumn
|
|||
|
|||
|
|||
// ------------------------ RANKCOL functions ---------------------------
|
|||
|
|||
/***********************************************************************/ |
|||
/* ReadColumn: what this routine does is to access the Mth columns of */ |
|||
/* list, extract its name and set to it the rank column value. */ |
|||
/***********************************************************************/ |
|||
void RANKCOL::ReadColumn(PGLOBAL g) |
|||
{ |
|||
PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb; |
|||
PCOL *col = tdbp->Col; |
|||
|
|||
// Set the RANK column value from the Mth source column name
|
|||
if (tdbp->M) |
|||
Value->SetValue_psz(col[tdbp->M - 1]->GetName()); |
|||
else { |
|||
Value->Reset(); |
|||
|
|||
if (Nullable) |
|||
Value->SetNull(true); |
|||
|
|||
} // endelse
|
|||
|
|||
} // end of ReadColumn
|
|||
@ -0,0 +1,145 @@ |
|||
// TABOCCUR.H Olivier Bertrand 2013 |
|||
// Defines the OCCUR tables |
|||
|
|||
#include "tabutil.h" |
|||
|
|||
#define TYPE_AM_OCCUR (AMT)128 |
|||
|
|||
typedef class OCCURDEF *POCCURDEF; |
|||
typedef class TDBOCCUR *PTDBOCCUR; |
|||
typedef class OCCURCOL *POCCURCOL; |
|||
typedef class RANKCOL *PRANKCOL; |
|||
typedef class SRTCOL *PSRTCOL; |
|||
|
|||
/* -------------------------- OCCUR classes -------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* OCCUR: OEM table that provides a view of a source table where the */ |
|||
/* contain of several columns of the source table is placed in only */ |
|||
/* one column, the OCCUR column, this resulting into several rows. */ |
|||
/***********************************************************************/ |
|||
|
|||
/***********************************************************************/ |
|||
/* OCCUR table. */ |
|||
/***********************************************************************/ |
|||
class OCCURDEF : public PRXDEF { /* Logical table description */ |
|||
friend class TDBOCCUR; |
|||
public: |
|||
// Constructor |
|||
OCCURDEF(void) {Pseudo = 3; Colist = Xcol = NULL;} |
|||
|
|||
// Implementation |
|||
virtual const char *GetType(void) {return "OCCUR";} |
|||
|
|||
// Methods |
|||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); |
|||
virtual PTDB GetTable(PGLOBAL g, MODE m); |
|||
|
|||
protected: |
|||
// Members |
|||
//char *Tabname; /* The source table name */ |
|||
char *Colist; /* The source column list */ |
|||
char *Xcol; /* The multiple occurence column */ |
|||
char *Rcol; /* The rank column */ |
|||
}; // end of OCCURDEF |
|||
|
|||
/***********************************************************************/ |
|||
/* This is the class declaration for the OCCUR table. */ |
|||
/***********************************************************************/ |
|||
class TDBOCCUR : public TDBPRX { |
|||
friend class OCCURCOL; |
|||
friend class RANKCOL; |
|||
friend class SRTCOL; |
|||
public: |
|||
// Constructor |
|||
TDBOCCUR(POCCURDEF tdp); |
|||
|
|||
// Implementation |
|||
virtual AMT GetAmType(void) {return TYPE_AM_OCCUR;} |
|||
void SetTdbp(PTDBASE tdbp) {Tdbp = tdbp;} |
|||
|
|||
// Methods |
|||
//virtual int GetRecpos(void) {return N;} |
|||
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();} |
|||
virtual int RowNumber(PGLOBAL g, bool b = FALSE); |
|||
PTDB GetSourceTable(PGLOBAL g); |
|||
int MakeColumnList(PGLOBAL g); |
|||
|
|||
// Database routines |
|||
//virtual PCOL ColDB(PGLOBAL g, PSZ colname, int num); |
|||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); |
|||
virtual int GetMaxSize(PGLOBAL g); |
|||
virtual bool OpenDB(PGLOBAL g); |
|||
virtual int ReadDB(PGLOBAL g); |
|||
|
|||
protected: |
|||
// Members |
|||
//PTDBASE Tdbp; // To the source table or view |
|||
LPCSTR Tabname; // Name of source table |
|||
char *Colist; // Source column list |
|||
char *Xcolumn; // Occurence column name |
|||
char *Rcolumn; // Rank column name |
|||
POCCURCOL Xcolp; // To the OCCURCOL column |
|||
PCOL *Col; // To source multiple columns |
|||
int Mult; // Multiplication factor |
|||
int N; // The current table index |
|||
int M; // The occurence rank |
|||
BYTE RowFlag; // 0: Ok, 1: Same, 2: Skip |
|||
}; // end of class TDBOCCUR |
|||
|
|||
/***********************************************************************/ |
|||
/* Class OCCURCOL: for the multiple occurence column. */ |
|||
/***********************************************************************/ |
|||
class OCCURCOL : public COLBLK { |
|||
public: |
|||
// Constructors |
|||
OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n); |
|||
//OCCURCOL(OCCURCOL *colp, PTDB tdbp); // Constructor used in copy process |
|||
|
|||
// Implementation |
|||
virtual int GetAmType(void) {return TYPE_AM_OCCUR;} |
|||
int GetI(void) {return I;} |
|||
|
|||
// Methods |
|||
virtual void Reset(void) {} // Evaluated only by TDBOCCUR |
|||
virtual void ReadColumn(PGLOBAL g); |
|||
void Xreset(void) {I = 0;}; |
|||
|
|||
protected: |
|||
// Default constructor not to be used |
|||
OCCURCOL(void) {} |
|||
|
|||
// Members |
|||
int I; |
|||
}; // end of class OCCURCOL |
|||
|
|||
/***********************************************************************/ |
|||
/* Class RANKCOL: for the multiple occurence column ranking. */ |
|||
/***********************************************************************/ |
|||
class RANKCOL : public COLBLK { |
|||
public: |
|||
// Constructors |
|||
RANKCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n) : COLBLK(cdp, tdbp, n) {} |
|||
//RANKCOL(RANKCOL *colp, PTDB tdbp); // Constructor used in copy process |
|||
|
|||
// Implementation |
|||
virtual int GetAmType(void) {return TYPE_AM_OCCUR;} |
|||
|
|||
// Methods |
|||
virtual void ReadColumn(PGLOBAL g); |
|||
|
|||
protected: |
|||
// Default constructor not to be used |
|||
RANKCOL(void) {} |
|||
|
|||
// Members |
|||
}; // end of class RANKCOL |
|||
|
|||
/***********************************************************************/ |
|||
/* Definition of class XCOLDEF. */ |
|||
/* This class purpose is just to access COLDEF protected items! */ |
|||
/***********************************************************************/ |
|||
class XCOLDEF: public COLDEF { |
|||
friend class TDBOCCUR; |
|||
}; // end of class XCOLDEF |
|||
|
|||
@ -0,0 +1,596 @@ |
|||
/************* Tabutil cpp Declares Source Code File (.H) **************/ |
|||
/* Name: TABUTIL.CPP Version 1.0 */ |
|||
/* */ |
|||
/* (C) Copyright to the author Olivier BERTRAND 2013 */ |
|||
/* */ |
|||
/* Utility function used by TBL and PRX tables. */ |
|||
/***********************************************************************/ |
|||
|
|||
/***********************************************************************/ |
|||
/* Include relevant section of system dependant header files. */ |
|||
/***********************************************************************/ |
|||
#include "my_global.h"
|
|||
#include "sql_class.h"
|
|||
#include "table.h"
|
|||
#include "field.h"
|
|||
#if defined(WIN32)
|
|||
#include <stdlib.h>
|
|||
#include <stdio.h>
|
|||
#if defined(__BORLANDC__)
|
|||
#define __MFC_COMPAT__ // To define min/max as macro
|
|||
#endif
|
|||
//#include <windows.h>
|
|||
#else
|
|||
#if defined(UNIX)
|
|||
#include <fnmatch.h>
|
|||
#include <errno.h>
|
|||
#include <stdlib.h>
|
|||
#include <stdio.h>
|
|||
#include <string.h>
|
|||
#include "osutil.h"
|
|||
#else
|
|||
//#include <io.h>
|
|||
#endif
|
|||
//#include <fcntl.h>
|
|||
#endif
|
|||
|
|||
/***********************************************************************/ |
|||
/* Include application header files: */ |
|||
/***********************************************************************/ |
|||
#include "table.h" // MySQL table definitions
|
|||
#include "global.h"
|
|||
#include "plgdbsem.h"
|
|||
#include "plgcnx.h" // For DB types
|
|||
#include "myutil.h"
|
|||
#include "mycat.h"
|
|||
#include "valblk.h"
|
|||
#include "resource.h"
|
|||
#include "reldef.h"
|
|||
#include "xtable.h"
|
|||
#if defined(MYSQL_SUPPORT)
|
|||
#include "tabmysql.h"
|
|||
#endif // MYSQL_SUPPORT
|
|||
#include "tabcol.h"
|
|||
#include "tabutil.h"
|
|||
#include "ha_connect.h"
|
|||
|
|||
extern "C" int trace; |
|||
|
|||
/************************************************************************/ |
|||
/* GetTableShare: allocates and open a table share. */ |
|||
/************************************************************************/ |
|||
TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db, |
|||
const char *name, bool& mysql) |
|||
{ |
|||
char key[256]; |
|||
uint k; |
|||
//TABLE_LIST table_list;
|
|||
TABLE_SHARE *s; |
|||
|
|||
//table_list.init_one_table(db, strlen(db), name, strlen(name),
|
|||
// NULL, TL_IGNORE);
|
|||
k = sprintf(key, "%s", db); |
|||
k += sprintf(key + ++k, "%s", name); |
|||
key[++k] = 0; |
|||
|
|||
if (!(s = alloc_table_share(db, name, key, ++k))) { |
|||
strcpy(g->Message, "Error allocating share\n"); |
|||
return NULL; |
|||
} // endif s
|
|||
|
|||
// 1 2 4 8
|
|||
//flags = GTS_TABLE | GTS_VIEW | GTS_NOLOCK | GTS_FORCE_DISCOVERY;
|
|||
|
|||
if (!open_table_def(thd, s, GTS_TABLE)) { |
|||
#ifdef DBUG_OFF
|
|||
if (stricmp(s->db_plugin->name.str, "connect")) { |
|||
#else
|
|||
if (stricmp((*s->db_plugin)->name.str, "connect")) { |
|||
#endif
|
|||
#if defined(MYSQL_SUPPORT)
|
|||
mysql = true; |
|||
#else // !MYSQL_SUPPORT
|
|||
sprintf(g->Message, "%s.%s is not a CONNECT table", db, name); |
|||
return NULL; |
|||
#endif // MYSQL_SUPPORT
|
|||
} else |
|||
mysql = false; |
|||
|
|||
} else { |
|||
sprintf(g->Message, "Error %d opening share\n", s->error); |
|||
free_table_share(s); |
|||
return NULL; |
|||
} // endif open_table_def
|
|||
|
|||
return s; |
|||
} // end of GetTableShare
|
|||
|
|||
/************************************************************************/ |
|||
/* TabColumns: constructs the result blocks containing all the columns */ |
|||
/* of the object table that will be retrieved by GetData commands. */ |
|||
/* key = TRUE when called from Create Table to get key informations. */ |
|||
/************************************************************************/ |
|||
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, |
|||
const char *name, bool info) |
|||
{ |
|||
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT, |
|||
DB_INT, DB_SHORT, DB_SHORT, DB_SHORT, |
|||
DB_CHAR, DB_CHAR, DB_CHAR}; |
|||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, |
|||
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, |
|||
TYPE_STRING, TYPE_STRING, TYPE_STRING}; |
|||
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, |
|||
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL, |
|||
FLD_REM, FLD_NO, FLD_CHARSET}; |
|||
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32}; |
|||
char *fld, *fmt; |
|||
int i, n, ncol = sizeof(dbtype) / sizeof(int); |
|||
int len, type, prec; |
|||
bool mysql; |
|||
TABLE_SHARE *s; |
|||
Field* *field; |
|||
Field *fp; |
|||
PQRYRES qrp; |
|||
PCOLRES crp; |
|||
|
|||
if (!info) { |
|||
if (!(s = GetTableShare(g, thd, db, name, mysql))) |
|||
return NULL; |
|||
else |
|||
n = s->fieldnames.count; |
|||
|
|||
} else { |
|||
n = 0; |
|||
length[0] = 128; |
|||
} // endif info
|
|||
|
|||
/**********************************************************************/ |
|||
/* Allocate the structures used to refer to the result set. */ |
|||
/**********************************************************************/ |
|||
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, |
|||
dbtype, buftyp, fldtyp, length, true, true); |
|||
|
|||
// Some columns must be renamed
|
|||
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) |
|||
switch (++i) { |
|||
case 10: crp->Name = "Date_fmt"; break; |
|||
case 11: crp->Name = "Collation"; break; |
|||
} // endswitch i
|
|||
|
|||
if (info) |
|||
return qrp; |
|||
|
|||
/**********************************************************************/ |
|||
/* Now get the results into blocks. */ |
|||
/**********************************************************************/ |
|||
for (i = 0, field= s->field; *field; i++, field++) { |
|||
fp= *field; |
|||
|
|||
// Get column name
|
|||
crp = qrp->Colresp; // Column_Name
|
|||
fld = (char *)fp->field_name; |
|||
crp->Kdata->SetValue(fld, i); |
|||
|
|||
if ((type = MYSQLtoPLG(fp->type())) == TYPE_ERROR) { |
|||
sprintf(g->Message, "Unsupported column type %s", GetTypeName(type)); |
|||
qrp = NULL; |
|||
break; |
|||
} // endif type
|
|||
|
|||
crp = crp->Next; // Data_Type
|
|||
crp->Kdata->SetValue(type, i); |
|||
crp = crp->Next; // Type_Name
|
|||
crp->Kdata->SetValue(GetTypeName(type), i); |
|||
|
|||
if (type == TYPE_DATE) { |
|||
// When creating tables we do need info about date columns
|
|||
if (mysql) { |
|||
fmt = MyDateFmt(fp->type()); |
|||
len = strlen(fmt); |
|||
} else { |
|||
fmt = (char*)fp->option_struct->dateformat; |
|||
len = fp->field_length; |
|||
} // endif mysql
|
|||
|
|||
} else { |
|||
fmt = NULL; |
|||
len = fp->char_length(); |
|||
} // endif type
|
|||
|
|||
crp = crp->Next; // Precision
|
|||
crp->Kdata->SetValue(len, i); |
|||
|
|||
crp = crp->Next; // Length
|
|||
len = fp->field_length; |
|||
crp->Kdata->SetValue(len, i); |
|||
|
|||
prec = (type == TYPE_FLOAT) ? fp->decimals() : 0; |
|||
crp = crp->Next; // Scale
|
|||
crp->Kdata->SetValue(prec, i); |
|||
|
|||
crp = crp->Next; // Radix
|
|||
crp->Kdata->SetValue(0, i); |
|||
|
|||
crp = crp->Next; // Nullable
|
|||
crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i); |
|||
|
|||
crp = crp->Next; // Remark
|
|||
fld = fp->comment.str; |
|||
crp->Kdata->SetValue(fld, fp->comment.length, i); |
|||
|
|||
crp = crp->Next; // New
|
|||
crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i); |
|||
|
|||
crp = crp->Next; // New (charset)
|
|||
fld = (char *)fp->charset()->name; |
|||
crp->Kdata->SetValue(fld, i); |
|||
|
|||
// Add this item
|
|||
qrp->Nblin++; |
|||
} // endfor field
|
|||
|
|||
/**********************************************************************/ |
|||
/* Return the result pointer for use by GetData routines. */ |
|||
/**********************************************************************/ |
|||
free_table_share(s); |
|||
return qrp; |
|||
} // end of TabColumns
|
|||
|
|||
/* -------------- Implementation of the XCOL classes ---------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* PRXDEF constructor. */ |
|||
/***********************************************************************/ |
|||
PRXDEF::PRXDEF(void) |
|||
{ |
|||
Tablep = NULL; |
|||
Pseudo = 3; |
|||
} // end of PRXDEF constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* DefineAM: define specific AM block values from XCOL file. */ |
|||
/***********************************************************************/ |
|||
bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) |
|||
{ |
|||
char *pn, *db, *tab; |
|||
|
|||
db = Cat->GetStringCatInfo(g, "Dbname", "*"); |
|||
tab = Cat->GetStringCatInfo(g, "Tabname", NULL); |
|||
|
|||
// Analyze the table name, it may have the format: [dbname.]tabname
|
|||
if ((pn = strchr(tab, '.'))) { |
|||
*pn++ = 0; |
|||
db = tab; |
|||
tab = pn; |
|||
} // endif pn
|
|||
|
|||
Tablep = new(g) XTAB(tab); |
|||
Tablep->SetQualifier(db); |
|||
return FALSE; |
|||
} // end of DefineAM
|
|||
|
|||
/***********************************************************************/ |
|||
/* GetTable: makes a new TDB of the proper type. */ |
|||
/***********************************************************************/ |
|||
PTDB PRXDEF::GetTable(PGLOBAL g, MODE mode) |
|||
{ |
|||
if (Catfunc == FNC_COL) |
|||
return new(g) TDBTBC(this); |
|||
else |
|||
return new(g) TDBPRX(this); |
|||
|
|||
} // end of GetTable
|
|||
|
|||
/* ------------------------------------------------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* Implementation of the TDBPRX class. */ |
|||
/***********************************************************************/ |
|||
TDBPRX::TDBPRX(PPRXDEF tdp) : TDBASE(tdp) |
|||
{ |
|||
Tdbp = NULL; // The object table
|
|||
} // end of TDBPRX constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* Get the PTDB of the sub-table. */ |
|||
/***********************************************************************/ |
|||
PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp) |
|||
{ |
|||
char *db, *name; |
|||
bool mysql; |
|||
PTDB tdbp = NULL; |
|||
TABLE_SHARE *s; |
|||
PCATLG cat = To_Def->GetCat(); |
|||
PHC hc = ((MYCAT*)cat)->GetHandler(); |
|||
THD *thd = (hc->GetTable())->in_use; |
|||
|
|||
db = (char*)tabp->GetQualifier(); |
|||
name = (char*)tabp->GetName(); |
|||
|
|||
if (!(s = GetTableShare(g, thd, db, name, mysql))) |
|||
return NULL; |
|||
|
|||
hc->tshp = s; |
|||
|
|||
if (mysql) { |
|||
#if defined(MYSQL_SUPPORT)
|
|||
// Access sub-table via MySQL API
|
|||
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYSQL"))) { |
|||
sprintf(g->Message, "Cannot access %s.%s", db, name); |
|||
goto err; |
|||
} // endif Define
|
|||
|
|||
if (db) |
|||
((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier()); |
|||
|
|||
#else // !MYSQL_SUPPORT
|
|||
sprintf(g->Message, "%s.%s is not a CONNECT table", |
|||
db, tblp->Name); |
|||
goto err; |
|||
#endif // MYSQL_SUPPORT
|
|||
} else |
|||
// Sub-table is a CONNECT table
|
|||
tdbp = cat->GetTable(g, tabp); |
|||
|
|||
hc->tshp = NULL; |
|||
|
|||
if (trace && tdbp) |
|||
htrc("Subtable %s in %s\n", |
|||
name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB())); |
|||
|
|||
err: |
|||
free_table_share(s); |
|||
return tdbp; |
|||
} // end of GetSubTable
|
|||
|
|||
/***********************************************************************/ |
|||
/* Initializes the table. */ |
|||
/***********************************************************************/ |
|||
bool TDBPRX::InitTable(PGLOBAL g) |
|||
{ |
|||
if (!Tdbp) { |
|||
// Get the table description block of this table
|
|||
if (!(Tdbp = (PTDBASE)GetSubTable(g, ((PPRXDEF)To_Def)->Tablep))) |
|||
return TRUE; |
|||
|
|||
} // endif Tdbp
|
|||
|
|||
return FALSE; |
|||
} // end of InitTable
|
|||
|
|||
/***********************************************************************/ |
|||
/* Allocate PRX column description block. */ |
|||
/***********************************************************************/ |
|||
PCOL TDBPRX::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) |
|||
{ |
|||
return new(g) PRXCOL(cdp, this, cprec, n); |
|||
} // end of MakeCol
|
|||
|
|||
/***********************************************************************/ |
|||
/* PRX GetMaxSize: returns the maximum number of rows in the table. */ |
|||
/***********************************************************************/ |
|||
int TDBPRX::GetMaxSize(PGLOBAL g) |
|||
{ |
|||
if (MaxSize < 0) { |
|||
if (InitTable(g)) |
|||
return NULL; |
|||
|
|||
MaxSize = Tdbp->GetMaxSize(g); |
|||
} // endif MaxSize
|
|||
|
|||
return MaxSize; |
|||
} // end of GetMaxSize
|
|||
|
|||
/***********************************************************************/ |
|||
/* In this sample, ROWID will be the (virtual) row number, */ |
|||
/* while ROWNUM will be the occurence rank in the multiple column. */ |
|||
/***********************************************************************/ |
|||
int TDBPRX::RowNumber(PGLOBAL g, bool b) |
|||
{ |
|||
return Tdbp->RowNumber(g, b); |
|||
} // end of RowNumber
|
|||
|
|||
/***********************************************************************/ |
|||
/* XCV Access Method opening routine. */ |
|||
/***********************************************************************/ |
|||
bool TDBPRX::OpenDB(PGLOBAL g) |
|||
{ |
|||
if (Use == USE_OPEN) { |
|||
/*******************************************************************/ |
|||
/* Table already open, just replace it at its beginning. */ |
|||
/*******************************************************************/ |
|||
return Tdbp->OpenDB(g); |
|||
} // endif use
|
|||
|
|||
if (Mode != MODE_READ) { |
|||
/*******************************************************************/ |
|||
/* Currently XCOL tables cannot be modified. */ |
|||
/*******************************************************************/ |
|||
strcpy(g->Message, "PROXY tables are read only"); |
|||
return TRUE; |
|||
} // endif Mode
|
|||
|
|||
if (InitTable(g)) |
|||
return NULL; |
|||
|
|||
/*********************************************************************/ |
|||
/* Check and initialize the subtable columns. */ |
|||
/*********************************************************************/ |
|||
for (PCOL cp = Columns; cp; cp = cp->GetNext()) |
|||
if (((PPRXCOL)cp)->Init(g)) |
|||
return TRUE; |
|||
|
|||
/*********************************************************************/ |
|||
/* Physically open the object table. */ |
|||
/*********************************************************************/ |
|||
if (Tdbp->OpenDB(g)) |
|||
return TRUE; |
|||
|
|||
return FALSE; |
|||
} // end of OpenDB
|
|||
|
|||
/***********************************************************************/ |
|||
/* Data Base read routine for XCV access method. */ |
|||
/***********************************************************************/ |
|||
int TDBPRX::ReadDB(PGLOBAL g) |
|||
{ |
|||
/*********************************************************************/ |
|||
/* Now start the reading process. */ |
|||
/*********************************************************************/ |
|||
return Tdbp->ReadDB(g); |
|||
} // end of ReadDB
|
|||
|
|||
/***********************************************************************/ |
|||
/* WriteDB: Data Base write routine for XCV access methods. */ |
|||
/***********************************************************************/ |
|||
int TDBPRX::WriteDB(PGLOBAL g) |
|||
{ |
|||
sprintf(g->Message, "%s tables are read only", To_Def->GetType()); |
|||
return RC_FX; |
|||
} // end of WriteDB
|
|||
|
|||
/***********************************************************************/ |
|||
/* Data Base delete line routine for XCV access methods. */ |
|||
/***********************************************************************/ |
|||
int TDBPRX::DeleteDB(PGLOBAL g, int irc) |
|||
{ |
|||
sprintf(g->Message, "Delete not enabled for %s tables", |
|||
To_Def->GetType()); |
|||
return RC_FX; |
|||
} // end of DeleteDB
|
|||
|
|||
/* ---------------------------- PRXCOL ------------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* PRXCOL public constructor. */ |
|||
/***********************************************************************/ |
|||
PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) |
|||
: COLBLK(cdp, tdbp, i) |
|||
{ |
|||
if (cprec) { |
|||
Next = cprec->GetNext(); |
|||
cprec->SetNext(this); |
|||
} else { |
|||
Next = tdbp->GetColumns(); |
|||
tdbp->SetColumns(this); |
|||
} // endif cprec
|
|||
|
|||
// Set additional Dos access method information for column.
|
|||
Long = cdp->GetLong(); // Useful ???
|
|||
//strcpy(F_Date, cdp->F_Date);
|
|||
Colp = NULL; |
|||
To_Val = NULL; |
|||
Pseudo = FALSE; |
|||
Colnum = cdp->GetOffset(); // If columns are retrieved by number
|
|||
|
|||
if (trace) |
|||
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); |
|||
|
|||
} // end of PRXCOL constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* PRXCOL initialization routine. */ |
|||
/* Look for the matching column in the object table. */ |
|||
/***********************************************************************/ |
|||
bool PRXCOL::Init(PGLOBAL g) |
|||
{ |
|||
PTDBPRX tdbp = (PTDBPRX)To_Tdb; |
|||
|
|||
if (!(Colp = tdbp->Tdbp->ColDB(g, Name, 0)) && Colnum) |
|||
Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum); |
|||
|
|||
if (Colp) { |
|||
Colp->InitValue(g); // May not have been done elsewhere
|
|||
To_Val = Colp->GetValue(); |
|||
} else { |
|||
sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName()); |
|||
return TRUE; |
|||
} // endif Colp
|
|||
|
|||
return FALSE; |
|||
} // end of Init
|
|||
|
|||
/***********************************************************************/ |
|||
/* ReadColumn: */ |
|||
/***********************************************************************/ |
|||
void PRXCOL::ReadColumn(PGLOBAL g) |
|||
{ |
|||
if (trace) |
|||
htrc("PRX ReadColumn: name=%s\n", Name); |
|||
|
|||
if (Colp) { |
|||
Colp->ReadColumn(g); |
|||
Value->SetValue_pval(To_Val); |
|||
|
|||
// Set null when applicable
|
|||
if (Nullable) |
|||
Value->SetNull(Value->IsNull()); |
|||
|
|||
} // endif Colp
|
|||
|
|||
} // end of ReadColumn
|
|||
|
|||
#if 0
|
|||
/* ---------------------------TBCDEF class --------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* DefineAM: define specific AM block values from CATLG table. */ |
|||
/***********************************************************************/ |
|||
bool TBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) |
|||
{ |
|||
Desc = "Catalog Table"; |
|||
Database = Cat->GetStringCatInfo(g, "Database", "*"); |
|||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname); |
|||
return FALSE; |
|||
} // end of DefineAM
|
|||
|
|||
/***********************************************************************/ |
|||
/* GetTable: makes a new TDB of the proper type. */ |
|||
/***********************************************************************/ |
|||
PTDB TBCDEF::GetTable(PGLOBAL g, MODE m) |
|||
{ |
|||
return new(g) TDBTBC(this); |
|||
} // end of GetTable
|
|||
#endif // 0
|
|||
|
|||
/* ---------------------------TDBTBC class --------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* TDBTBC class constructor. */ |
|||
/***********************************************************************/ |
|||
TDBTBC::TDBTBC(PPRXDEF tdp) : TDBCAT(tdp) |
|||
{ |
|||
// Db = tdp->Database;
|
|||
// Tab = tdp->Tabname;
|
|||
Db = (PSZ)tdp->Tablep->GetQualifier(); |
|||
Tab = (PSZ)tdp->Tablep->GetName(); |
|||
} // end of TDBTBC constructor
|
|||
|
|||
#if 0
|
|||
/***********************************************************************/ |
|||
/* TDBTBC class constructor from TBL table. */ |
|||
/***********************************************************************/ |
|||
TDBTBC::TDBTBC(PTBLDEF tdp) : TDBCAT(tdp) |
|||
{ |
|||
Db = tdp->To_Tables->DB; |
|||
Tab = tdp->To_Tables->Name; |
|||
} // end of TDBTBC constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* TDBTBC class constructor from PRX table. */ |
|||
/***********************************************************************/ |
|||
TDBTBC::TDBTBC(PXCLDEF tdp) : TDBCAT(tdp) |
|||
{ |
|||
Db = (PSZ)tdp->Tablep->GetQualifier(); |
|||
Tab = (PSZ)tdp->Tablep->GetName(); |
|||
} // end of TDBTBC constructor
|
|||
#endif // 0
|
|||
|
|||
/***********************************************************************/ |
|||
/* GetResult: Get the list the MYSQL table columns. */ |
|||
/***********************************************************************/ |
|||
PQRYRES TDBTBC::GetResult(PGLOBAL g) |
|||
{ |
|||
return TabColumns(g, current_thd, Db, Tab, false); |
|||
} // end of GetResult
|
|||
|
|||
@ -0,0 +1,181 @@ |
|||
// TABUTIL.H Olivier Bertrand 2013 |
|||
// Defines the TAB catalog tables |
|||
|
|||
#ifndef TABUTIL |
|||
#define TABUTIL 1 |
|||
|
|||
//#include "tabtbl.h" |
|||
|
|||
#define TYPE_AM_PRX (AMT)129 |
|||
|
|||
typedef class PRXDEF *PPRXDEF; |
|||
typedef class TDBPRX *PTDBPRX; |
|||
typedef class XXLCOL *PXXLCOL; |
|||
typedef class PRXCOL *PPRXCOL; |
|||
typedef class TBCDEF *PTBCDEF; |
|||
typedef class TDBTBC *PTDBTBC; |
|||
typedef class XTDBASE *PTDBX; |
|||
typedef class XCOLBLK *PCOLX; |
|||
|
|||
TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db, |
|||
const char *name, bool& mysql); |
|||
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, |
|||
const char *name, bool info); |
|||
|
|||
/***********************************************************************/ |
|||
/* This class is used to access protected members of TDBASE. */ |
|||
/***********************************************************************/ |
|||
class XTDBASE : public TDBASE { |
|||
friend class TDBXCL; |
|||
}; // end of class XCOLBLK |
|||
|
|||
/***********************************************************************/ |
|||
/* This class is used to access protected members of COLBLK. */ |
|||
/***********************************************************************/ |
|||
class XCOLBLK : public COLBLK { |
|||
friend class TDBXCL; |
|||
}; // end of class XCOLBLK |
|||
|
|||
/* -------------------------- PROXY classes -------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* PROXY: table based on another table. Can be used to have a */ |
|||
/* different view on an existing table. */ |
|||
/* However, its real use is to be the base of TBL and PRX tables. */ |
|||
/***********************************************************************/ |
|||
|
|||
/***********************************************************************/ |
|||
/* PRX table. */ |
|||
/***********************************************************************/ |
|||
class DllExport PRXDEF : public TABDEF { /* Logical table description */ |
|||
friend class TDBPRX; |
|||
friend class TDBTBC; |
|||
public: |
|||
// Constructor |
|||
PRXDEF(void); |
|||
|
|||
// Implementation |
|||
virtual const char *GetType(void) {return "PRX";} |
|||
|
|||
// Methods |
|||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); |
|||
virtual PTDB GetTable(PGLOBAL g, MODE mode); |
|||
|
|||
protected: |
|||
// Members |
|||
PTABLE Tablep; /* The object table */ |
|||
}; // end of PRXDEF |
|||
|
|||
/***********************************************************************/ |
|||
/* This is the class declaration for the XCSV table. */ |
|||
/***********************************************************************/ |
|||
class DllExport TDBPRX : public TDBASE { |
|||
//friend class MULINDX; |
|||
friend class PRXDEF; |
|||
friend class PRXCOL; |
|||
public: |
|||
// Constructor |
|||
TDBPRX(PPRXDEF tdp); |
|||
|
|||
// Implementation |
|||
virtual AMT GetAmType(void) {return TYPE_AM_PRX;} |
|||
|
|||
// Methods |
|||
virtual int GetRecpos(void) {return Tdbp->GetRecpos();} |
|||
virtual void ResetDB(void) {Tdbp->ResetDB();} |
|||
virtual int RowNumber(PGLOBAL g, bool b = FALSE); |
|||
|
|||
// Database routines |
|||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); |
|||
virtual bool InitTable(PGLOBAL g); |
|||
virtual int GetMaxSize(PGLOBAL g); |
|||
virtual bool OpenDB(PGLOBAL g); |
|||
virtual int ReadDB(PGLOBAL g); |
|||
virtual int WriteDB(PGLOBAL g); |
|||
virtual int DeleteDB(PGLOBAL g, int irc); |
|||
virtual void CloseDB(PGLOBAL g) {if (Tdbp) Tdbp->CloseDB(g);} |
|||
PTDB GetSubTable(PGLOBAL g, PTABLE tabp); |
|||
|
|||
protected: |
|||
// Members |
|||
PTDBASE Tdbp; // The object table |
|||
}; // end of class TDBPRX |
|||
|
|||
/***********************************************************************/ |
|||
/* Class PRXCOL: PRX access method column descriptor. */ |
|||
/* This A.M. is used for PRX tables. */ |
|||
/***********************************************************************/ |
|||
class DllExport PRXCOL : public COLBLK { |
|||
friend class TDBPRX; |
|||
friend class TDBTBL; |
|||
public: |
|||
// Constructors |
|||
PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX"); |
|||
|
|||
// Implementation |
|||
virtual int GetAmType(void) {return TYPE_AM_PRX;} |
|||
|
|||
// Methods |
|||
virtual bool IsSpecial(void) {return Pseudo;} |
|||
virtual void ReadColumn(PGLOBAL g); |
|||
bool Init(PGLOBAL g); |
|||
|
|||
protected: |
|||
// Default constructor not to be used |
|||
PRXCOL(void) {} |
|||
|
|||
// Members |
|||
PCOL Colp; // Points to matching table column |
|||
PVAL To_Val; // To the matching column value |
|||
bool Pseudo; // TRUE for special columns |
|||
int Colnum; // Used when retrieving columns by number |
|||
}; // end of class PRXCOL |
|||
|
|||
#if 0 |
|||
/***********************************************************************/ |
|||
/* TBC table. */ |
|||
/***********************************************************************/ |
|||
class TBCDEF : public TABDEF {/* Logical table description */ |
|||
friend class TDBTBC; |
|||
friend class ha_connect; |
|||
public: |
|||
// Constructor |
|||
TBCDEF(void) {Database = NULL; Tabname = NULL;} |
|||
|
|||
|
|||
// Implementation |
|||
virtual const char *GetType(void) {return "TBC";} |
|||
inline PSZ GetDatabase(void) {return Database;}; |
|||
inline PSZ GetTabname(void) {return Tabname;} |
|||
|
|||
// Methods |
|||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); |
|||
virtual PTDB GetTable(PGLOBAL g, MODE m); |
|||
|
|||
protected: |
|||
// Members |
|||
PSZ Database; /* Database to be used by server */ |
|||
PSZ Tabname; /* External table name */ |
|||
}; // end of TBCDEF |
|||
#endif // 0 |
|||
|
|||
/***********************************************************************/ |
|||
/* This is the class declaration for the TBC column catalog table. */ |
|||
/***********************************************************************/ |
|||
class TDBTBC : public TDBCAT { |
|||
public: |
|||
// Constructors |
|||
TDBTBC(PPRXDEF tdp); |
|||
//TDBTBC(PTBLDEF tdp); |
|||
//TDBTBC(PXCLDEF tdp); |
|||
|
|||
protected: |
|||
// Specific routines |
|||
virtual PQRYRES GetResult(PGLOBAL g); |
|||
|
|||
// Members |
|||
PSZ Db; // Database of the table |
|||
PSZ Tab; // Table name |
|||
}; // end of class TDBMCL |
|||
|
|||
#endif // TABUTIL |
|||
@ -0,0 +1,376 @@ |
|||
/************* TabXcl CPP Declares Source Code File (.CPP) *************/ |
|||
/* Name: TABXCL.CPP Version 1.0 */ |
|||
/* */ |
|||
/* (C) Copyright to the author Olivier BERTRAND 2013 */ |
|||
/* */ |
|||
/* XCOL: Table having one column containing several values */ |
|||
/* comma separated. When creating the table, the name of the X */ |
|||
/* column is given by the Name option. */ |
|||
/* This first version has one limitation: */ |
|||
/* - The X column has the same length than in the physical file. */ |
|||
/* This tables produces as many rows for a physical row than the */ |
|||
/* number of items in the X column (eventually 0). */ |
|||
/***********************************************************************/ |
|||
|
|||
/***********************************************************************/ |
|||
/* Include relevant section of system dependant header files. */ |
|||
/***********************************************************************/ |
|||
#include "my_global.h"
|
|||
#if defined(WIN32)
|
|||
#include <stdlib.h>
|
|||
#include <stdio.h>
|
|||
#if defined(__BORLANDC__)
|
|||
#define __MFC_COMPAT__ // To define min/max as macro
|
|||
#endif
|
|||
//#include <windows.h>
|
|||
#else
|
|||
#if defined(UNIX)
|
|||
#include <fnmatch.h>
|
|||
#include <errno.h>
|
|||
#include <stdlib.h>
|
|||
#include <stdio.h>
|
|||
#include <string.h>
|
|||
#include "osutil.h"
|
|||
#else
|
|||
//#include <io.h>
|
|||
#endif
|
|||
//#include <fcntl.h>
|
|||
#endif
|
|||
|
|||
/***********************************************************************/ |
|||
/* Include application header files: */ |
|||
/***********************************************************************/ |
|||
#include "table.h" // MySQL table definitions
|
|||
#include "global.h"
|
|||
#include "plgdbsem.h"
|
|||
#include "plgcnx.h" // For DB types
|
|||
#include "resource.h"
|
|||
#include "reldef.h"
|
|||
#include "filamtxt.h"
|
|||
#include "tabdos.h"
|
|||
#include "tabcol.h"
|
|||
#include "tabxcl.h"
|
|||
#include "xtable.h"
|
|||
#if defined(MYSQL_SUPPORT)
|
|||
#include "tabmysql.h"
|
|||
#endif // MYSQL_SUPPORT
|
|||
#include "ha_connect.h"
|
|||
#include "mycat.h"
|
|||
|
|||
extern "C" int trace; |
|||
|
|||
/* -------------- Implementation of the XCOL classes ---------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* XCLDEF constructor. */ |
|||
/***********************************************************************/ |
|||
XCLDEF::XCLDEF(void) |
|||
{ |
|||
Pseudo = 3; |
|||
Xcol = NULL; |
|||
Sep = ','; |
|||
Mult = 10; |
|||
} // end of XCLDEF constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* DefineAM: define specific AM block values from XCOL file. */ |
|||
/***********************************************************************/ |
|||
bool XCLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) |
|||
{ |
|||
char buf[8]; |
|||
|
|||
Xcol = Cat->GetStringCatInfo(g, "Colname", ""); |
|||
Cat->GetCharCatInfo("Separator", ",", buf, sizeof(buf)); |
|||
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf; |
|||
Mult = Cat->GetIntCatInfo("Mult", 10); |
|||
return PRXDEF::DefineAM(g, am, poff); |
|||
} // end of DefineAM
|
|||
|
|||
/***********************************************************************/ |
|||
/* GetTable: makes a new TDB of the proper type. */ |
|||
/***********************************************************************/ |
|||
PTDB XCLDEF::GetTable(PGLOBAL g, MODE mode) |
|||
{ |
|||
if (Catfunc == FNC_COL) |
|||
return new(g) TDBTBC(this); |
|||
else |
|||
return new(g) TDBXCL(this); |
|||
|
|||
} // end of GetTable
|
|||
|
|||
/* ------------------------------------------------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* Implementation of the TDBXCL class. */ |
|||
/***********************************************************************/ |
|||
TDBXCL::TDBXCL(PXCLDEF tdp) : TDBPRX(tdp) |
|||
{ |
|||
//Tdbp = NULL; // The physical table
|
|||
Xcolumn = tdp->Xcol; // CSV column name
|
|||
Xcolp = NULL; // To the XCVCOL column
|
|||
Mult = tdp->Mult; // Multiplication factor
|
|||
N = 0; // The current table index
|
|||
M = 0; // The occurence rank
|
|||
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
|
|||
New = TRUE; // TRUE for new line
|
|||
Sep = tdp->Sep; // The Xcol separator
|
|||
} // end of TDBXCL constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* Initializes the table. */ |
|||
/***********************************************************************/ |
|||
bool TDBXCL::InitTable(PGLOBAL g) |
|||
{ |
|||
if (!Tdbp) { |
|||
PCOLDEF cdp; |
|||
|
|||
// Get the table description block of this table
|
|||
if (!(Tdbp = (PTDBASE)GetSubTable(g, ((PXCLDEF)To_Def)->Tablep))) |
|||
return TRUE; |
|||
|
|||
for (cdp = Tdbp->GetDef()->GetCols(); cdp; cdp = cdp->GetNext()) |
|||
if (!stricmp(cdp->GetName(), Xcolumn)) |
|||
break; |
|||
|
|||
if (!cdp) { |
|||
sprintf(g->Message, "%s is not a %s column", |
|||
Xcolumn, Tdbp->GetName()); |
|||
return TRUE; |
|||
} // endif cdp
|
|||
|
|||
} // endif Tdbp
|
|||
|
|||
return FALSE; |
|||
} // end of InitTable
|
|||
|
|||
/***********************************************************************/ |
|||
/* Allocate XCL column description block. */ |
|||
/***********************************************************************/ |
|||
PCOL TDBXCL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) |
|||
{ |
|||
PCOL colp; |
|||
|
|||
if (!stricmp(cdp->GetName(), Xcolumn)) { |
|||
Xcolp = new(g) XCLCOL(g, cdp, this, cprec, n); |
|||
colp = Xcolp; |
|||
} else |
|||
colp = new(g) PRXCOL(cdp, this, cprec, n); |
|||
|
|||
return colp; |
|||
} // end of MakeCol
|
|||
|
|||
/***********************************************************************/ |
|||
/* XCL GetMaxSize: returns the maximum number of rows in the table. */ |
|||
/***********************************************************************/ |
|||
int TDBXCL::GetMaxSize(PGLOBAL g) |
|||
{ |
|||
if (MaxSize < 0) { |
|||
if (InitTable(g)) |
|||
return NULL; |
|||
|
|||
MaxSize = Mult * Tdbp->GetMaxSize(g); |
|||
} // endif MaxSize
|
|||
|
|||
return MaxSize; |
|||
} // end of GetMaxSize
|
|||
|
|||
/***********************************************************************/ |
|||
/* In this sample, ROWID will be the (virtual) row number, */ |
|||
/* while ROWNUM will be the occurence rank in the multiple column. */ |
|||
/***********************************************************************/ |
|||
int TDBXCL::RowNumber(PGLOBAL g, bool b) |
|||
{ |
|||
return (b) ? M : N; |
|||
} // end of RowNumber
|
|||
|
|||
/***********************************************************************/ |
|||
/* XCV Access Method opening routine. */ |
|||
/***********************************************************************/ |
|||
bool TDBXCL::OpenDB(PGLOBAL g) |
|||
{ |
|||
if (Use == USE_OPEN) { |
|||
/*******************************************************************/ |
|||
/* Table already open, just replace it at its beginning. */ |
|||
/*******************************************************************/ |
|||
M = N = 0; |
|||
RowFlag = 0; |
|||
New = TRUE; |
|||
return Tdbp->OpenDB(g); |
|||
} // endif use
|
|||
|
|||
if (Mode != MODE_READ) { |
|||
/*******************************************************************/ |
|||
/* Currently XCOL tables cannot be modified. */ |
|||
/*******************************************************************/ |
|||
strcpy(g->Message, "XCOL tables are read only"); |
|||
return TRUE; |
|||
} // endif Mode
|
|||
|
|||
if (InitTable(g)) |
|||
return NULL; |
|||
|
|||
/*********************************************************************/ |
|||
/* Check and initialize the subtable columns. */ |
|||
/*********************************************************************/ |
|||
for (PCOL cp = Columns; cp; cp = cp->GetNext()) |
|||
if (((PXCLCOL)cp)->Init(g)) |
|||
return TRUE; |
|||
|
|||
/*********************************************************************/ |
|||
/* Physically open the object table. */ |
|||
/*********************************************************************/ |
|||
if (Tdbp->OpenDB(g)) |
|||
return TRUE; |
|||
|
|||
#if 0
|
|||
/*********************************************************************/ |
|||
/* Check for direct access. */ |
|||
/*********************************************************************/ |
|||
if (To_Key_Col) |
|||
if (!Tdbp->GetDef()->Indexable()) { |
|||
strcpy(g->Message, "Object table is not indexable"); |
|||
return TRUE; |
|||
} else { |
|||
((PTDBX)Tdbp)->To_Key_Col = To_Key_Col; |
|||
((PTDBX)Tdbp)->To_Link = To_Link; |
|||
((PTDBX)Tdbp)->Knum = Knum; |
|||
To_Kindex = (PKXBASE)new(g) KINDEX(Tdbp); |
|||
|
|||
if (To_Kindex->Init(g)) |
|||
return TRUE; |
|||
|
|||
((PKINDEX)To_Kindex)->SetMult(Mult); |
|||
Tdbp->SetKindex(To_Kindex); |
|||
} // endif Indexable
|
|||
#endif // 0
|
|||
|
|||
return FALSE; |
|||
} // end of OpenDB
|
|||
|
|||
/***********************************************************************/ |
|||
/* Data Base read routine for XCV access method. */ |
|||
/***********************************************************************/ |
|||
int TDBXCL::ReadDB(PGLOBAL g) |
|||
{ |
|||
int rc = RC_OK; |
|||
|
|||
/*********************************************************************/ |
|||
/* Now start the multi reading process. */ |
|||
/*********************************************************************/ |
|||
do { |
|||
if (RowFlag != 1) { |
|||
if ((rc = Tdbp->ReadDB(g)) != RC_OK) |
|||
break; |
|||
|
|||
New = TRUE; |
|||
M = 1; |
|||
} else { |
|||
New = FALSE; |
|||
M++; |
|||
} // endif RowFlag
|
|||
|
|||
if (Xcolp) { |
|||
RowFlag = 0; |
|||
Xcolp->ReadColumn(g); |
|||
} // endif Xcolp
|
|||
|
|||
N++; |
|||
} while (RowFlag == 2); |
|||
|
|||
return rc; |
|||
} // end of ReadDB
|
|||
|
|||
|
|||
// ------------------------ XCLCOL functions ----------------------------
|
|||
|
|||
/***********************************************************************/ |
|||
/* XCLCOL public constructor. */ |
|||
/***********************************************************************/ |
|||
XCLCOL::XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) |
|||
: PRXCOL(cdp, tdbp, cprec, i, "XCL") |
|||
{ |
|||
// Set additional XXL access method information for column.
|
|||
Cbuf = (char*)PlugSubAlloc(g, NULL, Long + 1); |
|||
Cp = NULL; // Pointer to current position in Cbuf
|
|||
Sep = ((PTDBXCL)tdbp)->Sep; |
|||
AddStatus(BUF_READ); // Only evaluated from TDBXCL::ReadDB
|
|||
} // end of XCLCOL constructor
|
|||
|
|||
/***********************************************************************/ |
|||
/* What this routine does is to get the comma-separated string */ |
|||
/* from the source table column, extract the single values and */ |
|||
/* set the flag for the table ReadDB function. */ |
|||
/***********************************************************************/ |
|||
void XCLCOL::ReadColumn(PGLOBAL g) |
|||
{ |
|||
if (((PTDBXCL)To_Tdb)->New) { |
|||
Colp->ReadColumn(g); |
|||
strcpy(Cbuf, To_Val->GetCharValue()); |
|||
Cp = Cbuf; |
|||
} // endif New
|
|||
|
|||
if (*Cp) { |
|||
PSZ p; |
|||
|
|||
// Trim left
|
|||
for (p = Cp; *p == ' '; p++) ; |
|||
|
|||
if ((Cp = strchr(Cp, Sep))) |
|||
// Separator is found
|
|||
*Cp++ = '\0'; |
|||
|
|||
Value->SetValue_psz(p); |
|||
} else if (Nullable) { |
|||
Value->Reset(); |
|||
Value->SetNull(true); |
|||
} else |
|||
// Skip that row
|
|||
((PTDBXCL)To_Tdb)->RowFlag = 2; |
|||
|
|||
if (Cp && *Cp) |
|||
// More to come from the same row
|
|||
((PTDBXCL)To_Tdb)->RowFlag = 1; |
|||
|
|||
} // end of ReadColumn
|
|||
|
|||
#if 0
|
|||
/* -------------- Implementation of the MULINDX class ---------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* Returns FALSE if Ok, TRUE if there are no more equal values. */ |
|||
/***********************************************************************/ |
|||
bool MULINDX::HaveSame(void) |
|||
{ |
|||
return (Op == OP_SAME || Txlp->RowFlag == 1); |
|||
} // end of HaveSame
|
|||
|
|||
/***********************************************************************/ |
|||
/* Returns FALSE if Ok, TRUE if there are no more equal values. */ |
|||
/***********************************************************************/ |
|||
bool MULINDX::NextVal(bool eq) |
|||
{ |
|||
return (Pof) ? KINDEX::NextVal(eq) : TRUE; |
|||
} // end of NextVal
|
|||
|
|||
/***********************************************************************/ |
|||
/* Returns TRUE if there are more same values. */ |
|||
/***********************************************************************/ |
|||
bool MULINDX::MoreVal(void) |
|||
{ |
|||
Op = OP_SAME; // There may be more equal values
|
|||
return (Pof) ? Pof[Val_K] : Val_K; |
|||
} // end of MoreVal
|
|||
|
|||
/***********************************************************************/ |
|||
/* Change the index multiple status. */ |
|||
/***********************************************************************/ |
|||
bool MULINDX::Init(PGLOBAL g) |
|||
{ |
|||
if (KINDEX::Init(g)) |
|||
return TRUE; |
|||
|
|||
Mul = TRUE; |
|||
MaxSame *= Txlp->Mult; |
|||
return FALSE; |
|||
} // end of Init
|
|||
#endif // 0
|
|||
@ -0,0 +1,133 @@ |
|||
// TABXCL.H Olivier Bertrand 2013 |
|||
// Defines the XCOL tables |
|||
|
|||
#include "tabutil.h" |
|||
|
|||
#define TYPE_AM_XCOL (AMT)124 |
|||
|
|||
typedef class XCLDEF *PXCLDEF; |
|||
typedef class TDBXCL *PTDBXCL; |
|||
typedef class XCLCOL *PXCLCOL; |
|||
//pedef class MULINDX *PMINDX; |
|||
|
|||
/* -------------------------- XCOL classes --------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* XCOL: table having one column containing several values comma */ |
|||
/* (or any other character) separated. When creating the table, the */ |
|||
/* name of the X column is given by the NAME option. */ |
|||
/* This sample has a limitation: */ |
|||
/* - The X column has the same length than in the physical file. */ |
|||
/* This tables produces as many rows for a physical row than the */ |
|||
/* number of items in the X column (eventually 0). */ |
|||
/***********************************************************************/ |
|||
|
|||
/***********************************************************************/ |
|||
/* XCL table. */ |
|||
/***********************************************************************/ |
|||
class XCLDEF : public PRXDEF { /* Logical table description */ |
|||
friend class TDBXCL; |
|||
public: |
|||
// Constructor |
|||
XCLDEF(void); |
|||
|
|||
// Implementation |
|||
virtual const char *GetType(void) {return "XCL";} |
|||
|
|||
// Methods |
|||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); |
|||
virtual PTDB GetTable(PGLOBAL g, MODE mode); |
|||
|
|||
protected: |
|||
// Members |
|||
char *Xcol; /* The column containing separated fields */ |
|||
char Sep; /* The field separator, defaults to comma */ |
|||
int Mult; /* Multiplication factor */ |
|||
}; // end of XCLDEF |
|||
|
|||
/***********************************************************************/ |
|||
/* This is the class declaration for the XCSV table. */ |
|||
/***********************************************************************/ |
|||
class TDBXCL : public TDBPRX { |
|||
//friend class MULINDX; |
|||
friend class XCLDEF; |
|||
friend class PRXCOL; |
|||
friend class XCLCOL; |
|||
public: |
|||
// Constructor |
|||
TDBXCL(PXCLDEF tdp); |
|||
|
|||
// Implementation |
|||
virtual AMT GetAmType(void) {return TYPE_AM_XCOL;} |
|||
|
|||
// Methods |
|||
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();} |
|||
virtual int RowNumber(PGLOBAL g, bool b = FALSE); |
|||
//virtual bool HaveSame(void) {return RowFlag == 1;} |
|||
|
|||
// Database routines |
|||
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); |
|||
virtual bool InitTable(PGLOBAL g); |
|||
virtual int GetMaxSize(PGLOBAL g); |
|||
virtual bool OpenDB(PGLOBAL g); |
|||
virtual int ReadDB(PGLOBAL g); |
|||
|
|||
protected: |
|||
// Members |
|||
char *Xcolumn; // Multiple column name |
|||
PXCLCOL Xcolp; // To the XCVCOL column |
|||
int Mult; // Multiplication factor |
|||
int N; // The current table index |
|||
int M; // The occurence rank |
|||
BYTE RowFlag; // 0: Ok, 1: Same, 2: Skip |
|||
BOOL New; // TRUE for new line |
|||
char Sep; // The Xcol separator |
|||
}; // end of class TDBXCL |
|||
|
|||
/***********************************************************************/ |
|||
/* Class XCLCOL: for the multiple CSV column. */ |
|||
/***********************************************************************/ |
|||
class XCLCOL : public PRXCOL { |
|||
friend class TDBXCL; |
|||
public: |
|||
// Constructors |
|||
XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i); |
|||
|
|||
// Methods |
|||
virtual void Reset(void) {} // Evaluated only by TDBXCL |
|||
virtual void ReadColumn(PGLOBAL g); |
|||
|
|||
protected: |
|||
// Default constructor not to be used |
|||
XCLCOL(void) {} |
|||
|
|||
// Members |
|||
char *Cbuf; // The column buffer |
|||
char *Cp; // Pointer to current position |
|||
char Sep; // The separator |
|||
}; // end of class XCLCOL |
|||
|
|||
#if 0 |
|||
/* ------------------------- MULINDX classes ------------------------- */ |
|||
|
|||
/***********************************************************************/ |
|||
/* This represents a KINDEX class for an XCOL table. */ |
|||
/***********************************************************************/ |
|||
class MULINDX : public KINDEX { |
|||
public: |
|||
// Constructor |
|||
MULINDX(PTDBXCL txlp) : KINDEX(txlp->Tdbp) {Txlp = txlp;} |
|||
|
|||
// Implementation |
|||
virtual BOOL HaveSame(void); |
|||
|
|||
// Methods |
|||
virtual BOOL Init(PGLOBAL g); |
|||
virtual BOOL NextVal(BOOL eq); |
|||
virtual int MoreVal(void); |
|||
|
|||
protected: |
|||
//Member |
|||
PTDBXCL Txlp; |
|||
}; // end of class MULINDX |
|||
#endif // 0 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue