Added support more support for DB2
Added support for PervasiveSQL Fixed MSAccess testing of DROP TABLE result when the table does not exist git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10136 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1892,9 +1892,16 @@ bool wxDb::DropView(const wxString &viewName)
|
|||||||
/********** wxDb::ExecSql() **********/
|
/********** wxDb::ExecSql() **********/
|
||||||
bool wxDb::ExecSql(const wxString &pSqlStmt)
|
bool wxDb::ExecSql(const wxString &pSqlStmt)
|
||||||
{
|
{
|
||||||
|
RETCODE retcode;
|
||||||
|
|
||||||
SQLFreeStmt(hstmt, SQL_CLOSE);
|
SQLFreeStmt(hstmt, SQL_CLOSE);
|
||||||
if (SQLExecDirect(hstmt, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) == SQL_SUCCESS)
|
|
||||||
|
retcode = SQLExecDirect(hstmt, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);
|
||||||
|
if (retcode == SQL_SUCCESS ||
|
||||||
|
(Dbms() == dbmsDB2 && (retcode == SQL_SUCCESS_WITH_INFO || retcode == SQL_NO_DATA_FOUND)))
|
||||||
|
{
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DispAllErrors(henv, hdbc, hstmt);
|
DispAllErrors(henv, hdbc, hstmt);
|
||||||
@@ -3123,7 +3130,9 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx
|
|||||||
if (!UserID.IsEmpty() &&
|
if (!UserID.IsEmpty() &&
|
||||||
Dbms() != dbmsMY_SQL &&
|
Dbms() != dbmsMY_SQL &&
|
||||||
Dbms() != dbmsACCESS &&
|
Dbms() != dbmsACCESS &&
|
||||||
Dbms() != dbmsMS_SQL_SERVER)
|
Dbms() != dbmsMS_SQL_SERVER &&
|
||||||
|
Dbms() != dbmsDB2 &&
|
||||||
|
Dbms() != dbmsPERVASIVE_SQL)
|
||||||
{
|
{
|
||||||
retcode = SQLTables(hstmt,
|
retcode = SQLTables(hstmt,
|
||||||
NULL, 0, // All qualifiers
|
NULL, 0, // All qualifiers
|
||||||
@@ -3373,6 +3382,11 @@ wxDBMS wxDb::Dbms(void)
|
|||||||
*
|
*
|
||||||
* DB2
|
* DB2
|
||||||
* - Primary keys must be declared as NOT NULL
|
* - Primary keys must be declared as NOT NULL
|
||||||
|
* - Table and index names must not be longer than 13 characters in length (technically
|
||||||
|
* table names can be up to 18 characters, but the primary index is created using the
|
||||||
|
* base table name plus "_PIDX", so the limit if the table has a primary index is 13.
|
||||||
|
*
|
||||||
|
* PERVASIVE SQL
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
@@ -3418,6 +3432,10 @@ wxDBMS wxDb::Dbms(void)
|
|||||||
if (!wxStricmp(dbInf.dbmsName,wxT("PostgreSQL"))) // v6.5.0
|
if (!wxStricmp(dbInf.dbmsName,wxT("PostgreSQL"))) // v6.5.0
|
||||||
return((wxDBMS)(dbmsType = dbmsPOSTGRES));
|
return((wxDBMS)(dbmsType = dbmsPOSTGRES));
|
||||||
|
|
||||||
|
baseName[9] = 0;
|
||||||
|
if (!wxStricmp(dbInf.dbmsName,wxT("Pervasive")))
|
||||||
|
return((wxDBMS)(dbmsType = dbmsPERVASIVE_SQL));
|
||||||
|
|
||||||
baseName[8] = 0;
|
baseName[8] = 0;
|
||||||
if (!wxStricmp(baseName,wxT("Informix")))
|
if (!wxStricmp(baseName,wxT("Informix")))
|
||||||
return((wxDBMS)(dbmsType = dbmsINFORMIX));
|
return((wxDBMS)(dbmsType = dbmsINFORMIX));
|
||||||
|
@@ -417,7 +417,7 @@ ODBC 3.0 says to use this form
|
|||||||
/***************************** PRIVATE FUNCTIONS *****************************/
|
/***************************** PRIVATE FUNCTIONS *****************************/
|
||||||
|
|
||||||
|
|
||||||
/********** wxDbTable::bindUpdateParams() **********/
|
/********** wxDbTable::bindParams() **********/
|
||||||
bool wxDbTable::bindParams(bool forUpdate)
|
bool wxDbTable::bindParams(bool forUpdate)
|
||||||
{
|
{
|
||||||
wxASSERT(!queryOnly);
|
wxASSERT(!queryOnly);
|
||||||
@@ -431,17 +431,18 @@ bool wxDbTable::bindParams(bool forUpdate)
|
|||||||
// Bind each column of the table that should be bound
|
// Bind each column of the table that should be bound
|
||||||
// to a parameter marker
|
// to a parameter marker
|
||||||
int i;
|
int i;
|
||||||
UWORD colNo;
|
UWORD colNo;
|
||||||
for (i = 0, colNo = 1; i < noCols; i++)
|
|
||||||
|
for (i=0, colNo=1; i < noCols; i++)
|
||||||
{
|
{
|
||||||
if (forUpdate)
|
if (forUpdate)
|
||||||
{
|
{
|
||||||
if (! colDefs[i].Updateable)
|
if (!colDefs[i].Updateable)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! colDefs[i].InsertAllowed)
|
if (!colDefs[i].InsertAllowed)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,8 +542,6 @@ bool wxDbTable::bindUpdateParams(void)
|
|||||||
/********** wxDbTable::bindCols() **********/
|
/********** wxDbTable::bindCols() **********/
|
||||||
bool wxDbTable::bindCols(HSTMT cursor)
|
bool wxDbTable::bindCols(HSTMT cursor)
|
||||||
{
|
{
|
||||||
//RG-NULL static SDWORD cb;
|
|
||||||
|
|
||||||
// Bind each column of the table to a memory address for fetching data
|
// Bind each column of the table to a memory address for fetching data
|
||||||
UWORD i;
|
UWORD i;
|
||||||
for (i = 0; i < noCols; i++)
|
for (i = 0; i < noCols; i++)
|
||||||
@@ -618,12 +617,21 @@ bool wxDbTable::getRec(UWORD fetchType)
|
|||||||
/********** wxDbTable::execDelete() **********/
|
/********** wxDbTable::execDelete() **********/
|
||||||
bool wxDbTable::execDelete(const wxString &pSqlStmt)
|
bool wxDbTable::execDelete(const wxString &pSqlStmt)
|
||||||
{
|
{
|
||||||
// Execute the DELETE statement
|
RETCODE retcode;
|
||||||
if (SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
|
|
||||||
return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));
|
|
||||||
|
|
||||||
// Record deleted successfully
|
// Execute the DELETE statement
|
||||||
return(TRUE);
|
retcode = SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);
|
||||||
|
|
||||||
|
if (retcode == SQL_SUCCESS ||
|
||||||
|
retcode == SQL_NO_DATA_FOUND ||
|
||||||
|
retcode == SQL_SUCCESS_WITH_INFO)
|
||||||
|
{
|
||||||
|
// Record deleted successfully
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Problem deleting record
|
||||||
|
return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));
|
||||||
|
|
||||||
} // wxDbTable::execDelete()
|
} // wxDbTable::execDelete()
|
||||||
|
|
||||||
@@ -631,12 +639,21 @@ bool wxDbTable::execDelete(const wxString &pSqlStmt)
|
|||||||
/********** wxDbTable::execUpdate() **********/
|
/********** wxDbTable::execUpdate() **********/
|
||||||
bool wxDbTable::execUpdate(const wxString &pSqlStmt)
|
bool wxDbTable::execUpdate(const wxString &pSqlStmt)
|
||||||
{
|
{
|
||||||
// Execute the UPDATE statement
|
RETCODE retcode;
|
||||||
if (SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
|
|
||||||
return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
|
|
||||||
|
|
||||||
// Record deleted successfully
|
// Execute the UPDATE statement
|
||||||
return(TRUE);
|
retcode = SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);
|
||||||
|
|
||||||
|
if (retcode == SQL_SUCCESS ||
|
||||||
|
retcode == SQL_NO_DATA_FOUND ||
|
||||||
|
retcode == SQL_SUCCESS_WITH_INFO)
|
||||||
|
{
|
||||||
|
// Record updated successfully
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Problem updating record
|
||||||
|
return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
|
||||||
|
|
||||||
} // wxDbTable::execUpdate()
|
} // wxDbTable::execUpdate()
|
||||||
|
|
||||||
@@ -1001,7 +1018,7 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti
|
|||||||
for (i = 0; i < noCols; i++)
|
for (i = 0; i < noCols; i++)
|
||||||
{
|
{
|
||||||
// If joining tables, the base table column names must be qualified to avoid ambiguity
|
// If joining tables, the base table column names must be qualified to avoid ambiguity
|
||||||
if (appendFromClause)
|
if (appendFromClause || pDb->Dbms() == dbmsACCESS)
|
||||||
{
|
{
|
||||||
pSqlStmt += queryTableName;
|
pSqlStmt += queryTableName;
|
||||||
pSqlStmt += wxT(".");
|
pSqlStmt += wxT(".");
|
||||||
@@ -1016,7 +1033,7 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti
|
|||||||
if (!distinct && CanUpdByROWID())
|
if (!distinct && CanUpdByROWID())
|
||||||
{
|
{
|
||||||
// If joining tables, the base table column names must be qualified to avoid ambiguity
|
// If joining tables, the base table column names must be qualified to avoid ambiguity
|
||||||
if (appendFromClause)
|
if (appendFromClause || pDb->Dbms() == dbmsACCESS)
|
||||||
{
|
{
|
||||||
pSqlStmt += wxT(",");
|
pSqlStmt += wxT(",");
|
||||||
pSqlStmt += queryTableName;
|
pSqlStmt += queryTableName;
|
||||||
@@ -1115,7 +1132,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin
|
|||||||
|
|
||||||
bool firstColumn = TRUE;
|
bool firstColumn = TRUE;
|
||||||
|
|
||||||
pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName.c_str());
|
pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName.Upper().c_str());
|
||||||
|
|
||||||
// Append a list of columns to be updated
|
// Append a list of columns to be updated
|
||||||
int i;
|
int i;
|
||||||
@@ -1405,14 +1422,22 @@ bool wxDbTable::CreateTable(bool attemptDrop)
|
|||||||
case dbmsSYBASE_ASE:
|
case dbmsSYBASE_ASE:
|
||||||
case dbmsMY_SQL:
|
case dbmsMY_SQL:
|
||||||
{
|
{
|
||||||
/* MySQL goes out on this one. We also declare the relevant key NON NULL above */
|
// MySQL goes out on this one. We also declare the relevant key NON NULL above
|
||||||
sqlStmt += wxT(",PRIMARY KEY (");
|
sqlStmt += wxT(",PRIMARY KEY (");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
sqlStmt += wxT(",CONSTRAINT ");
|
sqlStmt += wxT(",CONSTRAINT ");
|
||||||
sqlStmt += tableName;
|
// DB2 is limited to 18 characters for index names
|
||||||
|
if (pDb->Dbms() == dbmsDB2)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG((tableName && wxStrlen(tableName) <= 13), wxT("DB2 table/index names must be no longer than 13 characters in length.\n\nTruncating table name to 13 characters."));
|
||||||
|
sqlStmt += tableName.substr(0, 13);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sqlStmt += tableName;
|
||||||
|
|
||||||
sqlStmt += wxT("_PIDX PRIMARY KEY (");
|
sqlStmt += wxT("_PIDX PRIMARY KEY (");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1428,15 +1453,15 @@ bool wxDbTable::CreateTable(bool attemptDrop)
|
|||||||
sqlStmt += colDefs[i].ColName;
|
sqlStmt += colDefs[i].ColName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlStmt += wxT(")");
|
sqlStmt += wxT(")");
|
||||||
|
|
||||||
if (pDb->Dbms() == dbmsSYBASE_ASA ||
|
if (pDb->Dbms() == dbmsSYBASE_ASA ||
|
||||||
pDb->Dbms() == dbmsSYBASE_ASE)
|
pDb->Dbms() == dbmsSYBASE_ASE)
|
||||||
{
|
{
|
||||||
sqlStmt += wxT(" CONSTRAINT ");
|
sqlStmt += wxT(" CONSTRAINT ");
|
||||||
sqlStmt += tableName;
|
sqlStmt += tableName;
|
||||||
sqlStmt += wxT("_PIDX");
|
sqlStmt += wxT("_PIDX");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Append the closing parentheses for the create table statement
|
// Append the closing parentheses for the create table statement
|
||||||
sqlStmt += wxT(")");
|
sqlStmt += wxT(")");
|
||||||
@@ -1487,17 +1512,19 @@ bool wxDbTable::DropTable()
|
|||||||
cout << endl << sqlStmt.c_str() << endl;
|
cout << endl << sqlStmt.c_str() << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
|
RETCODE retcode = SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS);
|
||||||
|
if (retcode != SQL_SUCCESS)
|
||||||
{
|
{
|
||||||
// Check for "Base table not found" error and ignore
|
// Check for "Base table not found" error and ignore
|
||||||
pDb->GetNextError(henv, hdbc, hstmt);
|
pDb->GetNextError(henv, hdbc, hstmt);
|
||||||
if (wxStrcmp(pDb->sqlState, wxT("S0002")) &&
|
if (wxStrcmp(pDb->sqlState, wxT("S0002")) /*&&
|
||||||
wxStrcmp(pDb->sqlState, wxT("S1000"))) // "Base table not found"
|
wxStrcmp(pDb->sqlState, wxT("S1000"))*/) // "Base table not found"
|
||||||
{
|
{
|
||||||
// Check for product specific error codes
|
// Check for product specific error codes
|
||||||
if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,wxT("42000"))) || // 5.x (and lower?)
|
if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,wxT("42000"))) || // 5.x (and lower?)
|
||||||
(pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,wxT("37000"))) ||
|
(pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,wxT("37000"))) ||
|
||||||
(pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,wxT("08S01")))))
|
(pDb->Dbms() == dbmsPERVASIVE_SQL && !wxStrcmp(pDb->sqlState,wxT("S1000"))) || // Returns an S1000 then an S0002
|
||||||
|
(pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,wxT("08S01")))))
|
||||||
{
|
{
|
||||||
pDb->DispNextError();
|
pDb->DispNextError();
|
||||||
pDb->DispAllErrors(henv, hdbc, hstmt);
|
pDb->DispAllErrors(henv, hdbc, hstmt);
|
||||||
@@ -1520,7 +1547,7 @@ bool wxDbTable::DropTable()
|
|||||||
|
|
||||||
/********** wxDbTable::CreateIndex() **********/
|
/********** wxDbTable::CreateIndex() **********/
|
||||||
bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCols,
|
bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCols,
|
||||||
wxDbIdxDef *pIdxDefs, bool attemptDrop)
|
wxDbIdxDef *pIdxDefs, bool attemptDrop)
|
||||||
{
|
{
|
||||||
wxString sqlStmt;
|
wxString sqlStmt;
|
||||||
|
|
||||||
@@ -1704,7 +1731,7 @@ bool wxDbTable::DropIndex(const wxString &idxName)
|
|||||||
/********** wxDbTable::SetOrderByColNums() **********/
|
/********** wxDbTable::SetOrderByColNums() **********/
|
||||||
bool wxDbTable::SetOrderByColNums(UWORD first, ... )
|
bool wxDbTable::SetOrderByColNums(UWORD first, ... )
|
||||||
{
|
{
|
||||||
int colNo = first; // using 'int' to be able to look for wxDB_NO_MORE_COLUN_NUMBERS
|
int colNo = first; // using 'int' to be able to look for wxDB_NO_MORE_COLUN_NUMBERS
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
|
||||||
bool abort = FALSE;
|
bool abort = FALSE;
|
||||||
@@ -2152,7 +2179,7 @@ wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, UWORD numCols)
|
|||||||
pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP;
|
pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP;
|
||||||
break;
|
break;
|
||||||
case DB_DATA_TYPE_BLOB:
|
case DB_DATA_TYPE_BLOB:
|
||||||
int notSupportedYet = 0;
|
int notSupportedYet = 0;
|
||||||
wxASSERT_MSG(notSupportedYet, wxT("This form of ::SetColDefs() cannot be used with BLOB columns"));
|
wxASSERT_MSG(notSupportedYet, wxT("This form of ::SetColDefs() cannot be used with BLOB columns"));
|
||||||
pColDataPtrs[index].PtrDataObj = /*BLOB ADDITION NEEDED*/NULL;
|
pColDataPtrs[index].PtrDataObj = /*BLOB ADDITION NEEDED*/NULL;
|
||||||
pColDataPtrs[index].SzDataObj = /*BLOB ADDITION NEEDED*/sizeof(void *);
|
pColDataPtrs[index].SzDataObj = /*BLOB ADDITION NEEDED*/sizeof(void *);
|
||||||
|
Reference in New Issue
Block a user