Commit 9f7c3fed authored by Olivier Bertrand's avatar Olivier Bertrand

- Extending connect_assisted_discovery column automatic definition

  to OCCUR and PIVOT table types.

modified:
  storage/connect/ha_connect.cc
  storage/connect/myconn.cpp
  storage/connect/myconn.h
  storage/connect/plgdbsem.h
  storage/connect/plgdbutl.cpp
  storage/connect/taboccur.cpp
  storage/connect/taboccur.h
  storage/connect/tabpivot.cpp
  storage/connect/tabpivot.h

- Fix wrong definition of GetVlen for TYPE template

modified:
  storage/connect/valblk.h
parent cc8174db
......@@ -27,11 +27,12 @@
ha_connect will let you create/open/delete tables, the created table can be
done specifying an already existing file, the drop table command will just
suppress the table definition but not the eventual data file.
Indexes are not yet supported but data can be inserted, updated or deleted.
Indexes are not supported for all table types but data can be inserted,
updated or deleted.
You can enable the CONNECT storage engine in your build by doing the
following during your build process:<br> ./configure
--with-connect-storage-engine (not implemented yet)
--with-connect-storage-engine
You can install the CONNECT handler as all other storage handlers.
......@@ -166,6 +167,16 @@ extern "C" {
int trace= 0; // The general trace value
} // extern "C"
bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
const char *ocr, const char *rank);
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
const char *ocr, const char *rank);
PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
const char *picol, const char *fncol,
const char *host, const char *db,
const char *user, const char *pwd,
int port);
/****************************************************************************/
/* Initialize the ha_connect static members. */
/****************************************************************************/
......@@ -3333,7 +3344,7 @@ static char *encode(PGLOBAL g, char *cnm)
*/
static bool add_field(String *sql, const char *field_name, const char *type,
int len, int dec, uint tm, const char *rem)
int len, int dec, uint tm, const char *rem, int flag)
{
bool error= false;
......@@ -3341,15 +3352,18 @@ static bool add_field(String *sql, const char *field_name, const char *type,
error|= sql->append(field_name);
error|= sql->append("` ");
error|= sql->append(type);
if (len) {
error|= sql->append('(');
error|= sql->append_ulonglong(len);
if (dec || !strcmp(type, "DOUBLE")) {
error|= sql->append(',');
error|= sql->append_ulonglong(dec);
}
} // endif dec
error|= sql->append(')');
}
} // endif len
if (tm)
error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
......@@ -3358,10 +3372,14 @@ static bool add_field(String *sql, const char *field_name, const char *type,
error|= sql->append(" COMMENT '");
error|= sql->append_for_single_quote(rem, strlen(rem));
error|= sql->append("'");
}
} // endif rem
sql->append(',');
if (flag) {
error|= sql->append(" FLAG=");
error|= sql->append_ulonglong(flag);
} // endif flag
sql->append(',');
return error;
} // end of add_field
......@@ -3381,6 +3399,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
char spc= ',', qch= 0;
const char *fncn= "?";
const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src;
const char *col, *ocl, *rnk, *pic, *fcl;
char *tab, *dsn;
#if defined(WIN32)
char *nsp= NULL, *cls= NULL;
......@@ -3402,7 +3421,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
user= host= pwd= prt= tbl= src= dsn= NULL;
user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= dsn= NULL;
// Get the useful create options
ttp= GetTypeID(topt->type);
......@@ -3417,12 +3436,18 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
hdr= (int)topt->header;
tbl= topt->tablist;
col= topt->colist;
if (topt->oplist) {
host= GetListOption(g,"host", topt->oplist, "localhost");
user= GetListOption(g,"user", topt->oplist, "root");
// Default value db can come from the DBNAME=xxx option.
db= GetListOption(g,"database", topt->oplist, db);
col= GetListOption(g,"colist", topt->oplist, col);
ocl= GetListOption(g,"occurcol", topt->oplist, NULL);
pic= GetListOption(g,"pivotcol", topt->oplist, NULL);
fcl= GetListOption(g,"fnccol", topt->oplist, NULL);
rnk= GetListOption(g,"rankcol", topt->oplist, NULL);
pwd= GetListOption(g,"password", topt->oplist);
prt= GetListOption(g,"port", topt->oplist);
port= (prt) ? atoi(prt) : 0;
......@@ -3537,9 +3562,12 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
ok= true;
break;
#endif // WIN32
case TAB_PIVOT:
supfnc = FNC_NO;
case TAB_PRX:
case TAB_TBL:
case TAB_XCL:
case TAB_OCCUR:
ok= true;
break;
default:
......@@ -3563,7 +3591,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (ok) {
char *cnm, *rem;
int i, len, dec, typ;
int i, len, dec, typ, flg;
const char *type;
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
......@@ -3573,9 +3601,16 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
else
return HA_ERR_INTERNAL_ERROR; // Should never happen
if (src)
if (src && ttp != TAB_PIVOT) {
qrp= SrcColumns(g, host, db, user, pwd, src, port);
else switch (ttp) {
if (ttp == TAB_OCCUR)
if (OcrSrcCols(g, qrp, col, ocl, rnk)) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return HA_ERR_INTERNAL_ERROR;
} // endif OcrSrcCols
} else switch (ttp) {
case TAB_DBF:
qrp= DBFColumns(g, fn, fnc == FNC_COL);
break;
......@@ -3618,12 +3653,22 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case TAB_PRX:
case TAB_TBL:
case TAB_XCL:
case TAB_OCCUR:
bif= fnc == FNC_COL;
qrp= TabColumns(g, thd, db, tab, bif);
if (!qrp && bif && fnc != FNC_COL) // tab is a view
qrp= MyColumns(g, host, db, user, pwd, tab, NULL, port, false);
if (ttp == TAB_OCCUR && fnc != FNC_COL)
if (OcrColumns(g, qrp, col, ocl, rnk)) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return HA_ERR_INTERNAL_ERROR;
} // endif OcrColumns
break;
case TAB_PIVOT:
qrp= PivotColumns(g, tab, src, pic, fcl, host, db, user, pwd, port);
break;
default:
strcpy(g->Message, "System error during assisted discovery");
......@@ -3635,16 +3680,17 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
return HA_ERR_INTERNAL_ERROR;
} // endif qrp
if (fnc != FNC_NO || src) {
// Catalog table
if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
// Catalog like table
for (crp=qrp->Colresp; !b && crp; crp= crp->Next) {
cnm= encode(g, crp->Name);
type= PLGtoMYSQLtype(crp->Type, dbf);
len= crp->Length;
dec= crp->Prec;
flg= crp->Flag;
// Now add the field
if (add_field(&sql, cnm, type, len, dec, NOT_NULL_FLAG, 0))
if (add_field(&sql, cnm, type, len, dec, NOT_NULL_FLAG, 0, flg))
b= HA_ERR_OUT_OF_MEM;
} // endfor crp
......@@ -3714,7 +3760,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
len= 0;
// Now add the field
if (add_field(&sql, cnm, type, len, dec, tm, rem))
if (add_field(&sql, cnm, type, len, dec, tm, rem, 0))
b= HA_ERR_OUT_OF_MEM;
} // endfor i
......
......@@ -64,6 +64,12 @@ static char *server_groups[] = {
extern "C" int trace;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
// Returns the current used port
uint GetDefaultPort(void)
{
return mysqld_port;
} // end of GetDefaultPort
/************************************************************************/
/* MyColumns: constructs the result blocks containing all columns */
/* of a MySQL table or view. */
......@@ -673,6 +679,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
*pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
crp = *pcrp;
pcrp = &crp->Next;
memset(crp, 0, sizeof(COLRES));
crp->Ncol = ++qrp->Nbcol;
crp->Name = (char*)PlugSubAlloc(g, NULL, fld->name_length + 1);
......@@ -686,7 +693,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
// For direct MySQL connection, display the MySQL date string
crp->Type = TYPE_STRING;
crp->Prec = fld->decimals;
crp->Prec = (crp->Type == TYPE_FLOAT) ? fld->decimals : 0;
crp->Length = fld->max_length;
crp->Clen = GetTypeSize(crp->Type, crp->Length);
......
......@@ -44,6 +44,8 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
const char *user, const char *pwd,
const char *srcdef, int port);
uint GetDefaultPort(void);
/* -------------------------- MYCONN class --------------------------- */
/***********************************************************************/
......
......@@ -518,6 +518,7 @@ typedef struct _colres {
int Clen; /* Data individual internal size */
int Length; /* Data individual print length */
int Prec; /* Precision */
int Flag; /* Flag option value */
XFLD Fld; /* Type of field info */
} COLRES;
......
......@@ -298,6 +298,7 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
*pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
crp = *pcrp;
pcrp = &crp->Next;
memset(crp, 0, sizeof(COLRES));
crp->Colp = NULL;
crp->Ncol = ++qrp->Nbcol;
crp->Type = buftyp[i];
......
/************ TabOccur CPP Declares Source Code File (.CPP) ************/
/* Name: TABOCCUR.CPP Version 1.0 */
/* Name: TABOCCUR.CPP Version 1.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2013 */
/* */
......@@ -53,6 +53,210 @@
extern "C" int trace;
/***********************************************************************/
/* Prepare and count columns in the column list. */
/***********************************************************************/
int PrepareColist(char *colist)
{
char *p, *pn;
int n = 0;
// Count the number of columns and change separator into null char
for (pn = colist; ; pn += (strlen(pn) + 1))
// Separator can be ; if colist was specified in the option_list
if ((p = strchr(pn, ',')) || (p = strchr(pn, ';'))) {
*p++ = '\0';
n++;
} else {
if (*pn)
n++;
break;
} // endif p
return n;
} // end of PrepareColist
/************************************************************************/
/* OcrColumns: constructs the result blocks containing all the columns */
/* of the object table that will be retrieved by GetData commands. */
/************************************************************************/
bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
const char *ocr, const char *rank)
{
char *pn, *colist;
int i, k, m, n = 0, c = 0, j = qrp->Nblin;
bool rk, b = false;
PCOLRES crp;
if (!col || !*col) {
strcpy(g->Message, "Missing colist");
return true;
} // endif col
// Prepare the column list
colist = (char*)PlugSubAlloc(g, NULL, strlen(col) + 1);
strcpy(colist, col);
m = PrepareColist(colist);
if ((rk = (rank && *rank))) {
if (m == 1) {
strcpy(g->Message, "Cannot handle one column colist and rank");
return true;
} // endif m
for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
n = max(n, (signed)strlen(pn));
} // endif k
// Default occur column name is the 1st colist column name
if (!ocr || !*ocr)
ocr = colist;
/**********************************************************************/
/* Replace the columns of the colist by the rank and occur columns. */
/**********************************************************************/
for (i = 0; i < qrp->Nblin; i++) {
for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
if (!stricmp(pn, qrp->Colresp->Kdata->GetCharValue(i)))
break;
if (k < m) {
// This column belongs to colist
if (rk) {
// Place the rank column here
for (crp = qrp->Colresp; crp; crp = crp->Next)
switch (crp->Fld) {
case FLD_NAME: crp->Kdata->SetValue((char*)rank, i); break;
case FLD_TYPE: crp->Kdata->SetValue(TYPE_STRING, i); break;
case FLD_PREC: crp->Kdata->SetValue(n, i); break;
case FLD_SCALE: crp->Kdata->SetValue(0, i); break;
case FLD_NULL: crp->Kdata->SetValue(0, i); break;
case FLD_REM: crp->Kdata->Reset(i); break;
default: ; // Ignored by CONNECT
} // endswich Fld
rk = false;
} else if (!b) {
// First remaining listed column, will be the occur column
for (crp = qrp->Colresp; crp; crp = crp->Next)
switch (crp->Fld) {
case FLD_NAME: crp->Kdata->SetValue((char*)ocr, i); break;
case FLD_REM: crp->Kdata->Reset(i); break;
default: ; // Nothing to do
} // endswich Fld
b = true;
} else if (j == qrp->Nblin)
j = i; // Column to remove
c++;
} else if (j < i) {
// Move this column in empty spot
for (crp = qrp->Colresp; crp; crp = crp->Next)
crp->Kdata->Move(i, j);
j++;
} // endif k
} // endfor i
// Check whether all columns of the list where found
if (c < m) {
strcpy(g->Message, "Some colist columns are not in the source table");
return true;
} // endif crp
/**********************************************************************/
/* Set the number of columns of the table. */
/**********************************************************************/
qrp->Nblin = j;
return false;
} // end of OcrColumns
/************************************************************************/
/* OcrSrcCols: constructs the result blocks containing all the columns */
/* of the object table that will be retrieved by GetData commands. */
/************************************************************************/
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
const char *ocr, const char *rank)
{
char *pn, *colist;
int i, k, m, n = 0, c = 0;
bool rk, b = false;
PCOLRES crp, rcrp, *pcrp;
if (!col || !*col) {
strcpy(g->Message, "Missing colist");
return true;
} // endif col
// Prepare the column list
colist = (char*)PlugSubAlloc(g, NULL, strlen(col) + 1);
strcpy(colist, col);
m = PrepareColist(colist);
if ((rk = (rank && *rank)))
for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
n = max(n, (signed)strlen(pn));
// Default occur column name is the 1st colist column name
if (!ocr || !*ocr)
ocr = colist;
/**********************************************************************/
/* Replace the columns of the colist by the rank and occur columns. */
/**********************************************************************/
for (i = 0, pcrp = &qrp->Colresp; crp = *pcrp; ) {
for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
if (!stricmp(pn, crp->Name))
break;
if (k < m) {
// This column belongs to colist
c++;
if (!b) {
if (rk) {
// Add the rank column here
rcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
memset(rcrp, 0, sizeof(COLRES));
rcrp->Next = crp;
rcrp->Name = (char*)rank;
rcrp->Type = TYPE_STRING;
rcrp->Length = n;
rcrp->Ncol = ++i;
*pcrp = rcrp;
} // endif rk
// First remaining listed column, will be the occur column
crp->Name = (char*)ocr;
b = true;
} else {
*pcrp = crp->Next; // Remove this column
continue;
} // endif b
} // endif k
crp->Ncol = ++i;
pcrp = &crp->Next;
} // endfor pcrp
// Check whether all columns of the list where found
if (c < m) {
strcpy(g->Message, "Some colist columns are not in the source table");
return true;
} // endif crp
/**********************************************************************/
/* Set the number of columns of the table. */
/**********************************************************************/
qrp->Nblin = i;
return false;
} // end of OcrSrcCols
/* -------------- Implementation of the OCCUR classes ---------------- */
/***********************************************************************/
......@@ -60,9 +264,9 @@ extern "C" int trace;
/***********************************************************************/
bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Xcol = Cat->GetStringCatInfo(g, "OccurCol", "");
Rcol = Cat->GetStringCatInfo(g, "RankCol", "");
Colist = Cat->GetStringCatInfo(g, "Colist", "");
Xcol = Cat->GetStringCatInfo(g, "OccurCol", Colist);
return PRXDEF::DefineAM(g, am, poff);
} // end of DefineAM
......@@ -92,36 +296,12 @@ TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
Rcolumn = tdp->Rcol; // Rank column name
Xcolp = NULL; // To the OCCURCOL column
Col = NULL; // To source column blocks array
Mult = PrepareColist(); // Multiplication factor
Mult = PrepareColist(Colist); // 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
/***********************************************************************/
/* Prepare and count columns in the column list. */
/***********************************************************************/
int TDBOCCUR::PrepareColist(void)
{
char *p, *pn;
int n = 0;
// Count the number of columns and change separator into null char
for (pn = Colist; ; pn += (strlen(pn) + 1))
// Separator can be ; if colist was specified in the option_list
if ((p = strchr(pn, ',')) || (p = strchr(pn, ';'))) {
*p++ = '\0';
n++;
} else {
if (*pn)
n++;
break;
} // endif p
return n;
} // end of PrepareColist
/***********************************************************************/
/* Allocate OCCUR/SRC column description block. */
/***********************************************************************/
......
......@@ -58,7 +58,6 @@ class TDBOCCUR : public TDBPRX {
// Methods
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
int PrepareColist(void);
bool MakeColumnList(PGLOBAL g);
bool ViewColumnList(PGLOBAL g);
......
/************ TabPivot C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABPIVOT */
/* ------------- */
/* Version 1.5 */
/* Version 1.6 */
/* */
/* COPYRIGHT: */
/* ---------- */
......@@ -53,6 +53,182 @@
extern "C" int trace;
/***********************************************************************/
/* Make the Pivot table column list. */
/***********************************************************************/
PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
const char *picol, const char *fncol,
const char *host, const char *db,
const char *user, const char *pwd,
int port)
{
PIVAID pvd(tab, src, picol, fncol, host, db, user, pwd, port);
return pvd.MakePivotColumns(g);
} // end of PivotColumns
/* --------------- Implementation of the PIVAID classe --------------- */
/***********************************************************************/
/* PIVAID constructor. */
/***********************************************************************/
PIVAID::PIVAID(const char *tab, const char *src, const char *picol,
const char *fncol, const char *host, const char *db,
const char *user, const char *pwd, int port)
: CSORT(false)
{
Host = (char*)host;
User = (char*)user;
Pwd = (char*)pwd;
Qryp = NULL;
Database = (char*)db;
Tabname = (char*)tab;
Tabsrc = (char*)src;
Picol = (char*)picol;
Fncol = (char*)fncol;
Rblkp = NULL;
Port = (port) ? port : GetDefaultPort();
} // end of PIVAID constructor
/***********************************************************************/
/* Make the Pivot table column list. */
/***********************************************************************/
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
{
char *query, *colname, buf[32];
int ndif, nblin, w = 0;
PVAL valp;
PCOLRES *pcrp, crp, fncrp = NULL;
if (!Tabsrc && Tabname) {
// Locate the query
query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 16);
sprintf(query, "SELECT * FROM %s", Tabname);
} else if (!Tabsrc) {
strcpy(g->Message, MSG(SRC_TABLE_UNDEF));
return NULL;
} else
query = Tabsrc;
// Open a MySQL connection for this table
if (Myc.Open(g, Host, Database, User, Pwd, Port))
return NULL;
// Send the source command to MySQL
if (Myc.ExecSQL(g, query, &w) == RC_FX) {
Myc.Close();
return NULL;
} // endif Exec
// We must have a storage query to get pivot column values
Qryp = Myc.GetResult(g);
Myc.Close();
if (!Fncol) {
for (crp = Qryp->Colresp; crp; crp = crp->Next)
if (!Picol || stricmp(Picol, crp->Name))
Fncol = crp->Name;
if (!Fncol) {
strcpy(g->Message, MSG(NO_DEF_FNCCOL));
return NULL;
} // endif Fncol
} // endif Fncol
if (!Picol) {
// Find default Picol as the last one not equal to Fncol
for (crp = Qryp->Colresp; crp; crp = crp->Next)
if (stricmp(Fncol, crp->Name))
Picol = crp->Name;
if (!Picol) {
strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
return NULL;
} // endif Picol
} // endif picol
// Prepare the column list
for (pcrp = &Qryp->Colresp; crp = *pcrp; )
if (!stricmp(Picol, crp->Name)) {
Rblkp = crp->Kdata;
*pcrp = crp->Next;
} else if (!stricmp(Fncol, crp->Name)) {
fncrp = crp;
*pcrp = crp->Next;
} else
pcrp = &crp->Next;
if (!Rblkp) {
strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
return NULL;
} else if (!fncrp) {
strcpy(g->Message, MSG(NO_DEF_FNCCOL));
return NULL;
} // endif
// Before calling sort, initialize all
nblin = Qryp->Nblin;
Index.Size = nblin * sizeof(int);
Index.Sub = TRUE; // Should be small enough
if (!PlgDBalloc(g, NULL, Index))
return NULL;
Offset.Size = (nblin + 1) * sizeof(int);
Offset.Sub = TRUE; // Should be small enough
if (!PlgDBalloc(g, NULL, Offset))
return NULL;
ndif = Qsort(g, nblin);
if (ndif < 0) // error
return NULL;
// Allocate the Value used to retieve column names
if (!(valp = AllocateValue(g, Rblkp->GetType(),
Rblkp->GetVlen(),
Rblkp->GetPrec())))
return NULL;
// Now make the functional columns
for (int i = 0; i < ndif; i++) {
if (i) {
crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
memcpy(crp, fncrp, sizeof(COLRES));
} else
crp = fncrp;
// Get the value that will be the generated column name
valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]);
colname = valp->GetCharString(buf);
crp->Name = (char*)PlugSubAlloc(g, NULL, strlen(colname) + 1);
strcpy(crp->Name, colname);
crp->Flag = 1;
// Add this column
*pcrp = crp;
crp->Next = NULL;
pcrp = &crp->Next;
} // endfor i
// We added ndif columns and removed 2 (picol and fncol)
Qryp->Nbcol += (ndif - 2);
return Qryp;
} // end of MakePivotColumns
/***********************************************************************/
/* PIVAID: Compare routine for sorting pivot column values. */
/***********************************************************************/
int PIVAID::Qcompare(int *i1, int *i2)
{
// TODO: the actual comparison between pivot column result values.
return Rblkp->CompVal(*i1, *i2);
} // end of Qcompare
/* --------------- Implementation of the PIVOT classes --------------- */
/***********************************************************************/
......
/************** TabPivot H Declares Source Code File (.H) **************/
/* Name: TABPIVOT.H Version 1.4 */
/* Name: TABPIVOT.H Version 1.5 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
/* */
......@@ -10,6 +10,40 @@ typedef class TDBPIVOT *PTDBPIVOT;
typedef class FNCCOL *PFNCCOL;
typedef class SRCCOL *PSRCCOL;
/***********************************************************************/
/* This class is used to generate PIVOT table column definitions. */
/***********************************************************************/
class PIVAID : public CSORT {
friend class FNCCOL;
friend class SRCCOL;
public:
// Constructor
PIVAID(const char *tab, const char *src, const char *picol,
const char *fncol, const char *host, const char *db,
const char *user, const char *pwd, int port);
// Methods
PQRYRES MakePivotColumns(PGLOBAL g);
// The sorting function
virtual int Qcompare(int *, int *);
protected:
// Members
MYSQLC Myc; // MySQL connection class
char *Host; // Host machine to use
char *User; // User logon info
char *Pwd; // Password logon info
char *Database; // Database to be used by server
PQRYRES Qryp; // Points to Query result block
char *Tabname; // Name of source table
char *Tabsrc; // SQL of source table
char *Picol; // Pivot column name
char *Fncol; // Function column name
PVBLK Rblkp; // The value block of the pivot column
int Port; // MySQL port number
}; // end of class PIVAID
/* -------------------------- PIVOT classes -------------------------- */
/***********************************************************************/
......
......@@ -36,6 +36,7 @@ class VALBLK : public BLOCK {
void *GetValPointer(void) {return Blkp;}
void SetValPointer(void *mp) {Blkp = mp;}
int GetType(void) {return Type;}
int GetPrec(void) {return Prec;}
void SetCheck(bool b) {Check = b;}
void MoveNull(int i, int j)
{if (To_Nulls) To_Nulls[j] = To_Nulls[j];}
......@@ -110,7 +111,7 @@ class TYPBLK : public VALBLK {
// Implementation
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(int);}
virtual int GetVlen(void) {return sizeof(TYPE);}
//virtual PSZ GetCharValue(int n);
virtual short GetShortValue(int n) {return (short)Typp[n];}
virtual int GetIntValue(int n) {return (int)Typp[n];}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment