Commit 793f05c3 authored by Olivier Bertrand's avatar Olivier Bertrand

- Modify the way UPDATE and DELETE statements are sent to ODBC

  and MYSQL CONNECT tables to take care of kewords such as IGNORE.

modified:
  storage/connect/myconn.cpp
  storage/connect/odbconn.cpp
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
  storage/connect/tabodbc.cpp
  storage/connect/tabodbc.h
parent 260c0de9
...@@ -808,7 +808,7 @@ int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w) ...@@ -808,7 +808,7 @@ int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w)
//if (mysql_query(m_DB, query) != 0) { //if (mysql_query(m_DB, query) != 0) {
if (mysql_real_query(m_DB, query, strlen(query))) { if (mysql_real_query(m_DB, query, strlen(query))) {
m_Afrw = (int)mysql_errno(m_DB); m_Afrw = (int)mysql_errno(m_DB);
sprintf(g->Message, "%s", mysql_error(m_DB)); sprintf(g->Message, "Remote: %s", mysql_error(m_DB));
rc = RC_FX; rc = RC_FX;
//} else if (!(m_Fields = mysql_field_count(m_DB))) { //} else if (!(m_Fields = mysql_field_count(m_DB))) {
} else if (!(m_Fields = (int)m_DB->field_count)) { } else if (!(m_Fields = (int)m_DB->field_count)) {
......
...@@ -1735,7 +1735,7 @@ bool ODBConn::ExecSQLcommand(char *sql) ...@@ -1735,7 +1735,7 @@ bool ODBConn::ExecSQLcommand(char *sql)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "Remote: %s", x->GetErrorMessage(0));
if (b) if (b)
SQLCancel(hstmt); SQLCancel(hstmt);
......
...@@ -622,6 +622,53 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) ...@@ -622,6 +622,53 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
return FALSE; return FALSE;
} // end of MakeInsert } // end of MakeInsert
/***********************************************************************/
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
int TDBMYSQL::MakeCommand(PGLOBAL g)
{
Query = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
if (Quoted > 0 || stricmp(Name, Tabname)) {
char *p, *qrystr, name[68];
bool qtd = Quoted > 0;
// Make a lower case copy of the originale query
qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
strlwr(strcpy(qrystr, Qrystr));
// Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, "`"), Name), "`"));
if (!strstr("`update`delete`low_priority`ignore`quick`from`", name))
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
memcpy(Query, Qrystr, p - qrystr);
Query[p - qrystr] = 0;
if (qtd && *(p-1) == ' ')
strcat(strcat(strcat(Query, "`"), Tabname), "`");
else
strcat(Query, Tabname);
strcat(Query, Qrystr + (p - qrystr) + strlen(name));
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return RC_FX;
} // endif p
} else
strcpy(Query, Qrystr);
return RC_OK;
} // end of MakeCommand
#if 0
/***********************************************************************/ /***********************************************************************/
/* MakeUpdate: make the Update statement use with MySQL connection. */ /* MakeUpdate: make the Update statement use with MySQL connection. */
/* Limited to remote values and filtering. */ /* Limited to remote values and filtering. */
...@@ -636,7 +683,8 @@ int TDBMYSQL::MakeUpdate(PGLOBAL g) ...@@ -636,7 +683,8 @@ int TDBMYSQL::MakeUpdate(PGLOBAL g)
if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 || if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 ||
sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2) sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2)
qc = "`"; qc = "`";
else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2) else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2
&& !stricmp(tab, Name))
qc = (Quoted) ? "`" : ""; qc = (Quoted) ? "`" : "";
else { else {
strcpy(g->Message, "Cannot use this UPDATE command"); strcpy(g->Message, "Cannot use this UPDATE command");
...@@ -678,6 +726,7 @@ int TDBMYSQL::MakeDelete(PGLOBAL g) ...@@ -678,6 +726,7 @@ int TDBMYSQL::MakeDelete(PGLOBAL g)
return RC_OK; return RC_OK;
} // end of MakeDelete } // end of MakeDelete
#endif // 0
/***********************************************************************/ /***********************************************************************/
/* XCV GetMaxSize: returns the maximum number of rows in the table. */ /* XCV GetMaxSize: returns the maximum number of rows in the table. */
...@@ -829,7 +878,8 @@ bool TDBMYSQL::OpenDB(PGLOBAL g) ...@@ -829,7 +878,8 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
} // endif m_Rc } // endif m_Rc
} else } else
m_Rc = (Mode == MODE_DELETE) ? MakeDelete(g) : MakeUpdate(g); // m_Rc = (Mode == MODE_DELETE) ? MakeDelete(g) : MakeUpdate(g);
m_Rc = MakeCommand(g);
if (m_Rc == RC_FX) { if (m_Rc == RC_FX) {
Myc.Close(); Myc.Close();
......
...@@ -106,9 +106,10 @@ class TDBMYSQL : public TDBASE { ...@@ -106,9 +106,10 @@ class TDBMYSQL : public TDBASE {
// Internal functions // Internal functions
bool MakeSelect(PGLOBAL g); bool MakeSelect(PGLOBAL g);
bool MakeInsert(PGLOBAL g); bool MakeInsert(PGLOBAL g);
int MakeUpdate(PGLOBAL g);
int MakeDelete(PGLOBAL g);
int BindColumns(PGLOBAL g); int BindColumns(PGLOBAL g);
int MakeCommand(PGLOBAL g);
//int MakeUpdate(PGLOBAL g);
//int MakeDelete(PGLOBAL g);
int SendCommand(PGLOBAL g); int SendCommand(PGLOBAL g);
// Members // Members
......
...@@ -518,6 +518,61 @@ bool TDBODBC::BindParameters(PGLOBAL g) ...@@ -518,6 +518,61 @@ bool TDBODBC::BindParameters(PGLOBAL g)
return false; return false;
} // end of BindParameters } // end of BindParameters
/***********************************************************************/
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
char *TDBODBC::MakeCommand(PGLOBAL g)
{
char *p, name[68], *qc = Ocp->GetQuoteChar();
char *stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
bool qtd = Quoted > 0;
int i = 0, k = 0;
// Make a lower case copy of the originale query and change
// back ticks to the data source identifier quoting character
do {
qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]);
} while (Qrystr[i++]);
// Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
if (!strstr(" update delete low_priority ignore quick from ", name))
strlwr(strcpy(name, Name)); // Not a keyword
else
strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
if ((p = strstr(qrystr, name))) {
for (i = 0; i < p - qrystr; i++)
stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i];
stmt[i] = 0;
k = i + (int)strlen(Name);
if (qtd && *(p-1) == ' ')
strcat(strcat(strcat(stmt, qc), TableName), qc);
else
strcat(stmt, TableName);
i = (int)strlen(stmt);
do {
stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k];
} while (Qrystr[k++]);
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return NULL;
} // endif p
return stmt;
} // end of MakeCommand
#if 0
/***********************************************************************/ /***********************************************************************/
/* MakeUpdate: make the SQL statement to send to ODBC connection. */ /* MakeUpdate: make the SQL statement to send to ODBC connection. */
/***********************************************************************/ /***********************************************************************/
...@@ -582,6 +637,7 @@ char *TDBODBC::MakeDelete(PGLOBAL g) ...@@ -582,6 +637,7 @@ char *TDBODBC::MakeDelete(PGLOBAL g)
return stmt; return stmt;
} // end of MakeDelete } // end of MakeDelete
#endif // 0
/***********************************************************************/ /***********************************************************************/
/* ResetSize: call by TDBMUL when calculating size estimate. */ /* ResetSize: call by TDBMUL when calculating size estimate. */
...@@ -713,10 +769,8 @@ bool TDBODBC::OpenDB(PGLOBAL g) ...@@ -713,10 +769,8 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} // endif Query } // endif Query
} else if (Mode == MODE_UPDATE) } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
Query = MakeUpdate(g); Query = MakeCommand(g);
else if (Mode == MODE_DELETE)
Query = MakeDelete(g);
else else
sprintf(g->Message, "Invalid mode %d", Mode); sprintf(g->Message, "Invalid mode %d", Mode);
......
...@@ -102,10 +102,11 @@ class TDBODBC : public TDBASE { ...@@ -102,10 +102,11 @@ class TDBODBC : public TDBASE {
int Decode(char *utf, char *buf, size_t n); int Decode(char *utf, char *buf, size_t n);
char *MakeSQL(PGLOBAL g, bool cnt); char *MakeSQL(PGLOBAL g, bool cnt);
char *MakeInsert(PGLOBAL g); char *MakeInsert(PGLOBAL g);
char *MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c); //bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g); bool BindParameters(PGLOBAL g);
char *MakeUpdate(PGLOBAL g); //char *MakeUpdate(PGLOBAL g);
char *MakeDelete(PGLOBAL g); //char *MakeDelete(PGLOBAL g);
// Members // Members
ODBConn *Ocp; // Points to an ODBC connection class ODBConn *Ocp; // Points to an ODBC connection class
......
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