diff options
-rw-r--r-- | storage/connect/myconn.cpp | 2 | ||||
-rw-r--r-- | storage/connect/odbconn.cpp | 2 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 54 | ||||
-rw-r--r-- | storage/connect/tabmysql.h | 5 | ||||
-rw-r--r-- | storage/connect/tabodbc.cpp | 62 | ||||
-rw-r--r-- | storage/connect/tabodbc.h | 5 |
6 files changed, 118 insertions, 12 deletions
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index d29c116756a..643d25daac1 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -808,7 +808,7 @@ int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w) //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)); + sprintf(g->Message, "Remote: %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)) { diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index c6a6fe0ed02..36cdd8e7330 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -1735,7 +1735,7 @@ bool ODBConn::ExecSQLcommand(char *sql) 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)); + sprintf(g->Message, "Remote: %s", x->GetErrorMessage(0)); if (b) SQLCancel(hstmt); diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 469e659ade9..520b301ee68 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -623,6 +623,53 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) } // 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. */ /* Limited to remote values and filtering. */ /***********************************************************************/ @@ -636,7 +683,8 @@ int TDBMYSQL::MakeUpdate(PGLOBAL g) if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 || sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2) 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) ? "`" : ""; else { strcpy(g->Message, "Cannot use this UPDATE command"); @@ -678,6 +726,7 @@ int TDBMYSQL::MakeDelete(PGLOBAL g) return RC_OK; } // end of MakeDelete +#endif // 0 /***********************************************************************/ /* XCV GetMaxSize: returns the maximum number of rows in the table. */ @@ -829,7 +878,8 @@ bool TDBMYSQL::OpenDB(PGLOBAL g) } // endif m_Rc } 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) { Myc.Close(); diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h index 969d51beff9..74b1d49e227 100644 --- a/storage/connect/tabmysql.h +++ b/storage/connect/tabmysql.h @@ -106,9 +106,10 @@ class TDBMYSQL : public TDBASE { // Internal functions bool MakeSelect(PGLOBAL g); bool MakeInsert(PGLOBAL g); - int MakeUpdate(PGLOBAL g); - int MakeDelete(PGLOBAL g); int BindColumns(PGLOBAL g); + int MakeCommand(PGLOBAL g); +//int MakeUpdate(PGLOBAL g); +//int MakeDelete(PGLOBAL g); int SendCommand(PGLOBAL g); // Members diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index bb7588e0d66..643b5e734c4 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -519,6 +519,61 @@ bool TDBODBC::BindParameters(PGLOBAL g) } // 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. */ /***********************************************************************/ char *TDBODBC::MakeUpdate(PGLOBAL g) @@ -582,6 +637,7 @@ char *TDBODBC::MakeDelete(PGLOBAL g) return stmt; } // end of MakeDelete +#endif // 0 /***********************************************************************/ /* ResetSize: call by TDBMUL when calculating size estimate. */ @@ -713,10 +769,8 @@ bool TDBODBC::OpenDB(PGLOBAL g) } // endif Query - } else if (Mode == MODE_UPDATE) - Query = MakeUpdate(g); - else if (Mode == MODE_DELETE) - Query = MakeDelete(g); + } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) + Query = MakeCommand(g); else sprintf(g->Message, "Invalid mode %d", Mode); diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h index 10a3f819f69..10c7207b954 100644 --- a/storage/connect/tabodbc.h +++ b/storage/connect/tabodbc.h @@ -102,10 +102,11 @@ class TDBODBC : public TDBASE { int Decode(char *utf, char *buf, size_t n); char *MakeSQL(PGLOBAL g, bool cnt); char *MakeInsert(PGLOBAL g); + char *MakeCommand(PGLOBAL g); //bool MakeFilter(PGLOBAL g, bool c); bool BindParameters(PGLOBAL g); - char *MakeUpdate(PGLOBAL g); - char *MakeDelete(PGLOBAL g); +//char *MakeUpdate(PGLOBAL g); +//char *MakeDelete(PGLOBAL g); // Members ODBConn *Ocp; // Points to an ODBC connection class |