2013-05-05 12:45:26 +02:00
|
|
|
/************* Tabutil cpp Declares Source Code File (.CPP) ************/
|
2013-04-29 13:50:20 +02:00
|
|
|
/* Name: TABUTIL.CPP Version 1.0 */
|
|
|
|
/* */
|
|
|
|
/* (C) Copyright to the author Olivier BERTRAND 2013 */
|
|
|
|
/* */
|
2013-05-05 12:45:26 +02:00
|
|
|
/* Utility function used by the PROXY, XCOL, OCCUR, and TBL tables. */
|
2013-04-29 13:50:20 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* 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;
|
|
|
|
|
2013-04-30 16:16:32 +02:00
|
|
|
/************************************************************************/
|
|
|
|
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
|
|
|
|
/* table (PROXY, TBL, XCL, or OCCUR) when used by one of these. */
|
|
|
|
/************************************************************************/
|
|
|
|
void Remove_tshp(PCATLG cat)
|
|
|
|
{
|
|
|
|
((MYCAT*)cat)->GetHandler()->tshp = NULL;
|
|
|
|
} // end of Remove_thsp
|
|
|
|
|
2013-04-29 13:50:20 +02:00
|
|
|
/************************************************************************/
|
|
|
|
/* 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);
|
2013-06-03 14:43:47 +02:00
|
|
|
k = sprintf(key, "%s", db) + 1;
|
|
|
|
k += sprintf(key + k, "%s", name);
|
2013-04-29 13:50:20 +02:00
|
|
|
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;
|
|
|
|
|
2013-05-19 19:25:06 +02:00
|
|
|
if (!open_table_def(thd, s, GTS_TABLE | GTS_VIEW)) {
|
|
|
|
if (!s->is_view) {
|
|
|
|
if (stricmp(plugin_name(s->db_plugin)->str, "connect")) {
|
2013-04-29 13:50:20 +02:00
|
|
|
#if defined(MYSQL_SUPPORT)
|
2013-05-19 19:25:06 +02:00
|
|
|
mysql = true;
|
2013-04-29 13:50:20 +02:00
|
|
|
#else // !MYSQL_SUPPORT
|
2013-05-19 19:25:06 +02:00
|
|
|
sprintf(g->Message, "%s.%s is not a CONNECT table", db, name);
|
|
|
|
return NULL;
|
2013-04-29 13:50:20 +02:00
|
|
|
#endif // MYSQL_SUPPORT
|
2013-05-19 19:25:06 +02:00
|
|
|
} else
|
|
|
|
mysql = false;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
mysql = true;
|
|
|
|
} // endif is_view
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
} 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. */
|
|
|
|
/************************************************************************/
|
|
|
|
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
2013-05-24 00:19:26 +02:00
|
|
|
const char *name, bool& info)
|
2013-04-29 13:50:20 +02:00
|
|
|
{
|
2013-05-10 20:22:21 +02:00
|
|
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
2013-04-29 13:50:20 +02:00
|
|
|
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;
|
2013-05-10 20:22:21 +02:00
|
|
|
int i, n, ncol = sizeof(buftyp) / sizeof(int);
|
2013-04-29 13:50:20 +02:00
|
|
|
int len, type, prec;
|
|
|
|
bool mysql;
|
2013-07-08 19:03:15 +02:00
|
|
|
TABLE_SHARE *s = NULL;
|
2013-04-29 13:50:20 +02:00
|
|
|
Field* *field;
|
|
|
|
Field *fp;
|
|
|
|
PQRYRES qrp;
|
|
|
|
PCOLRES crp;
|
|
|
|
|
|
|
|
if (!info) {
|
2013-05-19 19:25:06 +02:00
|
|
|
if (!(s = GetTableShare(g, thd, db, name, mysql))) {
|
|
|
|
return NULL;
|
|
|
|
} else if (s->is_view) {
|
2013-05-24 00:19:26 +02:00
|
|
|
strcpy(g->Message, "Use MYSQL type to see columns from a view");
|
|
|
|
info = true; // To tell caller name is a view
|
|
|
|
free_table_share(s);
|
2013-04-29 13:50:20 +02:00
|
|
|
return NULL;
|
2013-05-19 19:25:06 +02:00
|
|
|
} else
|
2013-04-29 13:50:20 +02:00
|
|
|
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,
|
2013-05-10 20:22:21 +02:00
|
|
|
buftyp, fldtyp, length, true, true);
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
// 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. */
|
|
|
|
/**********************************************************************/
|
2013-07-08 19:03:15 +02:00
|
|
|
if (s)
|
|
|
|
free_table_share(s);
|
|
|
|
|
2013-04-29 13:50:20 +02:00
|
|
|
return qrp;
|
|
|
|
} // end of TabColumns
|
|
|
|
|
2013-05-02 16:33:15 +02:00
|
|
|
/* -------------- Implementation of the PROXY classes ---------------- */
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* 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)
|
|
|
|
{
|
2013-05-19 19:25:06 +02:00
|
|
|
char *pn, *db, *tab, *def = NULL;
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
db = Cat->GetStringCatInfo(g, "Dbname", "*");
|
2013-05-19 19:25:06 +02:00
|
|
|
def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
2013-05-05 12:45:26 +02:00
|
|
|
|
|
|
|
if (!(tab = Cat->GetStringCatInfo(g, "Tabname", NULL))) {
|
2013-05-19 19:25:06 +02:00
|
|
|
if (!def) {
|
|
|
|
strcpy(g->Message, "Missing object table definition");
|
|
|
|
return TRUE;
|
|
|
|
} else
|
|
|
|
tab = "Noname";
|
|
|
|
|
|
|
|
} else
|
|
|
|
// 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, def);
|
2013-04-29 13:50:20 +02:00
|
|
|
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. */
|
|
|
|
/***********************************************************************/
|
2013-05-19 19:25:06 +02:00
|
|
|
PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
|
2013-04-29 13:50:20 +02:00
|
|
|
{
|
2013-07-08 19:03:15 +02:00
|
|
|
const char *sp = NULL;
|
2013-04-29 13:50:20 +02:00
|
|
|
char *db, *name;
|
2013-05-19 19:25:06 +02:00
|
|
|
bool mysql = true;
|
2013-04-29 13:50:20 +02:00
|
|
|
PTDB tdbp = NULL;
|
2013-05-19 19:25:06 +02:00
|
|
|
TABLE_SHARE *s = NULL;
|
2013-07-08 19:03:15 +02:00
|
|
|
Field* *fp = NULL;
|
2013-04-29 13:50:20 +02:00
|
|
|
PCATLG cat = To_Def->GetCat();
|
|
|
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
2013-05-02 16:33:15 +02:00
|
|
|
LPCSTR cdb, curdb = hc->GetDBName(NULL);
|
2013-04-29 13:50:20 +02:00
|
|
|
THD *thd = (hc->GetTable())->in_use;
|
|
|
|
|
|
|
|
db = (char*)tabp->GetQualifier();
|
|
|
|
name = (char*)tabp->GetName();
|
|
|
|
|
2013-05-02 16:33:15 +02:00
|
|
|
// Check for eventual loop
|
|
|
|
for (PTABLE tp = To_Table; tp; tp = tp->Next) {
|
|
|
|
cdb = (tp->Qualifier) ? tp->Qualifier : curdb;
|
|
|
|
|
|
|
|
if (!stricmp(name, tp->Name) && !stricmp(db, cdb)) {
|
|
|
|
sprintf(g->Message, "Table %s.%s pointing on itself", db, name);
|
|
|
|
return NULL;
|
|
|
|
} // endif
|
|
|
|
|
|
|
|
} // endfor tp
|
|
|
|
|
2013-05-19 19:25:06 +02:00
|
|
|
if (!tabp->GetSrc()) {
|
|
|
|
if (!(s = GetTableShare(g, thd, db, name, mysql)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (s->is_view && !b)
|
|
|
|
s->field = hc->get_table()->s->field;
|
2013-04-29 13:50:20 +02:00
|
|
|
|
2013-05-19 19:25:06 +02:00
|
|
|
hc->tshp = s;
|
|
|
|
} else if (b) {
|
|
|
|
// Don't use caller's columns
|
|
|
|
fp = hc->get_table()->field;
|
|
|
|
hc->get_table()->field = NULL;
|
2013-05-20 13:12:34 +02:00
|
|
|
|
|
|
|
// Make caller use the source definition
|
|
|
|
sp = hc->get_table()->s->option_struct->srcdef;
|
2013-05-19 19:25:06 +02:00
|
|
|
hc->get_table()->s->option_struct->srcdef = tabp->GetSrc();
|
|
|
|
} // endif srcdef
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
if (mysql) {
|
|
|
|
#if defined(MYSQL_SUPPORT)
|
|
|
|
// Access sub-table via MySQL API
|
2013-04-30 16:16:32 +02:00
|
|
|
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYPRX"))) {
|
2013-04-29 13:50:20 +02:00
|
|
|
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
|
2013-05-02 16:33:15 +02:00
|
|
|
} else {
|
2013-04-29 13:50:20 +02:00
|
|
|
// Sub-table is a CONNECT table
|
2013-05-02 16:33:15 +02:00
|
|
|
tabp->Next = To_Table; // For loop checking
|
2013-04-29 13:50:20 +02:00
|
|
|
tdbp = cat->GetTable(g, tabp);
|
2013-05-02 16:33:15 +02:00
|
|
|
} // endif mysql
|
2013-04-29 13:50:20 +02:00
|
|
|
|
2013-05-19 19:25:06 +02:00
|
|
|
if (s) {
|
|
|
|
if (s->is_view && !b)
|
|
|
|
s->field = NULL;
|
|
|
|
|
|
|
|
hc->tshp = NULL;
|
2013-05-20 13:12:34 +02:00
|
|
|
} else if (b) {
|
|
|
|
// Restore s structure that can be in cache
|
2013-05-19 19:25:06 +02:00
|
|
|
hc->get_table()->field = fp;
|
2013-05-20 13:12:34 +02:00
|
|
|
hc->get_table()->s->option_struct->srcdef = sp;
|
|
|
|
} // endif s
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
if (trace && tdbp)
|
|
|
|
htrc("Subtable %s in %s\n",
|
|
|
|
name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
|
|
|
|
|
|
|
err:
|
2013-05-19 19:25:06 +02:00
|
|
|
if (s)
|
|
|
|
free_table_share(s);
|
|
|
|
|
|
|
|
return (PTDBASE)tdbp;
|
2013-04-29 13:50:20 +02:00
|
|
|
} // end of GetSubTable
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Initializes the table. */
|
|
|
|
/***********************************************************************/
|
|
|
|
bool TDBPRX::InitTable(PGLOBAL g)
|
|
|
|
{
|
|
|
|
if (!Tdbp) {
|
|
|
|
// Get the table description block of this table
|
2013-05-19 19:25:06 +02:00
|
|
|
if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
|
2013-04-29 13:50:20 +02:00
|
|
|
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))
|
2013-05-13 14:48:03 +02:00
|
|
|
return 0;
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
/***********************************************************************/
|
2013-05-05 12:45:26 +02:00
|
|
|
/* PROXY Access Method opening routine. */
|
2013-04-29 13:50:20 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
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))
|
2013-05-02 16:33:15 +02:00
|
|
|
return TRUE;
|
2013-04-29 13:50:20 +02:00
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
/* 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
|
|
|
|
|
|
|
|
/***********************************************************************/
|
2013-05-05 12:45:26 +02:00
|
|
|
/* Data Base read routine for PROY access method. */
|
2013-04-29 13:50:20 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
int TDBPRX::ReadDB(PGLOBAL g)
|
|
|
|
{
|
|
|
|
/*********************************************************************/
|
|
|
|
/* Now start the reading process. */
|
|
|
|
/*********************************************************************/
|
|
|
|
return Tdbp->ReadDB(g);
|
|
|
|
} // end of ReadDB
|
|
|
|
|
|
|
|
/***********************************************************************/
|
2013-05-05 12:45:26 +02:00
|
|
|
/* WriteDB: Data Base write routine for PROXY access methods. */
|
2013-04-29 13:50:20 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
int TDBPRX::WriteDB(PGLOBAL g)
|
|
|
|
{
|
|
|
|
sprintf(g->Message, "%s tables are read only", To_Def->GetType());
|
|
|
|
return RC_FX;
|
|
|
|
} // end of WriteDB
|
|
|
|
|
|
|
|
/***********************************************************************/
|
2013-05-05 12:45:26 +02:00
|
|
|
/* Data Base delete line routine for PROXY access methods. */
|
2013-04-29 13:50:20 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
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
|
|
|
|
|
2013-05-02 16:33:15 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
/* Used by the TBL tables. */
|
|
|
|
/***********************************************************************/
|
|
|
|
void TDBPRX::RemoveNext(PTABLE tp)
|
|
|
|
{
|
|
|
|
tp->Next = NULL;
|
|
|
|
} // end of RemoveNext
|
|
|
|
|
2013-04-29 13:50:20 +02:00
|
|
|
/* ---------------------------- PRXCOL ------------------------------- */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* PRXCOL public constructor. */
|
|
|
|
/***********************************************************************/
|
|
|
|
PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
2013-05-05 12:45:26 +02:00
|
|
|
: COLBLK(cdp, tdbp, i)
|
2013-04-29 13:50:20 +02:00
|
|
|
{
|
|
|
|
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) {
|
2013-05-13 11:37:34 +02:00
|
|
|
// May not have been done elsewhere
|
|
|
|
Colp->InitValue(g);
|
2013-04-29 13:50:20 +02:00
|
|
|
To_Val = Colp->GetValue();
|
2013-05-13 11:37:34 +02:00
|
|
|
|
|
|
|
// this may be needed by some tables (which?)
|
|
|
|
Colp->SetColUse(ColUse);
|
2013-04-29 13:50:20 +02:00
|
|
|
} 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
|
|
|
|
|
|
|
|
/* ---------------------------TDBTBC class --------------------------- */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* TDBTBC class constructor. */
|
|
|
|
/***********************************************************************/
|
|
|
|
TDBTBC::TDBTBC(PPRXDEF tdp) : TDBCAT(tdp)
|
|
|
|
{
|
|
|
|
Db = (PSZ)tdp->Tablep->GetQualifier();
|
|
|
|
Tab = (PSZ)tdp->Tablep->GetName();
|
|
|
|
} // end of TDBTBC constructor
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* GetResult: Get the list the MYSQL table columns. */
|
|
|
|
/***********************************************************************/
|
|
|
|
PQRYRES TDBTBC::GetResult(PGLOBAL g)
|
|
|
|
{
|
2013-05-24 00:19:26 +02:00
|
|
|
bool b = false;
|
|
|
|
|
|
|
|
return TabColumns(g, current_thd, Db, Tab, b);
|
2013-04-29 13:50:20 +02:00
|
|
|
} // end of GetResult
|
|
|
|
|