1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

- Commit merge files (implementing "remote" indexes)

modified:
  storage/connect/connect.cc
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/mycat.cc
  storage/connect/plgdbsem.h
  storage/connect/reldef.h
  storage/connect/tabdos.h
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
  storage/connect/tabodbc.cpp
  storage/connect/tabodbc.h
  storage/connect/xindex.cpp
  storage/connect/xtable.h
This commit is contained in:
Olivier Bertrand
2014-04-19 18:02:01 +02:00
13 changed files with 800 additions and 685 deletions

View File

@@ -587,7 +587,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
tbxp= (TDBDOX*)tdbp; tbxp= (TDBDOX*)tdbp;
tbxp->SetKindex(NULL); tbxp->SetKindex(NULL);
tbxp->To_Key_Col= NULL; tbxp->To_Key_Col= NULL;
rc= tbxp->ResetTableOpt(g, false, ((PTDBASE)tdbp)->GetDef()->Indexable()); rc= tbxp->ResetTableOpt(g, true,
((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
err: err:
if (trace > 1) if (trace > 1)
@@ -709,7 +710,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
const void *key, int len, bool mrr) const void *key, int len, bool mrr)
{ {
char *kp= (char*)key; char *kp= (char*)key;
int n; int n, x;
short lg; short lg;
bool rcb; bool rcb;
RCODE rc; RCODE rc;
@@ -720,9 +721,18 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
if (!ptdb) if (!ptdb)
return RC_FX; return RC_FX;
if (!((PTDBASE)ptdb)->GetDef()->Indexable()) { else
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName()); sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName());
return RC_FX; return RC_FX;
} else if (x == 2) {
// Remote index
if (ptdb->ReadKey(g, op, key, len))
return RC_FX;
goto rnd;
} else } else
tdbp= (PTDBDOX)ptdb; tdbp= (PTDBDOX)ptdb;
@@ -782,8 +792,9 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
xbp->SetOp(op); xbp->SetOp(op);
xbp->SetNth(0); xbp->SetNth(0);
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK) rnd:
rc= EvalColumns(g, tdbp, mrr); if ((rc= (RCODE)ptdb->ReadDB(g)) == RC_OK)
rc= EvalColumns(g, ptdb, mrr);
return rc; return rc;
} // end of CntIndexRead } // end of CntIndexRead
@@ -795,7 +806,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
bool *incl, key_part_map *kmap) bool *incl, key_part_map *kmap)
{ {
const uchar *p, *kp; const uchar *p, *kp;
int i, n, k[2]; int i, n, x, k[2];
short lg; short lg;
bool b, rcb; bool b, rcb;
PVAL valp; PVAL valp;
@@ -805,10 +816,16 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
if (!ptdb) if (!ptdb)
return -1; return -1;
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName()); sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName());
DBUG_PRINT("Range", ("%s", g->Message)); DBUG_PRINT("Range", ("%s", g->Message));
return -1; return -1;
} else if (x == 2) {
// Remote index
return 2;
} else } else
tdbp= (PTDBDOX)ptdb; tdbp= (PTDBDOX)ptdb;

View File

@@ -1243,9 +1243,10 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
if (!xp->CheckQuery(valid_query_id) && tdbp if (!xp->CheckQuery(valid_query_id) && tdbp
&& !stricmp(tdbp->GetName(), table_name) && !stricmp(tdbp->GetName(), table_name)
&& (tdbp->GetMode() == xmod && (tdbp->GetMode() == xmod
|| (tdbp->GetMode() == MODE_READ && xmod == MODE_READX)
|| tdbp->GetAmType() == TYPE_AM_XML)) { || tdbp->GetAmType() == TYPE_AM_XML)) {
tp= tdbp; tp= tdbp;
// tp->SetMode(xmod); tp->SetMode(xmod);
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) { } else if ((tp= CntGetTDB(g, table_name, xmod, this))) {
valid_query_id= xp->last_query_id; valid_query_id= xp->last_query_id;
tp->SetMode(xmod); tp->SetMode(xmod);
@@ -1642,6 +1643,88 @@ int ha_connect::CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf)
} // end of dummy CheckRecord } // end of dummy CheckRecord
/***********************************************************************/
/* Return the where clause for remote indexed read. */
/***********************************************************************/
bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
const void *key, int klen)
{
const uchar *ptr;
uint rem, len, stlen; //, prtlen;
bool nq, b= false;
Field *fp;
KEY *kfp;
KEY_PART_INFO *kpart;
if (active_index == MAX_KEY)
return 0;
strcat(qry, " WHERE (");
kfp= &table->key_info[active_index];
rem= kfp->user_defined_key_parts,
len= klen,
ptr= (const uchar *)key;
for (kpart= kfp->key_part; rem; rem--, kpart++) {
fp= kpart->field;
stlen= kpart->store_length;
// prtlen= min(stlen, len);
nq= fp->str_needs_quotes();
if (b)
strcat(qry, " AND ");
else
b= true;
strcat(strncat(strcat(qry, q), fp->field_name, strlen(fp->field_name)), q);
switch (op) {
case OP_EQ:
case OP_GT:
case OP_GE:
strcat(qry, GetValStr(op, false));
break;
default:
strcat(qry, " ??? ");
} // endwitch op
if (nq)
strcat(qry, "'");
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
String varchar;
uint var_length= uint2korr(ptr);
varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
strncat(qry, varchar.ptr(), varchar.length());
} else {
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
res= fp->val_str(&str, ptr);
strncat(qry, res->ptr(), res->length());
} // endif flag
if (nq)
strcat(qry, "'");
if (stlen >= len)
break;
len-= stlen;
/* For nullable columns, null-byte is already skipped before, that is
ptr was incremented by 1. Since store_length still counts null-byte,
we need to subtract 1 from store_length. */
ptr+= stlen - test(kpart->null_bit);
} // endfor kpart
strcat(qry, ")");
return false;
} // end of MakeKeyWhere
/***********************************************************************/ /***********************************************************************/
/* Return the string representing an operator. */ /* Return the string representing an operator. */
/***********************************************************************/ /***********************************************************************/
@@ -1948,7 +2031,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
} else { } else {
p1= p2 + strlen(p2); p1= p2 + strlen(p2);
strcpy(p1, GetValStr(vop, FALSE)); strcpy(p1, GetValStr(vop, false));
p2= p1 + strlen(p1); p2= p1 + strlen(p1);
} // endif CheckCond } // endif CheckCond
@@ -2311,7 +2394,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
dup->Check |= CHK_OPT; dup->Check |= CHK_OPT;
if (tdbp) { if (tdbp) {
bool b= ((PTDBASE)tdbp)->GetDef()->Indexable(); bool b= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, true, b))) { if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, true, b))) {
if (rc == RC_INFO) { if (rc == RC_INFO) {
@@ -2523,6 +2606,18 @@ int ha_connect::index_init(uint idx, bool sorted)
if (xtrace) if (xtrace)
htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted); htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
if (GetIndexType(GetRealType()) == 2) {
// This is a remote index
xmod= MODE_READX;
if (!(rc= rnd_init(0))) {
active_index= idx;
indexing= 2; // TO DO: mul?
} //endif rc
DBUG_RETURN(rc);
} // endif index type
if ((rc= rnd_init(0))) if ((rc= rnd_init(0)))
return rc; return rc;
@@ -3040,12 +3135,16 @@ int ha_connect::info(uint flag)
if (cat && table) if (cat && table)
cat->SetDataPath(g, table->s->db.str); cat->SetDataPath(g, table->s->db.str);
else else
return HA_ERR_INTERNAL_ERROR; // Should never happen DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
tdbp= GetTDB(g); tdbp= GetTDB(g);
} // endif tdbp } // endif tdbp
valid_info= CntInfo(g, tdbp, &xinfo); valid_info= CntInfo(g, tdbp, &xinfo);
if (((signed)xinfo.records) < 0)
DBUG_RETURN(HA_ERR_INITIALIZATION); // Error in Cardinality
} // endif valid_info } // endif valid_info
if (flag & HA_STATUS_VARIABLE) { if (flag & HA_STATUS_VARIABLE) {
@@ -3305,7 +3404,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
newmode= MODE_ALTER; newmode= MODE_ALTER;
break; break;
default: default:
htrc("Unsupported sql_command=%d", thd_sql_command(thd)); htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command"); strcpy(g->Message, "CONNECT Unsupported command");
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0)); my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
newmode= MODE_ERROR; newmode= MODE_ERROR;
@@ -3350,7 +3449,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
newmode= MODE_ALTER; newmode= MODE_ALTER;
break; break;
default: default:
htrc("Unsupported sql_command=%d", thd_sql_command(thd)); htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command"); strcpy(g->Message, "CONNECT Unsupported command");
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0)); my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
newmode= MODE_ERROR; newmode= MODE_ERROR;
@@ -3474,87 +3573,88 @@ int ha_connect::external_lock(THD *thd, int lock_type)
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error // DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
DBUG_RETURN(0); DBUG_RETURN(0);
} // endif Indexable } else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 1) {
bool oldsep= ((PCHK)g->Xchk)->oldsep;
bool oldsep= ((PCHK)g->Xchk)->oldsep; bool newsep= ((PCHK)g->Xchk)->newsep;
bool newsep= ((PCHK)g->Xchk)->newsep; PTDBDOS tdp= (PTDBDOS)tdbp;
PTDBDOS tdp= (PTDBDOS)tdbp;
PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
PDOSDEF ddp= (PDOSDEF)tdp->GetDef(); PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL; PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix; PIXDEF newpix= ((PCHK)g->Xchk)->newpix;
PIXDEF newpix= ((PCHK)g->Xchk)->newpix; PIXDEF *xlst, *xprc;
PIXDEF *xlst, *xprc;
ddp->SetIndx(oldpix);
ddp->SetIndx(oldpix);
if (oldsep != newsep) {
if (oldsep != newsep) { // All indexes have to be remade
// All indexes have to be remade
ddp->DeleteIndexFile(g, NULL);
oldpix= NULL;
ddp->SetIndx(NULL);
SetBooleanOption("Sepindex", newsep);
} else if (newsep) {
// Make the list of dropped indexes
xlst= &drp; xprc= &oldpix;
for (xp2= oldpix; xp2; xp2= xp) {
for (xp1= newpix; xp1; xp1= xp1->Next)
if (IsSameIndex(xp1, xp2))
break; // Index not to drop
xp= xp2->GetNext();
if (!xp1) {
*xlst= xp2;
*xprc= xp;
*(xlst= &xp2->Next)= NULL;
} else
xprc= &xp2->Next;
} // endfor xp2
if (drp) {
// Here we erase the index files
ddp->DeleteIndexFile(g, drp);
} // endif xp1
} else if (oldpix) {
// TODO: optimize the case of just adding new indexes
if (!newpix)
ddp->DeleteIndexFile(g, NULL); ddp->DeleteIndexFile(g, NULL);
oldpix= NULL;
oldpix= NULL; // To remake all indexes ddp->SetIndx(NULL);
ddp->SetIndx(NULL); SetBooleanOption("Sepindex", newsep);
} // endif sepindex } else if (newsep) {
// Make the list of dropped indexes
// Make the list of new created indexes xlst= &drp; xprc= &oldpix;
xlst= &adp; xprc= &newpix;
for (xp2= oldpix; xp2; xp2= xp) {
for (xp1= newpix; xp1; xp1= xp) { for (xp1= newpix; xp1; xp1= xp1->Next)
for (xp2= oldpix; xp2; xp2= xp2->Next) if (IsSameIndex(xp1, xp2))
if (IsSameIndex(xp1, xp2)) break; // Index not to drop
break; // Index already made
xp= xp2->GetNext();
xp= xp1->Next;
if (!xp1) {
if (!xp2) { *xlst= xp2;
*xlst= xp1; *xprc= xp;
*xprc= xp; *(xlst= &xp2->Next)= NULL;
*(xlst= &xp1->Next)= NULL; } else
} else xprc= &xp2->Next;
xprc= &xp1->Next;
} // endfor xp2
} // endfor xp1
if (drp) {
if (adp) // Here we erase the index files
// Here we do make the new indexes ddp->DeleteIndexFile(g, drp);
if (tdp->MakeIndex(g, adp, true) == RC_FX) { } // endif xp1
// Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, } else if (oldpix) {
0, g->Message); // TODO: optimize the case of just adding new indexes
rc= 0; if (!newpix)
} // endif MakeIndex ddp->DeleteIndexFile(g, NULL);
oldpix= NULL; // To remake all indexes
ddp->SetIndx(NULL);
} // endif sepindex
// Make the list of new created indexes
xlst= &adp; xprc= &newpix;
for (xp1= newpix; xp1; xp1= xp) {
for (xp2= oldpix; xp2; xp2= xp2->Next)
if (IsSameIndex(xp1, xp2))
break; // Index already made
xp= xp1->Next;
if (!xp2) {
*xlst= xp1;
*xprc= xp;
*(xlst= &xp1->Next)= NULL;
} else
xprc= &xp1->Next;
} // endfor xp1
if (adp)
// Here we do make the new indexes
if (tdp->MakeIndex(g, adp, true) == RC_FX) {
// Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
0, g->Message);
rc= 0;
} // endif MakeIndex
} // endif indexable
} // endif Tdbp } // endif Tdbp
@@ -5276,7 +5376,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
sprintf(g->Message, "Table type %s is not indexable", options->type); sprintf(g->Message, "Table type %s is not indexable", options->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_UNSUPPORTED; rc= HA_ERR_UNSUPPORTED;
} // endif Indexable } // endif index type
} // endif xdp } // endif xdp
@@ -5285,62 +5385,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
my_message(ER_UNKNOWN_ERROR, my_message(ER_UNKNOWN_ERROR,
"CONNECT index modification should be in-place", MYF(0)); "CONNECT index modification should be in-place", MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED); DBUG_RETURN(HA_ERR_UNSUPPORTED);
#if 0
PIXDEF xdp= GetIndexInfo();
PCHK xcp= (PCHK)g->Xchk;
if (xdp) {
if (!IsTypeIndexable(type)) {
g->Xchk= NULL;
sprintf(g->Message, "Table type %s is not indexable", options->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
} else {
xcp->newpix= xdp;
xcp->newsep= GetBooleanOption("Sepindex", false);
} // endif Indexable
} else if (!xcp->oldpix)
g->Xchk= NULL;
if (xtrace && g->Xchk)
htrc("oldsep=%d newsep=%d oldpix=%p newpix=%p\n",
xcp->oldsep, xcp->newsep, xcp->oldpix, xcp->newpix);
// if (g->Xchk &&
// (sqlcom != SQLCOM_CREATE_INDEX && sqlcom != SQLCOM_DROP_INDEX)) {
if (g->Xchk) {
PIXDEF xp1, xp2;
bool b= false; // true if index changes
if (xcp->oldsep == xcp->newsep) {
for (xp1= xcp->newpix, xp2= xcp->oldpix;
xp1 || xp2;
xp1= xp1->Next, xp2= xp2->Next)
if (!xp1 || !xp2 || !IsSameIndex(xp1, xp2)) {
b= true;
break;
} // endif xp1
} else
b= true;
if (!b)
g->Xchk= NULL;
#if 0
if (b) {
// CONNECT does not support indexing via ALTER TABLE
my_message(ER_UNKNOWN_ERROR,
"CONNECT does not support index modification via ALTER TABLE",
MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED);
} // endif b
#endif // 0
} // endif Xchk
#endif // 0
} // endif Xchk } // endif Xchk
table= st; table= st;

View File

@@ -213,6 +213,8 @@ public:
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf); int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL, int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
uint key_len= 0); uint key_len= 0);
bool MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
const void *key, int klen);
/** @brief /** @brief
The name that will be used for display purposes. The name that will be used for display purposes.

View File

@@ -275,9 +275,10 @@ int GetIndexType(TABTYPE type)
xtyp= 1; xtyp= 1;
break; break;
case TAB_MYSQL: case TAB_MYSQL:
// case TAB_ODBC:
xtyp= 2;
break;
case TAB_ODBC: case TAB_ODBC:
// xtyp= 2; Remote indexes not implemented yet
// break;
default: default:
xtyp= 0; xtyp= 0;
break; break;

View File

@@ -160,6 +160,7 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
enum MODE {MODE_ERROR = -1, /* Invalid mode */ enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_ANY = 0, /* Unspecified mode */ MODE_ANY = 0, /* Unspecified mode */
MODE_READ = 10, /* Input/Output mode */ MODE_READ = 10, /* Input/Output mode */
MODE_READX = 11, /* Read indexed mode */
MODE_WRITE = 20, /* Input/Output mode */ MODE_WRITE = 20, /* Input/Output mode */
MODE_UPDATE = 30, /* Input/Output mode */ MODE_UPDATE = 30, /* Input/Output mode */
MODE_INSERT = 40, /* Input/Output mode */ MODE_INSERT = 40, /* Input/Output mode */

View File

@@ -31,6 +31,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
PSZ GetName(void) {return Name;} PSZ GetName(void) {return Name;}
PSZ GetDB(void) {return (PSZ)Database;} PSZ GetDB(void) {return (PSZ)Database;}
PCOLDEF GetCols(void) {return To_Cols;} PCOLDEF GetCols(void) {return To_Cols;}
PHC GetHandler(void) {return Hc;}
void SetCols(PCOLDEF pcd) {To_Cols = pcd;} void SetCols(PCOLDEF pcd) {To_Cols = pcd;}
PCATLG GetCat(void) {return Cat;} PCATLG GetCat(void) {return Cat;}
virtual const char *GetType(void) = 0; virtual const char *GetType(void) = 0;
@@ -45,7 +46,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
int GetSizeCatInfo(PSZ what, PSZ sdef); int GetSizeCatInfo(PSZ what, PSZ sdef);
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size); int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef); char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
virtual bool Indexable(void) {return false;} virtual int Indexable(void) {return 0;}
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0; virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0;
virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0; virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0;

View File

@@ -1,253 +1,253 @@
/*************** TabDos H Declares Source Code File (.H) ***************/ /*************** TabDos H Declares Source Code File (.H) ***************/
/* Name: TABDOS.H Version 3.3 */ /* Name: TABDOS.H Version 3.3 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 1999-2014 */ /* (C) Copyright to the author Olivier BERTRAND 1999-2014 */
/* */ /* */
/* This file contains the DOS classes declares. */ /* This file contains the DOS classes declares. */
/***********************************************************************/ /***********************************************************************/
#ifndef __TABDOS_H #ifndef __TABDOS_H
#define __TABDOS_H #define __TABDOS_H
#include "xtable.h" // Table base class declares #include "xtable.h" // Table base class declares
#include "colblk.h" // Column base class declares #include "colblk.h" // Column base class declares
#include "xindex.h" #include "xindex.h"
#include "filter.h" #include "filter.h"
//pedef struct _tabdesc *PTABD; // For friend setting //pedef struct _tabdesc *PTABD; // For friend setting
typedef class TXTFAM *PTXF; typedef class TXTFAM *PTXF;
typedef class BLOCKFILTER *PBF; typedef class BLOCKFILTER *PBF;
typedef class BLOCKINDEX *PBX; typedef class BLOCKINDEX *PBX;
/***********************************************************************/ /***********************************************************************/
/* DOS table. */ /* DOS table. */
/***********************************************************************/ /***********************************************************************/
class DllExport DOSDEF : public TABDEF { /* Logical table description */ class DllExport DOSDEF : public TABDEF { /* Logical table description */
friend class OEMDEF; friend class OEMDEF;
friend class TDBDOS; friend class TDBDOS;
friend class TDBFIX; friend class TDBFIX;
friend class TXTFAM; friend class TXTFAM;
friend class DBFBASE; friend class DBFBASE;
public: public:
// Constructor // Constructor
DOSDEF(void); DOSDEF(void);
// Implementation // Implementation
virtual AMT GetDefType(void) {return TYPE_AM_DOS;} virtual AMT GetDefType(void) {return TYPE_AM_DOS;}
virtual const char *GetType(void) {return "DOS";} virtual const char *GetType(void) {return "DOS";}
virtual PIXDEF GetIndx(void) {return To_Indx;} virtual PIXDEF GetIndx(void) {return To_Indx;}
virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;} virtual void SetIndx(PIXDEF xdp) {To_Indx = xdp;}
virtual bool IsHuge(void) {return Huge;} virtual bool IsHuge(void) {return Huge;}
PSZ GetFn(void) {return Fn;} PSZ GetFn(void) {return Fn;}
PSZ GetOfn(void) {return Ofn;} PSZ GetOfn(void) {return Ofn;}
void SetBlock(int block) {Block = block;} void SetBlock(int block) {Block = block;}
int GetBlock(void) {return Block;} int GetBlock(void) {return Block;}
int GetLast(void) {return Last;} int GetLast(void) {return Last;}
void SetLast(int last) {Last = last;} void SetLast(int last) {Last = last;}
int GetLrecl(void) {return Lrecl;} int GetLrecl(void) {return Lrecl;}
void SetLrecl(int lrecl) {Lrecl = lrecl;} void SetLrecl(int lrecl) {Lrecl = lrecl;}
bool GetPadded(void) {return Padded;} bool GetPadded(void) {return Padded;}
bool GetEof(void) {return Eof;} bool GetEof(void) {return Eof;}
int GetBlksize(void) {return Blksize;} int GetBlksize(void) {return Blksize;}
int GetEnding(void) {return Ending;} int GetEnding(void) {return Ending;}
bool IsOptimized(void) {return (Optimized == 1);} bool IsOptimized(void) {return (Optimized == 1);}
void SetOptimized(int opt) {Optimized = opt;} void SetOptimized(int opt) {Optimized = opt;}
void SetAllocBlks(int blks) {AllocBlks = blks;} void SetAllocBlks(int blks) {AllocBlks = blks;}
int GetAllocBlks(void) {return AllocBlks;} int GetAllocBlks(void) {return AllocBlks;}
int *GetTo_Pos(void) {return To_Pos;} int *GetTo_Pos(void) {return To_Pos;}
// Methods // Methods
virtual bool Indexable(void) {return Compressed != 1;} virtual int Indexable(void) {return (Compressed != 1) ? 1 : 0;}
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf); virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode); virtual PTDB GetTable(PGLOBAL g, MODE mode);
bool InvalidateIndex(PGLOBAL g); bool InvalidateIndex(PGLOBAL g);
bool GetOptFileName(PGLOBAL g, char *filename); bool GetOptFileName(PGLOBAL g, char *filename);
void RemoveOptValues(PGLOBAL g); void RemoveOptValues(PGLOBAL g);
protected: protected:
//virtual bool Erase(char *filename); //virtual bool Erase(char *filename);
// Members // Members
PSZ Fn; /* Path/Name of corresponding file */ PSZ Fn; /* Path/Name of corresponding file */
PSZ Ofn; /* Base Path/Name of matching index files*/ PSZ Ofn; /* Base Path/Name of matching index files*/
PIXDEF To_Indx; /* To index definitions blocks */ PIXDEF To_Indx; /* To index definitions blocks */
RECFM Recfm; /* 0:VAR, 1:FIX, 2:BIN, 3:VCT, 6:DBF */ RECFM Recfm; /* 0:VAR, 1:FIX, 2:BIN, 3:VCT, 6:DBF */
bool Mapped; /* 0: disk file, 1: memory mapped file */ bool Mapped; /* 0: disk file, 1: memory mapped file */
bool Padded; /* true for padded table file */ bool Padded; /* true for padded table file */
bool Huge; /* true for files larger than 2GB */ bool Huge; /* true for files larger than 2GB */
bool Accept; /* true if wrong lines are accepted (DBF)*/ bool Accept; /* true if wrong lines are accepted (DBF)*/
bool Eof; /* true if an EOF (0xA) character exists */ bool Eof; /* true if an EOF (0xA) character exists */
int *To_Pos; /* To array of block starting positions */ int *To_Pos; /* To array of block starting positions */
int Optimized; /* 0: No, 1:Yes, 2:Redo optimization */ int Optimized; /* 0: No, 1:Yes, 2:Redo optimization */
int AllocBlks; /* Number of suballocated opt blocks */ int AllocBlks; /* Number of suballocated opt blocks */
int Compressed; /* 0: No, 1: gz, 2:zlib compressed file */ int Compressed; /* 0: No, 1: gz, 2:zlib compressed file */
int Lrecl; /* Size of biggest record */ int Lrecl; /* Size of biggest record */
int AvgLen; /* Average size of records */ int AvgLen; /* Average size of records */
int Block; /* Number de blocks of FIX/VCT tables */ int Block; /* Number de blocks of FIX/VCT tables */
int Last; /* Number of elements of last block */ int Last; /* Number of elements of last block */
int Blksize; /* Size of padded blocks */ int Blksize; /* Size of padded blocks */
int Maxerr; /* Maximum number of bad records (DBF) */ int Maxerr; /* Maximum number of bad records (DBF) */
int ReadMode; /* Specific to DBF */ int ReadMode; /* Specific to DBF */
int Ending; /* Length of end of lines */ int Ending; /* Length of end of lines */
}; // end of DOSDEF }; // end of DOSDEF
/***********************************************************************/ /***********************************************************************/
/* This is the DOS/UNIX Access Method class declaration for files */ /* This is the DOS/UNIX Access Method class declaration for files */
/* that are standard files with columns starting at fixed offset. */ /* that are standard files with columns starting at fixed offset. */
/* The last column (and record) is of variable length. */ /* The last column (and record) is of variable length. */
/***********************************************************************/ /***********************************************************************/
class DllExport TDBDOS : public TDBASE { class DllExport TDBDOS : public TDBASE {
friend class XINDEX; friend class XINDEX;
friend class DOSCOL; friend class DOSCOL;
friend class MAPCOL; friend class MAPCOL;
friend class TXTFAM; friend class TXTFAM;
friend class DOSFAM; friend class DOSFAM;
friend class VCTCOL; friend class VCTCOL;
friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool); friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool);
public: public:
// Constructors // Constructors
TDBDOS(PDOSDEF tdp, PTXF txfp); TDBDOS(PDOSDEF tdp, PTXF txfp);
TDBDOS(PGLOBAL g, PTDBDOS tdbp); TDBDOS(PGLOBAL g, PTDBDOS tdbp);
// Inline functions // Inline functions
inline void SetTxfp(PTXF txfp) {Txfp = txfp; Txfp->SetTdbp(this);} inline void SetTxfp(PTXF txfp) {Txfp = txfp; Txfp->SetTdbp(this);}
inline PTXF GetTxfp(void) {return Txfp;} inline PTXF GetTxfp(void) {return Txfp;}
inline char *GetLine(void) {return To_Line;} inline char *GetLine(void) {return To_Line;}
inline int GetCurBlk(void) {return Txfp->GetCurBlk();} inline int GetCurBlk(void) {return Txfp->GetCurBlk();}
inline void SetLine(char *toline) {To_Line = toline;} inline void SetLine(char *toline) {To_Line = toline;}
inline void IncLine(int inc) {To_Line += inc;} inline void IncLine(int inc) {To_Line += inc;}
inline bool IsRead(void) {return Txfp->IsRead;} inline bool IsRead(void) {return Txfp->IsRead;}
inline PXOB *GetLink(void) {return To_Link;} inline PXOB *GetLink(void) {return To_Link;}
// Implementation // Implementation
virtual AMT GetAmType(void) {return Txfp->GetAmType();} virtual AMT GetAmType(void) {return Txfp->GetAmType();}
virtual PSZ GetFile(PGLOBAL g) {return Txfp->To_File;} virtual PSZ GetFile(PGLOBAL g) {return Txfp->To_File;}
virtual void SetFile(PGLOBAL g, PSZ fn) {Txfp->To_File = fn;} virtual void SetFile(PGLOBAL g, PSZ fn) {Txfp->To_File = fn;}
virtual RECFM GetFtype(void) {return Ftype;} virtual RECFM GetFtype(void) {return Ftype;}
virtual bool SkipHeader(PGLOBAL g) {return false;} virtual bool SkipHeader(PGLOBAL g) {return false;}
virtual void RestoreNrec(void) {Txfp->SetNrec(1);} virtual void RestoreNrec(void) {Txfp->SetNrec(1);}
virtual PTDB Duplicate(PGLOBAL g) virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBDOS(g, this);} {return (PTDB)new(g) TDBDOS(g, this);}
// Methods // Methods
virtual PTDB CopyOne(PTABS t); virtual PTDB CopyOne(PTABS t);
virtual void ResetDB(void) {Txfp->Reset();} virtual void ResetDB(void) {Txfp->Reset();}
virtual bool IsUsingTemp(PGLOBAL g); virtual bool IsUsingTemp(PGLOBAL g);
virtual void ResetSize(void) {MaxSize = Cardinal = -1;} virtual void ResetSize(void) {MaxSize = Cardinal = -1;}
virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox); virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox);
virtual int MakeBlockValues(PGLOBAL g); virtual int MakeBlockValues(PGLOBAL g);
virtual bool SaveBlockValues(PGLOBAL g); virtual bool SaveBlockValues(PGLOBAL g);
virtual bool GetBlockValues(PGLOBAL g); virtual bool GetBlockValues(PGLOBAL g);
virtual PBF InitBlockFilter(PGLOBAL g, PFIL filp); virtual PBF InitBlockFilter(PGLOBAL g, PFIL filp);
//virtual PBX InitBlockIndex(PGLOBAL g); //virtual PBX InitBlockIndex(PGLOBAL g);
virtual int TestBlock(PGLOBAL g); virtual int TestBlock(PGLOBAL g);
virtual void PrintAM(FILE *f, char *m); virtual void PrintAM(FILE *f, char *m);
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual char *GetOpenMode(PGLOBAL g, char *opmode) {return NULL;} virtual char *GetOpenMode(PGLOBAL g, char *opmode) {return NULL;}
virtual int GetFileLength(PGLOBAL g) {return Txfp->GetFileLength(g);} virtual int GetFileLength(PGLOBAL g) {return Txfp->GetFileLength(g);}
virtual int GetProgMax(PGLOBAL g); virtual int GetProgMax(PGLOBAL g);
virtual int GetProgCur(void); virtual int GetProgCur(void);
virtual int GetAffectedRows(void) {return Txfp->GetDelRows();} virtual int GetAffectedRows(void) {return Txfp->GetDelRows();}
virtual int GetRecpos(void) {return Txfp->GetPos();} virtual int GetRecpos(void) {return Txfp->GetPos();}
virtual bool SetRecpos(PGLOBAL g, int recpos) virtual bool SetRecpos(PGLOBAL g, int recpos)
{return Txfp->SetPos(g, recpos);} {return Txfp->SetPos(g, recpos);}
virtual int RowNumber(PGLOBAL g, bool b = false); virtual int RowNumber(PGLOBAL g, bool b = false);
virtual int Cardinality(PGLOBAL g); virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc); virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g) {return Txfp->ReadBuffer(g);} virtual int ReadBuffer(PGLOBAL g) {return Txfp->ReadBuffer(g);}
// Specific routine // Specific routine
virtual int EstimatedLength(PGLOBAL g); virtual int EstimatedLength(PGLOBAL g);
// Optimization routines // Optimization routines
int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add); virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
void ResetBlockFilter(PGLOBAL g); void ResetBlockFilter(PGLOBAL g);
bool GetDistinctColumnValues(PGLOBAL g, int nrec); bool GetDistinctColumnValues(PGLOBAL g, int nrec);
protected: protected:
PBF CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv); PBF CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv);
// Members // Members
PTXF Txfp; // To the File access method class PTXF Txfp; // To the File access method class
//PBX To_BlkIdx; // To index test block //PBX To_BlkIdx; // To index test block
PBF To_BlkFil; // To evaluation block filter PBF To_BlkFil; // To evaluation block filter
PFIL SavFil; // Saved hidden filter PFIL SavFil; // Saved hidden filter
char *To_Line; // Points to current processed line char *To_Line; // Points to current processed line
int Cardinal; // Table Cardinality int Cardinal; // Table Cardinality
RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT) RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT)
int Lrecl; // Logical Record Length int Lrecl; // Logical Record Length
int AvgLen; // Logical Record Average Length int AvgLen; // Logical Record Average Length
//int Xeval; // BlockTest return value //int Xeval; // BlockTest return value
int Beval; // BlockEval return value int Beval; // BlockEval return value
}; // end of class TDBDOS }; // end of class TDBDOS
/***********************************************************************/ /***********************************************************************/
/* Class DOSCOL: DOS access method column descriptor. */ /* Class DOSCOL: DOS access method column descriptor. */
/* This A.M. is used for text file tables under operating systems */ /* This A.M. is used for text file tables under operating systems */
/* DOS, OS2, UNIX, WIN16 and WIN32. */ /* DOS, OS2, UNIX, WIN16 and WIN32. */
/***********************************************************************/ /***********************************************************************/
class DllExport DOSCOL : public COLBLK { class DllExport DOSCOL : public COLBLK {
friend class TDBDOS; friend class TDBDOS;
friend class TDBFIX; friend class TDBFIX;
public: public:
// Constructors // Constructors
DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am = "DOS"); DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am = "DOS");
DOSCOL(DOSCOL *colp, PTDB tdbp); // Constructor used in copy process DOSCOL(DOSCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation // Implementation
virtual int GetAmType(void) {return TYPE_AM_DOS;} virtual int GetAmType(void) {return TYPE_AM_DOS;}
virtual void SetTo_Val(PVAL valp) {To_Val = valp;} virtual void SetTo_Val(PVAL valp) {To_Val = valp;}
virtual int GetClustered(void) {return Clustered;} virtual int GetClustered(void) {return Clustered;}
virtual int IsClustered(void) {return (Clustered && virtual int IsClustered(void) {return (Clustered &&
((PDOSDEF)(((PTDBDOS)To_Tdb)->To_Def))->IsOptimized());} ((PDOSDEF)(((PTDBDOS)To_Tdb)->To_Def))->IsOptimized());}
virtual int IsSorted(void) {return Sorted;} virtual int IsSorted(void) {return Sorted;}
virtual PVBLK GetMin(void) {return Min;} virtual PVBLK GetMin(void) {return Min;}
virtual PVBLK GetMax(void) {return Max;} virtual PVBLK GetMax(void) {return Max;}
virtual int GetNdv(void) {return Ndv;} virtual int GetNdv(void) {return Ndv;}
virtual int GetNbm(void) {return Nbm;} virtual int GetNbm(void) {return Nbm;}
virtual PVBLK GetBmap(void) {return Bmap;} virtual PVBLK GetBmap(void) {return Bmap;}
virtual PVBLK GetDval(void) {return Dval;} virtual PVBLK GetDval(void) {return Dval;}
// Methods // Methods
virtual bool VarSize(void); virtual bool VarSize(void);
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL g); virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g); virtual void WriteColumn(PGLOBAL g);
virtual void Print(PGLOBAL g, FILE *, uint); virtual void Print(PGLOBAL g, FILE *, uint);
protected: protected:
virtual bool SetMinMax(PGLOBAL g); virtual bool SetMinMax(PGLOBAL g);
virtual bool SetBitMap(PGLOBAL g); virtual bool SetBitMap(PGLOBAL g);
bool CheckSorted(PGLOBAL g); bool CheckSorted(PGLOBAL g);
bool AddDistinctValue(PGLOBAL g); bool AddDistinctValue(PGLOBAL g);
// Default constructor not to be used // Default constructor not to be used
DOSCOL(void) {} DOSCOL(void) {}
// Members // Members
PVBLK Min; // Array of block min values PVBLK Min; // Array of block min values
PVBLK Max; // Array of block max values PVBLK Max; // Array of block max values
PVBLK Bmap; // Array of block bitmap values PVBLK Bmap; // Array of block bitmap values
PVBLK Dval; // Array of column distinct values PVBLK Dval; // Array of column distinct values
PVAL To_Val; // To value used for Update/Insert PVAL To_Val; // To value used for Update/Insert
PVAL OldVal; // The previous value of the object. PVAL OldVal; // The previous value of the object.
char *Buf; // Buffer used in write operations char *Buf; // Buffer used in write operations
bool Ldz; // True if field contains leading zeros bool Ldz; // True if field contains leading zeros
bool Nod; // True if no decimal point bool Nod; // True if no decimal point
int Dcm; // Last Dcm digits are decimals int Dcm; // Last Dcm digits are decimals
int Deplac; // Offset in dos_buf int Deplac; // Offset in dos_buf
int Clustered; // 0:No 1:Yes int Clustered; // 0:No 1:Yes
int Sorted; // 0:No 1:Asc (2:Desc - NIY) int Sorted; // 0:No 1:Asc (2:Desc - NIY)
int Ndv; // Number of distinct values int Ndv; // Number of distinct values
int Nbm; // Number of uint in bitmap int Nbm; // Number of uint in bitmap
}; // end of class DOSCOL }; // end of class DOSCOL
#endif // __TABDOS_H #endif // __TABDOS_H

View File

@@ -61,6 +61,7 @@
#include "tabmysql.h" #include "tabmysql.h"
#include "valblk.h" #include "valblk.h"
#include "tabutil.h" #include "tabutil.h"
#include "ha_connect.h"
#if defined(_CONSOLE) #if defined(_CONSOLE)
void PrintResult(PGLOBAL, PSEM, PQRYRES); void PrintResult(PGLOBAL, PSEM, PQRYRES);
@@ -481,16 +482,16 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* Note: when implementing EOM filtering, column only used in local */ /* Note: when implementing EOM filtering, column only used in local */
/* filter should be removed from column list. */ /* filter should be removed from column list. */
/***********************************************************************/ /***********************************************************************/
bool TDBMYSQL::MakeSelect(PGLOBAL g) bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
{ {
char *tk = "`"; char *tk = "`";
int rank = 0; int len = 0, rank = 0;
bool b = FALSE; bool b = false;
PCOL colp; PCOL colp;
//PDBUSER dup = PlgGetUser(g); //PDBUSER dup = PlgGetUser(g);
if (Query) if (Query)
return FALSE; // already done return false; // already done
if (Srcdef) { if (Srcdef) {
Query = Srcdef; Query = Srcdef;
@@ -506,12 +507,12 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
if (!colp->IsSpecial()) { if (!colp->IsSpecial()) {
// if (colp->IsSpecial()) { // if (colp->IsSpecial()) {
// strcpy(g->Message, MSG(NO_SPEC_COL)); // strcpy(g->Message, MSG(NO_SPEC_COL));
// return TRUE; // return true;
// } else { // } else {
if (b) if (b)
strcat(Query, ", "); strcat(Query, ", ");
else else
b = TRUE; b = true;
strcat(strcat(strcat(Query, tk), colp->GetName()), tk); strcat(strcat(strcat(Query, tk), colp->GetName()), tk);
((PMYCOL)colp)->Rank = rank++; ((PMYCOL)colp)->Rank = rank++;
@@ -526,16 +527,24 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
} // endif ncol } // endif ncol
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk); strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
len = strlen(Query);
if (To_CondFil) if (To_CondFil) {
strcat(strcat(Query, " WHERE "), To_CondFil->Body); if (!mx) {
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
len = strlen(Query) + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
} else
len += (mx ? 256 : 1);
if (trace) if (trace)
htrc("Query=%s\n", Query); htrc("Query=%s\n", Query);
// Now we know how much to suballocate // Now we know how much to suballocate
PlugSubAlloc(g, NULL, strlen(Query) + 1); PlugSubAlloc(g, NULL, len);
return FALSE; return false;
} // end of MakeSelect } // end of MakeSelect
/***********************************************************************/ /***********************************************************************/
@@ -833,9 +842,9 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* Allocate whatever is used for getting results. */ /* Allocate whatever is used for getting results. */
/*********************************************************************/ /*********************************************************************/
if (Mode == MODE_READ) { if (Mode == MODE_READ || Mode == MODE_READX) {
if (!MakeSelect(g)) MakeSelect(g, Mode == MODE_READX);
m_Rc = Myc.ExecSQL(g, Query); m_Rc = (Mode == MODE_READ) ? Myc.ExecSQL(g, Query) : RC_OK;
#if 0 #if 0
if (!Myc.m_Res || !Myc.m_Fields) { if (!Myc.m_Res || !Myc.m_Fields) {
@@ -994,6 +1003,36 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
} // end of SendCommand } // end of SendCommand
/***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{
int oldlen = strlen(Query);
bool rc;
if (op == OP_NEXT)
return false;
else if (op == OP_FIRST) {
if (To_CondFil)
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
} else {
if (Myc.m_Res)
Myc.FreeResult();
rc = To_Def->GetHandler()->MakeKeyWhere(g, Query, op, "`", key, len);
if (To_CondFil)
strcat(strcat(strcat(Query, " AND ("), To_CondFil->Body), ")");
} // endif's op
m_Rc = Myc.ExecSQL(g, Query);
Query[oldlen] = 0;
return false;
} // end of ReadKey
/***********************************************************************/ /***********************************************************************/
/* Data Base read routine for MYSQL access method. */ /* Data Base read routine for MYSQL access method. */
/***********************************************************************/ /***********************************************************************/
@@ -1452,7 +1491,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ) { if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables"); strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables");
return true; return true;
} // endif Mode } // endif Mode

View File

@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
inline int GetPortnumber(void) {return Portnumber;} inline int GetPortnumber(void) {return Portnumber;}
// Methods // Methods
virtual int Indexable(void) {return 2;}
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m); virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url, bool b = true); bool ParseURL(PGLOBAL g, char *url, bool b = true);
@@ -96,6 +97,7 @@ class TDBMYSQL : public TDBASE {
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc); virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len);
// Specific routines // Specific routines
bool SetColumnRanks(PGLOBAL g); bool SetColumnRanks(PGLOBAL g);
@@ -104,7 +106,7 @@ class TDBMYSQL : public TDBASE {
protected: protected:
// Internal functions // Internal functions
bool MakeSelect(PGLOBAL g); bool MakeSelect(PGLOBAL g, bool mx);
bool MakeInsert(PGLOBAL g); bool MakeInsert(PGLOBAL g);
int BindColumns(PGLOBAL g); int BindColumns(PGLOBAL g);
int MakeCommand(PGLOBAL g); int MakeCommand(PGLOBAL g);

View File

@@ -752,7 +752,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* Make the command and allocate whatever is used for getting results. */ /* Make the command and allocate whatever is used for getting results. */
/*********************************************************************/ /*********************************************************************/
if (Mode == MODE_READ) { if (Mode == MODE_READ || Mode == MODE_READX) {
if ((Query = MakeSQL(g, false))) { if ((Query = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp; for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext()) colp = (PODBCCOL)colp->GetNext())
@@ -1315,7 +1315,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ) { if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables"); strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
return true; return true;
} // endif Mode } // endif Mode

View File

@@ -90,6 +90,7 @@ class TDBODBC : public TDBASE {
virtual void ResetSize(void); virtual void ResetSize(void);
virtual int GetAffectedRows(void) {return AftRows;} virtual int GetAffectedRows(void) {return AftRows;}
virtual PSZ GetServer(void) {return "ODBC";} virtual PSZ GetServer(void) {return "ODBC";}
virtual int Indexable(void) {return 2;}
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
@@ -100,6 +101,8 @@ class TDBODBC : public TDBASE {
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc); virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{return true;}
protected: protected:
// Internal functions // Internal functions

View File

@@ -79,7 +79,7 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
{ {
int rc; int rc;
PTABLE tablep; PTABLE tablep;
PTDBDOS tdbp; PTDBASE tdbp;
PCATLG cat = PlgGetCatalog(g, true); PCATLG cat = PlgGetCatalog(g, true);
/*********************************************************************/ /*********************************************************************/
@@ -87,13 +87,13 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
/*********************************************************************/ /*********************************************************************/
tablep = new(g) XTAB(name); tablep = new(g) XTAB(name);
if (!(tdbp = (PTDBDOS)cat->GetTable(g, tablep))) if (!(tdbp = (PTDBASE)cat->GetTable(g, tablep)))
rc = RC_NF; rc = RC_NF;
else if (!tdbp->GetDef()->Indexable()) { else if (!tdbp->GetDef()->Indexable()) {
sprintf(g->Message, MSG(TABLE_NO_INDEX), name); sprintf(g->Message, MSG(TABLE_NO_INDEX), name);
rc = RC_NF; rc = RC_NF;
} else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO) } else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO)
rc = RC_OK; // No index rc = RC_OK; // No or remote index
return rc; return rc;
} // end of PlgMakeIndex } // end of PlgMakeIndex

View File

@@ -1,259 +1,264 @@
/**************** Table H Declares Source Code File (.H) ***************/ /**************** Table H Declares Source Code File (.H) ***************/
/* Name: TABLE.H Version 2.3 */ /* Name: TABLE.H Version 2.3 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 1999-2014 */ /* (C) Copyright to the author Olivier BERTRAND 1999-2014 */
/* */ /* */
/* This file contains the TBX, OPJOIN and TDB class definitions. */ /* This file contains the TBX, OPJOIN and TDB class definitions. */
/***********************************************************************/ /***********************************************************************/
#if !defined(TABLE_DEFINED) #if !defined(TABLE_DEFINED)
#define TABLE_DEFINED #define TABLE_DEFINED
/***********************************************************************/ /***********************************************************************/
/* Include required application header files */ /* Include required application header files */
/* block.h is header containing Block global declarations. */ /* block.h is header containing Block global declarations. */
/***********************************************************************/ /***********************************************************************/
#include "assert.h" #include "assert.h"
#include "block.h" #include "block.h"
#include "colblk.h" #include "colblk.h"
#include "m_ctype.h" #include "m_ctype.h"
typedef class CMD *PCMD; typedef class CMD *PCMD;
// Commands executed by XDBC and MYX tables // Commands executed by XDBC and MYX tables
class CMD : public BLOCK { class CMD : public BLOCK {
public: public:
// Constructor // Constructor
CMD(PGLOBAL g, char *cmd) { CMD(PGLOBAL g, char *cmd) {
Cmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1); Cmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
strcpy(Cmd, cmd); Next = NULL; } strcpy(Cmd, cmd); Next = NULL; }
// Members // Members
PCMD Next; PCMD Next;
char *Cmd; char *Cmd;
}; // end of class CMD }; // end of class CMD
// Condition filter structure // Condition filter structure
typedef struct _cond_filter { typedef struct _cond_filter {
char *Body; char *Body;
OPVAL Op; OPVAL Op;
PCMD Cmds; PCMD Cmds;
} CONDFIL, *PCFIL; } CONDFIL, *PCFIL;
typedef class TDBCAT *PTDBCAT; typedef class TDBCAT *PTDBCAT;
typedef class CATCOL *PCATCOL; typedef class CATCOL *PCATCOL;
/***********************************************************************/ /***********************************************************************/
/* Definition of class TDB with all its method functions. */ /* Definition of class TDB with all its method functions. */
/***********************************************************************/ /***********************************************************************/
class DllExport TDB: public BLOCK { // Table Descriptor Block. class DllExport TDB: public BLOCK { // Table Descriptor Block.
public: public:
// Constructors // Constructors
TDB(PTABDEF tdp = NULL); TDB(PTABDEF tdp = NULL);
TDB(PTDB tdbp); TDB(PTDB tdbp);
// Implementation // Implementation
static void SetTnum(int n) {Tnum = n;} static void SetTnum(int n) {Tnum = n;}
inline PTDB GetOrig(void) {return To_Orig;} inline PTDB GetOrig(void) {return To_Orig;}
inline TUSE GetUse(void) {return Use;} inline TUSE GetUse(void) {return Use;}
inline PCFIL GetCondFil(void) {return To_CondFil;} inline PCFIL GetCondFil(void) {return To_CondFil;}
inline LPCSTR GetName(void) {return Name;} inline LPCSTR GetName(void) {return Name;}
inline PTABLE GetTable(void) {return To_Table;} inline PTABLE GetTable(void) {return To_Table;}
inline PCOL GetColumns(void) {return Columns;} inline PCOL GetColumns(void) {return Columns;}
inline int GetDegree(void) {return Degree;} inline int GetDegree(void) {return Degree;}
inline MODE GetMode(void) {return Mode;} inline MODE GetMode(void) {return Mode;}
inline PFIL GetFilter(void) {return To_Filter;} inline PFIL GetFilter(void) {return To_Filter;}
inline void SetFilter(PFIL fp) {To_Filter = fp;} inline void SetFilter(PFIL fp) {To_Filter = fp;}
inline void SetOrig(PTDB txp) {To_Orig = txp;} inline void SetOrig(PTDB txp) {To_Orig = txp;}
inline void SetUse(TUSE n) {Use = n;} inline void SetUse(TUSE n) {Use = n;}
inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;} inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;}
inline void SetNext(PTDB tdbp) {Next = tdbp;} inline void SetNext(PTDB tdbp) {Next = tdbp;}
inline void SetName(LPCSTR name) {Name = name;} inline void SetName(LPCSTR name) {Name = name;}
inline void SetTable(PTABLE tablep) {To_Table = tablep;} inline void SetTable(PTABLE tablep) {To_Table = tablep;}
inline void SetColumns(PCOL colp) {Columns = colp;} inline void SetColumns(PCOL colp) {Columns = colp;}
inline void SetDegree(int degree) {Degree = degree;} inline void SetDegree(int degree) {Degree = degree;}
inline void SetMode(MODE mode) {Mode = mode;} inline void SetMode(MODE mode) {Mode = mode;}
//Properties // Properties
virtual AMT GetAmType(void) {return TYPE_AM_ERROR;} virtual AMT GetAmType(void) {return TYPE_AM_ERROR;}
virtual int GetTdb_No(void) {return Tdb_No;} virtual int GetTdb_No(void) {return Tdb_No;}
virtual PTDB GetNext(void) {return Next;} virtual PTDB GetNext(void) {return Next;}
virtual PCATLG GetCat(void) {return NULL;} virtual PCATLG GetCat(void) {return NULL;}
// Methods // Methods
virtual bool IsSame(PTDB tp) {return tp == this;} virtual bool IsSame(PTDB tp) {return tp == this;}
virtual bool GetBlockValues(PGLOBAL g) {return false;} virtual bool GetBlockValues(PGLOBAL g) {return false;}
virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;} virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;}
virtual int GetMaxSize(PGLOBAL) = 0; virtual int GetMaxSize(PGLOBAL) = 0;
virtual int GetProgMax(PGLOBAL) = 0; virtual int GetProgMax(PGLOBAL) = 0;
virtual int GetProgCur(void) = 0; virtual int GetProgCur(void) = 0;
virtual int RowNumber(PGLOBAL g, bool b = false); virtual int RowNumber(PGLOBAL g, bool b = false);
virtual bool IsReadOnly(void) {return true;} virtual bool IsReadOnly(void) {return true;}
virtual const CHARSET_INFO *data_charset() {return NULL;} virtual const CHARSET_INFO *data_charset() {return NULL;}
virtual PTDB Duplicate(PGLOBAL g) {return NULL;} virtual PTDB Duplicate(PGLOBAL g) {return NULL;}
virtual PTDB CopyOne(PTABS t) {return this;} virtual PTDB CopyOne(PTABS t) {return this;}
virtual PTDB Copy(PTABS t); virtual PTDB Copy(PTABS t);
virtual void PrintAM(FILE *f, char *m) virtual void PrintAM(FILE *f, char *m)
{fprintf(f, "%s AM(%d)\n", m, GetAmType());} {fprintf(f, "%s AM(%d)\n", m, GetAmType());}
virtual void Print(PGLOBAL g, FILE *f, uint n); virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z); virtual void Print(PGLOBAL g, char *ps, uint z);
virtual PSZ GetServer(void) = 0; virtual PSZ GetServer(void) = 0;
virtual int GetBadLines(void) {return 0;} virtual int GetBadLines(void) {return 0;}
// Database pure virtual routines // Database pure virtual routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num) = 0; virtual PCOL ColDB(PGLOBAL g, PSZ name, int num) = 0;
virtual void MarkDB(PGLOBAL, PTDB) = 0; virtual void MarkDB(PGLOBAL, PTDB) = 0;
virtual bool OpenDB(PGLOBAL) = 0; virtual bool OpenDB(PGLOBAL) = 0;
virtual int ReadDB(PGLOBAL) = 0; virtual int ReadDB(PGLOBAL) = 0;
virtual int WriteDB(PGLOBAL) = 0; virtual int WriteDB(PGLOBAL) = 0;
virtual int DeleteDB(PGLOBAL, int) = 0; virtual int DeleteDB(PGLOBAL, int) = 0;
virtual void CloseDB(PGLOBAL) = 0; virtual void CloseDB(PGLOBAL) = 0;
virtual int CheckWrite(PGLOBAL g) {return 0;} virtual int CheckWrite(PGLOBAL g) {return 0;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) = 0;
protected:
// Members protected:
PTDB To_Orig; // Pointer to original if it is a copy // Members
TUSE Use; PTDB To_Orig; // Pointer to original if it is a copy
PFIL To_Filter; TUSE Use;
PCFIL To_CondFil; // To condition filter structure PFIL To_Filter;
static int Tnum; // Used to generate Tdb_no's PCFIL To_CondFil; // To condition filter structure
const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN static int Tnum; // Used to generate Tdb_no's
PTDB Next; // Next in linearized queries const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN
PTABLE To_Table; // Points to the XTAB object PTDB Next; // Next in linearized queries
LPCSTR Name; // Table name PTABLE To_Table; // Points to the XTAB object
PCOL Columns; // Points to the first column of the table LPCSTR Name; // Table name
MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete PCOL Columns; // Points to the first column of the table
int Degree; // Number of columns MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete
}; // end of class TDB int Degree; // Number of columns
}; // end of class TDB
/***********************************************************************/
/* This is the base class for all query tables (except decode). */ /***********************************************************************/
/***********************************************************************/ /* This is the base class for all query tables (except decode). */
class DllExport TDBASE : public TDB { /***********************************************************************/
friend class INDEXDEF; class DllExport TDBASE : public TDB {
friend class XINDEX; friend class INDEXDEF;
friend class XINDXS; friend class XINDEX;
public: friend class XINDXS;
// Constructor public:
TDBASE(PTABDEF tdp = NULL); // Constructor
TDBASE(PTDBASE tdbp); TDBASE(PTABDEF tdp = NULL);
TDBASE(PTDBASE tdbp);
// Implementation
inline int GetKnum(void) {return Knum;} // Implementation
inline PTABDEF GetDef(void) {return To_Def;} inline int GetKnum(void) {return Knum;}
inline PKXBASE GetKindex(void) {return To_Kindex;} inline PTABDEF GetDef(void) {return To_Def;}
inline PCOL GetSetCols(void) {return To_SetCols;} inline PKXBASE GetKindex(void) {return To_Kindex;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;} inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
// Properties
void SetKindex(PKXBASE kxp); // Properties
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;} void SetKindex(PKXBASE kxp);
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
// Methods
virtual bool IsUsingTemp(PGLOBAL g) {return false;} // Methods
virtual PCATLG GetCat(void); virtual bool IsUsingTemp(PGLOBAL g) {return false;}
virtual PSZ GetPath(void); virtual PCATLG GetCat(void);
virtual void PrintAM(FILE *f, char *m); virtual PSZ GetPath(void);
virtual RECFM GetFtype(void) {return RECFM_NAF;} virtual void PrintAM(FILE *f, char *m);
virtual int GetAffectedRows(void) {return -1;} virtual RECFM GetFtype(void) {return RECFM_NAF;}
virtual int GetRecpos(void) = 0; virtual int GetAffectedRows(void) {return -1;}
virtual bool SetRecpos(PGLOBAL g, int recpos); virtual int GetRecpos(void) = 0;
virtual bool IsReadOnly(void) {return Read_Only;} virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual bool IsView(void) {return FALSE;} virtual bool IsReadOnly(void) {return Read_Only;}
virtual CHARSET_INFO *data_charset(void); virtual bool IsView(void) {return FALSE;}
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);} virtual CHARSET_INFO *data_charset(void);
virtual int GetProgCur(void) {return GetRecpos();} virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
virtual PSZ GetFile(PGLOBAL g) {return "Not a file";} virtual int GetProgCur(void) {return GetRecpos();}
virtual int GetRemote(void) {return 0;} virtual PSZ GetFile(PGLOBAL g) {return "Not a file";}
virtual void SetFile(PGLOBAL g, PSZ fn) {} virtual int GetRemote(void) {return 0;}
virtual void ResetDB(void) {} virtual void SetFile(PGLOBAL g, PSZ fn) {}
virtual void ResetSize(void) {MaxSize = -1;} virtual void ResetDB(void) {}
virtual void RestoreNrec(void) {} virtual void ResetSize(void) {MaxSize = -1;}
virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox); virtual void RestoreNrec(void) {}
virtual PSZ GetServer(void) {return "Current";} virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox);
virtual PSZ GetServer(void) {return "Current";}
// Database routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num); // Database routines
virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int) virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
{assert(false); return NULL;} virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp); {assert(false); return NULL;}
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp); virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2); virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
protected: virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
// Members {strcpy(g->Message, "Remote index"); return RC_INFO;}
PTABDEF To_Def; // Points to catalog description block virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
PXOB *To_Link; // Points to column of previous relations {assert(false); return true;}
PCOL *To_Key_Col; // Points to key columns in current file
PKXBASE To_Kindex; // Points to table key index protected:
PCOL To_SetCols; // Points to updated columns // Members
int MaxSize; // Max size in number of lines PTABDEF To_Def; // Points to catalog description block
int Knum; // Size of key arrays PXOB *To_Link; // Points to column of previous relations
bool Read_Only; // True for read only tables PCOL *To_Key_Col; // Points to key columns in current file
const CHARSET_INFO *m_data_charset; PKXBASE To_Kindex; // Points to table key index
}; // end of class TDBASE PCOL To_SetCols; // Points to updated columns
int MaxSize; // Max size in number of lines
/***********************************************************************/ int Knum; // Size of key arrays
/* The abstract base class declaration for the catalog tables. */ bool Read_Only; // True for read only tables
/***********************************************************************/ const CHARSET_INFO *m_data_charset;
class DllExport TDBCAT : public TDBASE { }; // end of class TDBASE
friend class CATCOL;
public: /***********************************************************************/
// Constructor /* The abstract base class declaration for the catalog tables. */
TDBCAT(PTABDEF tdp); /***********************************************************************/
class DllExport TDBCAT : public TDBASE {
// Implementation friend class CATCOL;
virtual AMT GetAmType(void) {return TYPE_AM_CAT;} public:
// Constructor
// Methods TDBCAT(PTABDEF tdp);
virtual int GetRecpos(void) {return N;}
virtual int GetProgCur(void) {return N;} // Implementation
virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;} virtual AMT GetAmType(void) {return TYPE_AM_CAT;}
virtual bool SetRecpos(PGLOBAL g, int recpos);
// Methods
// Database routines virtual int GetRecpos(void) {return N;}
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual int GetProgCur(void) {return N;}
virtual int GetMaxSize(PGLOBAL g); virtual int RowNumber(PGLOBAL g, bool b = false) {return N + 1;}
virtual bool OpenDB(PGLOBAL g); virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g); // Database routines
virtual int DeleteDB(PGLOBAL g, int irc); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual void CloseDB(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
protected: virtual int ReadDB(PGLOBAL g);
// Specific routines virtual int WriteDB(PGLOBAL g);
virtual PQRYRES GetResult(PGLOBAL g) = 0; virtual int DeleteDB(PGLOBAL g, int irc);
bool Initialize(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
bool InitCol(PGLOBAL g);
protected:
// Members // Specific routines
PQRYRES Qrp; virtual PQRYRES GetResult(PGLOBAL g) = 0;
int N; // Row number bool Initialize(PGLOBAL g);
bool Init; bool InitCol(PGLOBAL g);
}; // end of class TDBCAT
// Members
/***********************************************************************/ PQRYRES Qrp;
/* Class CATCOL: ODBC info column. */ int N; // Row number
/***********************************************************************/ bool Init;
class DllExport CATCOL : public COLBLK { }; // end of class TDBCAT
friend class TDBCAT;
public: /***********************************************************************/
// Constructors /* Class CATCOL: ODBC info column. */
CATCOL(PCOLDEF cdp, PTDB tdbp, int n); /***********************************************************************/
class DllExport CATCOL : public COLBLK {
// Implementation friend class TDBCAT;
virtual int GetAmType(void) {return TYPE_AM_ODBC;} public:
// Constructors
// Methods CATCOL(PCOLDEF cdp, PTDB tdbp, int n);
virtual void ReadColumn(PGLOBAL g);
// Implementation
protected: virtual int GetAmType(void) {return TYPE_AM_ODBC;}
CATCOL(void) {} // Default constructor not to be used
// Methods
// Members virtual void ReadColumn(PGLOBAL g);
PTDBCAT Tdbp; // Points to ODBC table block
PCOLRES Crp; // The column data array protected:
int Flag; CATCOL(void) {} // Default constructor not to be used
}; // end of class CATCOL
// Members
#endif // TABLE_DEFINED PTDBCAT Tdbp; // Points to ODBC table block
PCOLRES Crp; // The column data array
int Flag;
}; // end of class CATCOL
#endif // TABLE_DEFINED