mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Adding 3 new table types:
PROXY table base on another table. Used by several other types. XCOL proxy on a table having a colummn containing a list of values OCCUR proxy on a table having several columns containing the same type of values that can be put in a unique column and several rows. TBL Not new but now internally using the PROXY table class. - Fix 2 bugs in add_field: Change '=' to ' ' after the COMMENT keyword. Quote column names between '`' in the SQL string. - Update xml test result to the CONNECT version added: storage/connect/taboccur.cpp storage/connect/taboccur.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabxcl.cpp storage/connect/tabxcl.h modified: storage/connect/CMakeLists.txt storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mycat.cc storage/connect/myconn.cpp storage/connect/mysql-test/connect/r/xml.result storage/connect/plgdbsem.h storage/connect/tabmysql.cpp storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/valblk.cpp storage/connect/valblk.h
This commit is contained in:
@@ -25,12 +25,14 @@ filamap.cpp filamdbf.cpp filamfix.cpp filamtxt.cpp filamvct.cpp
|
|||||||
tabdos.cpp tabfix.cpp tabfmt.cpp tabmul.cpp tabsys.cpp tabvct.cpp
|
tabdos.cpp tabfix.cpp tabfmt.cpp tabmul.cpp tabsys.cpp tabvct.cpp
|
||||||
valblk.cpp value.cpp xindex.cpp xobject.cpp
|
valblk.cpp value.cpp xindex.cpp xobject.cpp
|
||||||
filamzip.cpp tabtbl.cpp myutil.cpp
|
filamzip.cpp tabtbl.cpp myutil.cpp
|
||||||
|
tabutil.cpp tabxcl.cpp taboccur.cpp
|
||||||
block.h catalog.h checklvl.h colblk.h connect.h csort.h engmsg.h
|
block.h catalog.h checklvl.h colblk.h connect.h csort.h engmsg.h
|
||||||
filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h
|
filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h
|
||||||
global.h ha_connect.h maputil.h msgid.h mycat.h myutil.h os.h
|
global.h ha_connect.h maputil.h msgid.h mycat.h myutil.h os.h
|
||||||
osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h resource.h tabcol.h
|
osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h resource.h tabcol.h
|
||||||
tabdos.h tabfix.h tabfmt.h tabmul.h tabsys.h tabtbl.h tabvct.h
|
tabdos.h tabfix.h tabfmt.h tabmul.h tabsys.h tabtbl.h tabvct.h
|
||||||
user_connect.h valblk.h value.h xindex.h xobject.h xtable.h)
|
user_connect.h valblk.h value.h xindex.h xobject.h xtable.h
|
||||||
|
tabutil.h tabxcl.h taboccur.h)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Definitions that are shared for all OSes
|
# Definitions that are shared for all OSes
|
||||||
|
@@ -122,6 +122,7 @@
|
|||||||
#include "tabmysql.h"
|
#include "tabmysql.h"
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
#include "filamdbf.h"
|
#include "filamdbf.h"
|
||||||
|
#include "tabxcl.h"
|
||||||
#include "tabfmt.h"
|
#include "tabfmt.h"
|
||||||
#include "reldef.h"
|
#include "reldef.h"
|
||||||
#include "tabcol.h"
|
#include "tabcol.h"
|
||||||
@@ -156,7 +157,7 @@ extern "C" char nmfile[];
|
|||||||
extern "C" char pdebug[];
|
extern "C" char pdebug[];
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
char version[]= "Version 1.01.0004 April 10, 2013";
|
char version[]= "Version 1.01.0005 April 27, 2013";
|
||||||
|
|
||||||
#if defined(XMSG)
|
#if defined(XMSG)
|
||||||
char msglang[]; // Default message language
|
char msglang[]; // Default message language
|
||||||
@@ -187,44 +188,13 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
handlerton *connect_hton;
|
handlerton *connect_hton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
structure for CREATE TABLE options (table options)
|
CREATE TABLE option list (table options)
|
||||||
|
|
||||||
These can be specified in the CREATE TABLE:
|
These can be specified in the CREATE TABLE:
|
||||||
CREATE TABLE ( ... ) {...here...}
|
CREATE TABLE ( ... ) {...here...}
|
||||||
*/
|
*/
|
||||||
struct ha_table_option_struct {
|
|
||||||
const char *type;
|
|
||||||
const char *filename;
|
|
||||||
const char *optname;
|
|
||||||
const char *tabname;
|
|
||||||
const char *tablist;
|
|
||||||
const char *dbname;
|
|
||||||
const char *separator;
|
|
||||||
//const char *connect;
|
|
||||||
const char *qchar;
|
|
||||||
const char *module;
|
|
||||||
const char *subtype;
|
|
||||||
const char *catfunc;
|
|
||||||
const char *oplist;
|
|
||||||
const char *data_charset;
|
|
||||||
ulonglong lrecl;
|
|
||||||
ulonglong elements;
|
|
||||||
//ulonglong estimate;
|
|
||||||
ulonglong multiple;
|
|
||||||
ulonglong header;
|
|
||||||
ulonglong quoted;
|
|
||||||
ulonglong ending;
|
|
||||||
ulonglong compressed;
|
|
||||||
bool mapped;
|
|
||||||
bool huge;
|
|
||||||
bool split;
|
|
||||||
bool readonly;
|
|
||||||
bool sepindex;
|
|
||||||
};
|
|
||||||
|
|
||||||
ha_create_table_option connect_table_option_list[]=
|
ha_create_table_option connect_table_option_list[]=
|
||||||
{
|
{
|
||||||
// These option are for stand alone Connect tables
|
|
||||||
HA_TOPTION_STRING("TABLE_TYPE", type),
|
HA_TOPTION_STRING("TABLE_TYPE", type),
|
||||||
HA_TOPTION_STRING("FILE_NAME", filename),
|
HA_TOPTION_STRING("FILE_NAME", filename),
|
||||||
HA_TOPTION_STRING("XFILE_NAME", optname),
|
HA_TOPTION_STRING("XFILE_NAME", optname),
|
||||||
@@ -258,22 +228,11 @@ ha_create_table_option connect_table_option_list[]=
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
structure for CREATE TABLE options (field options)
|
CREATE TABLE option list (field options)
|
||||||
|
|
||||||
These can be specified in the CREATE TABLE per field:
|
These can be specified in the CREATE TABLE per field:
|
||||||
CREATE TABLE ( field ... {...here...}, ... )
|
CREATE TABLE ( field ... {...here...}, ... )
|
||||||
*/
|
*/
|
||||||
struct ha_field_option_struct
|
|
||||||
{
|
|
||||||
ulonglong offset;
|
|
||||||
ulonglong freq; // Not used by this version
|
|
||||||
ulonglong opt; // Not used by this version
|
|
||||||
ulonglong fldlen;
|
|
||||||
const char *dateformat;
|
|
||||||
const char *fieldformat;
|
|
||||||
char *special;
|
|
||||||
};
|
|
||||||
|
|
||||||
ha_create_table_option connect_field_option_list[]=
|
ha_create_table_option connect_field_option_list[]=
|
||||||
{
|
{
|
||||||
HA_FOPTION_NUMBER("FLAG", offset, -1, 0, INT_MAX32, 1),
|
HA_FOPTION_NUMBER("FLAG", offset, -1, 0, INT_MAX32, 1),
|
||||||
@@ -345,9 +304,8 @@ static void init_connect_psi_keys() {}
|
|||||||
delete_table method in handler.cc
|
delete_table method in handler.cc
|
||||||
*/
|
*/
|
||||||
static const char *ha_connect_exts[]= {
|
static const char *ha_connect_exts[]= {
|
||||||
".tbl", ".dnx", ".fnx", ".bnx", ".vnx", ".dbx", ".dos", ".fix", ".csv",
|
".dos", ".fix", ".csv",".bin", ".fmt", ".dbf", ".xml", ".ini", ".vec",
|
||||||
".fmt", ".dbf", ".xml", ".ini", ".vec", ".odbc", ".mysql", ".dir",
|
".dnx", ".fnx", ".bnx", ".vnx", ".dbx",
|
||||||
".mac", ".wmi", ".bin", ".oem",
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -708,6 +666,10 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
|
|||||||
// Return the handler default value
|
// Return the handler default value
|
||||||
if (!stricmp(opname, "Dbname") || !stricmp(opname, "Database"))
|
if (!stricmp(opname, "Dbname") || !stricmp(opname, "Database"))
|
||||||
opval= (char*)GetDBName(NULL); // Current database
|
opval= (char*)GetDBName(NULL); // Current database
|
||||||
|
else if (!stricmp(opname, "User")) // Connected user
|
||||||
|
opval= table->in_use->main_security_ctx.user;
|
||||||
|
else if (!stricmp(opname, "Host")) // Connected user host
|
||||||
|
opval= table->in_use->main_security_ctx.host;
|
||||||
else
|
else
|
||||||
opval= sdef; // Caller default
|
opval= sdef; // Caller default
|
||||||
|
|
||||||
@@ -773,7 +735,7 @@ bool ha_connect::SetBooleanOption(char *opname, bool b)
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
int ha_connect::GetIntegerOption(char *opname)
|
int ha_connect::GetIntegerOption(char *opname)
|
||||||
{
|
{
|
||||||
int opval= NO_IVAL;
|
ulonglong opval= NO_IVAL;
|
||||||
char *pv;
|
char *pv;
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct(table);
|
||||||
|
|
||||||
@@ -801,9 +763,9 @@ int ha_connect::GetIntegerOption(char *opname)
|
|||||||
|
|
||||||
if (opval == NO_IVAL && options && options->oplist)
|
if (opval == NO_IVAL && options && options->oplist)
|
||||||
if ((pv= GetListOption(xp->g, opname, options->oplist)))
|
if ((pv= GetListOption(xp->g, opname, options->oplist)))
|
||||||
opval= atoi(pv);
|
opval= (unsigned)atoll(pv);
|
||||||
|
|
||||||
return opval;
|
return (int)opval;
|
||||||
} // end of GetIntegerOption
|
} // end of GetIntegerOption
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@@ -885,13 +847,13 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
pcf->Name= (char*)fp->field_name;
|
pcf->Name= (char*)fp->field_name;
|
||||||
|
|
||||||
pcf->Prec= 0;
|
pcf->Prec= 0;
|
||||||
pcf->Opt= (fop) ? fop->opt : 0;
|
pcf->Opt= (fop) ? (int)fop->opt : 0;
|
||||||
|
|
||||||
if ((pcf->Length= fp->field_length) < 0)
|
if ((pcf->Length= fp->field_length) < 0)
|
||||||
pcf->Length= 256; // BLOB?
|
pcf->Length= 256; // BLOB?
|
||||||
|
|
||||||
if (fop) {
|
if (fop) {
|
||||||
pcf->Offset= fop->offset;
|
pcf->Offset= (int)fop->offset;
|
||||||
// pcf->Freq= fop->freq;
|
// pcf->Freq= fop->freq;
|
||||||
pcf->Datefmt= (char*)fop->dateformat;
|
pcf->Datefmt= (char*)fop->dateformat;
|
||||||
pcf->Fieldfmt= (char*)fop->fieldformat;
|
pcf->Fieldfmt= (char*)fop->fieldformat;
|
||||||
@@ -905,6 +867,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
switch (fp->type()) {
|
switch (fp->type()) {
|
||||||
case MYSQL_TYPE_BLOB:
|
case MYSQL_TYPE_BLOB:
|
||||||
case MYSQL_TYPE_VARCHAR:
|
case MYSQL_TYPE_VARCHAR:
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
pcf->Flags |= U_VAR;
|
pcf->Flags |= U_VAR;
|
||||||
case MYSQL_TYPE_STRING:
|
case MYSQL_TYPE_STRING:
|
||||||
pcf->Type= TYPE_STRING;
|
pcf->Type= TYPE_STRING;
|
||||||
@@ -941,7 +904,7 @@ void *ha_connect::GetColumnOption(void *field, PCOLINFO pcf)
|
|||||||
|
|
||||||
// Field_length is only used for DATE columns
|
// Field_length is only used for DATE columns
|
||||||
if (fop->fldlen)
|
if (fop->fldlen)
|
||||||
pcf->Length= fop->fldlen;
|
pcf->Length= (int)fop->fldlen;
|
||||||
else {
|
else {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -2688,13 +2651,18 @@ int ha_connect::delete_all_rows()
|
|||||||
|
|
||||||
bool ha_connect::check_privileges(THD *thd, PTOS options)
|
bool ha_connect::check_privileges(THD *thd, PTOS options)
|
||||||
{
|
{
|
||||||
if (!options->type)
|
if (!options->type) {
|
||||||
|
if (options->tabname)
|
||||||
|
options->type= "PROXY";
|
||||||
|
else
|
||||||
options->type= "DOS";
|
options->type= "DOS";
|
||||||
|
|
||||||
|
} // endif type
|
||||||
|
|
||||||
switch (GetTypeID(options->type))
|
switch (GetTypeID(options->type))
|
||||||
{
|
{
|
||||||
case TAB_UNDEF:
|
case TAB_UNDEF:
|
||||||
case TAB_CATLG:
|
// case TAB_CATLG:
|
||||||
case TAB_PLG:
|
case TAB_PLG:
|
||||||
case TAB_JCT:
|
case TAB_JCT:
|
||||||
case TAB_DMY:
|
case TAB_DMY:
|
||||||
@@ -2733,13 +2701,17 @@ bool ha_connect::check_privileges(THD *thd, PTOS options)
|
|||||||
case TAB_OEM:
|
case TAB_OEM:
|
||||||
return check_access(thd, FILE_ACL, NULL, NULL, NULL, 0, 0);
|
return check_access(thd, FILE_ACL, NULL, NULL, NULL, 0, 0);
|
||||||
|
|
||||||
|
// This is temporary until a solution is found
|
||||||
case TAB_TBL:
|
case TAB_TBL:
|
||||||
|
case TAB_XCL:
|
||||||
|
case TAB_PRX:
|
||||||
|
case TAB_OCCUR:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
|
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
|
||||||
return true;
|
return true;
|
||||||
}
|
} // end of check_privileges
|
||||||
|
|
||||||
// Check that two indexes are equivalent
|
// Check that two indexes are equivalent
|
||||||
bool ha_connect::IsSameIndex(PIXDEF xp1, PIXDEF xp2)
|
bool ha_connect::IsSameIndex(PIXDEF xp1, PIXDEF xp2)
|
||||||
@@ -3272,8 +3244,9 @@ bool add_field(String *sql, const char *field_name, const char *type,
|
|||||||
{
|
{
|
||||||
bool error= false;
|
bool error= false;
|
||||||
|
|
||||||
|
error|= sql->append('`');
|
||||||
error|= sql->append(field_name);
|
error|= sql->append(field_name);
|
||||||
error|= sql->append(' ');
|
error|= sql->append("` ");
|
||||||
error|= sql->append(type);
|
error|= sql->append(type);
|
||||||
if (len) {
|
if (len) {
|
||||||
error|= sql->append('(');
|
error|= sql->append('(');
|
||||||
@@ -3289,7 +3262,7 @@ bool add_field(String *sql, const char *field_name, const char *type,
|
|||||||
error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
|
error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
|
||||||
|
|
||||||
if (rem && *rem) {
|
if (rem && *rem) {
|
||||||
error|= sql->append(" COMMENT='");
|
error|= sql->append(" COMMENT '");
|
||||||
error|= sql->append_for_single_quote(rem, strlen(rem));
|
error|= sql->append_for_single_quote(rem, strlen(rem));
|
||||||
error|= sql->append("'");
|
error|= sql->append("'");
|
||||||
}
|
}
|
||||||
@@ -3314,12 +3287,12 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
{
|
{
|
||||||
char spc= ',', qch= 0;
|
char spc= ',', qch= 0;
|
||||||
const char *fncn= "?";
|
const char *fncn= "?";
|
||||||
const char *user, *fn, *tab, *db, *host, *pwd, *prt, *sep; // *csn;
|
const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl; // *csn;
|
||||||
char *dsn;
|
char *tab, *dsn;
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
char *nsp= NULL, *cls= NULL;
|
char *nsp= NULL, *cls= NULL;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
int port= MYSQL_PORT, hdr= 0, mxr= 0, b= 0;
|
int port= 0, hdr= 0, mxr= 0, b= 0;
|
||||||
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
|
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
|
||||||
bool ok= false, dbf= false;
|
bool ok= false, dbf= false;
|
||||||
TABTYPE ttp= TAB_UNDEF;
|
TABTYPE ttp= TAB_UNDEF;
|
||||||
@@ -3338,19 +3311,21 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
|
|
||||||
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
|
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
|
||||||
|
|
||||||
user= host= pwd= prt= dsn= NULL;
|
user= host= pwd= prt= tbl= dsn= NULL;
|
||||||
|
|
||||||
// Get the useful create options
|
// Get the useful create options
|
||||||
ttp= GetTypeID(topt->type);
|
ttp= GetTypeID(topt->type);
|
||||||
fn= topt->filename;
|
fn= topt->filename;
|
||||||
tab= topt->tabname;
|
tab= (char*)topt->tabname;
|
||||||
db= topt->dbname;
|
db= topt->dbname;
|
||||||
fncn= topt->catfunc;
|
fncn= topt->catfunc;
|
||||||
fnc= GetFuncID(fncn);
|
fnc= GetFuncID(fncn);
|
||||||
sep= topt->separator;
|
sep= topt->separator;
|
||||||
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
|
spc= (!sep || !strcmp(sep, "\\t")) ? '\t' : *sep;
|
||||||
qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
|
qch= topt->qchar ? *topt->qchar : topt->quoted >= 0 ? '"' : 0;
|
||||||
hdr= topt->header;
|
hdr= (int)topt->header;
|
||||||
|
tbl= topt->tablist;
|
||||||
|
|
||||||
if (topt->oplist) {
|
if (topt->oplist) {
|
||||||
host= GetListOption(g,"host", topt->oplist, "localhost");
|
host= GetListOption(g,"host", topt->oplist, "localhost");
|
||||||
user= GetListOption(g,"user", topt->oplist, "root");
|
user= GetListOption(g,"user", topt->oplist, "root");
|
||||||
@@ -3364,26 +3339,74 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
cls= GetListOption(g,"class", topt->oplist);
|
cls= GetListOption(g,"class", topt->oplist);
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
|
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
|
||||||
} // endelse option_list
|
} // endif option_list
|
||||||
|
|
||||||
if (!db)
|
if (!db)
|
||||||
db= thd->db; // Default value
|
db= thd->db; // Default value
|
||||||
|
|
||||||
// Check table type
|
// Check table type
|
||||||
if (ttp == TAB_UNDEF) {
|
if (ttp == TAB_UNDEF) {
|
||||||
|
if (!tab) {
|
||||||
strcpy(g->Message, "No table_type. Was set to DOS");
|
strcpy(g->Message, "No table_type. Was set to DOS");
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
ttp= TAB_DOS;
|
ttp= TAB_DOS;
|
||||||
topt->type= "DOS";
|
topt->type= "DOS";
|
||||||
|
} else {
|
||||||
|
strcpy(g->Message, "No table_type. Was set to PROXY");
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
|
ttp= TAB_PRX;
|
||||||
|
topt->type= "PROXY";
|
||||||
|
} // endif fnc
|
||||||
|
|
||||||
} else if (ttp == TAB_NIY) {
|
} else if (ttp == TAB_NIY) {
|
||||||
sprintf(g->Message, "Unsupported table type %s", topt->type);
|
sprintf(g->Message, "Unsupported table type %s", topt->type);
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
return HA_ERR_INTERNAL_ERROR;
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
} // endif ttp
|
} // endif ttp
|
||||||
|
|
||||||
if (!tab && !(fnc & (FNC_TABLE | FNC_COL)))
|
if (!tab) {
|
||||||
|
if (ttp == TAB_TBL) {
|
||||||
|
// Make tab the first table of the list
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!tbl) {
|
||||||
|
strcpy(g->Message, "Missing table list");
|
||||||
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
|
} // endif tbl
|
||||||
|
|
||||||
|
tab= (char*)PlugSubAlloc(g, NULL, strlen(tbl) + 1);
|
||||||
|
strcpy(tab, tbl);
|
||||||
|
|
||||||
|
if ((p= strchr(tab, ',')))
|
||||||
|
*p= 0;
|
||||||
|
|
||||||
|
if ((p=strchr(tab, '.'))) {
|
||||||
|
*p= 0;
|
||||||
|
db= tab;
|
||||||
|
tab= p + 1;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
|
} else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL)))
|
||||||
tab= (char*)create_info->alias;
|
tab= (char*)create_info->alias;
|
||||||
|
|
||||||
|
} // endif tab
|
||||||
|
|
||||||
|
// Check whether a table is defined on itself
|
||||||
|
switch (ttp) {
|
||||||
|
case TAB_PRX:
|
||||||
|
case TAB_XCL:
|
||||||
|
case TAB_TBL:
|
||||||
|
case TAB_OCCUR:
|
||||||
|
if (!stricmp(tab, create_info->alias) &&
|
||||||
|
!stricmp(db, thd->db)) {
|
||||||
|
sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
|
||||||
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
|
} // endif tab
|
||||||
|
|
||||||
|
} // endswitch ttp
|
||||||
|
|
||||||
switch (ttp) {
|
switch (ttp) {
|
||||||
#if defined(ODBC_SUPPORT)
|
#if defined(ODBC_SUPPORT)
|
||||||
case TAB_ODBC:
|
case TAB_ODBC:
|
||||||
@@ -3433,7 +3456,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
ok= false;
|
ok= false;
|
||||||
|
|
||||||
} else if (!user)
|
} else if (!user)
|
||||||
user= "root"; // Avoid crash
|
user= thd->main_security_ctx.user;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
@@ -3442,6 +3465,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
ok= true;
|
ok= true;
|
||||||
break;
|
break;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
case TAB_PRX:
|
||||||
|
case TAB_TBL:
|
||||||
|
case TAB_XCL:
|
||||||
|
ok= true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
|
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
|
||||||
} // endif ttp
|
} // endif ttp
|
||||||
@@ -3453,6 +3481,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
ok= false;
|
ok= false;
|
||||||
} // endif supfnc
|
} // endif supfnc
|
||||||
|
|
||||||
|
// Here we should test the flag column options when
|
||||||
|
// this function is called in case of CREATE .. SELECT
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
char *cnm, *rem;
|
char *cnm, *rem;
|
||||||
int i, len, dec, typ;
|
int i, len, dec, typ;
|
||||||
@@ -3505,6 +3536,11 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
qrp= WMIColumns(g, nsp, cls, fnc == FNC_COL);
|
qrp= WMIColumns(g, nsp, cls, fnc == FNC_COL);
|
||||||
break;
|
break;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
case TAB_PRX:
|
||||||
|
case TAB_TBL:
|
||||||
|
case TAB_XCL:
|
||||||
|
qrp= TabColumns(g, thd, db, tab, fnc == FNC_COL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
strcpy(g->Message, "System error during assisted discovery");
|
strcpy(g->Message, "System error during assisted discovery");
|
||||||
break;
|
break;
|
||||||
@@ -3587,11 +3623,16 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
} // endif ttp
|
} // endif ttp
|
||||||
#endif // ODBC_SUPPORT
|
#endif // ODBC_SUPPORT
|
||||||
|
|
||||||
|
// Make the arguments as required by add_fields
|
||||||
type= PLGtoMYSQLtype(typ, true);
|
type= PLGtoMYSQLtype(typ, true);
|
||||||
|
|
||||||
if (typ == TYPE_DATE)
|
if (typ == TYPE_DATE)
|
||||||
len= 0;
|
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))
|
||||||
b= HA_ERR_OUT_OF_MEM;
|
b= HA_ERR_OUT_OF_MEM;
|
||||||
|
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
sql.length(sql.length()-1); // remove the trailing comma
|
sql.length(sql.length()-1); // remove the trailing comma
|
||||||
@@ -3602,59 +3643,76 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
ulonglong vull;
|
ulonglong vull;
|
||||||
const char *vstr;
|
const char *vstr;
|
||||||
bool oom= false;
|
bool oom= false;
|
||||||
|
|
||||||
switch (opt->type) {
|
switch (opt->type) {
|
||||||
case HA_OPTION_TYPE_ULL:
|
case HA_OPTION_TYPE_ULL:
|
||||||
vull= *(ulonglong*)(((char*)topt) + opt->offset);
|
vull= *(ulonglong*)(((char*)topt) + opt->offset);
|
||||||
|
|
||||||
if (vull != opt->def_value) {
|
if (vull != opt->def_value) {
|
||||||
oom|= sql.append(' ');
|
oom|= sql.append(' ');
|
||||||
oom|= sql.append(opt->name);
|
oom|= sql.append(opt->name);
|
||||||
oom|= sql.append('=');
|
oom|= sql.append('=');
|
||||||
oom|= sql.append_ulonglong(vull);
|
oom|= sql.append_ulonglong(vull);
|
||||||
}
|
} // endif vull
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case HA_OPTION_TYPE_STRING:
|
case HA_OPTION_TYPE_STRING:
|
||||||
vstr= *(char**)(((char*)topt) + opt->offset);
|
vstr= *(char**)(((char*)topt) + opt->offset);
|
||||||
|
|
||||||
if (vstr) {
|
if (vstr) {
|
||||||
oom|= sql.append(' ');
|
oom|= sql.append(' ');
|
||||||
oom|= sql.append(opt->name);
|
oom|= sql.append(opt->name);
|
||||||
oom|= sql.append("='");
|
oom|= sql.append("='");
|
||||||
oom|= sql.append_for_single_quote(vstr, strlen(vstr));
|
oom|= sql.append_for_single_quote(vstr, strlen(vstr));
|
||||||
oom|= sql.append('\'');
|
oom|= sql.append('\'');
|
||||||
}
|
} // endif vstr
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case HA_OPTION_TYPE_BOOL:
|
case HA_OPTION_TYPE_BOOL:
|
||||||
vull= *(bool*)(((char*)topt) + opt->offset);
|
vull= *(bool*)(((char*)topt) + opt->offset);
|
||||||
|
|
||||||
if (vull != opt->def_value) {
|
if (vull != opt->def_value) {
|
||||||
oom|= sql.append(' ');
|
oom|= sql.append(' ');
|
||||||
oom|= sql.append(opt->name);
|
oom|= sql.append(opt->name);
|
||||||
oom|= sql.append('=');
|
oom|= sql.append('=');
|
||||||
oom|= sql.append(vull ? "ON" : "OFF");
|
oom|= sql.append(vull ? "ON" : "OFF");
|
||||||
}
|
} // endif vull
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: // no enums here, good :)
|
default: // no enums here, good :)
|
||||||
break;
|
break;
|
||||||
}
|
} // endswitch type
|
||||||
|
|
||||||
if (oom)
|
if (oom)
|
||||||
b= HA_ERR_OUT_OF_MEM;
|
b= HA_ERR_OUT_OF_MEM;
|
||||||
}
|
|
||||||
|
} // endfor opt
|
||||||
|
|
||||||
if (create_info->connect_string.length) {
|
if (create_info->connect_string.length) {
|
||||||
bool oom= false;
|
bool oom= false;
|
||||||
|
|
||||||
oom|= sql.append(' ');
|
oom|= sql.append(' ');
|
||||||
oom|= sql.append("CONNECTION='");
|
oom|= sql.append("CONNECTION='");
|
||||||
oom|= sql.append_for_single_quote(create_info->connect_string.str,
|
oom|= sql.append_for_single_quote(create_info->connect_string.str,
|
||||||
create_info->connect_string.length);
|
create_info->connect_string.length);
|
||||||
oom|= sql.append('\'');
|
oom|= sql.append('\'');
|
||||||
|
|
||||||
if (oom)
|
if (oom)
|
||||||
b= HA_ERR_OUT_OF_MEM;
|
b= HA_ERR_OUT_OF_MEM;
|
||||||
}
|
|
||||||
|
} // endif string
|
||||||
|
|
||||||
if (create_info->default_table_charset) {
|
if (create_info->default_table_charset) {
|
||||||
bool oom= false;
|
bool oom= false;
|
||||||
|
|
||||||
oom|= sql.append(' ');
|
oom|= sql.append(' ');
|
||||||
oom|= sql.append("CHARSET=");
|
oom|= sql.append("CHARSET=");
|
||||||
oom|= sql.append(create_info->default_table_charset->csname);
|
oom|= sql.append(create_info->default_table_charset->csname);
|
||||||
}
|
|
||||||
|
if (oom)
|
||||||
|
b= HA_ERR_OUT_OF_MEM;
|
||||||
|
|
||||||
|
} // endif charset
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
b= table_s->init_from_sql_statement_string(thd, true,
|
b= table_s->init_from_sql_statement_string(thd, true,
|
||||||
@@ -3664,7 +3722,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
|
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
return HA_ERR_INTERNAL_ERROR;
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
} // end of pre_create
|
} // end of connect_assisted_discovery
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief
|
@brief
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) Olivier Bertrand 2004 - 2011
|
/* Copyright (C) Olivier Bertrand 2004 - 2013
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -64,6 +64,59 @@ typedef struct ha_field_option_struct FOS, *PFOS;
|
|||||||
|
|
||||||
extern handlerton *connect_hton;
|
extern handlerton *connect_hton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
structure for CREATE TABLE options (table options)
|
||||||
|
|
||||||
|
These can be specified in the CREATE TABLE:
|
||||||
|
CREATE TABLE ( ... ) {...here...}
|
||||||
|
*/
|
||||||
|
struct ha_table_option_struct {
|
||||||
|
const char *type;
|
||||||
|
const char *filename;
|
||||||
|
const char *optname;
|
||||||
|
const char *tabname;
|
||||||
|
const char *tablist;
|
||||||
|
const char *dbname;
|
||||||
|
const char *separator;
|
||||||
|
//const char *connect;
|
||||||
|
const char *qchar;
|
||||||
|
const char *module;
|
||||||
|
const char *subtype;
|
||||||
|
const char *catfunc;
|
||||||
|
const char *oplist;
|
||||||
|
const char *data_charset;
|
||||||
|
ulonglong lrecl;
|
||||||
|
ulonglong elements;
|
||||||
|
//ulonglong estimate;
|
||||||
|
ulonglong multiple;
|
||||||
|
ulonglong header;
|
||||||
|
ulonglong quoted;
|
||||||
|
ulonglong ending;
|
||||||
|
ulonglong compressed;
|
||||||
|
bool mapped;
|
||||||
|
bool huge;
|
||||||
|
bool split;
|
||||||
|
bool readonly;
|
||||||
|
bool sepindex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
structure for CREATE TABLE options (field options)
|
||||||
|
|
||||||
|
These can be specified in the CREATE TABLE per field:
|
||||||
|
CREATE TABLE ( field ... {...here...}, ... )
|
||||||
|
*/
|
||||||
|
struct ha_field_option_struct
|
||||||
|
{
|
||||||
|
ulonglong offset;
|
||||||
|
ulonglong freq; // Not used by this version
|
||||||
|
ulonglong opt; // Not used by this version
|
||||||
|
ulonglong fldlen;
|
||||||
|
const char *dateformat;
|
||||||
|
const char *fieldformat;
|
||||||
|
char *special;
|
||||||
|
};
|
||||||
|
|
||||||
/** @brief
|
/** @brief
|
||||||
CONNECT_SHARE is a structure that will be shared among all open handlers.
|
CONNECT_SHARE is a structure that will be shared among all open handlers.
|
||||||
This example implements the minimum of what you will probably need.
|
This example implements the minimum of what you will probably need.
|
||||||
@@ -143,8 +196,7 @@ public:
|
|||||||
{
|
{
|
||||||
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_HAS_RECORDS |
|
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_HAS_RECORDS |
|
||||||
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
|
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
|
||||||
HA_NO_COPY_ON_ALTER |
|
HA_NO_COPY_ON_ALTER | HA_CAN_VIRTUAL_COLUMNS |
|
||||||
HA_CAN_VIRTUAL_COLUMNS |
|
|
||||||
HA_NULL_IN_KEY | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
|
HA_NULL_IN_KEY | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,7 +68,10 @@
|
|||||||
#include "tabmac.h"
|
#include "tabmac.h"
|
||||||
#include "tabwmi.h"
|
#include "tabwmi.h"
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
//#include "tabtbl.h"
|
||||||
|
#include "tabxcl.h"
|
||||||
#include "tabtbl.h"
|
#include "tabtbl.h"
|
||||||
|
#include "taboccur.h"
|
||||||
#if defined(XML_SUPPORT)
|
#if defined(XML_SUPPORT)
|
||||||
#include "tabxml.h"
|
#include "tabxml.h"
|
||||||
#endif // XML_SUPPORT
|
#endif // XML_SUPPORT
|
||||||
@@ -124,6 +127,10 @@ TABTYPE GetTypeID(const char *type)
|
|||||||
: (!stricmp(type, "WMI")) ? TAB_WMI
|
: (!stricmp(type, "WMI")) ? TAB_WMI
|
||||||
#endif
|
#endif
|
||||||
: (!stricmp(type, "TBL")) ? TAB_TBL
|
: (!stricmp(type, "TBL")) ? TAB_TBL
|
||||||
|
: (!stricmp(type, "XCOL")) ? TAB_XCL
|
||||||
|
: (!stricmp(type, "OCCUR")) ? TAB_OCCUR
|
||||||
|
: (!stricmp(type, "CATLG")) ? TAB_PRX // Legacy
|
||||||
|
: (!stricmp(type, "PROXY")) ? TAB_PRX
|
||||||
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
|
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
|
||||||
} // end of GetTypeID
|
} // end of GetTypeID
|
||||||
|
|
||||||
@@ -186,7 +193,6 @@ bool IsTypeNullable(TABTYPE type)
|
|||||||
break;
|
break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
|
|
||||||
return nullable;
|
return nullable;
|
||||||
} // end of IsTypeNullable
|
} // end of IsTypeNullable
|
||||||
|
|
||||||
@@ -414,7 +420,7 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
|
|||||||
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
|
||||||
|
|
||||||
// Get a unique char identifier for type
|
// Get a unique char identifier for type
|
||||||
tc= (defp->Catfunc == FNC_NO) ? GetTypeID(type) : TAB_CATLG;
|
tc= (defp->Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
|
||||||
|
|
||||||
// Take care of the column definitions
|
// Take care of the column definitions
|
||||||
i= poff= nof= nlg= 0;
|
i= poff= nof= nlg= 0;
|
||||||
@@ -443,6 +449,9 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
|
|||||||
case TAB_INI:
|
case TAB_INI:
|
||||||
case TAB_MAC:
|
case TAB_MAC:
|
||||||
case TAB_TBL:
|
case TAB_TBL:
|
||||||
|
case TAB_XCL:
|
||||||
|
case TAB_OCCUR:
|
||||||
|
case TAB_PRX:
|
||||||
case TAB_OEM:
|
case TAB_OEM:
|
||||||
poff = 0; // Offset represents an independant flag
|
poff = 0; // Offset represents an independant flag
|
||||||
break;
|
break;
|
||||||
@@ -592,7 +601,7 @@ PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name,
|
|||||||
|
|
||||||
// If not specified get the type of this table
|
// If not specified get the type of this table
|
||||||
if (!type && !(type= Hc->GetStringOption("Type")))
|
if (!type && !(type= Hc->GetStringOption("Type")))
|
||||||
type= "DOS";
|
type= (Hc->GetStringOption("Tabname")) ? "PROXY" : "DOS";
|
||||||
|
|
||||||
return MakeTableDesc(g, name, type);
|
return MakeTableDesc(g, name, type);
|
||||||
} // end of GetTableDesc
|
} // end of GetTableDesc
|
||||||
@@ -636,6 +645,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
|
|||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
case TAB_OEM: tdp= new(g) OEMDEF; break;
|
case TAB_OEM: tdp= new(g) OEMDEF; break;
|
||||||
case TAB_TBL: tdp= new(g) TBLDEF; break;
|
case TAB_TBL: tdp= new(g) TBLDEF; break;
|
||||||
|
case TAB_XCL: tdp= new(g) XCLDEF; break;
|
||||||
|
case TAB_PRX: tdp= new(g) PRXDEF; break;
|
||||||
|
case TAB_OCCUR: tdp= new(g) OCCURDEF; break;
|
||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
case TAB_MYSQL: tdp= new(g) MYSQLDEF; break;
|
case TAB_MYSQL: tdp= new(g) MYSQLDEF; break;
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
@@ -646,7 +658,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
|
|||||||
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
|
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
|
||||||
} // endswitch
|
} // endswitch
|
||||||
|
|
||||||
// Do make the table/view definition from XDB file information
|
// Do make the table/view definition
|
||||||
if (tdp && tdp->Define(g, this, name, am))
|
if (tdp && tdp->Define(g, this, name, am))
|
||||||
tdp= NULL;
|
tdp= NULL;
|
||||||
|
|
||||||
|
@@ -62,6 +62,7 @@ static char *server_groups[] = {
|
|||||||
#endif // EMBEDDED
|
#endif // EMBEDDED
|
||||||
|
|
||||||
extern "C" int trace;
|
extern "C" int trace;
|
||||||
|
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* MyColumns: constructs the result blocks containing all columns */
|
/* MyColumns: constructs the result blocks containing all columns */
|
||||||
@@ -90,6 +91,9 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
MYSQLC myc;
|
MYSQLC myc;
|
||||||
|
|
||||||
|
if (!port)
|
||||||
|
port = mysqld_port;
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
/* Open the connection with the MySQL server. */
|
/* Open the connection with the MySQL server. */
|
||||||
|
@@ -507,7 +507,7 @@ DROP TABLE t1;
|
|||||||
SET @a=LOAD_FILE('test/t1.xml');
|
SET @a=LOAD_FILE('test/t1.xml');
|
||||||
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
|
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
|
||||||
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
|
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Created by CONNECT Version 1.01.0004 April 10, 2013 -->
|
<!-- Created by CONNECT Version 1.01.0005 April 27, 2013 -->
|
||||||
<t1>
|
<t1>
|
||||||
<line>
|
<line>
|
||||||
<node>ÀÁÂÃ</node>
|
<node>ÀÁÂÃ</node>
|
||||||
|
@@ -69,12 +69,14 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
|
|||||||
TAB_WMI = 14, /* WMI tables (Windows only) */
|
TAB_WMI = 14, /* WMI tables (Windows only) */
|
||||||
TAB_TBL = 15, /* Collection of CONNECT tables */
|
TAB_TBL = 15, /* Collection of CONNECT tables */
|
||||||
TAB_OEM = 16, /* OEM implemented table */
|
TAB_OEM = 16, /* OEM implemented table */
|
||||||
TAB_CATLG = 17, /* Catalog table */
|
TAB_XCL = 17, /* XCL table */
|
||||||
TAB_PLG = 18, /* PLG NIY */
|
TAB_OCCUR = 18, /* OCCUR table */
|
||||||
TAB_PIVOT = 19, /* PIVOT NIY */
|
TAB_PRX = 19, /* Proxy (catalog) table */
|
||||||
TAB_JCT = 20, /* Junction tables NIY */
|
TAB_PLG = 20, /* PLG NIY */
|
||||||
TAB_DMY = 21, /* DMY Dummy tables NIY */
|
TAB_PIVOT = 21, /* PIVOT NIY */
|
||||||
TAB_NIY = 22}; /* Table not implemented yet */
|
TAB_JCT = 22, /* Junction tables NIY */
|
||||||
|
TAB_DMY = 23, /* DMY Dummy tables NIY */
|
||||||
|
TAB_NIY = 24}; /* Table not implemented yet */
|
||||||
|
|
||||||
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
||||||
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
|
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
|
||||||
|
@@ -63,6 +63,7 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
|
|||||||
#endif // _CONSOLE
|
#endif // _CONSOLE
|
||||||
|
|
||||||
extern "C" int trace;
|
extern "C" int trace;
|
||||||
|
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
|
||||||
|
|
||||||
/* -------------- Implementation of the MYSQLDEF class --------------- */
|
/* -------------- Implementation of the MYSQLDEF class --------------- */
|
||||||
|
|
||||||
@@ -243,10 +244,13 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
|||||||
if ((sport = strchr(Hostname, ':')))
|
if ((sport = strchr(Hostname, ':')))
|
||||||
*sport++ = 0;
|
*sport++ = 0;
|
||||||
|
|
||||||
Portnumber = (sport && sport[0]) ? atoi(sport) : MYSQL_PORT;
|
Portnumber = (sport && sport[0]) ? atoi(sport) : mysqld_port;
|
||||||
|
|
||||||
|
if (Username[0] == 0)
|
||||||
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
|
|
||||||
if (Hostname[0] == 0)
|
if (Hostname[0] == 0)
|
||||||
Hostname = "localhost";
|
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
||||||
|
|
||||||
if (!Database || !*Database)
|
if (!Database || !*Database)
|
||||||
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||||
@@ -282,9 +286,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||||
Tabname = Cat->GetStringCatInfo(g, "Name", Name); // Deprecated
|
Tabname = Cat->GetStringCatInfo(g, "Name", Name); // Deprecated
|
||||||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
||||||
Username = Cat->GetStringCatInfo(g, "User", "root");
|
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||||
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
Password = Cat->GetStringCatInfo(g, "Password", NULL);
|
||||||
Portnumber = Cat->GetIntCatInfo("Port", MYSQL_PORT);
|
Portnumber = Cat->GetIntCatInfo("Port", mysqld_port);
|
||||||
} else if (ParseURL(g, url))
|
} else if (ParseURL(g, url))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
375
storage/connect/taboccur.cpp
Normal file
375
storage/connect/taboccur.cpp
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
/************ TabOccur CPP Declares Source Code File (.CPP) ************/
|
||||||
|
/* Name: TABOCCUR.CPP Version 1.0 */
|
||||||
|
/* */
|
||||||
|
/* (C) Copyright to the author Olivier BERTRAND 2013 */
|
||||||
|
/* */
|
||||||
|
/* OCCUR: Table that provides a view of a source table where the */
|
||||||
|
/* contain of several columns of the source table is placed in only */
|
||||||
|
/* one column, the OCCUR column, this resulting into several rows. */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Include relevant section of system dependant header files. */
|
||||||
|
/***********************************************************************/
|
||||||
|
#include "my_global.h"
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(__BORLANDC__)
|
||||||
|
#define __MFC_COMPAT__ // To define min/max as macro
|
||||||
|
#endif
|
||||||
|
//#include <windows.h>
|
||||||
|
#else
|
||||||
|
#if defined(UNIX)
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "osutil.h"
|
||||||
|
#else
|
||||||
|
//#include <io.h>
|
||||||
|
#endif
|
||||||
|
//#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Include application header files: */
|
||||||
|
/***********************************************************************/
|
||||||
|
#include "table.h" // MySQL table definitions
|
||||||
|
#include "global.h"
|
||||||
|
#include "plgdbsem.h"
|
||||||
|
#include "reldef.h"
|
||||||
|
#include "filamtxt.h"
|
||||||
|
#include "tabdos.h"
|
||||||
|
#include "tabcol.h"
|
||||||
|
#include "taboccur.h"
|
||||||
|
#include "xtable.h"
|
||||||
|
#if defined(MYSQL_SUPPORT)
|
||||||
|
#include "tabmysql.h"
|
||||||
|
#endif // MYSQL_SUPPORT
|
||||||
|
#include "ha_connect.h"
|
||||||
|
#include "mycat.h"
|
||||||
|
|
||||||
|
extern "C" int trace;
|
||||||
|
|
||||||
|
/* -------------- Implementation of the OCCUR classes ---------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DefineAM: define specific AM block values from OCCUR table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
|
{
|
||||||
|
//Tabname = Cat->GetStringCatInfo(g, "SrcTable", "");
|
||||||
|
Xcol = Cat->GetStringCatInfo(g, "OccurCol", "");
|
||||||
|
Rcol = Cat->GetStringCatInfo(g, "RankCol", "");
|
||||||
|
Colist = Cat->GetStringCatInfo(g, "Colist", "");
|
||||||
|
return PRXDEF::DefineAM(g, am, poff);
|
||||||
|
} // end of DefineAM
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* GetTable: makes a new TDB of the proper type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PTDB OCCURDEF::GetTable(PGLOBAL g, MODE m)
|
||||||
|
{
|
||||||
|
if (Catfunc != FNC_COL) {
|
||||||
|
PTDB tdbp;
|
||||||
|
PTDBOCCUR tocp = new(g) TDBOCCUR(this);
|
||||||
|
|
||||||
|
// Check that the source table is available
|
||||||
|
if (!tocp || !(tdbp = tocp->GetSubTable(g, Tablep)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Set Tdbp now
|
||||||
|
tocp->SetTdbp((PTDBASE)tdbp);
|
||||||
|
|
||||||
|
if (tocp->MakeColumnList(g) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return tocp;
|
||||||
|
} else
|
||||||
|
return new(g) TDBTBC(this);
|
||||||
|
|
||||||
|
} // end of GetTable
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Implementation of the TDBOCCUR class. */
|
||||||
|
/***********************************************************************/
|
||||||
|
TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp)
|
||||||
|
{
|
||||||
|
//Tdbp = NULL; // Source table
|
||||||
|
Tabname = tdp->Tablep->GetName(); // Name of source table
|
||||||
|
Colist = tdp->Colist; // List of source columns
|
||||||
|
Xcolumn = tdp->Xcol; // Occur column name
|
||||||
|
Rcolumn = tdp->Rcol; // Rank column name
|
||||||
|
Xcolp = NULL; // To the OCCURCOL column
|
||||||
|
Col = NULL; // To source column blocks array
|
||||||
|
Mult = -1; // Multiplication factor
|
||||||
|
N = 0; // The current table index
|
||||||
|
M = 0; // The occurence rank
|
||||||
|
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
|
||||||
|
} // end of TDBOCCUR constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Allocate OCCUR/SRC column description block. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
||||||
|
{
|
||||||
|
PCOL colp = NULL;
|
||||||
|
|
||||||
|
if (!stricmp(cdp->GetName(), Rcolumn)) {
|
||||||
|
// Allocate a RANK column
|
||||||
|
colp = new(g) RANKCOL(cdp, this, n);
|
||||||
|
} else if (!stricmp(cdp->GetName(), Xcolumn)) {
|
||||||
|
// Allocate the OCCUR column
|
||||||
|
colp = Xcolp = new(g) OCCURCOL(cdp, this, n);
|
||||||
|
} else {
|
||||||
|
colp = new(g) PRXCOL(cdp, this, cprec, n);
|
||||||
|
|
||||||
|
if (((PPRXCOL)colp)->Init(g))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return colp;
|
||||||
|
} //endif name
|
||||||
|
|
||||||
|
if (cprec) {
|
||||||
|
colp->SetNext(cprec->GetNext());
|
||||||
|
cprec->SetNext(colp);
|
||||||
|
} else {
|
||||||
|
colp->SetNext(Columns);
|
||||||
|
Columns = colp;
|
||||||
|
} // endif cprec
|
||||||
|
|
||||||
|
return colp;
|
||||||
|
} // end of MakeCol
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Allocate OCCUR column description block. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBOCCUR::MakeColumnList(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (Mult < 0) {
|
||||||
|
char *p, *pn;
|
||||||
|
int i;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
// Count the number of columns and change separator into null char
|
||||||
|
for (pn = Colist; ; pn += (strlen(pn) + 1))
|
||||||
|
if ((p = strchr(pn, ';'))) {
|
||||||
|
*p++ = '\0';
|
||||||
|
n++;
|
||||||
|
} else {
|
||||||
|
if (*pn)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
|
Col = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL));
|
||||||
|
|
||||||
|
for (i = 0, pn = Colist; i < n; i++, pn += (strlen(pn) + 1)) {
|
||||||
|
if (!(Col[i] = Tdbp->ColDB(g, pn, 0))) {
|
||||||
|
// Column not found in table
|
||||||
|
sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname);
|
||||||
|
return -1;
|
||||||
|
} // endif Col
|
||||||
|
|
||||||
|
if (Col[i]->InitValue(g)) {
|
||||||
|
strcpy(g->Message, "OCCUR InitValue failed");
|
||||||
|
return -1;
|
||||||
|
} // endif InitValue
|
||||||
|
|
||||||
|
} // endfor i
|
||||||
|
|
||||||
|
// OCCUR column name defaults to the name of the list first column
|
||||||
|
if (!Xcolumn)
|
||||||
|
Xcolumn = Colist;
|
||||||
|
|
||||||
|
Mult = n;
|
||||||
|
} // endif Mult
|
||||||
|
|
||||||
|
return Mult;
|
||||||
|
} // end of MakeColumnList
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* OCCUR GetMaxSize: returns the maximum number of rows in the table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBOCCUR::GetMaxSize(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (MaxSize < 0) {
|
||||||
|
// Mult = MakeColumnList(g);
|
||||||
|
MaxSize = Mult * Tdbp->GetMaxSize(g);
|
||||||
|
} // endif MaxSize
|
||||||
|
|
||||||
|
return MaxSize;
|
||||||
|
} // end of GetMaxSize
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* In this sample, ROWID will be the (virtual) row number, */
|
||||||
|
/* while ROWNUM will be the occurence rank in the multiple column. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBOCCUR::RowNumber(PGLOBAL g, bool b)
|
||||||
|
{
|
||||||
|
return (b) ? M : N;
|
||||||
|
} // end of RowNumber
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* OCCUR Access Method opening routine. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBOCCUR::OpenDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (Use == USE_OPEN) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Table already open, just replace it at its beginning. */
|
||||||
|
/*******************************************************************/
|
||||||
|
N = M = 0;
|
||||||
|
RowFlag = 0;
|
||||||
|
|
||||||
|
if (Xcolp)
|
||||||
|
Xcolp->Xreset();
|
||||||
|
|
||||||
|
return Tdbp->OpenDB(g);
|
||||||
|
} // endif use
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Do it here if not done yet. */
|
||||||
|
/*********************************************************************/
|
||||||
|
// if (MakeColumnList(g) < 0)
|
||||||
|
// return TRUE;
|
||||||
|
|
||||||
|
if (Mode != MODE_READ) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Currently OCCUR tables cannot be modified. */
|
||||||
|
/*******************************************************************/
|
||||||
|
strcpy(g->Message, "OCCUR tables are read only");
|
||||||
|
return TRUE;
|
||||||
|
} // endif Mode
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Be sure OCCUR column exist. */
|
||||||
|
/*********************************************************************/
|
||||||
|
if (!Xcolp) {
|
||||||
|
if (!(Xcolp = (POCCURCOL)ColDB(g, Xcolumn, 0))) {
|
||||||
|
sprintf(g->Message, "OCCUR column %s definition error", Xcolumn);
|
||||||
|
return TRUE;
|
||||||
|
} else if (Xcolp->InitValue(g)) {
|
||||||
|
strcpy(g->Message, "OCCUR InitValue failed");
|
||||||
|
return TRUE;
|
||||||
|
} // endif's Xcolp
|
||||||
|
|
||||||
|
} // endif Xcolp
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
if (Xcolp)
|
||||||
|
// Lock this column so it is evaluated by its table only
|
||||||
|
Xcolp->AddStatus(BUF_READ);
|
||||||
|
|
||||||
|
if (To_Key_Col || To_Kindex) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Direct access of OCCUR tables is not implemented yet. */
|
||||||
|
/*******************************************************************/
|
||||||
|
strcpy(g->Message, "No direct access to OCCUR tables");
|
||||||
|
return TRUE;
|
||||||
|
} // endif To_Key_Col
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Do open the source table. */
|
||||||
|
/*********************************************************************/
|
||||||
|
return Tdbp->OpenDB(g);
|
||||||
|
} // end of OpenDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Data Base read routine for OCCUR access method. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBOCCUR::ReadDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
int rc = RC_OK;
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Now start the multi reading process. */
|
||||||
|
/*********************************************************************/
|
||||||
|
do {
|
||||||
|
if (RowFlag != 1)
|
||||||
|
if ((rc = Tdbp->ReadDB(g)) != RC_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (Xcolp) {
|
||||||
|
RowFlag = 0;
|
||||||
|
Xcolp->ReadColumn(g);
|
||||||
|
M = Xcolp->GetI();
|
||||||
|
} // endif Xcolp
|
||||||
|
|
||||||
|
} while (RowFlag == 2);
|
||||||
|
|
||||||
|
N++;
|
||||||
|
return rc;
|
||||||
|
} // end of ReadDB
|
||||||
|
|
||||||
|
// ------------------------ OCCURCOL functions ----------------------------
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* OCCURCOL public constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
OCCURCOL::OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n)
|
||||||
|
: COLBLK(cdp, tdbp, n)
|
||||||
|
{
|
||||||
|
// Set additional OCCUR access method information for column.
|
||||||
|
I = 0;
|
||||||
|
} // end of OCCURCOL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* ReadColumn: what this routine does is to access the columns of */
|
||||||
|
/* list, extract their value and convert it to buffer type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void OCCURCOL::ReadColumn(PGLOBAL g)
|
||||||
|
{
|
||||||
|
PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb;
|
||||||
|
PCOL *col = tdbp->Col;
|
||||||
|
|
||||||
|
for (; I < tdbp->Mult; I++) {
|
||||||
|
col[I]->ReadColumn(g);
|
||||||
|
|
||||||
|
if (Nullable || !col[I]->GetValue()->IsZero())
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // endfor I
|
||||||
|
|
||||||
|
if (I == tdbp->Mult) {
|
||||||
|
// No more values, go to next source row
|
||||||
|
tdbp->RowFlag = 2;
|
||||||
|
I = 0;
|
||||||
|
return;
|
||||||
|
} // endif I
|
||||||
|
|
||||||
|
// Set the OCCUR column value from the Ith source column value
|
||||||
|
Value->SetValue_pval(col[I++]->GetValue());
|
||||||
|
tdbp->RowFlag = 1;
|
||||||
|
} // end of ReadColumn
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------ RANKCOL functions ---------------------------
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* ReadColumn: what this routine does is to access the Mth columns of */
|
||||||
|
/* list, extract its name and set to it the rank column value. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void RANKCOL::ReadColumn(PGLOBAL g)
|
||||||
|
{
|
||||||
|
PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb;
|
||||||
|
PCOL *col = tdbp->Col;
|
||||||
|
|
||||||
|
// Set the RANK column value from the Mth source column name
|
||||||
|
if (tdbp->M)
|
||||||
|
Value->SetValue_psz(col[tdbp->M - 1]->GetName());
|
||||||
|
else {
|
||||||
|
Value->Reset();
|
||||||
|
|
||||||
|
if (Nullable)
|
||||||
|
Value->SetNull(true);
|
||||||
|
|
||||||
|
} // endelse
|
||||||
|
|
||||||
|
} // end of ReadColumn
|
145
storage/connect/taboccur.h
Normal file
145
storage/connect/taboccur.h
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
// TABOCCUR.H Olivier Bertrand 2013
|
||||||
|
// Defines the OCCUR tables
|
||||||
|
|
||||||
|
#include "tabutil.h"
|
||||||
|
|
||||||
|
#define TYPE_AM_OCCUR (AMT)128
|
||||||
|
|
||||||
|
typedef class OCCURDEF *POCCURDEF;
|
||||||
|
typedef class TDBOCCUR *PTDBOCCUR;
|
||||||
|
typedef class OCCURCOL *POCCURCOL;
|
||||||
|
typedef class RANKCOL *PRANKCOL;
|
||||||
|
typedef class SRTCOL *PSRTCOL;
|
||||||
|
|
||||||
|
/* -------------------------- OCCUR classes -------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* OCCUR: OEM table that provides a view of a source table where the */
|
||||||
|
/* contain of several columns of the source table is placed in only */
|
||||||
|
/* one column, the OCCUR column, this resulting into several rows. */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* OCCUR table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class OCCURDEF : public PRXDEF { /* Logical table description */
|
||||||
|
friend class TDBOCCUR;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
OCCURDEF(void) {Pseudo = 3; Colist = Xcol = NULL;}
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual const char *GetType(void) {return "OCCUR";}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
|
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
//char *Tabname; /* The source table name */
|
||||||
|
char *Colist; /* The source column list */
|
||||||
|
char *Xcol; /* The multiple occurence column */
|
||||||
|
char *Rcol; /* The rank column */
|
||||||
|
}; // end of OCCURDEF
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This is the class declaration for the OCCUR table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class TDBOCCUR : public TDBPRX {
|
||||||
|
friend class OCCURCOL;
|
||||||
|
friend class RANKCOL;
|
||||||
|
friend class SRTCOL;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
TDBOCCUR(POCCURDEF tdp);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual AMT GetAmType(void) {return TYPE_AM_OCCUR;}
|
||||||
|
void SetTdbp(PTDBASE tdbp) {Tdbp = tdbp;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
//virtual int GetRecpos(void) {return N;}
|
||||||
|
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();}
|
||||||
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
|
PTDB GetSourceTable(PGLOBAL g);
|
||||||
|
int MakeColumnList(PGLOBAL g);
|
||||||
|
|
||||||
|
// Database routines
|
||||||
|
//virtual PCOL ColDB(PGLOBAL g, PSZ colname, int num);
|
||||||
|
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||||
|
virtual int GetMaxSize(PGLOBAL g);
|
||||||
|
virtual bool OpenDB(PGLOBAL g);
|
||||||
|
virtual int ReadDB(PGLOBAL g);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
//PTDBASE Tdbp; // To the source table or view
|
||||||
|
LPCSTR Tabname; // Name of source table
|
||||||
|
char *Colist; // Source column list
|
||||||
|
char *Xcolumn; // Occurence column name
|
||||||
|
char *Rcolumn; // Rank column name
|
||||||
|
POCCURCOL Xcolp; // To the OCCURCOL column
|
||||||
|
PCOL *Col; // To source multiple columns
|
||||||
|
int Mult; // Multiplication factor
|
||||||
|
int N; // The current table index
|
||||||
|
int M; // The occurence rank
|
||||||
|
BYTE RowFlag; // 0: Ok, 1: Same, 2: Skip
|
||||||
|
}; // end of class TDBOCCUR
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Class OCCURCOL: for the multiple occurence column. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class OCCURCOL : public COLBLK {
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n);
|
||||||
|
//OCCURCOL(OCCURCOL *colp, PTDB tdbp); // Constructor used in copy process
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual int GetAmType(void) {return TYPE_AM_OCCUR;}
|
||||||
|
int GetI(void) {return I;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual void Reset(void) {} // Evaluated only by TDBOCCUR
|
||||||
|
virtual void ReadColumn(PGLOBAL g);
|
||||||
|
void Xreset(void) {I = 0;};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Default constructor not to be used
|
||||||
|
OCCURCOL(void) {}
|
||||||
|
|
||||||
|
// Members
|
||||||
|
int I;
|
||||||
|
}; // end of class OCCURCOL
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Class RANKCOL: for the multiple occurence column ranking. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class RANKCOL : public COLBLK {
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
RANKCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n) : COLBLK(cdp, tdbp, n) {}
|
||||||
|
//RANKCOL(RANKCOL *colp, PTDB tdbp); // Constructor used in copy process
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual int GetAmType(void) {return TYPE_AM_OCCUR;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual void ReadColumn(PGLOBAL g);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Default constructor not to be used
|
||||||
|
RANKCOL(void) {}
|
||||||
|
|
||||||
|
// Members
|
||||||
|
}; // end of class RANKCOL
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Definition of class XCOLDEF. */
|
||||||
|
/* This class purpose is just to access COLDEF protected items! */
|
||||||
|
/***********************************************************************/
|
||||||
|
class XCOLDEF: public COLDEF {
|
||||||
|
friend class TDBOCCUR;
|
||||||
|
}; // end of class XCOLDEF
|
||||||
|
|
@@ -1,7 +1,7 @@
|
|||||||
/************* TabTbl C++ Program Source Code File (.CPP) **************/
|
/************* TabTbl C++ Program Source Code File (.CPP) **************/
|
||||||
/* PROGRAM NAME: TABTBL */
|
/* PROGRAM NAME: TABTBL */
|
||||||
/* ------------- */
|
/* ------------- */
|
||||||
/* Version 1.4 */
|
/* Version 1.5 */
|
||||||
/* */
|
/* */
|
||||||
/* COPYRIGHT: */
|
/* COPYRIGHT: */
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
#include "filamtxt.h"
|
#include "filamtxt.h"
|
||||||
#include "tabcol.h"
|
#include "tabcol.h"
|
||||||
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
|
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
|
||||||
#include "tabtbl.h" // TDBTBL and TBLCOL classes dcls
|
#include "tabtbl.h"
|
||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
#include "tabmysql.h"
|
#include "tabmysql.h"
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
@@ -86,7 +86,7 @@ extern "C" int trace;
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
TBLDEF::TBLDEF(void)
|
TBLDEF::TBLDEF(void)
|
||||||
{
|
{
|
||||||
To_Tables = NULL;
|
//To_Tables = NULL;
|
||||||
Ntables = 0;
|
Ntables = 0;
|
||||||
Pseudo = 3;
|
Pseudo = 3;
|
||||||
} // end of TBLDEF constructor
|
} // end of TBLDEF constructor
|
||||||
@@ -100,18 +100,18 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
|
|
||||||
Desc = "Table list table";
|
Desc = "Table list table";
|
||||||
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
|
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
|
||||||
dbname = Cat->GetStringCatInfo(g, "Database", NULL);
|
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
|
||||||
Ntables = 0;
|
Ntables = 0;
|
||||||
|
|
||||||
if (*tablist) {
|
if (*tablist) {
|
||||||
char *p, *pn, *pdb;
|
char *p, *pn, *pdb;
|
||||||
PTBL *ptbl = &To_Tables, tbl;
|
PTABLE tbl;
|
||||||
|
|
||||||
for (pdb = tablist; ;) {
|
for (pdb = tablist; ;) {
|
||||||
if ((p = strchr(pdb, ',')))
|
if ((p = strchr(pdb, ',')))
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
// Analyze the table name, it has the format:
|
// Analyze the table name, it may have the format:
|
||||||
// [dbname.]tabname
|
// [dbname.]tabname
|
||||||
if ((pn = strchr(pdb, '.'))) {
|
if ((pn = strchr(pdb, '.'))) {
|
||||||
*pn++ = 0;
|
*pn++ = 0;
|
||||||
@@ -121,17 +121,18 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
// Allocate the TBLIST block for that table
|
// Allocate the TBLIST block for that table
|
||||||
tbl = (PTBL)PlugSubAlloc(g, NULL, sizeof(TBLIST));
|
tbl = new(g) XTAB(pn);
|
||||||
tbl->Next = NULL;
|
tbl->SetQualifier(pdb);
|
||||||
tbl->Name = pn;
|
|
||||||
tbl->DB = pdb;
|
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("TBL: Name=%s db=%s\n", tbl->Name, SVP(tbl->DB));
|
htrc("TBL: Name=%s db=%s\n", tbl->GetName(), tbl->GetQualifier());
|
||||||
|
|
||||||
// Link the blocks
|
// Link the blocks
|
||||||
*ptbl = tbl;
|
if (Tablep)
|
||||||
ptbl = &tbl->Next;
|
Tablep->Link(tbl);
|
||||||
|
else
|
||||||
|
Tablep = tbl;
|
||||||
|
|
||||||
Ntables++;
|
Ntables++;
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
@@ -153,15 +154,11 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PTDB TBLDEF::GetTable(PGLOBAL g, MODE m)
|
PTDB TBLDEF::GetTable(PGLOBAL g, MODE m)
|
||||||
{
|
{
|
||||||
PTDB tdbp;
|
if (Catfunc == FNC_COL)
|
||||||
|
return new(g) TDBTBC(this);
|
||||||
|
else
|
||||||
|
return new(g) TDBTBL(this);
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
/* Allocate a TDB of the proper type. */
|
|
||||||
/* Column blocks will be allocated only when needed. */
|
|
||||||
/*********************************************************************/
|
|
||||||
tdbp = new(g) TDBTBL(this);
|
|
||||||
|
|
||||||
return tdbp;
|
|
||||||
} // end of GetTable
|
} // end of GetTable
|
||||||
|
|
||||||
/* ------------------------- Class TDBTBL ---------------------------- */
|
/* ------------------------- Class TDBTBL ---------------------------- */
|
||||||
@@ -169,11 +166,11 @@ PTDB TBLDEF::GetTable(PGLOBAL g, MODE m)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TDBTBL constructors. */
|
/* TDBTBL constructors. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
TDBTBL::TDBTBL(PTBLDEF tdp) : TDBASE(tdp)
|
TDBTBL::TDBTBL(PTBLDEF tdp) : TDBPRX(tdp)
|
||||||
{
|
{
|
||||||
Tablist = NULL;
|
Tablist = NULL;
|
||||||
CurTable = NULL;
|
CurTable = NULL;
|
||||||
Tdbp = NULL;
|
//Tdbp = NULL;
|
||||||
Accept = tdp->Accept;
|
Accept = tdp->Accept;
|
||||||
Maxerr = tdp->Maxerr;
|
Maxerr = tdp->Maxerr;
|
||||||
Nbf = 0;
|
Nbf = 0;
|
||||||
@@ -188,7 +185,7 @@ TDBTBL::TDBTBL(PTBLDEF tdp) : TDBASE(tdp)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PCOL TDBTBL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
PCOL TDBTBL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
||||||
{
|
{
|
||||||
return new(g) TBLCOL(cdp, this, cprec, n);
|
return new(g) PRXCOL(cdp, this, cprec, n);
|
||||||
} // end of MakeCol
|
} // end of MakeCol
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -212,13 +209,14 @@ PCOL TDBTBL::InsertSpecialColumn(PGLOBAL g, PCOL scp)
|
|||||||
return colp;
|
return colp;
|
||||||
} // end of InsertSpecialColumn
|
} // end of InsertSpecialColumn
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Get the PTDB of a table of the list. */
|
/* Get the PTDB of a table of the list. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
|
PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
|
||||||
{
|
{
|
||||||
char *db, key[256];
|
//char *db;
|
||||||
uint k;
|
bool mysql;
|
||||||
PTDB tdbp = NULL;
|
PTDB tdbp = NULL;
|
||||||
TABLE_SHARE *s;
|
TABLE_SHARE *s;
|
||||||
PCATLG cat = To_Def->GetCat();
|
PCATLG cat = To_Def->GetCat();
|
||||||
@@ -228,27 +226,21 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
|
|||||||
if (!thd)
|
if (!thd)
|
||||||
return NULL; // Should not happen anymore
|
return NULL; // Should not happen anymore
|
||||||
|
|
||||||
if (tblp->DB)
|
//if (tblp->DB)
|
||||||
db = tblp->DB;
|
// db = tblp->DB;
|
||||||
else
|
//else
|
||||||
db = (char*)hc->GetDBName(NULL);
|
// db = (char*)hc->GetDBName(NULL);
|
||||||
|
|
||||||
k = sprintf(key, "%s", db) + 1;
|
//if (!(s = GetTableShare(g, thd, db, tblp->Name, mysql)))
|
||||||
k += sprintf(key + k, "%s", tblp->Name);
|
if (!(s = GetTableShare(g, thd, tblp->DB, tblp->Name, mysql)))
|
||||||
key[++k] = 0;
|
|
||||||
|
|
||||||
if (!(s = alloc_table_share(db, tblp->Name, key, ++k))) {
|
|
||||||
strcpy(g->Message, "Error allocating share\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
} // endif s
|
|
||||||
|
|
||||||
if (!open_table_def(thd, s)) {
|
if (mysql) {
|
||||||
if (plugin_data(s->db_plugin, handlerton*) != connect_hton) {
|
|
||||||
#if defined(MYSQL_SUPPORT)
|
#if defined(MYSQL_SUPPORT)
|
||||||
// Access sub-table via MySQL API
|
// Access sub-table via MySQL API
|
||||||
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYSQL"))) {
|
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYSQL"))) {
|
||||||
sprintf(g->Message, "Cannot access %s.%s", db, tblp->Name);
|
sprintf(g->Message, "Cannot access %s.%s", tblp->DB, tblp->Name);
|
||||||
return NULL;
|
goto err;
|
||||||
} // endif Define
|
} // endif Define
|
||||||
|
|
||||||
if (tabp->GetQualifier())
|
if (tabp->GetQualifier())
|
||||||
@@ -257,7 +249,7 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
|
|||||||
#else // !MYSQL_SUPPORT
|
#else // !MYSQL_SUPPORT
|
||||||
sprintf(g->Message, "%s.%s is not a CONNECT table",
|
sprintf(g->Message, "%s.%s is not a CONNECT table",
|
||||||
db, tblp->Name);
|
db, tblp->Name);
|
||||||
return NULL;
|
goto err;
|
||||||
#endif // MYSQL_SUPPORT
|
#endif // MYSQL_SUPPORT
|
||||||
} else {
|
} else {
|
||||||
// Sub-table is a CONNECT table
|
// Sub-table is a CONNECT table
|
||||||
@@ -266,16 +258,15 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
|
|||||||
hc->tshp = NULL;
|
hc->tshp = NULL;
|
||||||
} // endif plugin
|
} // endif plugin
|
||||||
|
|
||||||
} else
|
|
||||||
sprintf(g->Message, "Error %d opening share\n", s->error);
|
|
||||||
|
|
||||||
if (trace && tdbp)
|
if (trace && tdbp)
|
||||||
htrc("Subtable %s in %s\n",
|
htrc("Subtable %s in %s\n",
|
||||||
tblp->Name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
tblp->Name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
||||||
|
|
||||||
|
err:
|
||||||
free_table_share(s);
|
free_table_share(s);
|
||||||
return tdbp;
|
return tdbp;
|
||||||
} // end of GetSubTable
|
} // end of GetSubTable
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Initializes the table table list. */
|
/* Initializes the table table list. */
|
||||||
@@ -284,22 +275,19 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
char *colname;
|
char *colname;
|
||||||
int n, colpos;
|
int n, colpos;
|
||||||
PTBL tblp;
|
PTABLE tp, tabp;
|
||||||
PTABLE tabp;
|
|
||||||
PTDB tdbp;
|
PTDB tdbp;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
PTBLDEF tdp = (PTBLDEF)To_Def;
|
PTBLDEF tdp = (PTBLDEF)To_Def;
|
||||||
|
|
||||||
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
// PlugSetPath(filename, Tdbp->GetFile(g), Tdbp->GetPath());
|
||||||
|
|
||||||
for (n = 0, tblp = tdp->GetTables(); tblp; tblp = tblp->Next) {
|
for (n = 0, tp = tdp->Tablep; tp; tp = tp->GetNext()) {
|
||||||
if (TestFil(g, To_Filter, tblp)) {
|
if (TestFil(g, To_Filter, tp)) {
|
||||||
// Table or named view
|
tabp = new(g) XTAB(tp);
|
||||||
tabp = new(g) XTAB(tblp->Name);
|
|
||||||
tabp->SetQualifier(tblp->DB);
|
|
||||||
|
|
||||||
// Get the table description block of this table
|
// Get the table description block of this table
|
||||||
if (!(tdbp = GetSubTable(g, tblp, tabp))) {
|
if (!(tdbp = GetSubTable(g, tabp))) {
|
||||||
if (++Nbf > Maxerr)
|
if (++Nbf > Maxerr)
|
||||||
return TRUE; // Error return
|
return TRUE; // Error return
|
||||||
else
|
else
|
||||||
@@ -313,7 +301,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
||||||
if (!cp->IsSpecial()) {
|
if (!cp->IsSpecial()) {
|
||||||
colname = cp->GetName();
|
colname = cp->GetName();
|
||||||
colpos = ((PTBLCOL)cp)->Colnum;
|
colpos = ((PPRXCOL)cp)->Colnum;
|
||||||
|
|
||||||
// We try first to get the column by name
|
// We try first to get the column by name
|
||||||
if (!(colp = tdbp->ColDB(g, colname, 0)) && colpos)
|
if (!(colp = tdbp->ColDB(g, colname, 0)) && colpos)
|
||||||
@@ -328,7 +316,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
return TRUE; // Error return
|
return TRUE; // Error return
|
||||||
} // endif !Accept
|
} // endif !Accept
|
||||||
|
|
||||||
} else // this is needed in particular by PLG tables
|
} else // this is needed by some tables (which?)
|
||||||
colp->SetColUse(cp->GetColUse());
|
colp->SetColUse(cp->GetColUse());
|
||||||
|
|
||||||
} // endif !special
|
} // endif !special
|
||||||
@@ -351,7 +339,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Test the tablename against the pseudo "local" filter. */
|
/* Test the tablename against the pseudo "local" filter. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTBL tblp)
|
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTABLE tabp)
|
||||||
{
|
{
|
||||||
char *fil, op[8], tn[NAME_LEN];
|
char *fil, op[8], tn[NAME_LEN];
|
||||||
bool neg;
|
bool neg;
|
||||||
@@ -374,7 +362,7 @@ bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTBL tblp)
|
|||||||
if (sscanf(fil, "TABID = '%[^']'", tn) != 1)
|
if (sscanf(fil, "TABID = '%[^']'", tn) != 1)
|
||||||
return TRUE; // ignore invalid filter
|
return TRUE; // ignore invalid filter
|
||||||
|
|
||||||
return !stricmp(tn, tblp->Name);
|
return !stricmp(tn, tabp->GetName());
|
||||||
} else if (!strcmp(op, "IN")) {
|
} else if (!strcmp(op, "IN")) {
|
||||||
char *p, *tnl = (char*)PlugSubAlloc(g, NULL, strlen(fil) - 10);
|
char *p, *tnl = (char*)PlugSubAlloc(g, NULL, strlen(fil) - 10);
|
||||||
int n;
|
int n;
|
||||||
@@ -393,7 +381,7 @@ bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTBL tblp)
|
|||||||
|
|
||||||
if (sscanf(tnl, "'%[^']'", tn) != 1)
|
if (sscanf(tnl, "'%[^']'", tn) != 1)
|
||||||
return TRUE; // ignore invalid filter
|
return TRUE; // ignore invalid filter
|
||||||
else if (!stricmp(tn, tblp->Name))
|
else if (!stricmp(tn, tabp->GetName()))
|
||||||
return !neg; // Found
|
return !neg; // Found
|
||||||
|
|
||||||
tnl = p;
|
tnl = p;
|
||||||
@@ -405,19 +393,19 @@ bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTBL tblp)
|
|||||||
return TRUE; // invalid operator
|
return TRUE; // invalid operator
|
||||||
} // end of TestFil
|
} // end of TestFil
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TBL GetProgMax: get the max value for progress information. */
|
/* TBL GetProgMax: get the max value for progress information. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBTBL::GetProgMax(PGLOBAL g)
|
int TDBTBL::GetProgMax(PGLOBAL g)
|
||||||
{
|
{
|
||||||
PTABLE tblp;
|
|
||||||
int n, pmx = 0;
|
int n, pmx = 0;
|
||||||
|
|
||||||
if (!Tablist && InitTableList(g))
|
if (!Tablist && InitTableList(g))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (tblp = Tablist; tblp; tblp = tblp->GetNext())
|
for (PTABLE tabp = Tablist; tabp; tblp = tabp->GetNext())
|
||||||
if ((n = tblp->GetTo_Tdb()->GetProgMax(g)) > 0)
|
if ((n = tabp->GetTo_Tdb()->GetProgMax(g)) > 0)
|
||||||
pmx += n;
|
pmx += n;
|
||||||
|
|
||||||
return pmx;
|
return pmx;
|
||||||
@@ -431,7 +419,6 @@ int TDBTBL::GetProgCur(void)
|
|||||||
return Crp + Tdbp->GetProgCur();
|
return Crp + Tdbp->GetProgCur();
|
||||||
} // end of GetProgCur
|
} // end of GetProgCur
|
||||||
|
|
||||||
#if 0
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TBL Cardinality: returns table cardinality in number of rows. */
|
/* TBL Cardinality: returns table cardinality in number of rows. */
|
||||||
/* This function can be called with a null argument to test the */
|
/* This function can be called with a null argument to test the */
|
||||||
@@ -470,7 +457,6 @@ int TDBTBL::Cardinality(PGLOBAL g)
|
|||||||
int TDBTBL::GetMaxSize(PGLOBAL g)
|
int TDBTBL::GetMaxSize(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (MaxSize < 0) {
|
if (MaxSize < 0) {
|
||||||
PTABLE tblp;
|
|
||||||
int mxsz;
|
int mxsz;
|
||||||
|
|
||||||
if (!Tablist && InitTableList(g))
|
if (!Tablist && InitTableList(g))
|
||||||
@@ -482,8 +468,8 @@ int TDBTBL::GetMaxSize(PGLOBAL g)
|
|||||||
// } else
|
// } else
|
||||||
MaxSize = 0;
|
MaxSize = 0;
|
||||||
|
|
||||||
for (tblp = Tablist; tblp; tblp = tblp->GetNext()) {
|
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) {
|
||||||
if ((mxsz = tblp->GetTo_Tdb()->GetMaxSize(g)) < 0) {
|
if ((mxsz = tabp->GetTo_Tdb()->GetMaxSize(g)) < 0) {
|
||||||
MaxSize = -1;
|
MaxSize = -1;
|
||||||
return mxsz;
|
return mxsz;
|
||||||
} // endif mxsz
|
} // endif mxsz
|
||||||
@@ -505,8 +491,8 @@ void TDBTBL::ResetDB(void)
|
|||||||
if (colp->GetAmType() == TYPE_AM_TABID)
|
if (colp->GetAmType() == TYPE_AM_TABID)
|
||||||
colp->COLBLK::Reset();
|
colp->COLBLK::Reset();
|
||||||
|
|
||||||
for (PTABLE tblp = Tablist; tblp; tblp = tblp->GetNext())
|
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
|
||||||
((PTDBASE)tblp->GetTo_Tdb())->ResetDB();
|
((PTDBASE)tabp->GetTo_Tdb())->ResetDB();
|
||||||
|
|
||||||
Tdbp = (PTDBASE)Tablist->GetTo_Tdb();
|
Tdbp = (PTDBASE)Tablist->GetTo_Tdb();
|
||||||
Crp = 0;
|
Crp = 0;
|
||||||
@@ -573,7 +559,7 @@ bool TDBTBL::OpenDB(PGLOBAL g)
|
|||||||
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
||||||
if (cp->GetAmType() == TYPE_AM_TABID)
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
||||||
cp->COLBLK::Reset();
|
cp->COLBLK::Reset();
|
||||||
else if (((PTBLCOL)cp)->Init(g))
|
else if (((PPRXCOL)cp)->Init(g))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
@@ -627,7 +613,7 @@ int TDBTBL::ReadDB(PGLOBAL g)
|
|||||||
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
||||||
if (cp->GetAmType() == TYPE_AM_TABID)
|
if (cp->GetAmType() == TYPE_AM_TABID)
|
||||||
cp->COLBLK::Reset();
|
cp->COLBLK::Reset();
|
||||||
else if (((PTBLCOL)cp)->Init(g))
|
else if (((PPRXCOL)cp)->Init(g))
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
@@ -648,6 +634,7 @@ int TDBTBL::ReadDB(PGLOBAL g)
|
|||||||
return rc;
|
return rc;
|
||||||
} // end of ReadDB
|
} // end of ReadDB
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Data Base write routine for MUL access method. */
|
/* Data Base write routine for MUL access method. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -675,9 +662,11 @@ void TDBTBL::CloseDB(PGLOBAL g)
|
|||||||
Tdbp->CloseDB(g);
|
Tdbp->CloseDB(g);
|
||||||
|
|
||||||
} // end of CloseDB
|
} // end of CloseDB
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/* ---------------------------- TBLCOL ------------------------------- */
|
/* ---------------------------- TBLCOL ------------------------------- */
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TBLCOL public constructor. */
|
/* TBLCOL public constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -705,7 +694,6 @@ TBLCOL::TBLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|||||||
|
|
||||||
} // end of TBLCOL constructor
|
} // end of TBLCOL constructor
|
||||||
|
|
||||||
#if 0
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TBLCOL public constructor. */
|
/* TBLCOL public constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -733,7 +721,6 @@ TBLCOL::TBLCOL(TBLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
|
|||||||
To_Val = col1->To_Val;
|
To_Val = col1->To_Val;
|
||||||
Pseudo = col1->Pseudo;
|
Pseudo = col1->Pseudo;
|
||||||
} // end of TBLCOL copy constructor
|
} // end of TBLCOL copy constructor
|
||||||
#endif
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TBLCOL initialization routine. */
|
/* TBLCOL initialization routine. */
|
||||||
@@ -783,6 +770,7 @@ void TBLCOL::ReadColumn(PGLOBAL g)
|
|||||||
} // endif Colp
|
} // endif Colp
|
||||||
|
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/* ---------------------------- TBTBLK ------------------------------- */
|
/* ---------------------------- TBTBLK ------------------------------- */
|
||||||
|
|
||||||
|
@@ -1,41 +1,30 @@
|
|||||||
/*************** TabTbl H Declares Source Code File (.H) ***************/
|
/*************** TabTbl H Declares Source Code File (.H) ***************/
|
||||||
/* Name: TABTBL.H Version 1.2 */
|
/* Name: TABTBL.H Version 1.2 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2008-2012 */
|
/* (C) Copyright to the author Olivier BERTRAND 2008-2013 */
|
||||||
/* */
|
/* */
|
||||||
/* This file contains the TDBTBL classes declares. */
|
/* This file contains the TDBTBL classes declares. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
//#include "osutil.h"
|
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
#include "colblk.h"
|
#include "colblk.h"
|
||||||
|
#include "tabutil.h"
|
||||||
|
|
||||||
typedef class TBLDEF *PTBLDEF;
|
typedef class TBLDEF *PTBLDEF;
|
||||||
typedef class TDBTBL *PTDBTBL;
|
typedef class TDBTBL *PTDBTBL;
|
||||||
typedef class TBLCOL *PTBLCOL;
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* Defines the structure used for multiple tables. */
|
|
||||||
/***********************************************************************/
|
|
||||||
typedef struct _tablist *PTBL;
|
|
||||||
|
|
||||||
typedef struct _tablist {
|
|
||||||
PTBL Next;
|
|
||||||
char *Name;
|
|
||||||
char *DB;
|
|
||||||
} TBLIST;
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TBL table. */
|
/* TBL table. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class DllExport TBLDEF : public TABDEF { /* Logical table description */
|
class DllExport TBLDEF : public PRXDEF { /* Logical table description */
|
||||||
friend class TDBTBL;
|
friend class TDBTBL;
|
||||||
|
friend class TDBTBC;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TBLDEF(void);
|
TBLDEF(void);
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual const char *GetType(void) {return "TBL";}
|
virtual const char *GetType(void) {return "TBL";}
|
||||||
PTBL GetTables(void) {return To_Tables;}
|
//PTABLE GetTables(void) {return Tablep;}
|
||||||
//int GetNtables(void) {return Ntables;}
|
//int GetNtables(void) {return Ntables;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -44,7 +33,7 @@ class DllExport TBLDEF : public TABDEF { /* Logical table description */
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
PTBL To_Tables; /* To the list of tables */
|
//PTABLE To_Tables; /* To the list of tables */
|
||||||
bool Accept; /* TRUE if bad tables are accepted */
|
bool Accept; /* TRUE if bad tables are accepted */
|
||||||
int Maxerr; /* Maximum number of bad tables */
|
int Maxerr; /* Maximum number of bad tables */
|
||||||
int Ntables; /* Number of tables */
|
int Ntables; /* Number of tables */
|
||||||
@@ -53,50 +42,46 @@ class DllExport TBLDEF : public TABDEF { /* Logical table description */
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This is the TBL Access Method class declaration. */
|
/* This is the TBL Access Method class declaration. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class DllExport TDBTBL : public TDBASE {
|
class DllExport TDBTBL : public TDBPRX {
|
||||||
friend class TBLCOL;
|
//friend class TBLCOL;
|
||||||
friend class TBTBLK;
|
friend class TBTBLK;
|
||||||
friend class TDBPLG;
|
friend class TDBPLG;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TDBTBL(PTBLDEF tdp = NULL);
|
TDBTBL(PTBLDEF tdp = NULL);
|
||||||
//TDBTBL(PTDBTBL tdbp);
|
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual AMT GetAmType(void) {return TYPE_AM_TBL;}
|
virtual AMT GetAmType(void) {return TYPE_AM_TBL;}
|
||||||
//virtual PTDB Duplicate(PGLOBAL g)
|
|
||||||
// {return (PTDB)new(g) TDBTBL(this);}
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void ResetDB(void);
|
virtual void ResetDB(void);
|
||||||
//virtual PTABLE GetTablist(void) {return (PSZ)Tablist;}
|
//virtual PTABLE GetTablist(void) {return (PSZ)Tablist;}
|
||||||
//virtual PTDB CopyOne(PTABS t);
|
|
||||||
virtual int GetRecpos(void) {return Rows;}
|
virtual int GetRecpos(void) {return Rows;}
|
||||||
virtual int GetBadLines(void) {return (int)Nbf;}
|
virtual int GetBadLines(void) {return (int)Nbf;}
|
||||||
|
|
||||||
// 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 int GetMaxSize(PGLOBAL g);
|
virtual int GetMaxSize(PGLOBAL g);
|
||||||
virtual int GetProgMax(PGLOBAL g);
|
//virtual int GetProgMax(PGLOBAL g);
|
||||||
virtual int GetProgCur(void);
|
//virtual int GetProgCur(void);
|
||||||
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL scp);
|
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL scp);
|
||||||
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);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal functions
|
// Internal functions
|
||||||
PTDB GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp);
|
//PTDB GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp);
|
||||||
bool InitTableList(PGLOBAL g);
|
bool InitTableList(PGLOBAL g);
|
||||||
bool TestFil(PGLOBAL g, PFIL filp, PTBL tblp);
|
bool TestFil(PGLOBAL g, PFIL filp, PTABLE tabp);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
PTABLE Tablist; // Points to the table list
|
PTABLE Tablist; // Points to the table list
|
||||||
PTABLE CurTable; // Points to the current table
|
PTABLE CurTable; // Points to the current table
|
||||||
PTDBASE Tdbp; // Current table PTDB
|
//PTDBASE Tdbp; // Current table PTDB
|
||||||
bool Accept; // TRUE if bad tables are accepted
|
bool Accept; // TRUE if bad tables are accepted
|
||||||
int Maxerr; // Maximum number of bad tables
|
int Maxerr; // Maximum number of bad tables
|
||||||
int Nbf; // Number of bad connections
|
int Nbf; // Number of bad connections
|
||||||
@@ -104,6 +89,7 @@ class DllExport TDBTBL : public TDBASE {
|
|||||||
int Crp; // Used for CurPos
|
int Crp; // Used for CurPos
|
||||||
}; // end of class TDBTBL
|
}; // end of class TDBTBL
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Class TBLCOL: TBL access method column descriptor. */
|
/* Class TBLCOL: TBL access method column descriptor. */
|
||||||
/* This A.M. is used for TBL tables. */
|
/* This A.M. is used for TBL tables. */
|
||||||
@@ -136,6 +122,7 @@ class DllExport TBLCOL : public COLBLK {
|
|||||||
bool Pseudo; // TRUE for special columns
|
bool Pseudo; // TRUE for special columns
|
||||||
int Colnum; // Used when retrieving columns by number
|
int Colnum; // Used when retrieving columns by number
|
||||||
}; // end of class TBLCOL
|
}; // end of class TBLCOL
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Class TBTBLK: TDBPLG TABID special column descriptor. */
|
/* Class TBTBLK: TDBPLG TABID special column descriptor. */
|
||||||
|
596
storage/connect/tabutil.cpp
Normal file
596
storage/connect/tabutil.cpp
Normal file
@@ -0,0 +1,596 @@
|
|||||||
|
/************* Tabutil cpp Declares Source Code File (.H) **************/
|
||||||
|
/* Name: TABUTIL.CPP Version 1.0 */
|
||||||
|
/* */
|
||||||
|
/* (C) Copyright to the author Olivier BERTRAND 2013 */
|
||||||
|
/* */
|
||||||
|
/* Utility function used by TBL and PRX tables. */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Include relevant section of system dependant header files. */
|
||||||
|
/***********************************************************************/
|
||||||
|
#include "my_global.h"
|
||||||
|
#include "sql_class.h"
|
||||||
|
#include "table.h"
|
||||||
|
#include "field.h"
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(__BORLANDC__)
|
||||||
|
#define __MFC_COMPAT__ // To define min/max as macro
|
||||||
|
#endif
|
||||||
|
//#include <windows.h>
|
||||||
|
#else
|
||||||
|
#if defined(UNIX)
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "osutil.h"
|
||||||
|
#else
|
||||||
|
//#include <io.h>
|
||||||
|
#endif
|
||||||
|
//#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Include application header files: */
|
||||||
|
/***********************************************************************/
|
||||||
|
#include "table.h" // MySQL table definitions
|
||||||
|
#include "global.h"
|
||||||
|
#include "plgdbsem.h"
|
||||||
|
#include "plgcnx.h" // For DB types
|
||||||
|
#include "myutil.h"
|
||||||
|
#include "mycat.h"
|
||||||
|
#include "valblk.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "reldef.h"
|
||||||
|
#include "xtable.h"
|
||||||
|
#if defined(MYSQL_SUPPORT)
|
||||||
|
#include "tabmysql.h"
|
||||||
|
#endif // MYSQL_SUPPORT
|
||||||
|
#include "tabcol.h"
|
||||||
|
#include "tabutil.h"
|
||||||
|
#include "ha_connect.h"
|
||||||
|
|
||||||
|
extern "C" int trace;
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* GetTableShare: allocates and open a table share. */
|
||||||
|
/************************************************************************/
|
||||||
|
TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
|
||||||
|
const char *name, bool& mysql)
|
||||||
|
{
|
||||||
|
char key[256];
|
||||||
|
uint k;
|
||||||
|
//TABLE_LIST table_list;
|
||||||
|
TABLE_SHARE *s;
|
||||||
|
|
||||||
|
//table_list.init_one_table(db, strlen(db), name, strlen(name),
|
||||||
|
// NULL, TL_IGNORE);
|
||||||
|
k = sprintf(key, "%s", db);
|
||||||
|
k += sprintf(key + ++k, "%s", name);
|
||||||
|
key[++k] = 0;
|
||||||
|
|
||||||
|
if (!(s = alloc_table_share(db, name, key, ++k))) {
|
||||||
|
strcpy(g->Message, "Error allocating share\n");
|
||||||
|
return NULL;
|
||||||
|
} // endif s
|
||||||
|
|
||||||
|
// 1 2 4 8
|
||||||
|
//flags = GTS_TABLE | GTS_VIEW | GTS_NOLOCK | GTS_FORCE_DISCOVERY;
|
||||||
|
|
||||||
|
if (!open_table_def(thd, s, GTS_TABLE)) {
|
||||||
|
#ifdef DBUG_OFF
|
||||||
|
if (stricmp(s->db_plugin->name.str, "connect")) {
|
||||||
|
#else
|
||||||
|
if (stricmp((*s->db_plugin)->name.str, "connect")) {
|
||||||
|
#endif
|
||||||
|
#if defined(MYSQL_SUPPORT)
|
||||||
|
mysql = true;
|
||||||
|
#else // !MYSQL_SUPPORT
|
||||||
|
sprintf(g->Message, "%s.%s is not a CONNECT table", db, name);
|
||||||
|
return NULL;
|
||||||
|
#endif // MYSQL_SUPPORT
|
||||||
|
} else
|
||||||
|
mysql = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sprintf(g->Message, "Error %d opening share\n", s->error);
|
||||||
|
free_table_share(s);
|
||||||
|
return NULL;
|
||||||
|
} // endif open_table_def
|
||||||
|
|
||||||
|
return s;
|
||||||
|
} // end of GetTableShare
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* TabColumns: constructs the result blocks containing all the columns */
|
||||||
|
/* of the object table that will be retrieved by GetData commands. */
|
||||||
|
/* key = TRUE when called from Create Table to get key informations. */
|
||||||
|
/************************************************************************/
|
||||||
|
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
||||||
|
const char *name, bool info)
|
||||||
|
{
|
||||||
|
static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT,
|
||||||
|
DB_INT, DB_SHORT, DB_SHORT, DB_SHORT,
|
||||||
|
DB_CHAR, DB_CHAR, DB_CHAR};
|
||||||
|
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
||||||
|
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
|
||||||
|
TYPE_STRING, TYPE_STRING, TYPE_STRING};
|
||||||
|
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
|
||||||
|
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
|
||||||
|
FLD_REM, FLD_NO, FLD_CHARSET};
|
||||||
|
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
|
||||||
|
char *fld, *fmt;
|
||||||
|
int i, n, ncol = sizeof(dbtype) / sizeof(int);
|
||||||
|
int len, type, prec;
|
||||||
|
bool mysql;
|
||||||
|
TABLE_SHARE *s;
|
||||||
|
Field* *field;
|
||||||
|
Field *fp;
|
||||||
|
PQRYRES qrp;
|
||||||
|
PCOLRES crp;
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
if (!(s = GetTableShare(g, thd, db, name, mysql)))
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
n = s->fieldnames.count;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
n = 0;
|
||||||
|
length[0] = 128;
|
||||||
|
} // endif info
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Allocate the structures used to refer to the result set. */
|
||||||
|
/**********************************************************************/
|
||||||
|
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
|
||||||
|
dbtype, buftyp, fldtyp, length, true, true);
|
||||||
|
|
||||||
|
// Some columns must be renamed
|
||||||
|
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
|
||||||
|
switch (++i) {
|
||||||
|
case 10: crp->Name = "Date_fmt"; break;
|
||||||
|
case 11: crp->Name = "Collation"; break;
|
||||||
|
} // endswitch i
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
return qrp;
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Now get the results into blocks. */
|
||||||
|
/**********************************************************************/
|
||||||
|
for (i = 0, field= s->field; *field; i++, field++) {
|
||||||
|
fp= *field;
|
||||||
|
|
||||||
|
// Get column name
|
||||||
|
crp = qrp->Colresp; // Column_Name
|
||||||
|
fld = (char *)fp->field_name;
|
||||||
|
crp->Kdata->SetValue(fld, i);
|
||||||
|
|
||||||
|
if ((type = MYSQLtoPLG(fp->type())) == TYPE_ERROR) {
|
||||||
|
sprintf(g->Message, "Unsupported column type %s", GetTypeName(type));
|
||||||
|
qrp = NULL;
|
||||||
|
break;
|
||||||
|
} // endif type
|
||||||
|
|
||||||
|
crp = crp->Next; // Data_Type
|
||||||
|
crp->Kdata->SetValue(type, i);
|
||||||
|
crp = crp->Next; // Type_Name
|
||||||
|
crp->Kdata->SetValue(GetTypeName(type), i);
|
||||||
|
|
||||||
|
if (type == TYPE_DATE) {
|
||||||
|
// When creating tables we do need info about date columns
|
||||||
|
if (mysql) {
|
||||||
|
fmt = MyDateFmt(fp->type());
|
||||||
|
len = strlen(fmt);
|
||||||
|
} else {
|
||||||
|
fmt = (char*)fp->option_struct->dateformat;
|
||||||
|
len = fp->field_length;
|
||||||
|
} // endif mysql
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fmt = NULL;
|
||||||
|
len = fp->char_length();
|
||||||
|
} // endif type
|
||||||
|
|
||||||
|
crp = crp->Next; // Precision
|
||||||
|
crp->Kdata->SetValue(len, i);
|
||||||
|
|
||||||
|
crp = crp->Next; // Length
|
||||||
|
len = fp->field_length;
|
||||||
|
crp->Kdata->SetValue(len, i);
|
||||||
|
|
||||||
|
prec = (type == TYPE_FLOAT) ? fp->decimals() : 0;
|
||||||
|
crp = crp->Next; // Scale
|
||||||
|
crp->Kdata->SetValue(prec, i);
|
||||||
|
|
||||||
|
crp = crp->Next; // Radix
|
||||||
|
crp->Kdata->SetValue(0, i);
|
||||||
|
|
||||||
|
crp = crp->Next; // Nullable
|
||||||
|
crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i);
|
||||||
|
|
||||||
|
crp = crp->Next; // Remark
|
||||||
|
fld = fp->comment.str;
|
||||||
|
crp->Kdata->SetValue(fld, fp->comment.length, i);
|
||||||
|
|
||||||
|
crp = crp->Next; // New
|
||||||
|
crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
|
||||||
|
|
||||||
|
crp = crp->Next; // New (charset)
|
||||||
|
fld = (char *)fp->charset()->name;
|
||||||
|
crp->Kdata->SetValue(fld, i);
|
||||||
|
|
||||||
|
// Add this item
|
||||||
|
qrp->Nblin++;
|
||||||
|
} // endfor field
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Return the result pointer for use by GetData routines. */
|
||||||
|
/**********************************************************************/
|
||||||
|
free_table_share(s);
|
||||||
|
return qrp;
|
||||||
|
} // end of TabColumns
|
||||||
|
|
||||||
|
/* -------------- Implementation of the XCOL classes ---------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* PRXDEF constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PRXDEF::PRXDEF(void)
|
||||||
|
{
|
||||||
|
Tablep = NULL;
|
||||||
|
Pseudo = 3;
|
||||||
|
} // end of PRXDEF constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DefineAM: define specific AM block values from XCOL file. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
|
{
|
||||||
|
char *pn, *db, *tab;
|
||||||
|
|
||||||
|
db = Cat->GetStringCatInfo(g, "Dbname", "*");
|
||||||
|
tab = Cat->GetStringCatInfo(g, "Tabname", NULL);
|
||||||
|
|
||||||
|
// Analyze the table name, it may have the format: [dbname.]tabname
|
||||||
|
if ((pn = strchr(tab, '.'))) {
|
||||||
|
*pn++ = 0;
|
||||||
|
db = tab;
|
||||||
|
tab = pn;
|
||||||
|
} // endif pn
|
||||||
|
|
||||||
|
Tablep = new(g) XTAB(tab);
|
||||||
|
Tablep->SetQualifier(db);
|
||||||
|
return FALSE;
|
||||||
|
} // end of DefineAM
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* GetTable: makes a new TDB of the proper type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PTDB PRXDEF::GetTable(PGLOBAL g, MODE mode)
|
||||||
|
{
|
||||||
|
if (Catfunc == FNC_COL)
|
||||||
|
return new(g) TDBTBC(this);
|
||||||
|
else
|
||||||
|
return new(g) TDBPRX(this);
|
||||||
|
|
||||||
|
} // end of GetTable
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Implementation of the TDBPRX class. */
|
||||||
|
/***********************************************************************/
|
||||||
|
TDBPRX::TDBPRX(PPRXDEF tdp) : TDBASE(tdp)
|
||||||
|
{
|
||||||
|
Tdbp = NULL; // The object table
|
||||||
|
} // end of TDBPRX constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Get the PTDB of the sub-table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp)
|
||||||
|
{
|
||||||
|
char *db, *name;
|
||||||
|
bool mysql;
|
||||||
|
PTDB tdbp = NULL;
|
||||||
|
TABLE_SHARE *s;
|
||||||
|
PCATLG cat = To_Def->GetCat();
|
||||||
|
PHC hc = ((MYCAT*)cat)->GetHandler();
|
||||||
|
THD *thd = (hc->GetTable())->in_use;
|
||||||
|
|
||||||
|
db = (char*)tabp->GetQualifier();
|
||||||
|
name = (char*)tabp->GetName();
|
||||||
|
|
||||||
|
if (!(s = GetTableShare(g, thd, db, name, mysql)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hc->tshp = s;
|
||||||
|
|
||||||
|
if (mysql) {
|
||||||
|
#if defined(MYSQL_SUPPORT)
|
||||||
|
// Access sub-table via MySQL API
|
||||||
|
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYSQL"))) {
|
||||||
|
sprintf(g->Message, "Cannot access %s.%s", db, name);
|
||||||
|
goto err;
|
||||||
|
} // endif Define
|
||||||
|
|
||||||
|
if (db)
|
||||||
|
((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier());
|
||||||
|
|
||||||
|
#else // !MYSQL_SUPPORT
|
||||||
|
sprintf(g->Message, "%s.%s is not a CONNECT table",
|
||||||
|
db, tblp->Name);
|
||||||
|
goto err;
|
||||||
|
#endif // MYSQL_SUPPORT
|
||||||
|
} else
|
||||||
|
// Sub-table is a CONNECT table
|
||||||
|
tdbp = cat->GetTable(g, tabp);
|
||||||
|
|
||||||
|
hc->tshp = NULL;
|
||||||
|
|
||||||
|
if (trace && tdbp)
|
||||||
|
htrc("Subtable %s in %s\n",
|
||||||
|
name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
|
||||||
|
|
||||||
|
err:
|
||||||
|
free_table_share(s);
|
||||||
|
return tdbp;
|
||||||
|
} // end of GetSubTable
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Initializes the table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBPRX::InitTable(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (!Tdbp) {
|
||||||
|
// Get the table description block of this table
|
||||||
|
if (!(Tdbp = (PTDBASE)GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
} // endif Tdbp
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
} // end of InitTable
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Allocate PRX column description block. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PCOL TDBPRX::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
||||||
|
{
|
||||||
|
return new(g) PRXCOL(cdp, this, cprec, n);
|
||||||
|
} // end of MakeCol
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* PRX GetMaxSize: returns the maximum number of rows in the table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBPRX::GetMaxSize(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (MaxSize < 0) {
|
||||||
|
if (InitTable(g))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
MaxSize = Tdbp->GetMaxSize(g);
|
||||||
|
} // endif MaxSize
|
||||||
|
|
||||||
|
return MaxSize;
|
||||||
|
} // end of GetMaxSize
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* In this sample, ROWID will be the (virtual) row number, */
|
||||||
|
/* while ROWNUM will be the occurence rank in the multiple column. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBPRX::RowNumber(PGLOBAL g, bool b)
|
||||||
|
{
|
||||||
|
return Tdbp->RowNumber(g, b);
|
||||||
|
} // end of RowNumber
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCV Access Method opening routine. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBPRX::OpenDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (Use == USE_OPEN) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Table already open, just replace it at its beginning. */
|
||||||
|
/*******************************************************************/
|
||||||
|
return Tdbp->OpenDB(g);
|
||||||
|
} // endif use
|
||||||
|
|
||||||
|
if (Mode != MODE_READ) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Currently XCOL tables cannot be modified. */
|
||||||
|
/*******************************************************************/
|
||||||
|
strcpy(g->Message, "PROXY tables are read only");
|
||||||
|
return TRUE;
|
||||||
|
} // endif Mode
|
||||||
|
|
||||||
|
if (InitTable(g))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Check and initialize the subtable columns. */
|
||||||
|
/*********************************************************************/
|
||||||
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
||||||
|
if (((PPRXCOL)cp)->Init(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Physically open the object table. */
|
||||||
|
/*********************************************************************/
|
||||||
|
if (Tdbp->OpenDB(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
} // end of OpenDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Data Base read routine for XCV access method. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBPRX::ReadDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Now start the reading process. */
|
||||||
|
/*********************************************************************/
|
||||||
|
return Tdbp->ReadDB(g);
|
||||||
|
} // end of ReadDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* WriteDB: Data Base write routine for XCV access methods. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBPRX::WriteDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
sprintf(g->Message, "%s tables are read only", To_Def->GetType());
|
||||||
|
return RC_FX;
|
||||||
|
} // end of WriteDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Data Base delete line routine for XCV access methods. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBPRX::DeleteDB(PGLOBAL g, int irc)
|
||||||
|
{
|
||||||
|
sprintf(g->Message, "Delete not enabled for %s tables",
|
||||||
|
To_Def->GetType());
|
||||||
|
return RC_FX;
|
||||||
|
} // end of DeleteDB
|
||||||
|
|
||||||
|
/* ---------------------------- PRXCOL ------------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* PRXCOL public constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
||||||
|
: COLBLK(cdp, tdbp, i)
|
||||||
|
{
|
||||||
|
if (cprec) {
|
||||||
|
Next = cprec->GetNext();
|
||||||
|
cprec->SetNext(this);
|
||||||
|
} else {
|
||||||
|
Next = tdbp->GetColumns();
|
||||||
|
tdbp->SetColumns(this);
|
||||||
|
} // endif cprec
|
||||||
|
|
||||||
|
// Set additional Dos access method information for column.
|
||||||
|
Long = cdp->GetLong(); // Useful ???
|
||||||
|
//strcpy(F_Date, cdp->F_Date);
|
||||||
|
Colp = NULL;
|
||||||
|
To_Val = NULL;
|
||||||
|
Pseudo = FALSE;
|
||||||
|
Colnum = cdp->GetOffset(); // If columns are retrieved by number
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
|
||||||
|
|
||||||
|
} // end of PRXCOL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* PRXCOL initialization routine. */
|
||||||
|
/* Look for the matching column in the object table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool PRXCOL::Init(PGLOBAL g)
|
||||||
|
{
|
||||||
|
PTDBPRX tdbp = (PTDBPRX)To_Tdb;
|
||||||
|
|
||||||
|
if (!(Colp = tdbp->Tdbp->ColDB(g, Name, 0)) && Colnum)
|
||||||
|
Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum);
|
||||||
|
|
||||||
|
if (Colp) {
|
||||||
|
Colp->InitValue(g); // May not have been done elsewhere
|
||||||
|
To_Val = Colp->GetValue();
|
||||||
|
} else {
|
||||||
|
sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName());
|
||||||
|
return TRUE;
|
||||||
|
} // endif Colp
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
} // end of Init
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* ReadColumn: */
|
||||||
|
/***********************************************************************/
|
||||||
|
void PRXCOL::ReadColumn(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (trace)
|
||||||
|
htrc("PRX ReadColumn: name=%s\n", Name);
|
||||||
|
|
||||||
|
if (Colp) {
|
||||||
|
Colp->ReadColumn(g);
|
||||||
|
Value->SetValue_pval(To_Val);
|
||||||
|
|
||||||
|
// Set null when applicable
|
||||||
|
if (Nullable)
|
||||||
|
Value->SetNull(Value->IsNull());
|
||||||
|
|
||||||
|
} // endif Colp
|
||||||
|
|
||||||
|
} // end of ReadColumn
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* ---------------------------TBCDEF class --------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DefineAM: define specific AM block values from CATLG table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
|
{
|
||||||
|
Desc = "Catalog Table";
|
||||||
|
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||||
|
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
||||||
|
return FALSE;
|
||||||
|
} // end of DefineAM
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* GetTable: makes a new TDB of the proper type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PTDB TBCDEF::GetTable(PGLOBAL g, MODE m)
|
||||||
|
{
|
||||||
|
return new(g) TDBTBC(this);
|
||||||
|
} // end of GetTable
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
/* ---------------------------TDBTBC class --------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* TDBTBC class constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
TDBTBC::TDBTBC(PPRXDEF tdp) : TDBCAT(tdp)
|
||||||
|
{
|
||||||
|
// Db = tdp->Database;
|
||||||
|
// Tab = tdp->Tabname;
|
||||||
|
Db = (PSZ)tdp->Tablep->GetQualifier();
|
||||||
|
Tab = (PSZ)tdp->Tablep->GetName();
|
||||||
|
} // end of TDBTBC constructor
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/***********************************************************************/
|
||||||
|
/* TDBTBC class constructor from TBL table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
TDBTBC::TDBTBC(PTBLDEF tdp) : TDBCAT(tdp)
|
||||||
|
{
|
||||||
|
Db = tdp->To_Tables->DB;
|
||||||
|
Tab = tdp->To_Tables->Name;
|
||||||
|
} // end of TDBTBC constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* TDBTBC class constructor from PRX table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
TDBTBC::TDBTBC(PXCLDEF tdp) : TDBCAT(tdp)
|
||||||
|
{
|
||||||
|
Db = (PSZ)tdp->Tablep->GetQualifier();
|
||||||
|
Tab = (PSZ)tdp->Tablep->GetName();
|
||||||
|
} // end of TDBTBC constructor
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* GetResult: Get the list the MYSQL table columns. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PQRYRES TDBTBC::GetResult(PGLOBAL g)
|
||||||
|
{
|
||||||
|
return TabColumns(g, current_thd, Db, Tab, false);
|
||||||
|
} // end of GetResult
|
||||||
|
|
181
storage/connect/tabutil.h
Normal file
181
storage/connect/tabutil.h
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
// TABUTIL.H Olivier Bertrand 2013
|
||||||
|
// Defines the TAB catalog tables
|
||||||
|
|
||||||
|
#ifndef TABUTIL
|
||||||
|
#define TABUTIL 1
|
||||||
|
|
||||||
|
//#include "tabtbl.h"
|
||||||
|
|
||||||
|
#define TYPE_AM_PRX (AMT)129
|
||||||
|
|
||||||
|
typedef class PRXDEF *PPRXDEF;
|
||||||
|
typedef class TDBPRX *PTDBPRX;
|
||||||
|
typedef class XXLCOL *PXXLCOL;
|
||||||
|
typedef class PRXCOL *PPRXCOL;
|
||||||
|
typedef class TBCDEF *PTBCDEF;
|
||||||
|
typedef class TDBTBC *PTDBTBC;
|
||||||
|
typedef class XTDBASE *PTDBX;
|
||||||
|
typedef class XCOLBLK *PCOLX;
|
||||||
|
|
||||||
|
TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
|
||||||
|
const char *name, bool& mysql);
|
||||||
|
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
||||||
|
const char *name, bool info);
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This class is used to access protected members of TDBASE. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class XTDBASE : public TDBASE {
|
||||||
|
friend class TDBXCL;
|
||||||
|
}; // end of class XCOLBLK
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This class is used to access protected members of COLBLK. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class XCOLBLK : public COLBLK {
|
||||||
|
friend class TDBXCL;
|
||||||
|
}; // end of class XCOLBLK
|
||||||
|
|
||||||
|
/* -------------------------- PROXY classes -------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* PROXY: table based on another table. Can be used to have a */
|
||||||
|
/* different view on an existing table. */
|
||||||
|
/* However, its real use is to be the base of TBL and PRX tables. */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* PRX table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class DllExport PRXDEF : public TABDEF { /* Logical table description */
|
||||||
|
friend class TDBPRX;
|
||||||
|
friend class TDBTBC;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
PRXDEF(void);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual const char *GetType(void) {return "PRX";}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
|
virtual PTDB GetTable(PGLOBAL g, MODE mode);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
PTABLE Tablep; /* The object table */
|
||||||
|
}; // end of PRXDEF
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This is the class declaration for the XCSV table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class DllExport TDBPRX : public TDBASE {
|
||||||
|
//friend class MULINDX;
|
||||||
|
friend class PRXDEF;
|
||||||
|
friend class PRXCOL;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
TDBPRX(PPRXDEF tdp);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual AMT GetAmType(void) {return TYPE_AM_PRX;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
|
||||||
|
virtual void ResetDB(void) {Tdbp->ResetDB();}
|
||||||
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
|
|
||||||
|
// Database routines
|
||||||
|
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||||
|
virtual bool InitTable(PGLOBAL g);
|
||||||
|
virtual int GetMaxSize(PGLOBAL g);
|
||||||
|
virtual bool OpenDB(PGLOBAL g);
|
||||||
|
virtual int ReadDB(PGLOBAL g);
|
||||||
|
virtual int WriteDB(PGLOBAL g);
|
||||||
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
|
virtual void CloseDB(PGLOBAL g) {if (Tdbp) Tdbp->CloseDB(g);}
|
||||||
|
PTDB GetSubTable(PGLOBAL g, PTABLE tabp);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
PTDBASE Tdbp; // The object table
|
||||||
|
}; // end of class TDBPRX
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Class PRXCOL: PRX access method column descriptor. */
|
||||||
|
/* This A.M. is used for PRX tables. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class DllExport PRXCOL : public COLBLK {
|
||||||
|
friend class TDBPRX;
|
||||||
|
friend class TDBTBL;
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX");
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual int GetAmType(void) {return TYPE_AM_PRX;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool IsSpecial(void) {return Pseudo;}
|
||||||
|
virtual void ReadColumn(PGLOBAL g);
|
||||||
|
bool Init(PGLOBAL g);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Default constructor not to be used
|
||||||
|
PRXCOL(void) {}
|
||||||
|
|
||||||
|
// Members
|
||||||
|
PCOL Colp; // Points to matching table column
|
||||||
|
PVAL To_Val; // To the matching column value
|
||||||
|
bool Pseudo; // TRUE for special columns
|
||||||
|
int Colnum; // Used when retrieving columns by number
|
||||||
|
}; // end of class PRXCOL
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/***********************************************************************/
|
||||||
|
/* TBC table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class TBCDEF : public TABDEF {/* Logical table description */
|
||||||
|
friend class TDBTBC;
|
||||||
|
friend class ha_connect;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
TBCDEF(void) {Database = NULL; Tabname = NULL;}
|
||||||
|
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual const char *GetType(void) {return "TBC";}
|
||||||
|
inline PSZ GetDatabase(void) {return Database;};
|
||||||
|
inline PSZ GetTabname(void) {return Tabname;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
|
virtual PTDB GetTable(PGLOBAL g, MODE m);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
PSZ Database; /* Database to be used by server */
|
||||||
|
PSZ Tabname; /* External table name */
|
||||||
|
}; // end of TBCDEF
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This is the class declaration for the TBC column catalog table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class TDBTBC : public TDBCAT {
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
TDBTBC(PPRXDEF tdp);
|
||||||
|
//TDBTBC(PTBLDEF tdp);
|
||||||
|
//TDBTBC(PXCLDEF tdp);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Specific routines
|
||||||
|
virtual PQRYRES GetResult(PGLOBAL g);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
PSZ Db; // Database of the table
|
||||||
|
PSZ Tab; // Table name
|
||||||
|
}; // end of class TDBMCL
|
||||||
|
|
||||||
|
#endif // TABUTIL
|
376
storage/connect/tabxcl.cpp
Normal file
376
storage/connect/tabxcl.cpp
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
/************* TabXcl CPP Declares Source Code File (.CPP) *************/
|
||||||
|
/* Name: TABXCL.CPP Version 1.0 */
|
||||||
|
/* */
|
||||||
|
/* (C) Copyright to the author Olivier BERTRAND 2013 */
|
||||||
|
/* */
|
||||||
|
/* XCOL: Table having one column containing several values */
|
||||||
|
/* comma separated. When creating the table, the name of the X */
|
||||||
|
/* column is given by the Name option. */
|
||||||
|
/* This first version has one limitation: */
|
||||||
|
/* - The X column has the same length than in the physical file. */
|
||||||
|
/* This tables produces as many rows for a physical row than the */
|
||||||
|
/* number of items in the X column (eventually 0). */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Include relevant section of system dependant header files. */
|
||||||
|
/***********************************************************************/
|
||||||
|
#include "my_global.h"
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(__BORLANDC__)
|
||||||
|
#define __MFC_COMPAT__ // To define min/max as macro
|
||||||
|
#endif
|
||||||
|
//#include <windows.h>
|
||||||
|
#else
|
||||||
|
#if defined(UNIX)
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "osutil.h"
|
||||||
|
#else
|
||||||
|
//#include <io.h>
|
||||||
|
#endif
|
||||||
|
//#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Include application header files: */
|
||||||
|
/***********************************************************************/
|
||||||
|
#include "table.h" // MySQL table definitions
|
||||||
|
#include "global.h"
|
||||||
|
#include "plgdbsem.h"
|
||||||
|
#include "plgcnx.h" // For DB types
|
||||||
|
#include "resource.h"
|
||||||
|
#include "reldef.h"
|
||||||
|
#include "filamtxt.h"
|
||||||
|
#include "tabdos.h"
|
||||||
|
#include "tabcol.h"
|
||||||
|
#include "tabxcl.h"
|
||||||
|
#include "xtable.h"
|
||||||
|
#if defined(MYSQL_SUPPORT)
|
||||||
|
#include "tabmysql.h"
|
||||||
|
#endif // MYSQL_SUPPORT
|
||||||
|
#include "ha_connect.h"
|
||||||
|
#include "mycat.h"
|
||||||
|
|
||||||
|
extern "C" int trace;
|
||||||
|
|
||||||
|
/* -------------- Implementation of the XCOL classes ---------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCLDEF constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
XCLDEF::XCLDEF(void)
|
||||||
|
{
|
||||||
|
Pseudo = 3;
|
||||||
|
Xcol = NULL;
|
||||||
|
Sep = ',';
|
||||||
|
Mult = 10;
|
||||||
|
} // end of XCLDEF constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DefineAM: define specific AM block values from XCOL file. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool XCLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
||||||
|
{
|
||||||
|
char buf[8];
|
||||||
|
|
||||||
|
Xcol = Cat->GetStringCatInfo(g, "Colname", "");
|
||||||
|
Cat->GetCharCatInfo("Separator", ",", buf, sizeof(buf));
|
||||||
|
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf;
|
||||||
|
Mult = Cat->GetIntCatInfo("Mult", 10);
|
||||||
|
return PRXDEF::DefineAM(g, am, poff);
|
||||||
|
} // end of DefineAM
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* GetTable: makes a new TDB of the proper type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PTDB XCLDEF::GetTable(PGLOBAL g, MODE mode)
|
||||||
|
{
|
||||||
|
if (Catfunc == FNC_COL)
|
||||||
|
return new(g) TDBTBC(this);
|
||||||
|
else
|
||||||
|
return new(g) TDBXCL(this);
|
||||||
|
|
||||||
|
} // end of GetTable
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Implementation of the TDBXCL class. */
|
||||||
|
/***********************************************************************/
|
||||||
|
TDBXCL::TDBXCL(PXCLDEF tdp) : TDBPRX(tdp)
|
||||||
|
{
|
||||||
|
//Tdbp = NULL; // The physical table
|
||||||
|
Xcolumn = tdp->Xcol; // CSV column name
|
||||||
|
Xcolp = NULL; // To the XCVCOL column
|
||||||
|
Mult = tdp->Mult; // Multiplication factor
|
||||||
|
N = 0; // The current table index
|
||||||
|
M = 0; // The occurence rank
|
||||||
|
RowFlag = 0; // 0: Ok, 1: Same, 2: Skip
|
||||||
|
New = TRUE; // TRUE for new line
|
||||||
|
Sep = tdp->Sep; // The Xcol separator
|
||||||
|
} // end of TDBXCL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Initializes the table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBXCL::InitTable(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (!Tdbp) {
|
||||||
|
PCOLDEF cdp;
|
||||||
|
|
||||||
|
// Get the table description block of this table
|
||||||
|
if (!(Tdbp = (PTDBASE)GetSubTable(g, ((PXCLDEF)To_Def)->Tablep)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (cdp = Tdbp->GetDef()->GetCols(); cdp; cdp = cdp->GetNext())
|
||||||
|
if (!stricmp(cdp->GetName(), Xcolumn))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!cdp) {
|
||||||
|
sprintf(g->Message, "%s is not a %s column",
|
||||||
|
Xcolumn, Tdbp->GetName());
|
||||||
|
return TRUE;
|
||||||
|
} // endif cdp
|
||||||
|
|
||||||
|
} // endif Tdbp
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
} // end of InitTable
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Allocate XCL column description block. */
|
||||||
|
/***********************************************************************/
|
||||||
|
PCOL TDBXCL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
||||||
|
{
|
||||||
|
PCOL colp;
|
||||||
|
|
||||||
|
if (!stricmp(cdp->GetName(), Xcolumn)) {
|
||||||
|
Xcolp = new(g) XCLCOL(g, cdp, this, cprec, n);
|
||||||
|
colp = Xcolp;
|
||||||
|
} else
|
||||||
|
colp = new(g) PRXCOL(cdp, this, cprec, n);
|
||||||
|
|
||||||
|
return colp;
|
||||||
|
} // end of MakeCol
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCL GetMaxSize: returns the maximum number of rows in the table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBXCL::GetMaxSize(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (MaxSize < 0) {
|
||||||
|
if (InitTable(g))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
MaxSize = Mult * Tdbp->GetMaxSize(g);
|
||||||
|
} // endif MaxSize
|
||||||
|
|
||||||
|
return MaxSize;
|
||||||
|
} // end of GetMaxSize
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* In this sample, ROWID will be the (virtual) row number, */
|
||||||
|
/* while ROWNUM will be the occurence rank in the multiple column. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBXCL::RowNumber(PGLOBAL g, bool b)
|
||||||
|
{
|
||||||
|
return (b) ? M : N;
|
||||||
|
} // end of RowNumber
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCV Access Method opening routine. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TDBXCL::OpenDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (Use == USE_OPEN) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Table already open, just replace it at its beginning. */
|
||||||
|
/*******************************************************************/
|
||||||
|
M = N = 0;
|
||||||
|
RowFlag = 0;
|
||||||
|
New = TRUE;
|
||||||
|
return Tdbp->OpenDB(g);
|
||||||
|
} // endif use
|
||||||
|
|
||||||
|
if (Mode != MODE_READ) {
|
||||||
|
/*******************************************************************/
|
||||||
|
/* Currently XCOL tables cannot be modified. */
|
||||||
|
/*******************************************************************/
|
||||||
|
strcpy(g->Message, "XCOL tables are read only");
|
||||||
|
return TRUE;
|
||||||
|
} // endif Mode
|
||||||
|
|
||||||
|
if (InitTable(g))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Check and initialize the subtable columns. */
|
||||||
|
/*********************************************************************/
|
||||||
|
for (PCOL cp = Columns; cp; cp = cp->GetNext())
|
||||||
|
if (((PXCLCOL)cp)->Init(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Physically open the object table. */
|
||||||
|
/*********************************************************************/
|
||||||
|
if (Tdbp->OpenDB(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Check for direct access. */
|
||||||
|
/*********************************************************************/
|
||||||
|
if (To_Key_Col)
|
||||||
|
if (!Tdbp->GetDef()->Indexable()) {
|
||||||
|
strcpy(g->Message, "Object table is not indexable");
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
((PTDBX)Tdbp)->To_Key_Col = To_Key_Col;
|
||||||
|
((PTDBX)Tdbp)->To_Link = To_Link;
|
||||||
|
((PTDBX)Tdbp)->Knum = Knum;
|
||||||
|
To_Kindex = (PKXBASE)new(g) KINDEX(Tdbp);
|
||||||
|
|
||||||
|
if (To_Kindex->Init(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
((PKINDEX)To_Kindex)->SetMult(Mult);
|
||||||
|
Tdbp->SetKindex(To_Kindex);
|
||||||
|
} // endif Indexable
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
} // end of OpenDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Data Base read routine for XCV access method. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBXCL::ReadDB(PGLOBAL g)
|
||||||
|
{
|
||||||
|
int rc = RC_OK;
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Now start the multi reading process. */
|
||||||
|
/*********************************************************************/
|
||||||
|
do {
|
||||||
|
if (RowFlag != 1) {
|
||||||
|
if ((rc = Tdbp->ReadDB(g)) != RC_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
New = TRUE;
|
||||||
|
M = 1;
|
||||||
|
} else {
|
||||||
|
New = FALSE;
|
||||||
|
M++;
|
||||||
|
} // endif RowFlag
|
||||||
|
|
||||||
|
if (Xcolp) {
|
||||||
|
RowFlag = 0;
|
||||||
|
Xcolp->ReadColumn(g);
|
||||||
|
} // endif Xcolp
|
||||||
|
|
||||||
|
N++;
|
||||||
|
} while (RowFlag == 2);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
} // end of ReadDB
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------ XCLCOL functions ----------------------------
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCLCOL public constructor. */
|
||||||
|
/***********************************************************************/
|
||||||
|
XCLCOL::XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
|
||||||
|
: PRXCOL(cdp, tdbp, cprec, i, "XCL")
|
||||||
|
{
|
||||||
|
// Set additional XXL access method information for column.
|
||||||
|
Cbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
|
||||||
|
Cp = NULL; // Pointer to current position in Cbuf
|
||||||
|
Sep = ((PTDBXCL)tdbp)->Sep;
|
||||||
|
AddStatus(BUF_READ); // Only evaluated from TDBXCL::ReadDB
|
||||||
|
} // end of XCLCOL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* What this routine does is to get the comma-separated string */
|
||||||
|
/* from the source table column, extract the single values and */
|
||||||
|
/* set the flag for the table ReadDB function. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void XCLCOL::ReadColumn(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (((PTDBXCL)To_Tdb)->New) {
|
||||||
|
Colp->ReadColumn(g);
|
||||||
|
strcpy(Cbuf, To_Val->GetCharValue());
|
||||||
|
Cp = Cbuf;
|
||||||
|
} // endif New
|
||||||
|
|
||||||
|
if (*Cp) {
|
||||||
|
PSZ p;
|
||||||
|
|
||||||
|
// Trim left
|
||||||
|
for (p = Cp; *p == ' '; p++) ;
|
||||||
|
|
||||||
|
if ((Cp = strchr(Cp, Sep)))
|
||||||
|
// Separator is found
|
||||||
|
*Cp++ = '\0';
|
||||||
|
|
||||||
|
Value->SetValue_psz(p);
|
||||||
|
} else if (Nullable) {
|
||||||
|
Value->Reset();
|
||||||
|
Value->SetNull(true);
|
||||||
|
} else
|
||||||
|
// Skip that row
|
||||||
|
((PTDBXCL)To_Tdb)->RowFlag = 2;
|
||||||
|
|
||||||
|
if (Cp && *Cp)
|
||||||
|
// More to come from the same row
|
||||||
|
((PTDBXCL)To_Tdb)->RowFlag = 1;
|
||||||
|
|
||||||
|
} // end of ReadColumn
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* -------------- Implementation of the MULINDX class ---------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Returns FALSE if Ok, TRUE if there are no more equal values. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MULINDX::HaveSame(void)
|
||||||
|
{
|
||||||
|
return (Op == OP_SAME || Txlp->RowFlag == 1);
|
||||||
|
} // end of HaveSame
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Returns FALSE if Ok, TRUE if there are no more equal values. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MULINDX::NextVal(bool eq)
|
||||||
|
{
|
||||||
|
return (Pof) ? KINDEX::NextVal(eq) : TRUE;
|
||||||
|
} // end of NextVal
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Returns TRUE if there are more same values. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MULINDX::MoreVal(void)
|
||||||
|
{
|
||||||
|
Op = OP_SAME; // There may be more equal values
|
||||||
|
return (Pof) ? Pof[Val_K] : Val_K;
|
||||||
|
} // end of MoreVal
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Change the index multiple status. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool MULINDX::Init(PGLOBAL g)
|
||||||
|
{
|
||||||
|
if (KINDEX::Init(g))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Mul = TRUE;
|
||||||
|
MaxSame *= Txlp->Mult;
|
||||||
|
return FALSE;
|
||||||
|
} // end of Init
|
||||||
|
#endif // 0
|
133
storage/connect/tabxcl.h
Normal file
133
storage/connect/tabxcl.h
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// TABXCL.H Olivier Bertrand 2013
|
||||||
|
// Defines the XCOL tables
|
||||||
|
|
||||||
|
#include "tabutil.h"
|
||||||
|
|
||||||
|
#define TYPE_AM_XCOL (AMT)124
|
||||||
|
|
||||||
|
typedef class XCLDEF *PXCLDEF;
|
||||||
|
typedef class TDBXCL *PTDBXCL;
|
||||||
|
typedef class XCLCOL *PXCLCOL;
|
||||||
|
//pedef class MULINDX *PMINDX;
|
||||||
|
|
||||||
|
/* -------------------------- XCOL classes --------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCOL: table having one column containing several values comma */
|
||||||
|
/* (or any other character) separated. When creating the table, the */
|
||||||
|
/* name of the X column is given by the NAME option. */
|
||||||
|
/* This sample has a limitation: */
|
||||||
|
/* - The X column has the same length than in the physical file. */
|
||||||
|
/* This tables produces as many rows for a physical row than the */
|
||||||
|
/* number of items in the X column (eventually 0). */
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* XCL table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class XCLDEF : public PRXDEF { /* Logical table description */
|
||||||
|
friend class TDBXCL;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
XCLDEF(void);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual const char *GetType(void) {return "XCL";}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
|
virtual PTDB GetTable(PGLOBAL g, MODE mode);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
char *Xcol; /* The column containing separated fields */
|
||||||
|
char Sep; /* The field separator, defaults to comma */
|
||||||
|
int Mult; /* Multiplication factor */
|
||||||
|
}; // end of XCLDEF
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This is the class declaration for the XCSV table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class TDBXCL : public TDBPRX {
|
||||||
|
//friend class MULINDX;
|
||||||
|
friend class XCLDEF;
|
||||||
|
friend class PRXCOL;
|
||||||
|
friend class XCLCOL;
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
TDBXCL(PXCLDEF tdp);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual AMT GetAmType(void) {return TYPE_AM_XCOL;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual void ResetDB(void) {N = 0; Tdbp->ResetDB();}
|
||||||
|
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
|
||||||
|
//virtual bool HaveSame(void) {return RowFlag == 1;}
|
||||||
|
|
||||||
|
// Database routines
|
||||||
|
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
|
||||||
|
virtual bool InitTable(PGLOBAL g);
|
||||||
|
virtual int GetMaxSize(PGLOBAL g);
|
||||||
|
virtual bool OpenDB(PGLOBAL g);
|
||||||
|
virtual int ReadDB(PGLOBAL g);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Members
|
||||||
|
char *Xcolumn; // Multiple column name
|
||||||
|
PXCLCOL Xcolp; // To the XCVCOL column
|
||||||
|
int Mult; // Multiplication factor
|
||||||
|
int N; // The current table index
|
||||||
|
int M; // The occurence rank
|
||||||
|
BYTE RowFlag; // 0: Ok, 1: Same, 2: Skip
|
||||||
|
BOOL New; // TRUE for new line
|
||||||
|
char Sep; // The Xcol separator
|
||||||
|
}; // end of class TDBXCL
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Class XCLCOL: for the multiple CSV column. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class XCLCOL : public PRXCOL {
|
||||||
|
friend class TDBXCL;
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual void Reset(void) {} // Evaluated only by TDBXCL
|
||||||
|
virtual void ReadColumn(PGLOBAL g);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Default constructor not to be used
|
||||||
|
XCLCOL(void) {}
|
||||||
|
|
||||||
|
// Members
|
||||||
|
char *Cbuf; // The column buffer
|
||||||
|
char *Cp; // Pointer to current position
|
||||||
|
char Sep; // The separator
|
||||||
|
}; // end of class XCLCOL
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* ------------------------- MULINDX classes ------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* This represents a KINDEX class for an XCOL table. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class MULINDX : public KINDEX {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
MULINDX(PTDBXCL txlp) : KINDEX(txlp->Tdbp) {Txlp = txlp;}
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual BOOL HaveSame(void);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual BOOL Init(PGLOBAL g);
|
||||||
|
virtual BOOL NextVal(BOOL eq);
|
||||||
|
virtual int MoreVal(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//Member
|
||||||
|
PTDBXCL Txlp;
|
||||||
|
}; // end of class MULINDX
|
||||||
|
#endif // 0
|
@@ -266,7 +266,7 @@ char TYPBLK<char>::GetTypedValue(PVAL valp)
|
|||||||
{return valp->GetTinyValue();}
|
{return valp->GetTinyValue();}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block. */
|
/* Set one value in a block from a zero terminated string. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
void TYPBLK<TYPE>::SetValue(PSZ p, int n)
|
void TYPBLK<TYPE>::SetValue(PSZ p, int n)
|
||||||
@@ -294,6 +294,22 @@ double TYPBLK<double>::GetTypedValue(PSZ p) {return atof(p);}
|
|||||||
template <>
|
template <>
|
||||||
char TYPBLK<char>::GetTypedValue(PSZ p) {return (char)atoi(p);}
|
char TYPBLK<char>::GetTypedValue(PSZ p) {return (char)atoi(p);}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Set one value in a block from an array of characters. */
|
||||||
|
/***********************************************************************/
|
||||||
|
template <class TYPE>
|
||||||
|
void TYPBLK<TYPE>::SetValue(char *sp, uint len, int n)
|
||||||
|
{
|
||||||
|
PGLOBAL& g = Global;
|
||||||
|
PSZ spz = (PSZ)PlugSubAlloc(g, NULL, 0); // Temporary
|
||||||
|
|
||||||
|
if (sp)
|
||||||
|
memcpy(spz, sp, len);
|
||||||
|
|
||||||
|
spz[len] = 0;
|
||||||
|
SetValue(spz, n);
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block from a value in another block. */
|
/* Set one value in a block from a value in another block. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -552,11 +568,19 @@ void CHRBLK::SetValue(PVAL valp, int n)
|
|||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block. */
|
/* Set one value in a block from a zero terminated string. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void CHRBLK::SetValue(PSZ sp, int n)
|
void CHRBLK::SetValue(PSZ sp, int n)
|
||||||
{
|
{
|
||||||
size_t len = (sp) ? strlen(sp) : 0;
|
uint len = (sp) ? strlen(sp) : 0;
|
||||||
|
SetValue(sp, len, n);
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Set one value in a block from an array of characters. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void CHRBLK::SetValue(char *sp, uint len, int n)
|
||||||
|
{
|
||||||
char *p = Chrp + n * Long;
|
char *p = Chrp + n * Long;
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBTRACE)
|
#if defined(_DEBUG) || defined(DEBTRACE)
|
||||||
@@ -568,15 +592,16 @@ void CHRBLK::SetValue(PSZ sp, int n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sp)
|
if (sp)
|
||||||
strncpy(p, sp, Long);
|
memcpy(p, sp, len);
|
||||||
else
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
if (Blanks)
|
if (Blanks) {
|
||||||
// Suppress eventual ending zero and right fill with blanks
|
// Suppress eventual ending zero and right fill with blanks
|
||||||
for (register int i = len; i < Long; i++)
|
for (register int i = len; i < Long; i++)
|
||||||
p[i] = ' ';
|
p[i] = ' ';
|
||||||
|
|
||||||
|
} else if ((signed)len < Long)
|
||||||
|
p[len] = 0;
|
||||||
|
|
||||||
SetNull(n, false);
|
SetNull(n, false);
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
@@ -801,12 +826,33 @@ void STRBLK::SetValue(PVAL valp, int n)
|
|||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block. */
|
/* Set one value in a block from a zero terminated string. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void STRBLK::SetValue(PSZ p, int n)
|
void STRBLK::SetValue(PSZ p, int n)
|
||||||
{
|
{
|
||||||
|
if (p) {
|
||||||
Strp[n] = (PSZ)PlugSubAlloc(Global, NULL, strlen(p) + 1);
|
Strp[n] = (PSZ)PlugSubAlloc(Global, NULL, strlen(p) + 1);
|
||||||
strcpy(Strp[n], p);
|
strcpy(Strp[n], p);
|
||||||
|
} else
|
||||||
|
Strp[n] = NULL;
|
||||||
|
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Set one value in a block from an array of characters. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void STRBLK::SetValue(char *sp, uint len, int n)
|
||||||
|
{
|
||||||
|
PSZ p;
|
||||||
|
|
||||||
|
if (sp) {
|
||||||
|
p = (PSZ)PlugSubAlloc(Global, NULL, len + 1);
|
||||||
|
memcpy(p, sp, len);
|
||||||
|
p[len] = 0;
|
||||||
|
} else
|
||||||
|
p = NULL;
|
||||||
|
|
||||||
|
Strp[n] = p;
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -64,6 +64,7 @@ class VALBLK : public BLOCK {
|
|||||||
virtual void SetValue(double fval, int n) {assert(false);}
|
virtual void SetValue(double fval, int n) {assert(false);}
|
||||||
virtual void SetValue(char cval, int n) {assert(false);}
|
virtual void SetValue(char cval, int n) {assert(false);}
|
||||||
virtual void SetValue(PSZ sp, int n) {assert(false);}
|
virtual void SetValue(PSZ sp, int n) {assert(false);}
|
||||||
|
virtual void SetValue(char *sp, uint len, int n) {assert(false);}
|
||||||
virtual void SetValue(PVAL valp, int n) = 0;
|
virtual void SetValue(PVAL valp, int n) = 0;
|
||||||
virtual void SetValue(PVBLK pv, int n1, int n2) = 0;
|
virtual void SetValue(PVBLK pv, int n1, int n2) = 0;
|
||||||
#if 0
|
#if 0
|
||||||
@@ -120,6 +121,7 @@ class TYPBLK : public VALBLK {
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void SetValue(PSZ sp, int n);
|
virtual void SetValue(PSZ sp, int n);
|
||||||
|
virtual void SetValue(char *sp, uint len, int n);
|
||||||
virtual void SetValue(short sval, int n)
|
virtual void SetValue(short sval, int n)
|
||||||
{Typp[n] = (TYPE)sval; SetNull(n, false);}
|
{Typp[n] = (TYPE)sval; SetNull(n, false);}
|
||||||
virtual void SetValue(int lval, int n)
|
virtual void SetValue(int lval, int n)
|
||||||
@@ -175,6 +177,7 @@ class CHRBLK : public VALBLK {
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void SetValue(PSZ sp, int n);
|
virtual void SetValue(PSZ sp, int n);
|
||||||
|
virtual void SetValue(char *sp, uint len, int n);
|
||||||
virtual void SetValue(PVAL valp, int n);
|
virtual void SetValue(PVAL valp, int n);
|
||||||
virtual void SetValue(PVBLK pv, int n1, int n2);
|
virtual void SetValue(PVBLK pv, int n1, int n2);
|
||||||
//virtual void SetValues(PVBLK pv, int k, int n);
|
//virtual void SetValues(PVBLK pv, int k, int n);
|
||||||
@@ -221,6 +224,7 @@ class STRBLK : public VALBLK {
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void SetValue(PSZ sp, int n);
|
virtual void SetValue(PSZ sp, int n);
|
||||||
|
virtual void SetValue(char *sp, uint len, int n);
|
||||||
virtual void SetValue(PVAL valp, int n);
|
virtual void SetValue(PVAL valp, int n);
|
||||||
virtual void SetValue(PVBLK pv, int n1, int n2);
|
virtual void SetValue(PVBLK pv, int n1, int n2);
|
||||||
//virtual void SetValues(PVBLK pv, int k, int n);
|
//virtual void SetValues(PVBLK pv, int k, int n);
|
||||||
|
Reference in New Issue
Block a user