X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4fdae9972d39fbe62adaa1c1d721ba1762cd8950..02cf6fdd858bfab06627734dd7ca1ccdd9866e9d:/src/common/dbtable.cpp diff --git a/src/common/dbtable.cpp b/src/common/dbtable.cpp index f85c5904f7..524fb96e8e 100644 --- a/src/common/dbtable.cpp +++ b/src/common/dbtable.cpp @@ -102,22 +102,47 @@ ULONG lastTableID = 0; #endif -/********** wxDbTable::wxDbTable() **********/ -wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols, +/********** wxDbColDef::wxDbColDef() Constructor **********/ +wxDbColDef::wxDbColDef() +{ + Initialize(); +} // Constructor + + +bool wxDbColDef::Initialize() +{ + ColName[0] = 0; + DbDataType = DB_DATA_TYPE_INTEGER; + SqlCtype = SQL_C_LONG; + PtrDataObj = NULL; + SzDataObj = 0; + KeyField = FALSE; + Updateable = FALSE; + InsertAllowed = FALSE; + DerivedCol = FALSE; + CbValue = 0; + Null = FALSE; + + return TRUE; +} // wxDbColDef::Initialize() + + +/********** wxDbTable::wxDbTable() Constructor **********/ +wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const UWORD numColumns, const wxString &qryTblName, bool qryOnly, const wxString &tblPath) { - if (!initialize(pwxDb, tblName, nCols, qryTblName, qryOnly, tblPath)) + if (!initialize(pwxDb, tblName, numColumns, qryTblName, qryOnly, tblPath)) cleanup(); } // wxDbTable::wxDbTable() /***** DEPRECATED: use wxDbTable::wxDbTable() format above *****/ -wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols, +wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const UWORD numColumns, const wxChar *qryTblName, bool qryOnly, const wxString &tblPath) { wxString tempQryTblName; tempQryTblName = qryTblName; - if (!initialize(pwxDb, tblName, nCols, tempQryTblName, qryOnly, tblPath)) + if (!initialize(pwxDb, tblName, numColumns, tempQryTblName, qryOnly, tblPath)) cleanup(); } // wxDbTable::wxDbTable() @@ -129,7 +154,7 @@ wxDbTable::~wxDbTable() } // wxDbTable::~wxDbTable() -bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const int nCols, +bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const UWORD numColumns, const wxString &qryTblName, bool qryOnly, const wxString &tblPath) { // Initializing member variables @@ -145,7 +170,7 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const int nCols hstmtInternal = 0; colDefs = 0; tableID = 0; - noCols = nCols; // No. of cols in the table + noCols = numColumns; // Number of cols in the table where.Empty(); // Where clause orderBy.Empty(); // Order By clause from.Empty(); // From clause @@ -177,7 +202,7 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const int nCols wxString s; tableID = ++lastTableID; - s.Printf(wxT("wxDbTable constructor (%-20s) tableID:[%6lu] pDb:[%p]"), tblName,tableID,pDb); + s.Printf(wxT("wxDbTable constructor (%-20s) tableID:[%6lu] pDb:[%p]"), tblName.c_str(), tableID, pDb); #ifdef __WXDEBUG__ wxTablesInUse *tableInUse; @@ -300,7 +325,7 @@ void wxDbTable::cleanup() wxString s; if (pDb) { - s.Printf(wxT("wxDbTable destructor (%-20s) tableID:[%6lu] pDb:[%p]"), tableName,tableID,pDb); + s.Printf(wxT("wxDbTable destructor (%-20s) tableID:[%6lu] pDb:[%p]"), tableName.c_str(), tableID, pDb); pDb->WriteSqlLog(s); } @@ -344,20 +369,41 @@ void wxDbTable::cleanup() if (!queryOnly) { if (hstmtInsert) + { +/* +ODBC 3.0 says to use this form + if (SQLFreeHandle(*hstmtDel, SQL_DROP) != SQL_SUCCESS) +*/ if (SQLFreeStmt(hstmtInsert, SQL_DROP) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc); + } if (hstmtDelete) + { +/* +ODBC 3.0 says to use this form + if (SQLFreeHandle(*hstmtDel, SQL_DROP) != SQL_SUCCESS) +*/ if (SQLFreeStmt(hstmtDelete, SQL_DROP) != SQL_SUCCESS) + pDb->DispAllErrors(henv, hdbc); + } if (hstmtUpdate) + { +/* +ODBC 3.0 says to use this form + if (SQLFreeHandle(*hstmtDel, SQL_DROP) != SQL_SUCCESS) +*/ if (SQLFreeStmt(hstmtUpdate, SQL_DROP) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc); + } } if (hstmtInternal) + { if (SQLFreeStmt(hstmtInternal, SQL_DROP) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc); + } // Delete dynamically allocated cursors if (hstmtDefault) @@ -384,7 +430,8 @@ bool wxDbTable::bindParams(bool forUpdate) // Bind each column of the table that should be bound // to a parameter marker - int i,colNo; + int i; + UWORD colNo; for (i = 0, colNo = 1; i < noCols; i++) { if (forUpdate) @@ -441,6 +488,15 @@ bool wxDbTable::bindParams(bool forUpdate) else colDefs[i].CbValue = 0; break; + case DB_DATA_TYPE_BLOB: + fSqlType = pDb->GetTypeInfBlob().FsqlType; + precision = 50000; + scale = 0; + if (colDefs[i].Null) + colDefs[i].CbValue = SQL_NULL_DATA; + else + colDefs[i].CbValue = SQL_LEN_DATA_AT_EXEC(colDefs[i].SzDataObj); + break; } if (forUpdate) { @@ -488,11 +544,10 @@ bool wxDbTable::bindCols(HSTMT cursor) //RG-NULL static SDWORD cb; // Bind each column of the table to a memory address for fetching data - int i; + UWORD i; for (i = 0; i < noCols; i++) { - if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj, -//RG-NULL colDefs[i].SzDataObj, &cb) != SQL_SUCCESS) + if (SQLBindCol(cursor, (UWORD)(i+1), colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj, colDefs[i].SzDataObj, &colDefs[i].CbValue ) != SQL_SUCCESS) { return (pDb->DispAllErrors(henv, hdbc, cursor)); @@ -639,7 +694,7 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxStri /********** wxDbTable::Open() **********/ -bool wxDbTable::Open(bool checkPrivileges) +bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) { if (!pDb) return FALSE; @@ -650,7 +705,7 @@ bool wxDbTable::Open(bool checkPrivileges) s.Empty(); // Verify that the table exists in the database - if (!pDb->TableExists(tableName,/*pDb->GetUsername()*/NULL,tablePath)) + if (checkTableExists && !pDb->TableExists(tableName, pDb->GetUsername(), tablePath)) { s = wxT("Table/view does not exist in the database"); if ( *(pDb->dbInf.accessibleTables) == wxT('Y')) @@ -667,7 +722,7 @@ bool wxDbTable::Open(bool checkPrivileges) // Unfortunately this optimization doesn't seem to be // reliable! if (// *(pDb->dbInf.accessibleTables) == 'N' && - !pDb->TablePrivileges(tableName,wxT("SELECT"),NULL,pDb->GetUsername(),tablePath)) + !pDb->TablePrivileges(tableName,wxT("SELECT"), pDb->GetUsername(), pDb->GetUsername(), tablePath)) s = wxT("Current logged in user does not have sufficient privileges to access this table.\n"); } @@ -676,9 +731,9 @@ bool wxDbTable::Open(bool checkPrivileges) wxString p; if (!tablePath.IsEmpty()) - p.Printf(wxT("Error opening '%s/%s'.\n"),tablePath,tableName); + p.Printf(wxT("Error opening '%s/%s'.\n"),tablePath.c_str(),tableName.c_str()); else - p.Printf(wxT("Error opening '%s'.\n"), tableName); + p.Printf(wxT("Error opening '%s'.\n"), tableName.c_str()); p += s; pDb->LogError(p.GetData()); @@ -711,7 +766,7 @@ bool wxDbTable::Open(bool checkPrivileges) if (!queryOnly && noCols > 0) { bool needComma = FALSE; - sqlStmt.Printf(wxT("INSERT INTO %s ("), tableName); + sqlStmt.Printf(wxT("INSERT INTO %s ("), tableName.c_str()); for (i = 0; i < noCols; i++) { if (! colDefs[i].InsertAllowed) @@ -862,11 +917,11 @@ void wxDbTable::BuildDeleteStmt(wxString &pSqlStmt, int typeOfDel, const wxStrin // delete all records from the database in this case. if (typeOfDel == DB_DEL_WHERE && (pWhereClause.Length() == 0)) { - pSqlStmt.Printf(wxT("DELETE FROM %s"), tableName); + pSqlStmt.Printf(wxT("DELETE FROM %s"), tableName.c_str()); return; } - pSqlStmt.Printf(wxT("DELETE FROM %s WHERE "), tableName); + pSqlStmt.Printf(wxT("DELETE FROM %s WHERE "), tableName.c_str()); // Append the WHERE clause to the SQL DELETE statement switch(typeOfDel) @@ -883,7 +938,7 @@ void wxDbTable::BuildDeleteStmt(wxString &pSqlStmt, int typeOfDel, const wxStrin // Get the ROWID value. If not successful retreiving the ROWID, // simply fall down through the code and build the WHERE clause // based on the key fields. - if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) + if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) { pSqlStmt += wxT("ROWID = '"); pSqlStmt += rowid; @@ -1060,7 +1115,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin bool firstColumn = TRUE; - pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName); + pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName.c_str()); // Append a list of columns to be updated int i; @@ -1094,7 +1149,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin // Get the ROWID value. If not successful retreiving the ROWID, // simply fall down through the code and build the WHERE clause // based on the key fields. - if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) + if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) { pSqlStmt += wxT("ROWID = '"); pSqlStmt += rowid; @@ -1269,6 +1324,9 @@ bool wxDbTable::CreateTable(bool attemptDrop) case DB_DATA_TYPE_DATE: cout << pDb->typeInfDate.TypeName; break; + case DB_DATA_TYPE_BLOB: + cout << pDb->typeInfBlob.TypeName; + break; } cout << endl; } @@ -1276,7 +1334,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) // Build a CREATE TABLE string from the colDefs structure. bool needComma = FALSE; - sqlStmt.Printf(wxT("CREATE TABLE %s ("), tableName); + sqlStmt.Printf(wxT("CREATE TABLE %s ("), tableName.c_str()); for (i = 0; i < noCols; i++) { @@ -1304,9 +1362,13 @@ bool wxDbTable::CreateTable(bool attemptDrop) case DB_DATA_TYPE_DATE: sqlStmt += pDb->GetTypeInfDate().TypeName; break; + case DB_DATA_TYPE_BLOB: + sqlStmt += pDb->GetTypeInfBlob().TypeName; + break; } // For varchars, append the size of the string - if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR) + if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR)// || +// colDefs[i].DbDataType == DB_DATA_TYPE_BLOB) { wxString s; s.Printf(wxT("(%d)"), colDefs[i].SzDataObj); @@ -1402,7 +1464,7 @@ bool wxDbTable::DropTable() wxString sqlStmt; - sqlStmt.Printf(wxT("DROP TABLE %s"), tableName); + sqlStmt.Printf(wxT("DROP TABLE %s"), tableName.c_str()); pDb->WriteSqlLog(sqlStmt); @@ -1576,12 +1638,12 @@ bool wxDbTable::DropIndex(const wxString &idxName) wxString sqlStmt; if (pDb->Dbms() == dbmsACCESS || pDb->Dbms() == dbmsMY_SQL) - sqlStmt.Printf(wxT("DROP INDEX %s ON %s"),idxName,tableName); + sqlStmt.Printf(wxT("DROP INDEX %s ON %s"),idxName.c_str(), tableName.c_str()); else if ((pDb->Dbms() == dbmsMS_SQL_SERVER) || (pDb->Dbms() == dbmsSYBASE_ASE)) - sqlStmt.Printf(wxT("DROP INDEX %s.%s"),tableName,idxName); + sqlStmt.Printf(wxT("DROP INDEX %s.%s"),tableName.c_str(), idxName.c_str()); else - sqlStmt.Printf(wxT("DROP INDEX %s"),idxName); + sqlStmt.Printf(wxT("DROP INDEX %s"),idxName.c_str()); pDb->WriteSqlLog(sqlStmt); @@ -1880,12 +1942,12 @@ bool wxDbTable::CanUpdByROWID(void) * as the ROWID is not getting updated correctly */ return FALSE; - +/* if (pDb->Dbms() == dbmsORACLE) return(TRUE); else return(FALSE); - +*/ } // wxDbTable::CanUpdByROWID() @@ -1979,7 +2041,7 @@ bool wxDbTable::SetQueryTimeout(UDWORD nSeconds) /********** wxDbTable::SetColDefs() **********/ void wxDbTable::SetColDefs(int index, const wxString &fieldName, int dataType, void *pData, - int cType, int size, bool keyField, bool upd, + SWORD cType, int size, bool keyField, bool upd, bool insAllow, bool derivedCol) { if (!colDefs) // May happen if the database connection fails @@ -2073,8 +2135,26 @@ wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols) pColDataPtrs[index].SzDataObj = sizeof(TIMESTAMP_STRUCT); pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP; break; + case DB_DATA_TYPE_BLOB: + int notSupportedYet = 0; + wxASSERT_MSG(notSupportedYet, wxT("This form of ::SetColDefs() cannot be used with BLOB columns")); + pColDataPtrs[index].PtrDataObj = /*BLOB ADDITION NEEDED*/NULL; + pColDataPtrs[index].SzDataObj = /*BLOB ADDITION NEEDED*/sizeof(void *); + pColDataPtrs[index].SqlCtype = SQL_VARBINARY; + break; + } + if (pColDataPtrs[index].PtrDataObj != NULL) + SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj); + else + { + // Unable to build all the column definitions, as either one of + // the calls to "new" failed above, or there was a BLOB field + // to have a column definition for. If BLOBs are to be used, + // the other form of ::SetColDefs() must be used, as it is impossible + // to know the maximum size to create the PtrDataObj to be. + delete [] pColDataPtrs; + return NULL; } - SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj); } } @@ -2150,7 +2230,7 @@ ULONG wxDbTable::Count(const wxString &args) } // Obtain the result - if (SQLGetData(*hstmtCount, 1, SQL_C_ULONG, &count, sizeof(count), &cb) != SQL_SUCCESS) + if (SQLGetData(*hstmtCount, (UWORD)1, SQL_C_ULONG, &count, sizeof(count), &cb) != SQL_SUCCESS) { pDb->DispAllErrors(henv, hdbc, *hstmtCount); return(0); @@ -2195,7 +2275,7 @@ bool wxDbTable::Refresh(void) // Get the ROWID value. If not successful retreiving the ROWID, // simply fall down through the code and build the WHERE clause // based on the key fields. - if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) + if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) { whereClause += queryTableName; whereClause += wxT(".ROWID = '"); @@ -2319,6 +2399,11 @@ bool wxDbTable::DeleteCursor(HSTMT *hstmtDel) if (!hstmtDel) // Cursor already deleted return(result); +/* +ODBC 3.0 says to use this form + if (SQLFreeHandle(*hstmtDel, SQL_DROP) != SQL_SUCCESS) + +*/ if (SQLFreeStmt(*hstmtDel, SQL_DROP) != SQL_SUCCESS) { pDb->DispAllErrors(henv, hdbc);