Commit 056f35d0 authored by Olivier Bertrand's avatar Olivier Bertrand

- Move all enum AMT definitions in one place (plgdbsem.h)

modified:
  storage/connect/filamtxt.h
  storage/connect/filamzip.h
  storage/connect/myconn.h
  storage/connect/plgdbsem.h
  storage/connect/taboccur.h
  storage/connect/tabutil.h
  storage/connect/tabxcl.h

- Add the possibility to execute several commands in one query of
  an EXECSRC tables (using ...where command in (cmd list);)

modified:
  storage/connect/ha_connect.cc
  storage/connect/odbconn.cpp
  storage/connect/odbconn.h
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
  storage/connect/tabodbc.cpp
  storage/connect/tabodbc.h
  storage/connect/tabtbl.cpp
  storage/connect/tabwmi.cpp
  storage/connect/xtable.h

- Enhance retrieving column definitions in discovery:
  From SRCDEF adding LIMIT 0 to the executed query
  Testing if type, length, and precision are compatible
  Making the distinction between CHAR and VARCHAR

modified:
  storage/connect/ha_connect.cc
  storage/connect/myconn.cpp
  storage/connect/mysql-test/connect/r/mysql.result
  storage/connect/mysql-test/connect/r/odbc_sqlite3.result
  storage/connect/mysql-test/connect/r/odbc_sqlite3_grant.result
  storage/connect/myutil.h
  storage/connect/myutil.h
  storage/connect/odbconn.cpp
  storage/connect/value.h
parent f1325549
...@@ -17,8 +17,6 @@ typedef class BLKFAM *PBLKFAM; ...@@ -17,8 +17,6 @@ typedef class BLKFAM *PBLKFAM;
typedef class DOSDEF *PDOSDEF; typedef class DOSDEF *PDOSDEF;
typedef class TDBDOS *PTDBDOS; typedef class TDBDOS *PTDBDOS;
#define TYPE_AM_BLK (AMT)160
/***********************************************************************/ /***********************************************************************/
/* This is the base class for all file access method classes. */ /* This is the base class for all file access method classes. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
#include "zlib.h" #include "zlib.h"
#define TYPE_AM_ZIP (AMT)150
#define TYPE_AM_ZLIB (AMT)155
typedef class ZIPFAM *PZIPFAM; typedef class ZIPFAM *PZIPFAM;
typedef class ZBKFAM *PZBKFAM; typedef class ZBKFAM *PZBKFAM;
typedef class ZIXFAM *PZIXFAM; typedef class ZIXFAM *PZIXFAM;
......
...@@ -1557,8 +1557,9 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg) ...@@ -1557,8 +1557,9 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
/***********************************************************************/ /***********************************************************************/
PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
{ {
char *body= filp->Body;
unsigned int i; unsigned int i;
bool ismul= false; bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
PPARM pfirst= NULL, pprec= NULL, pp[2]= {NULL, NULL}; PPARM pfirst= NULL, pprec= NULL, pp[2]= {NULL, NULL};
OPVAL vop= OP_XX; OPVAL vop= OP_XX;
...@@ -1572,6 +1573,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) ...@@ -1572,6 +1573,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
char *p1, *p2; char *p1, *p2;
Item_cond *cond_item= (Item_cond *)cond; Item_cond *cond_item= (Item_cond *)cond;
if (x)
return NULL;
if (xtrace > 1) if (xtrace > 1)
printf("Cond: Ftype=%d name=%s\n", cond_item->functype(), printf("Cond: Ftype=%d name=%s\n", cond_item->functype(),
cond_item->func_name()); cond_item->func_name());
...@@ -1586,7 +1590,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) ...@@ -1586,7 +1590,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
List_iterator<Item> li(*arglist); List_iterator<Item> li(*arglist);
Item *subitem; Item *subitem;
p1= filp + strlen(filp); p1= body + strlen(body);
strcpy(p1, "("); strcpy(p1, "(");
p2= p1 + 1; p2= p1 + 1;
...@@ -1644,6 +1648,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) ...@@ -1644,6 +1648,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
else if (ismul && tty == TYPE_AM_WMI) else if (ismul && tty == TYPE_AM_WMI)
return NULL; // Not supported by WQL return NULL; // Not supported by WQL
if (x && (neg || !(vop == OP_EQ || vop == OP_IN)))
return NULL;
for (i= 0; i < condf->argument_count(); i++) { for (i= 0; i < condf->argument_count(); i++) {
if (xtrace > 1) if (xtrace > 1)
printf("Argtype(%d)=%d\n", i, args[i]->type()); printf("Argtype(%d)=%d\n", i, args[i]->type());
...@@ -1660,6 +1667,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) ...@@ -1660,6 +1667,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
ha_field_option_struct *fop; ha_field_option_struct *fop;
Item_field *pField= (Item_field *)args[i]; Item_field *pField= (Item_field *)args[i];
if (x && i)
return NULL;
if (pField->field->table != table) if (pField->field->table != table)
return NULL; // Field does not belong to this table return NULL; // Field does not belong to this table
else else
...@@ -1685,10 +1695,10 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) ...@@ -1685,10 +1695,10 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
if (i && ismul) if (i && ismul)
return NULL; return NULL;
strcat(filp, fnm); strcat(body, fnm);
} else { } else {
char buff[256]; char buff[256];
String *res, tmp(buff,sizeof(buff), &my_charset_bin); String *res, tmp(buff, sizeof(buff), &my_charset_bin);
Item_basic_constant *pval= (Item_basic_constant *)args[i]; Item_basic_constant *pval= (Item_basic_constant *)args[i];
if ((res= pval->val_str(&tmp)) == NULL) if ((res= pval->val_str(&tmp)) == NULL)
...@@ -1698,26 +1708,46 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond) ...@@ -1698,26 +1708,46 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
printf("Value=%.*s\n", res->length(), res->ptr()); printf("Value=%.*s\n", res->length(), res->ptr());
// IN and BETWEEN clauses should be col VOP list // IN and BETWEEN clauses should be col VOP list
if (!i && ismul) if (!i && (x || ismul))
return NULL; return NULL;
if (!x) {
// Append the value to the filter // Append the value to the filter
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) if (args[i]->field_type() == MYSQL_TYPE_VARCHAR)
strcat(strcat(strcat(filp, "'"), res->ptr()), "'"); strcat(strcat(strcat(body, "'"), res->ptr()), "'");
else else
strncat(filp, res->ptr(), res->length()); strncat(body, res->ptr(), res->length());
} else {
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) {
// Add the command to the list
PCMD *ncp, cmdp= new(g) CMD(g, (char*)res->ptr());
for (ncp= &filp->Cmds; *ncp; ncp= &(*ncp)->Next) ;
*ncp= cmdp;
} else
return NULL;
} // endif x
} // endif } // endif
if (!x) {
if (!i) if (!i)
strcat(filp, GetValStr(vop, neg)); strcat(body, GetValStr(vop, neg));
else if (vop == OP_XX && i == 1) else if (vop == OP_XX && i == 1)
strcat(filp, " AND "); strcat(body, " AND ");
else if (vop == OP_IN) else if (vop == OP_IN)
strcat(filp, (i == condf->argument_count() - 1) ? ")" : ","); strcat(body, (i == condf->argument_count() - 1) ? ")" : ",");
} // endif x
} // endfor i } // endfor i
if (x)
filp->Op= vop;
} else { } else {
if (xtrace > 1) if (xtrace > 1)
printf("Unsupported condition\n"); printf("Unsupported condition\n");
...@@ -1754,22 +1784,30 @@ const COND *ha_connect::cond_push(const COND *cond) ...@@ -1754,22 +1784,30 @@ const COND *ha_connect::cond_push(const COND *cond)
if (tdbp) { if (tdbp) {
AMT tty= tdbp->GetAmType(); AMT tty= tdbp->GetAmType();
bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
if (tty == TYPE_AM_WMI || tty == TYPE_AM_ODBC || if (tty == TYPE_AM_WMI || tty == TYPE_AM_ODBC ||
tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL) { tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL || x) {
PGLOBAL& g= xp->g; PGLOBAL& g= xp->g;
PFIL filp= (PFIL)PlugSubAlloc(g, NULL, 0); PFIL filp= (PFIL)PlugSubAlloc(g, NULL, sizeof(FILTER));
*filp= 0; filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body= 0;
filp->Op= OP_XX;
filp->Cmds= NULL;
if (CheckCond(g, filp, tty, (Item *)cond)) { if (CheckCond(g, filp, tty, (Item *)cond)) {
if (xtrace) if (xtrace)
puts(filp); puts(filp->Body);
if (!x)
PlugSubAlloc(g, NULL, strlen(filp->Body) + 1);
else
cond= NULL; // Does this work?
tdbp->SetFilter(filp); tdbp->SetFilter(filp);
// cond= NULL; // This does not work anyway } else if (x && cond)
PlugSubAlloc(g, NULL, strlen(filp) + 1); tdbp->SetFilter(filp); // Wrong filter
} // endif filp
} // endif tty } // endif tty
...@@ -3461,12 +3499,13 @@ static bool add_fields(PGLOBAL g, ...@@ -3461,12 +3499,13 @@ static bool add_fields(PGLOBAL g,
DBUG_RETURN(0); DBUG_RETURN(0);
} // end of add_fields } // end of add_fields
#else // !NEW_WAY #else // !NEW_WAY
static bool add_field(String *sql, const char *field_name, int typ, int len, static bool add_field(String *sql, const char *field_name, int typ,
int dec, uint tm, const char *rem, int flag, bool dbf) int len, int dec, uint tm, const char *rem,
int flag, bool dbf, char v)
{ {
char var = (len > 255) ? 'V' : v;
bool error= false; bool error= false;
const char *type= PLGtoMYSQLtype(typ, dbf); const char *type= PLGtoMYSQLtype(typ, dbf, var);
// type= PLGtoMYSQLtype(typ, true); ?????
error|= sql->append('`'); error|= sql->append('`');
error|= sql->append(field_name); error|= sql->append(field_name);
...@@ -3479,7 +3518,8 @@ static bool add_field(String *sql, const char *field_name, int typ, int len, ...@@ -3479,7 +3518,8 @@ static bool add_field(String *sql, const char *field_name, int typ, int len,
if (!strcmp(type, "DOUBLE")) { if (!strcmp(type, "DOUBLE")) {
error|= sql->append(','); error|= sql->append(',');
error|= sql->append_ulonglong(dec); // dec must be <= len and <= 31
error|= sql->append_ulonglong(min(dec, (len - 1)));
} // endif dec } // endif dec
error|= sql->append(')'); error|= sql->append(')');
...@@ -3518,6 +3558,8 @@ static int init_table_share(THD *thd, ...@@ -3518,6 +3558,8 @@ static int init_table_share(THD *thd,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
Alter_info *alter_info) Alter_info *alter_info)
{ {
KEY *not_used_1;
uint not_used_2;
int rc= 0; int rc= 0;
handler *file; handler *file;
LEX_CUSTRING frm= {0,0}; LEX_CUSTRING frm= {0,0};
...@@ -3577,9 +3619,8 @@ static int init_table_share(THD *thd, ...@@ -3577,9 +3619,8 @@ static int init_table_share(THD *thd,
tmp_disable_binlog(thd); tmp_disable_binlog(thd);
file= mysql_create_frm_image(thd, table_s->db.str, table_s->table_name.str, file= mysql_create_frm_image(thd, table_s->db.str, table_s->table_name.str,
create_info, alter_info, create_info, alter_info, C_ORDINARY_CREATE,
// &thd->lex->create_info, &thd->lex->alter_info, &not_used_1, &not_used_2, &frm);
C_ORDINARY_CREATE, &frm);
if (file) if (file)
delete file; delete file;
else else
...@@ -3777,7 +3818,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3777,7 +3818,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
//CHARSET_INFO *cs; //CHARSET_INFO *cs;
Alter_info alter_info; Alter_info alter_info;
#else // !NEW_WAY #else // !NEW_WAY
char buf[1024]; char v, buf[1024];
String sql(buf, sizeof(buf), system_charset_info); String sql(buf, sizeof(buf), system_charset_info);
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info); sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
...@@ -4097,7 +4138,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4097,7 +4138,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
NOT_NULL_FLAG, "", flg, dbf); NOT_NULL_FLAG, "", flg, dbf);
#else // !NEW_WAY #else // !NEW_WAY
// Now add the field // Now add the field
if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, flg, dbf)) if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, flg, dbf, 0))
rc= HA_ERR_OUT_OF_MEM; rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY #endif // !NEW_WAY
} // endfor crp } // endfor crp
...@@ -4121,6 +4162,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4121,6 +4162,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
break; break;
case FLD_TYPE: case FLD_TYPE:
typ= crp->Kdata->GetIntValue(i); typ= crp->Kdata->GetIntValue(i);
v = (crp->Nulls) ? crp->Nulls[i] : 0;
break; break;
case FLD_PREC: case FLD_PREC:
len= crp->Kdata->GetIntValue(i); len= crp->Kdata->GetIntValue(i);
...@@ -4151,7 +4193,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4151,7 +4193,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
int plgtyp; int plgtyp;
// typ must be PLG type, not SQL type // typ must be PLG type, not SQL type
if (!(plgtyp= TranslateSQLType(typ, dec, len))) { if (!(plgtyp= TranslateSQLType(typ, dec, len, v))) {
sprintf(g->Message, "Unsupported SQL type %d", typ); sprintf(g->Message, "Unsupported SQL type %d", typ);
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;
...@@ -4176,7 +4218,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -4176,7 +4218,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec, rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
tm, rem, 0, true); tm, rem, 0, true);
#else // !NEW_WAY #else // !NEW_WAY
if (add_field(&sql, cnm, typ, len, dec, tm, rem, 0, true)) if (add_field(&sql, cnm, typ, len, dec, tm, rem, 0, true, v))
rc= HA_ERR_OUT_OF_MEM; rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY #endif // !NEW_WAY
} // endfor i } // endfor i
......
...@@ -87,7 +87,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -87,7 +87,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET}; FLD_REM, FLD_NO, FLD_CHARSET};
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32}; static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
char *fld, *fmt, cmd[128]; char *fld, *fmt, v, cmd[128];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int); int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0; int len, type, prec, rc, k = 0;
PQRYRES qrp; PQRYRES qrp;
...@@ -139,6 +139,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -139,6 +139,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
// Some columns must be renamed // Some columns must be renamed
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
switch (++i) { switch (++i) {
case 2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
case 4: crp->Name = "Length"; break; case 4: crp->Name = "Length"; break;
case 5: crp->Name = "Key"; break; case 5: crp->Name = "Key"; break;
case 10: crp->Name = "Date_fmt"; break; case 10: crp->Name = "Date_fmt"; break;
...@@ -166,7 +167,8 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -166,7 +167,8 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
// Get type, type name, and precision // Get type, type name, and precision
fld = myc.GetCharField(1); fld = myc.GetCharField(1);
prec = 0; prec = 0;
len = 255; // Default for text or blob len = 0;
v = 0;
if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) { if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld); sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
...@@ -175,14 +177,16 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, ...@@ -175,14 +177,16 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} else } else
qrp->Nblin++; qrp->Nblin++;
if ((type = MYSQLtoPLG(cmd)) == TYPE_ERROR) { if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", cmd); sprintf(g->Message, "Unsupported column type %s", cmd);
myc.Close(); myc.Close();
return NULL; return NULL;
} // endif type } else if (type == TYPE_STRING)
len = min(len, 255);
crp = crp->Next; // Data_Type crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i); crp->Kdata->SetValue(type, i);
crp->Nulls[i] = v;
crp = crp->Next; // Type_Name crp = crp->Next; // Type_Name
crp->Kdata->SetValue(cmd, i); crp->Kdata->SetValue(cmd, i);
...@@ -253,6 +257,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db, ...@@ -253,6 +257,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
const char *user, const char *pwd, const char *user, const char *pwd,
const char *srcdef, int port) const char *srcdef, int port)
{ {
char *query;
int w; int w;
MYSQLC myc; MYSQLC myc;
PQRYRES qrp = NULL; PQRYRES qrp = NULL;
...@@ -260,12 +265,15 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db, ...@@ -260,12 +265,15 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
if (!port) if (!port)
port = mysqld_port; port = mysqld_port;
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9);
strcat(strcpy(query, srcdef), " LIMIT 0");
// Open a MySQL connection for this table // Open a MySQL connection for this table
if (myc.Open(g, host, db, user, pwd, port)) if (myc.Open(g, host, db, user, pwd, port))
return NULL; return NULL;
// Send the source command to MySQL // Send the source command to MySQL
if (myc.ExecSQL(g, srcdef, &w) == RC_OK) if (myc.ExecSQL(g, query, &w) == RC_OK)
qrp = myc.GetResult(g); qrp = myc.GetResult(g);
myc.Close(); myc.Close();
...@@ -778,6 +786,42 @@ void MYSQLC::Rewind(void) ...@@ -778,6 +786,42 @@ void MYSQLC::Rewind(void)
} // end of Rewind } // end of Rewind
/***********************************************************************/
/* Exec the Select SQL command and return ncol or afrws (TDBMYEXC). */
/***********************************************************************/
int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w)
{
int rc = RC_OK;
if (!m_DB) {
strcpy(g->Message, "MySQL not connected");
return RC_FX;
} else
*w = 0;
if (!stricmp(query, "Warning") || !stricmp(query, "Note")
|| !stricmp(query, "Error"))
return RC_INFO;
else
m_Afrw = 0;
//if (mysql_query(m_DB, query) != 0) {
if (mysql_real_query(m_DB, query, strlen(query))) {
m_Afrw = (int)mysql_errno(m_DB);
sprintf(g->Message, "%s", mysql_error(m_DB));
rc = RC_FX;
//} else if (!(m_Fields = mysql_field_count(m_DB))) {
} else if (!(m_Fields = (int)m_DB->field_count)) {
// m_Afrw = (int)mysql_affected_rows(m_DB);
m_Afrw = (int)m_DB->affected_rows;
rc = RC_NF;
} // endif's
//*w = mysql_warning_count(m_DB);
*w = m_DB->warning_count;
return rc;
} // end of ExecSQLcmd
/***********************************************************************/ /***********************************************************************/
/* Close the connection. */ /* Close the connection. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#define DllItem #define DllItem
#endif // !WIN32 #endif // !WIN32
//#define TYPE_AM_MYSQL (AMT)192
#define MYSQL_ENABLED 0x00000001 #define MYSQL_ENABLED 0x00000001
#define MYSQL_LOGON 0x00000002 #define MYSQL_LOGON 0x00000002
...@@ -75,9 +74,12 @@ class DllItem MYSQLC { ...@@ -75,9 +74,12 @@ class DllItem MYSQLC {
//const char *ServerInfo(void); //const char *ServerInfo(void);
int KillQuery(ulong id); int KillQuery(ulong id);
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL); int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
int ExecSQLcmd(PGLOBAL g, const char *query, int *w);
#if defined(MYSQL_PREPARED_STATEMENTS)
int PrepareSQL(PGLOBAL g, const char *query); int PrepareSQL(PGLOBAL g, const char *query);
int ExecStmt(PGLOBAL g); int ExecStmt(PGLOBAL g);
int BindParams(PGLOBAL g, MYSQL_BIND *bind); int BindParams(PGLOBAL g, MYSQL_BIND *bind);
#endif // MYSQL_PREPARED_STATEMENTS
PQRYRES GetResult(PGLOBAL g, bool pdb = FALSE); PQRYRES GetResult(PGLOBAL g, bool pdb = FALSE);
int Fetch(PGLOBAL g, int pos); int Fetch(PGLOBAL g, int pos);
char *GetCharField(int i); char *GetCharField(int i);
...@@ -99,5 +101,6 @@ class DllItem MYSQLC { ...@@ -99,5 +101,6 @@ class DllItem MYSQLC {
int m_Rows; // The number of rows of the result int m_Rows; // The number of rows of the result
int N; int N;
int m_Fields; // The number of result fields int m_Fields; // The number of result fields
int m_Afrw; // The number of affected rows
}; // end of class MYSQLC }; // end of class MYSQLC
...@@ -44,7 +44,7 @@ SHOW CREATE TABLE t2; ...@@ -44,7 +44,7 @@ SHOW CREATE TABLE t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL,
`b` varchar(10) DEFAULT NULL `b` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
SELECT * FROM t2; SELECT * FROM t2;
a b a b
...@@ -176,7 +176,7 @@ t1 CREATE TABLE `t1` ( ...@@ -176,7 +176,7 @@ t1 CREATE TABLE `t1` (
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`a` varchar(10) DEFAULT NULL `a` char(10) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
SELECT * FROM t2; SELECT * FROM t2;
a a
......
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`Description` varchar(128) NOT NULL, `Description` char(128) NOT NULL,
`Attributes` varchar(256) NOT NULL `Attributes` varchar(256) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
SET NAMES utf8; SET NAMES utf8;
......
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`Description` varchar(128) NOT NULL, `Description` char(128) NOT NULL,
`Attributes` varchar(256) NOT NULL `Attributes` varchar(256) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
SET NAMES utf8; SET NAMES utf8;
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/************************************************************************/ /************************************************************************/
/* Convert from MySQL type name to PlugDB type number */ /* Convert from MySQL type name to PlugDB type number */
/************************************************************************/ /************************************************************************/
int MYSQLtoPLG(char *typname) int MYSQLtoPLG(char *typname, char *var)
{ {
int type; int type;
...@@ -56,6 +56,10 @@ int MYSQLtoPLG(char *typname) ...@@ -56,6 +56,10 @@ int MYSQLtoPLG(char *typname)
else else
type = TYPE_ERROR; type = TYPE_ERROR;
// This is to make the difference between CHAR and VARCHAR
if (var && type == TYPE_STRING && stricmp(typname, "char"))
*var = 'V';
return type; return type;
} // end of MYSQLtoPLG } // end of MYSQLtoPLG
...@@ -98,14 +102,14 @@ enum enum_field_types PLGtoMYSQL(int type, bool dbf) ...@@ -98,14 +102,14 @@ enum enum_field_types PLGtoMYSQL(int type, bool dbf)
/************************************************************************/ /************************************************************************/
/* Convert from PlugDB type to MySQL type name */ /* Convert from PlugDB type to MySQL type name */
/************************************************************************/ /************************************************************************/
const char *PLGtoMYSQLtype(int type, bool dbf) const char *PLGtoMYSQLtype(int type, bool dbf, char var)
{ {
switch (type) { switch (type) {
case TYPE_INT: return "INT"; case TYPE_INT: return "INT";
case TYPE_SHORT: return "SMALLINT"; case TYPE_SHORT: return "SMALLINT";
case TYPE_FLOAT: return "DOUBLE"; case TYPE_FLOAT: return "DOUBLE";
case TYPE_DATE: return dbf ? "DATE" : "DATETIME"; case TYPE_DATE: return dbf ? "DATE" : "DATETIME";
case TYPE_STRING: return "VARCHAR"; case TYPE_STRING: return var ? "VARCHAR" : "CHAR";
case TYPE_BIGINT: return "BIGINT"; case TYPE_BIGINT: return "BIGINT";
case TYPE_TINY: return "TINYINT"; case TYPE_TINY: return "TINYINT";
default: return "CHAR(0)"; default: return "CHAR(0)";
......
/***********************************************************************/ /***********************************************************************/
/* Prototypes of Functions used externally. */ /* Prototypes of Functions used externally. */
/***********************************************************************/ /***********************************************************************/
#ifndef __MYUTIL__H
#define __MYUTIL__H
enum enum_field_types PLGtoMYSQL(int type, bool dbf); enum enum_field_types PLGtoMYSQL(int type, bool dbf);
const char *PLGtoMYSQLtype(int type, bool dbf); const char *PLGtoMYSQLtype(int type, bool dbf, char var = NULL);
int MYSQLtoPLG(char *typname); int MYSQLtoPLG(char *typname, char *var = NULL);
int MYSQLtoPLG(int mytype); int MYSQLtoPLG(int mytype);
char *MyDateFmt(int mytype); char *MyDateFmt(int mytype);
char *MyDateFmt(char *typname); char *MyDateFmt(char *typname);
#endif // __MYUTIL__H
...@@ -108,16 +108,18 @@ static int GetSQLCType(int type) ...@@ -108,16 +108,18 @@ static int GetSQLCType(int type)
/***********************************************************************/ /***********************************************************************/
/* TranslateSQLType: translate a SQL Type to a PLG type. */ /* TranslateSQLType: translate a SQL Type to a PLG type. */
/***********************************************************************/ /***********************************************************************/
int TranslateSQLType(int stp, int prec, int& len) int TranslateSQLType(int stp, int prec, int& len, char& v)
{ {
int type; int type;
switch (stp) { switch (stp) {
case SQL_CHAR: // 1
case SQL_VARCHAR: // 12 case SQL_VARCHAR: // 12
v = 'V';
case SQL_CHAR: // 1
type = TYPE_STRING; type = TYPE_STRING;
break; break;
case SQL_LONGVARCHAR: // (-1) case SQL_LONGVARCHAR: // (-1)
v = 'V';
type = TYPE_STRING; type = TYPE_STRING;
len = min(abs(len), 255); len = min(abs(len), 255);
break; break;
...@@ -889,7 +891,7 @@ bool ODBConn::Check(RETCODE rc) ...@@ -889,7 +891,7 @@ bool ODBConn::Check(RETCODE rc)
{ {
switch (rc) { switch (rc) {
case SQL_SUCCESS_WITH_INFO: case SQL_SUCCESS_WITH_INFO:
if (trace > 1) { if (trace) {
DBX x(rc); DBX x(rc);
x.BuildErrorMessage(this, m_hstmt); x.BuildErrorMessage(this, m_hstmt);
...@@ -1242,7 +1244,7 @@ void ODBConn::GetConnectInfo() ...@@ -1242,7 +1244,7 @@ void ODBConn::GetConnectInfo()
m_IDQuoteChar = ' '; m_IDQuoteChar = ' ';
if (trace) if (trace)
htrc("DBMS: %s, Version: %s", htrc("DBMS: %s, Version: %s\n",
GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER)); GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER));
} // end of GetConnectInfo } // end of GetConnectInfo
...@@ -1511,15 +1513,17 @@ int ODBConn::PrepareSQL(char *sql) ...@@ -1511,15 +1513,17 @@ int ODBConn::PrepareSQL(char *sql)
hstmt = m_hstmt; hstmt = m_hstmt;
m_hstmt = NULL; m_hstmt = NULL;
if (m_Tdb->GetAmType() != TYPE_AM_XDBC)
ThrowDBX(MSG(SEQUENCE_ERROR)); ThrowDBX(MSG(SEQUENCE_ERROR));
} else {
} // endif m_hstmt
rc = SQLAllocStmt(m_hdbc, &hstmt); rc = SQLAllocStmt(m_hdbc, &hstmt);
if (!Check(rc)) if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt"); ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
} // endif hstmt
OnSetOptions(hstmt); OnSetOptions(hstmt);
b = true; b = true;
...@@ -1565,7 +1569,7 @@ int ODBConn::PrepareSQL(char *sql) ...@@ -1565,7 +1569,7 @@ int ODBConn::PrepareSQL(char *sql)
/***********************************************************************/ /***********************************************************************/
/* Execute a prepared statement. */ /* Execute a prepared statement. */
/***********************************************************************/ /***********************************************************************/
int ODBConn::ExecuteSQL(bool x) int ODBConn::ExecuteSQL(void)
{ {
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
SWORD ncol = 0; SWORD ncol = 0;
...@@ -1580,26 +1584,17 @@ int ODBConn::ExecuteSQL(bool x) ...@@ -1580,26 +1584,17 @@ int ODBConn::ExecuteSQL(bool x)
if (!Check(rc)) if (!Check(rc))
ThrowDBX(rc, "SQLExecute", m_hstmt); ThrowDBX(rc, "SQLExecute", m_hstmt);
if (!Check(SQLNumResultCols(m_hstmt, &ncol))) if (!Check(rc = SQLNumResultCols(m_hstmt, &ncol)))
ThrowDBX(rc, "SQLNumResultCols", m_hstmt); ThrowDBX(rc, "SQLNumResultCols", m_hstmt);
if (ncol) { if (ncol) {
if (x) {
afrw = ncol;
strcpy(g->Message, "Result set column number");
} else {
// This should never happen while inserting // This should never happen while inserting
strcpy(g->Message, "Logical error while inserting"); strcpy(g->Message, "Logical error while inserting");
} // endif ncol
} else { } else {
// Insert, Update or Delete statement // Insert, Update or Delete statement
if (!Check(SQLRowCount(m_hstmt, &afrw))) if (!Check(rc = SQLRowCount(m_hstmt, &afrw)))
ThrowDBX(rc, "SQLRowCount", m_hstmt); ThrowDBX(rc, "SQLRowCount", m_hstmt);
if (x)
strcpy(g->Message, "Affected rows");
} // endif ncol } // endif ncol
} catch(DBX *x) { } catch(DBX *x) {
...@@ -1613,6 +1608,7 @@ int ODBConn::ExecuteSQL(bool x) ...@@ -1613,6 +1608,7 @@ int ODBConn::ExecuteSQL(bool x)
m_Transact = false; m_Transact = false;
} // endif m_Transact } // endif m_Transact
afrw = -1;
} // end try/catch } // end try/catch
return (int)afrw; return (int)afrw;
...@@ -1667,6 +1663,112 @@ bool ODBConn::BindParam(ODBCCOL *colp) ...@@ -1667,6 +1663,112 @@ bool ODBConn::BindParam(ODBCCOL *colp)
return false; return false;
} // end of BindParam } // end of BindParam
/***********************************************************************/
/* Execute an SQL command. */
/***********************************************************************/
bool ODBConn::ExecSQLcommand(char *sql)
{
char cmd[16];
bool b, rcd = false;
UINT txn = 0;
PGLOBAL& g = m_G;
SWORD ncol = 0;
SQLLEN afrw;
RETCODE rc;
HSTMT hstmt;
try {
b = FALSE;
// Check whether we should use transaction
if (sscanf(sql, " %15s ", cmd) == 1) {
if (!stricmp(cmd, "INSERT") || !stricmp(cmd, "UPDATE") ||
!stricmp(cmd, "DELETE") || !stricmp(cmd, "REPLACE")) {
// Does the data source support transactions
rc = SQLGetInfo(m_hdbc, SQL_TXN_CAPABLE, &txn, 0, NULL);
if (Check(rc) && txn != SQL_TC_NONE) {
rc = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT,
SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLSetConnectAttr");
m_Transact = TRUE;
} // endif txn
} // endif cmd
} // endif sql
// Allocate the statement handle
rc = SQLAllocStmt(m_hdbc, &hstmt);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
OnSetOptions(hstmt);
b = true;
if (trace)
htrc("ExecSQLcommand hstmt=%p %.64s\n", hstmt, sql);
// Proceed with command execution
do {
rc = SQLExecDirect(hstmt, (PUCHAR)sql, SQL_NTS);
} while (rc == SQL_STILL_EXECUTING);
if (!Check(rc))
ThrowDBX(rc, "SQLExecDirect", hstmt);
// Check whether this is a query returning a result set
if (!Check(rc = SQLNumResultCols(hstmt, &ncol)))
ThrowDBX(rc, "SQLNumResultCols", hstmt);
if (!ncol) {
if (!Check(SQLRowCount(hstmt, &afrw)))
ThrowDBX(rc, "SQLRowCount", hstmt);
m_Tdb->AftRows = (int)afrw;
strcpy(g->Message, "Affected rows");
} else {
m_Tdb->AftRows = (int)ncol;
strcpy(g->Message, "Result set column number");
} // endif ncol
} catch(DBX *x) {
if (trace)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]);
strcpy(g->Message, x->GetErrorMessage(0));
if (b)
SQLCancel(hstmt);
m_Tdb->AftRows = -1;
rcd = true;
} // end try/catch
if (!Check(rc = SQLFreeStmt(hstmt, SQL_CLOSE)))
sprintf(g->Message, "SQLFreeStmt: rc=%d", rc);
if (m_Transact) {
// Terminate the transaction
if (!Check(rc = SQLEndTran(SQL_HANDLE_DBC, m_hdbc,
(rcd) ? SQL_ROLLBACK : SQL_COMMIT)))
sprintf(g->Message, "SQLEndTran: rc=%d", rc);
if (!Check(rc = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER)))
sprintf(g->Message, "SQLSetConnectAttr: rc=%d", rc);
m_Transact = false;
} // endif m_Transact
return rcd;
} // end of ExecSQLcommand
/**************************************************************************/ /**************************************************************************/
/* GetMetaData: constructs the result blocks containing the */ /* GetMetaData: constructs the result blocks containing the */
/* description of all the columns of an SQL command. */ /* description of all the columns of an SQL command. */
......
...@@ -142,8 +142,9 @@ class ODBConn : public BLOCK { ...@@ -142,8 +142,9 @@ class ODBConn : public BLOCK {
int ExecDirectSQL(char *sql, ODBCCOL *tocols); int ExecDirectSQL(char *sql, ODBCCOL *tocols);
int Fetch(void); int Fetch(void);
int PrepareSQL(char *sql); int PrepareSQL(char *sql);
int ExecuteSQL(bool x); int ExecuteSQL(void);
bool BindParam(ODBCCOL *colp); bool BindParam(ODBCCOL *colp);
bool ExecSQLcommand(char *sql);
int GetCatInfo(CATPARM *cap); int GetCatInfo(CATPARM *cap);
bool GetDataSources(PQRYRES qrp); bool GetDataSources(PQRYRES qrp);
bool GetDrivers(PQRYRES qrp); bool GetDrivers(PQRYRES qrp);
......
...@@ -106,13 +106,20 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ ...@@ -106,13 +106,20 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_DOM = 80, /* DOM access method type no */ TYPE_AM_DOM = 80, /* DOM access method type no */
TYPE_AM_DIR = 90, /* DIR access method type no */ TYPE_AM_DIR = 90, /* DIR access method type no */
TYPE_AM_ODBC = 100, /* ODBC access method type no */ TYPE_AM_ODBC = 100, /* ODBC access method type no */
TYPE_AM_XDBC = 101, /* XDBC access method type no */
TYPE_AM_OEM = 110, /* OEM access method type no */ TYPE_AM_OEM = 110, /* OEM access method type no */
TYPE_AM_TBL = 115, /* TBL access method type no */ TYPE_AM_TBL = 115, /* TBL access method type no */
TYPE_AM_PIVOT = 120, /* PIVOT access method type no */ TYPE_AM_PIVOT = 120, /* PIVOT access method type no */
TYPE_AM_SRC = 121, /* PIVOT multiple column type no */ TYPE_AM_SRC = 121, /* PIVOT multiple column type no */
TYPE_AM_FNC = 122, /* PIVOT source column type no */ TYPE_AM_FNC = 122, /* PIVOT source column type no */
TYPE_AM_XCOL = 124, /* XCOL access method type no */
TYPE_AM_XML = 127, /* XML access method type no */ TYPE_AM_XML = 127, /* XML access method type no */
TYPE_AM_OCCUR = 128, /* OCCUR access method type no */
TYPE_AM_PRX = 129, /* PROXY access method type no */
TYPE_AM_XTB = 130, /* SYS table access method type */ TYPE_AM_XTB = 130, /* SYS table access method type */
TYPE_AM_BLK = 131, /* BLK access method type no */
TYPE_AM_ZIP = 132, /* ZIP access method type no */
TYPE_AM_ZLIB = 133, /* ZLIB access method type no */
TYPE_AM_MAC = 137, /* MAC table access method type */ TYPE_AM_MAC = 137, /* MAC table access method type */
TYPE_AM_WMI = 139, /* WMI table access method type */ TYPE_AM_WMI = 139, /* WMI table access method type */
TYPE_AM_XCL = 140, /* SYS column access method type */ TYPE_AM_XCL = 140, /* SYS column access method type */
...@@ -123,7 +130,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ ...@@ -123,7 +130,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */ TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
TYPE_AM_SET = 180, /* SET Set tables am type no */ TYPE_AM_SET = 180, /* SET Set tables am type no */
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */ TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
TYPE_AM_CAT = 193, /* Catalog access method type no */ TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */
TYPE_AM_CAT = 195, /* Catalog access method type no */
TYPE_AM_OUT = 200}; /* Output relations (storage) */ TYPE_AM_OUT = 200}; /* Output relations (storage) */
enum RECFM {RECFM_NAF = -2, /* Not a file */ enum RECFM {RECFM_NAF = -2, /* Not a file */
......
...@@ -355,7 +355,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -355,7 +355,9 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL))) if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
Isview = TRUE; Isview = TRUE;
// Specific for command executing tables
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE); Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
return FALSE; return FALSE;
} // end of DefineAM } // end of DefineAM
...@@ -516,7 +518,7 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g) ...@@ -516,7 +518,7 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk); strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
if (To_Filter) if (To_Filter)
strcat(strcat(Query, " WHERE "), To_Filter); strcat(strcat(Query, " WHERE "), To_Filter->Body);
if (trace) if (trace)
htrc("Query=%s\n", Query); htrc("Query=%s\n", Query);
...@@ -1294,8 +1296,30 @@ void MYSQLCOL::WriteColumn(PGLOBAL g) ...@@ -1294,8 +1296,30 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
/***********************************************************************/ /***********************************************************************/
/* Implementation of the TDBMYSQL class. */ /* Implementation of the TDBMYEXC class. */
/***********************************************************************/ /***********************************************************************/
TDBMYEXC::TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp)
{
Cmdlist = NULL;
Cmdcol = NULL;
Shw = false;
Havew = false;
Isw = false;
Warnings = 0;
Mxr = tdp->Mxr;
Nerr = 0;
} // end of TDBMYEXC constructor
TDBMYEXC::TDBMYEXC(PGLOBAL g, PTDBMYX tdbp) : TDBMYSQL(g, tdbp)
{
Cmdlist = tdbp->Cmdlist;
Cmdcol = tdbp->Cmdcol;
Shw = tdbp->Shw;
Havew = tdbp->Havew;
Isw = tdbp->Isw;
Mxr = tdbp->Mxr;
Nerr = tdbp->Nerr;
} // end of TDBMYEXC copy constructor
// Is this really useful ??? // Is this really useful ???
PTDB TDBMYEXC::CopyOne(PTABS t) PTDB TDBMYEXC::CopyOne(PTABS t)
...@@ -1331,23 +1355,15 @@ PCOL TDBMYEXC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) ...@@ -1331,23 +1355,15 @@ PCOL TDBMYEXC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/***********************************************************************/ /***********************************************************************/
/* MakeCMD: make the SQL statement to send to MYSQL connection. */ /* MakeCMD: make the SQL statement to send to MYSQL connection. */
/***********************************************************************/ /***********************************************************************/
char *TDBMYEXC::MakeCMD(PGLOBAL g) PCMD TDBMYEXC::MakeCMD(PGLOBAL g)
{ {
char *xcmd = NULL; PCMD xcmd = NULL;
if (To_Filter) { if (To_Filter) {
if (Cmdcol) { if (Cmdcol) {
char col[128], cmd[1024]; if (!stricmp(Cmdcol, To_Filter->Body) &&
int n; (To_Filter->Op == OP_EQ || To_Filter->Op == OP_IN)) {
xcmd = To_Filter->Cmds;
memset(cmd, 0, sizeof(cmd));
n = sscanf(To_Filter, "%s = '%1023c", col, cmd);
if (n == 2 && !stricmp(col, Cmdcol)) {
xcmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
strcpy(xcmd, cmd);
xcmd[strlen(xcmd) - 1] = 0;
} else } else
strcpy(g->Message, "Invalid command specification filter"); strcpy(g->Message, "Invalid command specification filter");
...@@ -1357,7 +1373,7 @@ char *TDBMYEXC::MakeCMD(PGLOBAL g) ...@@ -1357,7 +1373,7 @@ char *TDBMYEXC::MakeCMD(PGLOBAL g)
} else if (!Srcdef) } else if (!Srcdef)
strcpy(g->Message, "No Srcdef default command"); strcpy(g->Message, "No Srcdef default command");
else else
xcmd = Srcdef; xcmd = new(g) CMD(g, Srcdef);
return xcmd; return xcmd;
} // end of MakeCMD } // end of MakeCMD
...@@ -1368,7 +1384,7 @@ char *TDBMYEXC::MakeCMD(PGLOBAL g) ...@@ -1368,7 +1384,7 @@ char *TDBMYEXC::MakeCMD(PGLOBAL g)
int TDBMYEXC::GetMaxSize(PGLOBAL g) int TDBMYEXC::GetMaxSize(PGLOBAL g)
{ {
if (MaxSize < 0) { if (MaxSize < 0) {
MaxSize = 1; MaxSize = 10; // a guess
} // endif MaxSize } // endif MaxSize
return MaxSize; return MaxSize;
...@@ -1379,8 +1395,6 @@ int TDBMYEXC::GetMaxSize(PGLOBAL g) ...@@ -1379,8 +1395,6 @@ int TDBMYEXC::GetMaxSize(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
bool TDBMYEXC::OpenDB(PGLOBAL g) bool TDBMYEXC::OpenDB(PGLOBAL g)
{ {
int rc;
if (Use == USE_OPEN) { if (Use == USE_OPEN) {
strcpy(g->Message, "Multiple execution is not allowed"); strcpy(g->Message, "Multiple execution is not allowed");
return true; return true;
...@@ -1407,20 +1421,11 @@ bool TDBMYEXC::OpenDB(PGLOBAL g) ...@@ -1407,20 +1421,11 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* Get the command to execute. */ /* Get the command to execute. */
/*********************************************************************/ /*********************************************************************/
if (!(Query = MakeCMD(g))) { if (!(Cmdlist = MakeCMD(g))) {
Myc.Close(); Myc.Close();
return true; return true;
} // endif Query } // endif Query
if ((rc = Myc.ExecSQL(g, Query)) == RC_NF) {
strcpy(g->Message, "Affected rows");
AftRows = Myc.m_Rows;
} else if (rc == RC_OK) {
sprintf(g->Message, "Columns and %d rows", Myc.m_Rows);
AftRows = Myc.m_Fields;
} else
return true;
return false; return false;
} // end of OpenDB } // end of OpenDB
...@@ -1429,7 +1434,54 @@ bool TDBMYEXC::OpenDB(PGLOBAL g) ...@@ -1429,7 +1434,54 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBMYEXC::ReadDB(PGLOBAL g) int TDBMYEXC::ReadDB(PGLOBAL g)
{ {
return (++N) ? RC_EF : RC_OK; if (Havew) {
// Process result set from SHOW WARNINGS
if (Myc.Fetch(g, -1) != RC_OK) {
Myc.FreeResult();
Havew = Isw = false;
} else {
N++;
Isw = true;
return RC_OK;
} // endif Fetch
} // endif m_Res
if (Cmdlist) {
// Process query to send
int rc;
do {
Query = Cmdlist->Cmd;
switch (rc = Myc.ExecSQLcmd(g, Query, &Warnings)) {
case RC_NF:
AftRows = Myc.m_Afrw;
strcpy(g->Message, "Affected rows");
break;
case RC_OK:
AftRows = Myc.m_Fields;
strcpy(g->Message, "Result set columns");
break;
case RC_FX:
AftRows = Myc.m_Afrw;
Nerr++;
break;
case RC_INFO:
Shw = true;
} // endswitch rc
Cmdlist = (Nerr > Mxr) ? NULL : Cmdlist->Next;
} while (rc == RC_INFO);
if (Shw && Warnings)
Havew = (Myc.ExecSQL(g, "SHOW WARNINGS") == RC_OK);
++N;
return RC_OK;
} else
return RC_EF;
} // end of ReadDB } // end of ReadDB
/***********************************************************************/ /***********************************************************************/
...@@ -1480,10 +1532,21 @@ void MYXCOL::ReadColumn(PGLOBAL g) ...@@ -1480,10 +1532,21 @@ void MYXCOL::ReadColumn(PGLOBAL g)
{ {
PTDBMYX tdbp = (PTDBMYX)To_Tdb; PTDBMYX tdbp = (PTDBMYX)To_Tdb;
if (tdbp->Isw) {
char *buf = NULL;
if (Flag < 3) {
buf = tdbp->Myc.GetCharField(Flag);
Value->SetValue_psz(buf);
} else
Value->Reset();
} else
switch (Flag) { switch (Flag) {
case 0: Value->SetValue_psz(tdbp->Query); break; case 0: Value->SetValue_psz(tdbp->Query); break;
case 1: Value->SetValue(tdbp->AftRows); break; case 1: Value->SetValue(tdbp->AftRows); break;
case 2: Value->SetValue_psz(g->Message); break; case 2: Value->SetValue_psz(g->Message); break;
case 3: Value->SetValue(tdbp->Warnings); break;
default: Value->SetValue_psz("Invalid Flag"); break; default: Value->SetValue_psz("Invalid Flag"); break;
} // endswitch Flag } // endswitch Flag
......
...@@ -20,6 +20,7 @@ typedef class MYSQLC *PMYC; ...@@ -20,6 +20,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/ /***********************************************************************/
class MYSQLDEF : public TABDEF {/* Logical table description */ class MYSQLDEF : public TABDEF {/* Logical table description */
friend class TDBMYSQL; friend class TDBMYSQL;
friend class TDBMYEXC;
friend class TDBMCL; friend class TDBMCL;
friend class ha_connect; friend class ha_connect;
public: public:
...@@ -53,6 +54,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */ ...@@ -53,6 +54,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
PSZ Password; /* Password logon info */ PSZ Password; /* Password logon info */
PSZ Server; /* PServerID */ PSZ Server; /* PServerID */
int Portnumber; /* MySQL port number (0 = default) */ int Portnumber; /* MySQL port number (0 = default) */
int Mxr; /* Maxerr for an Exec table */
bool Isview; /* TRUE if this table is a MySQL view */ bool Isview; /* TRUE if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */ bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */ bool Delayed; /* Delayed insert */
...@@ -167,13 +169,12 @@ class MYSQLCOL : public COLBLK { ...@@ -167,13 +169,12 @@ class MYSQLCOL : public COLBLK {
class TDBMYEXC : public TDBMYSQL { class TDBMYEXC : public TDBMYSQL {
friend class MYXCOL; friend class MYXCOL;
public: public:
// Constructor // Constructors
TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp) {Cmdcol = NULL;} TDBMYEXC(PMYDEF tdp);
TDBMYEXC(PGLOBAL g, PTDBMYX tdbp) : TDBMYSQL(g, tdbp) TDBMYEXC(PGLOBAL g, PTDBMYX tdbp);
{Cmdcol = tdbp->Cmdcol;}
// Implementation // Implementation
//virtual AMT GetAmType(void) {return TYPE_AM_MYSQL;} virtual AMT GetAmType(void) {return TYPE_AM_MYX;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);} virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);}
// Methods // Methods
...@@ -203,13 +204,20 @@ class TDBMYEXC : public TDBMYSQL { ...@@ -203,13 +204,20 @@ class TDBMYEXC : public TDBMYSQL {
protected: protected:
// Internal functions // Internal functions
char *MakeCMD(PGLOBAL g); PCMD MakeCMD(PGLOBAL g);
//bool MakeSelect(PGLOBAL g); //bool MakeSelect(PGLOBAL g);
//bool MakeInsert(PGLOBAL g); //bool MakeInsert(PGLOBAL g);
//int BindColumns(PGLOBAL g); //int BindColumns(PGLOBAL g);
// Members // Members
PCMD Cmdlist; // The commands to execute
char *Cmdcol; // The name of the Xsrc command column char *Cmdcol; // The name of the Xsrc command column
bool Shw; // Show warnings
bool Havew; // True when processing warnings
bool Isw; // True for warning lines
int Warnings; // Warnings number
int Mxr; // Maximum errors before closing
int Nerr; // Number of errors so far
}; // end of class TDBMYEXC }; // end of class TDBMYEXC
/***********************************************************************/ /***********************************************************************/
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
#include "tabutil.h" #include "tabutil.h"
#define TYPE_AM_OCCUR (AMT)128
typedef class OCCURDEF *POCCURDEF; typedef class OCCURDEF *POCCURDEF;
typedef class TDBOCCUR *PTDBOCCUR; typedef class TDBOCCUR *PTDBOCCUR;
typedef class OCCURCOL *POCCURCOL; typedef class OCCURCOL *POCCURCOL;
......
...@@ -110,6 +110,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -110,6 +110,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Qchar = Cat->GetStringCatInfo(g, "Qchar", ""); Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
Catver = Cat->GetIntCatInfo("Catver", 2); Catver = Cat->GetIntCatInfo("Catver", 2);
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE); Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
Options = ODBConn::noOdbcDialog; Options = ODBConn::noOdbcDialog;
Pseudo = 2; // FILID is Ok but not ROWID Pseudo = 2; // FILID is Ok but not ROWID
return false; return false;
...@@ -395,7 +396,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt) ...@@ -395,7 +396,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
// Below 14 is length of 'select ' + length of ' from ' + 1 // Below 14 is length of 'select ' + length of ' from ' + 1
len = (strlen(colist) + strlen(buf) + 14); len = (strlen(colist) + strlen(buf) + 14);
len += (To_Filter ? strlen(To_Filter) + 7 : 0); len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
// if (tablep->GetQualifier()) This is used when using a table // if (tablep->GetQualifier()) This is used when using a table
// qualp = tablep->GetQualifier(); from anotherPlugDB database but // qualp = tablep->GetQualifier(); from anotherPlugDB database but
...@@ -432,7 +433,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt) ...@@ -432,7 +433,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
strcat(sql, tabname); strcat(sql, tabname);
if (To_Filter) if (To_Filter)
strcat(strcat(sql, " WHERE "), To_Filter); strcat(strcat(sql, " WHERE "), To_Filter->Body);
return sql; return sql;
} // end of MakeSQL } // end of MakeSQL
...@@ -720,7 +721,7 @@ int TDBODBC::ReadDB(PGLOBAL g) ...@@ -720,7 +721,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBODBC::WriteDB(PGLOBAL g) int TDBODBC::WriteDB(PGLOBAL g)
{ {
int n = Ocp->ExecuteSQL(false); int n = Ocp->ExecuteSQL();
if (n < 0) { if (n < 0) {
AftRows = n; AftRows = n;
...@@ -1004,6 +1005,22 @@ void ODBCCOL::WriteColumn(PGLOBAL g) ...@@ -1004,6 +1005,22 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Implementation of the TDBODBC class. */ /* Implementation of the TDBODBC class. */
/***********************************************************************/ /***********************************************************************/
TDBXDBC::TDBXDBC(PODEF tdp) : TDBODBC(tdp)
{
Cmdlist = NULL;
Cmdcol = NULL;
Mxr = tdp->Mxr;
Nerr = 0;
} // end of TDBXDBC constructor
TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp)
{
Cmdlist = tdbp->Cmdlist;
Cmdcol = tdbp->Cmdcol;
Mxr = tdbp->Mxr;
Nerr = tdbp->Nerr;
} // end of TDBXDBC copy constructor
PTDB TDBXDBC::CopyOne(PTABS t) PTDB TDBXDBC::CopyOne(PTABS t)
{ {
PTDB tp; PTDB tp;
...@@ -1036,23 +1053,15 @@ PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) ...@@ -1036,23 +1053,15 @@ PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/***********************************************************************/ /***********************************************************************/
/* MakeCMD: make the SQL statement to send to ODBC connection. */ /* MakeCMD: make the SQL statement to send to ODBC connection. */
/***********************************************************************/ /***********************************************************************/
char *TDBXDBC::MakeCMD(PGLOBAL g) PCMD TDBXDBC::MakeCMD(PGLOBAL g)
{ {
char *xcmd = NULL; PCMD xcmd = NULL;
if (To_Filter) { if (To_Filter) {
if (Cmdcol) { if (Cmdcol) {
char col[128], cmd[1024]; if (!stricmp(Cmdcol, To_Filter->Body) &&
int n; (To_Filter->Op == OP_EQ || To_Filter->Op == OP_IN)) {
xcmd = To_Filter->Cmds;
memset(cmd, 0, sizeof(cmd));
n = sscanf(To_Filter, "%s = '%1023c", col, cmd);
if (n == 2 && !stricmp(col, Cmdcol)) {
xcmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
strcpy(xcmd, cmd);
xcmd[strlen(xcmd) - 1] = 0;
} else } else
strcpy(g->Message, "Invalid command specification filter"); strcpy(g->Message, "Invalid command specification filter");
...@@ -1062,7 +1071,7 @@ char *TDBXDBC::MakeCMD(PGLOBAL g) ...@@ -1062,7 +1071,7 @@ char *TDBXDBC::MakeCMD(PGLOBAL g)
} else if (!Srcdef) } else if (!Srcdef)
strcpy(g->Message, "No Srcdef default command"); strcpy(g->Message, "No Srcdef default command");
else else
xcmd = Srcdef; xcmd = new(g) CMD(g, Srcdef);
return xcmd; return xcmd;
} // end of MakeCMD } // end of MakeCMD
...@@ -1088,12 +1097,12 @@ bool TDBXDBC::BindParameters(PGLOBAL g) ...@@ -1088,12 +1097,12 @@ bool TDBXDBC::BindParameters(PGLOBAL g)
#endif // 0 #endif // 0
/***********************************************************************/ /***********************************************************************/
/* XDBC GetMaxSize: returns table size (always one row). */ /* XDBC GetMaxSize: returns table size (not always one row). */
/***********************************************************************/ /***********************************************************************/
int TDBXDBC::GetMaxSize(PGLOBAL g) int TDBXDBC::GetMaxSize(PGLOBAL g)
{ {
if (MaxSize < 0) if (MaxSize < 0)
MaxSize = 1; MaxSize = 10; // Just a guess
return MaxSize; return MaxSize;
} // end of GetMaxSize } // end of GetMaxSize
...@@ -1142,19 +1151,12 @@ bool TDBXDBC::OpenDB(PGLOBAL g) ...@@ -1142,19 +1151,12 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* Get the command to execute. */ /* Get the command to execute. */
/*********************************************************************/ /*********************************************************************/
if (!(Query = MakeCMD(g))) { if (!(Cmdlist = MakeCMD(g))) {
Ocp->Close(); Ocp->Close();
return true; return true;
} // endif Query } // endif Query
Rows = 1; Rows = 1;
if (Ocp->PrepareSQL(Query)) {
strcpy(g->Message, "Parameters not supported");
AftRows = -1;
} else
AftRows = 0;
return false; return false;
} // end of OpenDB } // end of OpenDB
...@@ -1163,18 +1165,18 @@ bool TDBXDBC::OpenDB(PGLOBAL g) ...@@ -1163,18 +1165,18 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBXDBC::ReadDB(PGLOBAL g) int TDBXDBC::ReadDB(PGLOBAL g)
{ {
if (trace) if (Cmdlist) {
htrc("XDBC ReadDB: query=%s\n", SVP(Query)); Query = Cmdlist->Cmd;
if (Rows--) { if (Ocp->ExecSQLcommand(Query))
if (!AftRows) Nerr++;
AftRows = Ocp->ExecuteSQL(true);
Fpos++; // Used for progress info
Cmdlist = (Nerr > Mxr) ? NULL : Cmdlist->Next;
return RC_OK;
} else } else
return RC_EF; return RC_EF;
Fpos++; // Used for progress info
return RC_OK;
} // end of ReadDB } // end of ReadDB
/***********************************************************************/ /***********************************************************************/
......
...@@ -52,6 +52,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -52,6 +52,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Qchar; /* Identifier quoting character */ PSZ Qchar; /* Identifier quoting character */
int Catver; /* ODBC version for catalog functions */ int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */ int Options; /* Open connection options */
int Mxr; /* Maxerr for an Exec table */
bool Xsrc; /* Execution type */ bool Xsrc; /* Execution type */
}; // end of ODBCDEF }; // end of ODBCDEF
...@@ -179,12 +180,12 @@ class TDBXDBC : public TDBODBC { ...@@ -179,12 +180,12 @@ class TDBXDBC : public TDBODBC {
friend class XSRCCOL; friend class XSRCCOL;
friend class ODBConn; friend class ODBConn;
public: public:
// Constructor // Constructors
TDBXDBC(PODEF tdp = NULL) : TDBODBC(tdp) {Cmdcol = NULL;} TDBXDBC(PODEF tdp = NULL);
TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp) {Cmdcol = tdbp->Cmdcol;} TDBXDBC(PTDBXDBC tdbp);
// Implementation // Implementation
//virtual AMT GetAmType(void) {return TYPE_AM_ODBC;} virtual AMT GetAmType(void) {return TYPE_AM_XDBC;}
virtual PTDB Duplicate(PGLOBAL g) virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBXDBC(this);} {return (PTDB)new(g) TDBXDBC(this);}
...@@ -209,11 +210,14 @@ class TDBXDBC : public TDBODBC { ...@@ -209,11 +210,14 @@ class TDBXDBC : public TDBODBC {
protected: protected:
// Internal functions // Internal functions
char *MakeCMD(PGLOBAL g); PCMD MakeCMD(PGLOBAL g);
//bool BindParameters(PGLOBAL g); //bool BindParameters(PGLOBAL g);
// Members // Members
PCMD Cmdlist; // The commands to execute
char *Cmdcol; // The name of the Xsrc command column char *Cmdcol; // The name of the Xsrc command column
int Mxr; // Maximum errors before closing
int Nerr; // Number of errors so far
}; // end of class TDBXDBC }; // end of class TDBXDBC
/***********************************************************************/ /***********************************************************************/
......
...@@ -295,15 +295,18 @@ bool TDBTBL::InitTableList(PGLOBAL g) ...@@ -295,15 +295,18 @@ bool TDBTBL::InitTableList(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTABLE tabp) bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTABLE tabp)
{ {
char *fil, op[8], tn[NAME_LEN]; char *body, *fil, op[8], tn[NAME_LEN];
bool neg; bool neg;
if (!filp) if (!filp)
return TRUE; return TRUE;
else if (strstr(filp, " OR ") || strstr(filp, " AND ")) else
body = filp->Body;
if (strstr(body, " OR ") || strstr(body, " AND "))
return TRUE; // Not handled yet return TRUE; // Not handled yet
else else
fil = filp + (*filp == '(' ? 1 : 0); fil = body + (*body == '(' ? 1 : 0);
if (sscanf(fil, "TABID %s", op) != 1) if (sscanf(fil, "TABID %s", op) != 1)
return TRUE; // ignore invalid filter return TRUE; // ignore invalid filter
......
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
//#include "tabtbl.h" //#include "tabtbl.h"
#define TYPE_AM_PRX (AMT)129
typedef class PRXDEF *PPRXDEF; typedef class PRXDEF *PPRXDEF;
typedef class TDBPRX *PTDBPRX; typedef class TDBPRX *PTDBPRX;
typedef class XXLCOL *PXXLCOL; typedef class XXLCOL *PXXLCOL;
......
...@@ -480,18 +480,19 @@ bool TDBWMI::Initialize(PGLOBAL g) ...@@ -480,18 +480,19 @@ bool TDBWMI::Initialize(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
void TDBWMI::DoubleSlash(PGLOBAL g) void TDBWMI::DoubleSlash(PGLOBAL g)
{ {
if (To_Filter && strchr(To_Filter, '\\')) { if (To_Filter && strchr(To_Filter->Body, '\\')) {
char *buf = (char*)PlugSubAlloc(g, NULL, strlen(To_Filter) * 2); char *body = To_Filter->Body;
char *buf = (char*)PlugSubAlloc(g, NULL, strlen(body) * 2);
int i = 0, k = 0; int i = 0, k = 0;
do { do {
if (To_Filter[i] == '\\') if (body[i] == '\\')
buf[k++] = '\\'; buf[k++] = '\\';
buf[k++] = To_Filter[i]; buf[k++] = body[i];
} while (To_Filter[i++]); } while (body[i++]);
To_Filter = buf; To_Filter->Body = buf;
} // endif To_Filter } // endif To_Filter
} // end of DoubleSlash } // end of DoubleSlash
...@@ -539,13 +540,13 @@ char *TDBWMI::MakeWQL(PGLOBAL g) ...@@ -539,13 +540,13 @@ char *TDBWMI::MakeWQL(PGLOBAL g)
// Below 14 is length of 'select ' + length of ' from ' + 1 // Below 14 is length of 'select ' + length of ' from ' + 1
len = (strlen(colist) + strlen(Wclass) + 14); len = (strlen(colist) + strlen(Wclass) + 14);
len += (To_Filter ? strlen(To_Filter) + 7 : 0); len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
wql = (char*)PlugSubAlloc(g, NULL, len); wql = (char*)PlugSubAlloc(g, NULL, len);
strcat(strcat(strcpy(wql, "SELECT "), colist), " FROM "); strcat(strcat(strcpy(wql, "SELECT "), colist), " FROM ");
strcat(wql, Wclass); strcat(wql, Wclass);
if (To_Filter) if (To_Filter)
strcat(strcat(wql, " WHERE "), To_Filter); strcat(strcat(wql, " WHERE "), To_Filter->Body);
return wql; return wql;
} // end of MakeWQL } // end of MakeWQL
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
#include "tabutil.h" #include "tabutil.h"
#define TYPE_AM_XCOL (AMT)124
typedef class XCLDEF *PXCLDEF; typedef class XCLDEF *PXCLDEF;
typedef class TDBXCL *PTDBXCL; typedef class TDBXCL *PTDBXCL;
typedef class XCLCOL *PXCLCOL; typedef class XCLCOL *PXCLCOL;
......
...@@ -45,7 +45,7 @@ DllExport PSZ GetTypeName(int); ...@@ -45,7 +45,7 @@ DllExport PSZ GetTypeName(int);
DllExport int GetTypeSize(int, int); DllExport int GetTypeSize(int, int);
#ifdef ODBC_SUPPORT #ifdef ODBC_SUPPORT
/* This function is exported for use in EOM table type DLLs */ /* This function is exported for use in EOM table type DLLs */
DllExport int TranslateSQLType(int stp, int prec, int& len); DllExport int TranslateSQLType(int stp, int prec, int& len, char& v);
#endif #endif
DllExport char *GetFormatType(int); DllExport char *GetFormatType(int);
DllExport int GetFormatType(char); DllExport int GetFormatType(char);
......
...@@ -18,8 +18,28 @@ ...@@ -18,8 +18,28 @@
#include "colblk.h" #include "colblk.h"
#include "m_ctype.h" #include "m_ctype.h"
//pedef class INDEXDEF *PIXDEF; typedef class CMD *PCMD;
typedef char *PFIL; // Specific to CONNECT
// Commands executed by XDBC and MYX tables
class CMD : public BLOCK {
public:
// Constructor
CMD(PGLOBAL g, char *cmd) {
Cmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
strcpy(Cmd, cmd); Next = NULL; }
// Members
PCMD Next;
char *Cmd;
}; // end of class CMD
// Filter passed all tables
typedef struct _filter {
char *Body;
OPVAL Op;
PCMD Cmds;
} FILTER, *PFIL;
typedef class TDBCAT *PTDBCAT; typedef class TDBCAT *PTDBCAT;
typedef class CATCOL *PCATCOL; typedef class CATCOL *PCATCOL;
...@@ -39,24 +59,16 @@ class DllExport TBX: public BLOCK { // Base class for OPJOIN and TDB classes. ...@@ -39,24 +59,16 @@ class DllExport TBX: public BLOCK { // Base class for OPJOIN and TDB classes.
inline PFIL GetFilter(void) {return To_Filter;} inline PFIL GetFilter(void) {return To_Filter;}
inline void SetOrig(PTBX txp) {To_Orig = txp;} inline void SetOrig(PTBX txp) {To_Orig = txp;}
inline void SetFilter(PFIL fp) {To_Filter = fp;} inline void SetFilter(PFIL fp) {To_Filter = fp;}
//inline JTYPE GetJtype(void) {return Jtype;}
//inline void SetJtype(JTYPE jt) {Jtype = jt;}
//inline PFIL GetNoleft(void) {return To_Noleft;}
//inline void SetNoleft(PFIL fp) {To_Noleft = fp;}
// Methods // Methods
virtual bool IsSame(PTBX tp) {return tp == this;} virtual bool IsSame(PTBX tp) {return tp == this;}
//virtual bool Include(PTBX tbxp) = 0;
//virtual bool CheckFilter(void) = 0;
virtual int GetTdb_No(void) = 0; // Convenience during conversion virtual int GetTdb_No(void) = 0; // Convenience during conversion
virtual PTDB GetNext(void) = 0; virtual PTDB GetNext(void) = 0;
//virtual int GetMaxSame(PGLOBAL) = 0;
virtual int Cardinality(PGLOBAL) = 0; virtual int Cardinality(PGLOBAL) = 0;
virtual int GetMaxSize(PGLOBAL) = 0; virtual int GetMaxSize(PGLOBAL) = 0;
virtual int GetProgMax(PGLOBAL) = 0; virtual int GetProgMax(PGLOBAL) = 0;
virtual int GetProgCur(void) = 0; virtual int GetProgCur(void) = 0;
virtual int GetBadLines(void) {return 0;} virtual int GetBadLines(void) {return 0;}
//virtual bool IsJoin(void) = 0;
virtual PTBX Copy(PTABS t) = 0; virtual PTBX Copy(PTABS t) = 0;
protected: protected:
...@@ -66,8 +78,6 @@ class DllExport TBX: public BLOCK { // Base class for OPJOIN and TDB classes. ...@@ -66,8 +78,6 @@ class DllExport TBX: public BLOCK { // Base class for OPJOIN and TDB classes.
// Members // Members
PTBX To_Orig; // Pointer to original if it is a copy PTBX To_Orig; // Pointer to original if it is a copy
PFIL To_Filter; PFIL To_Filter;
//PFIL To_Noleft; // To filter not involved in LEFT JOIN
//JTYPE Jtype;
TUSE Use; TUSE Use;
}; // end of class TBX }; // end of class TBX
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment