X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/da38429d93af172fe944bb19c820f23f88138966..277f2e527e33de039146ab94358ffec9c98f6112:/src/common/dbtable.cpp diff --git a/src/common/dbtable.cpp b/src/common/dbtable.cpp index c6b7f6f4f6..49e2c2348d 100644 --- a/src/common/dbtable.cpp +++ b/src/common/dbtable.cpp @@ -35,7 +35,11 @@ #endif #ifdef DBDEBUG_CONSOLE - #include "iostream.h" +#if wxUSE_IOSTREAMH + #include +#else + #include +#endif #include "wx/ioswrap.h" #endif @@ -44,7 +48,9 @@ #include "wx/object.h" #include "wx/list.h" #include "wx/utils.h" - #include "wx/msgdlg.h" + #if wxUSE_GUI + #include "wx/msgdlg.h" + #endif #include "wx/log.h" #endif #include "wx/filefn.h" @@ -522,15 +528,16 @@ bool wxDbTable::bindUpdateParams(void) /********** wxDbTable::bindCols() **********/ bool wxDbTable::bindCols(HSTMT cursor) { + static SDWORD cb; + // Bind each column of the table to a memory address for fetching data UWORD i; for (i = 0; i < noCols; i++) { + cb = colDefs[i].CbValue; if (SQLBindCol(cursor, (UWORD)(i+1), colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj, - colDefs[i].SzDataObj, &colDefs[i].CbValue ) != SQL_SUCCESS) - { + colDefs[i].SzDataObj, &cb ) != SQL_SUCCESS) return (pDb->DispAllErrors(henv, hdbc, cursor)); - } } // Completed successfully @@ -761,14 +768,16 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) if (!queryOnly && noCols > 0) { bool needComma = FALSE; - sqlStmt.Printf(wxT("INSERT INTO %s ("), tableName.c_str()); + sqlStmt.Printf(wxT("INSERT INTO %s ("), + pDb->SQLTableName(tableName.c_str()).c_str()); for (i = 0; i < noCols; i++) { if (! colDefs[i].InsertAllowed) continue; if (needComma) sqlStmt += wxT(","); - sqlStmt += colDefs[i].ColName; + sqlStmt += pDb->SQLColumnName(colDefs[i].ColName); +// sqlStmt += colDefs[i].ColName; needComma = TRUE; } needComma = FALSE; @@ -912,11 +921,13 @@ 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.c_str()); + pSqlStmt.Printf(wxT("DELETE FROM %s"), + pDb->SQLTableName(tableName.c_str()).c_str()); return; } - pSqlStmt.Printf(wxT("DELETE FROM %s WHERE "), tableName.c_str()); + pSqlStmt.Printf(wxT("DELETE FROM %s WHERE "), + pDb->SQLTableName(tableName.c_str()).c_str()); // Append the WHERE clause to the SQL DELETE statement switch(typeOfDel) @@ -998,10 +1009,12 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti // If joining tables, the base table column names must be qualified to avoid ambiguity if (appendFromClause || pDb->Dbms() == dbmsACCESS) { - pSqlStmt += queryTableName; + pSqlStmt += pDb->SQLTableName(queryTableName.c_str()); +// pSqlStmt += queryTableName; pSqlStmt += wxT("."); } - pSqlStmt += colDefs[i].ColName; + pSqlStmt += pDb->SQLColumnName(colDefs[i].ColName); +// pSqlStmt += colDefs[i].ColName; if (i + 1 < noCols) pSqlStmt += wxT(","); } @@ -1014,7 +1027,8 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti if (appendFromClause || pDb->Dbms() == dbmsACCESS) { pSqlStmt += wxT(","); - pSqlStmt += queryTableName; + pSqlStmt += pDb->SQLTableName(queryTableName); +// pSqlStmt += queryTableName; pSqlStmt += wxT(".ROWID"); } else @@ -1023,7 +1037,8 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti // Append the FROM tablename portion pSqlStmt += wxT(" FROM "); - pSqlStmt += queryTableName; + pSqlStmt += pDb->SQLTableName(queryTableName); +// pSqlStmt += queryTableName; // Sybase uses the HOLDLOCK keyword to lock a record during query. // The HOLDLOCK keyword follows the table name in the from clause. @@ -1110,7 +1125,8 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin bool firstColumn = TRUE; - pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName.Upper().c_str()); + pSqlStmt.Printf(wxT("UPDATE %s SET "), + pDb->SQLTableName(tableName.c_str()).c_str()); // Append a list of columns to be updated int i; @@ -1123,7 +1139,9 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin pSqlStmt += wxT(","); else firstColumn = FALSE; - pSqlStmt += colDefs[i].ColName; + + pSqlStmt += pDb->SQLColumnName(colDefs[i].ColName); +// pSqlStmt += colDefs[i].ColName; pSqlStmt += wxT(" = ?"); } } @@ -1203,10 +1221,12 @@ void wxDbTable::BuildWhereClause(wxString &pWhereClause, int typeOfWhere, // Concatenate where phrase for the column if (qualTableName.Length()) { - pWhereClause += qualTableName; + pWhereClause += pDb->SQLTableName(qualTableName); +// pWhereClause += qualTableName; pWhereClause += wxT("."); } - pWhereClause += colDefs[i].ColName; + pWhereClause += pDb->SQLColumnName(colDefs[i].ColName); +// pWhereClause += colDefs[i].ColName; if (useLikeComparison && (colDefs[i].SqlCtype == SQL_C_CHAR)) pWhereClause += wxT(" LIKE "); else @@ -1329,7 +1349,9 @@ bool wxDbTable::CreateTable(bool attemptDrop) // Build a CREATE TABLE string from the colDefs structure. bool needComma = FALSE; - sqlStmt.Printf(wxT("CREATE TABLE %s ("), tableName.c_str()); + + sqlStmt.Printf(wxT("CREATE TABLE %s ("), + pDb->SQLTableName(tableName.c_str()).c_str()); for (i = 0; i < noCols; i++) { @@ -1340,7 +1362,8 @@ bool wxDbTable::CreateTable(bool attemptDrop) if (needComma) sqlStmt += wxT(","); // Column Name - sqlStmt += colDefs[i].ColName; + sqlStmt += pDb->SQLColumnName(colDefs[i].ColName); +// sqlStmt += colDefs[i].ColName; sqlStmt += wxT(" "); // Column Type switch(colDefs[i].DbDataType) @@ -1362,7 +1385,8 @@ bool wxDbTable::CreateTable(bool attemptDrop) 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 && + (pDb->Dbms() != dbmsMY_SQL || pDb->GetTypeInfVarchar().TypeName != "text"))// || // colDefs[i].DbDataType == DB_DATA_TYPE_BLOB) { wxString s; @@ -1397,6 +1421,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) { switch (pDb->Dbms()) { + case dbmsACCESS: case dbmsINFORMIX: case dbmsSYBASE_ASA: case dbmsSYBASE_ASE: @@ -1413,10 +1438,12 @@ bool wxDbTable::CreateTable(bool attemptDrop) 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); + sqlStmt += pDb->SQLTableName(tableName.substr(0, 13).c_str()); +// sqlStmt += tableName.substr(0, 13); } else - sqlStmt += tableName; + sqlStmt += pDb->SQLTableName(tableName.c_str()); +// sqlStmt += tableName; sqlStmt += wxT("_PIDX PRIMARY KEY ("); break; @@ -1430,7 +1457,15 @@ bool wxDbTable::CreateTable(bool attemptDrop) { if (j++) // Multi part key, comma separate names sqlStmt += wxT(","); - sqlStmt += colDefs[i].ColName; + sqlStmt += pDb->SQLColumnName(colDefs[i].ColName); + + if (pDb->Dbms() == dbmsMY_SQL && + colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR) + { + wxString s; + s.Printf(wxT("(%d)"), colDefs[i].SzDataObj); + sqlStmt += s; + } } } sqlStmt += wxT(")"); @@ -1440,7 +1475,8 @@ bool wxDbTable::CreateTable(bool attemptDrop) pDb->Dbms() == dbmsSYBASE_ASE) { sqlStmt += wxT(" CONSTRAINT "); - sqlStmt += tableName; + sqlStmt += pDb->SQLTableName(tableName); +// sqlStmt += tableName; sqlStmt += wxT("_PIDX"); } } @@ -1485,7 +1521,8 @@ bool wxDbTable::DropTable() wxString sqlStmt; - sqlStmt.Printf(wxT("DROP TABLE %s"), tableName.c_str()); + sqlStmt.Printf(wxT("DROP TABLE %s"), + pDb->SQLTableName(tableName.c_str()).c_str()); pDb->WriteSqlLog(sqlStmt); @@ -1493,9 +1530,6 @@ bool wxDbTable::DropTable() cout << endl << sqlStmt.c_str() << endl; #endif - - - RETCODE retcode = SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS); if (retcode != SQL_SUCCESS) { @@ -1601,16 +1635,19 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol sqlStmt += wxT("UNIQUE "); sqlStmt += wxT("INDEX "); - sqlStmt += idxName; + sqlStmt += pDb->SQLTableName(idxName); sqlStmt += wxT(" ON "); - sqlStmt += tableName; + + sqlStmt += pDb->SQLTableName(tableName); +// sqlStmt += tableName; sqlStmt += wxT(" ("); // Append list of columns making up index int i; for (i = 0; i < noIdxCols; i++) { - sqlStmt += pIdxDefs[i].ColName; + sqlStmt += pDb->SQLColumnName(pIdxDefs[i].ColName); +// sqlStmt += pIdxDefs[i].ColName; // Postgres and SQL Server 7 do not support the ASC/DESC keywords for index columns if (!((pDb->Dbms() == dbmsMS_SQL_SERVER) && (strncmp(pDb->dbInf.dbmsVer,"07",2)==0)) && @@ -1670,12 +1707,17 @@ bool wxDbTable::DropIndex(const wxString &idxName) if (pDb->Dbms() == dbmsACCESS || pDb->Dbms() == dbmsMY_SQL || pDb->Dbms() == dbmsDBASE /*|| Paradox needs this syntax too when we add support*/) - sqlStmt.Printf(wxT("DROP INDEX %s ON %s"),idxName.c_str(), tableName.c_str()); + sqlStmt.Printf(wxT("DROP INDEX %s ON %s"), + pDb->SQLTableName(idxName.c_str()).c_str(), + pDb->SQLTableName(tableName.c_str()).c_str()); else if ((pDb->Dbms() == dbmsMS_SQL_SERVER) || (pDb->Dbms() == dbmsSYBASE_ASE)) - sqlStmt.Printf(wxT("DROP INDEX %s.%s"),tableName.c_str(), idxName.c_str()); + sqlStmt.Printf(wxT("DROP INDEX %s.%s"), + pDb->SQLTableName(tableName.c_str()).c_str(), + pDb->SQLTableName(idxName.c_str()).c_str()); else - sqlStmt.Printf(wxT("DROP INDEX %s"),idxName.c_str()); + sqlStmt.Printf(wxT("DROP INDEX %s"), + pDb->SQLTableName(idxName.c_str()).c_str()); pDb->WriteSqlLog(sqlStmt); @@ -2077,6 +2119,9 @@ void wxDbTable::SetColDefs(UWORD index, const wxString &fieldName, int dataType, SWORD cType, int size, bool keyField, bool upd, bool insAllow, bool derivedCol) { + wxASSERT_MSG( index < noCols, + _T("Specified column index exceeds the maximum number of columns for this table.") ); + if (!colDefs) // May happen if the database connection fails return; @@ -2224,7 +2269,8 @@ ULONG wxDbTable::Count(const wxString &args) sqlStmt = wxT("SELECT COUNT("); sqlStmt += args; sqlStmt += wxT(") FROM "); - sqlStmt += queryTableName; + sqlStmt += pDb->SQLTableName(queryTableName); +// sqlStmt += queryTableName; #if wxODBC_BACKWARD_COMPATABILITY if (from && wxStrlen(from)) #else @@ -2316,7 +2362,8 @@ bool wxDbTable::Refresh(void) // based on the key fields. if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) { - whereClause += queryTableName; + whereClause += pDb->SQLTableName(queryTableName); +// whereClause += queryTableName; whereClause += wxT(".ROWID = '"); whereClause += rowid; whereClause += wxT("'"); @@ -2483,48 +2530,48 @@ void wxDbTable::SetRowMode(const rowmode_t rowmode) } // wxDbTable::SetRowMode() -wxVariant wxDbTable::GetCol(const int col) const +wxVariant wxDbTable::GetCol(const int colNo) const { wxVariant val; - if ((col < noCols) && (!IsColNull(col))) + if ((colNo < noCols) && (!IsColNull(colNo))) { - switch (colDefs[col].SqlCtype) + switch (colDefs[colNo].SqlCtype) { case SQL_CHAR: case SQL_VARCHAR: - val = (char *)(colDefs[col].PtrDataObj); + val = (wxChar *)(colDefs[colNo].PtrDataObj); break; case SQL_C_LONG: case SQL_C_SLONG: - val = *(long *)(colDefs[col].PtrDataObj); + val = *(long *)(colDefs[colNo].PtrDataObj); break; case SQL_C_SHORT: case SQL_C_SSHORT: - val = (long int )(*(short *)(colDefs[col].PtrDataObj)); + val = (long int )(*(short *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_ULONG: - val = (long)(*(unsigned long *)(colDefs[col].PtrDataObj)); + val = (long)(*(unsigned long *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_TINYINT: - val = (long)(*(char *)(colDefs[col].PtrDataObj)); + val = (long)(*(char *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_UTINYINT: - val = (long)(*(unsigned char *)(colDefs[col].PtrDataObj)); + val = (long)(*(unsigned char *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_USHORT: - val = (long)(*(UWORD *)(colDefs[col].PtrDataObj)); + val = (long)(*(UWORD *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_DATE: - val = (DATE_STRUCT *)(colDefs[col].PtrDataObj); + val = (DATE_STRUCT *)(colDefs[colNo].PtrDataObj); break; case SQL_C_TIME: - val = (TIME_STRUCT *)(colDefs[col].PtrDataObj); + val = (TIME_STRUCT *)(colDefs[colNo].PtrDataObj); break; case SQL_C_TIMESTAMP: - val = (TIMESTAMP_STRUCT *)(colDefs[col].PtrDataObj); + val = (TIMESTAMP_STRUCT *)(colDefs[colNo].PtrDataObj); break; case SQL_C_DOUBLE: - val = *(double *)(colDefs[col].PtrDataObj); + val = *(double *)(colDefs[colNo].PtrDataObj); break; default: assert(0); @@ -2542,57 +2589,57 @@ void csstrncpyt(char *s, const char *t, int n) *s = '\0'; } -void wxDbTable::SetCol(const int col, const wxVariant val) +void wxDbTable::SetCol(const int colNo, const wxVariant val) { //FIXME: Add proper wxDateTime support to wxVariant.. wxDateTime dateval; - SetColNull(col, val.IsNull()); + SetColNull(colNo, val.IsNull()); if (!val.IsNull()) { - if ((colDefs[col].SqlCtype == SQL_C_DATE) - || (colDefs[col].SqlCtype == SQL_C_TIME) - || (colDefs[col].SqlCtype == SQL_C_TIMESTAMP)) + if ((colDefs[colNo].SqlCtype == SQL_C_DATE) + || (colDefs[colNo].SqlCtype == SQL_C_TIME) + || (colDefs[colNo].SqlCtype == SQL_C_TIMESTAMP)) { //Returns null if invalid! if (!dateval.ParseDate(val.GetString())) - SetColNull(col,TRUE); + SetColNull(colNo, TRUE); } - switch (colDefs[col].SqlCtype) + switch (colDefs[colNo].SqlCtype) { case SQL_CHAR: case SQL_VARCHAR: - csstrncpyt((char *)(colDefs[col].PtrDataObj), + csstrncpyt((char *)(colDefs[colNo].PtrDataObj), val.GetString().c_str(), - colDefs[col].SzDataObj-1); + colDefs[colNo].SzDataObj-1); break; case SQL_C_LONG: case SQL_C_SLONG: - *(long *)(colDefs[col].PtrDataObj) = val; + *(long *)(colDefs[colNo].PtrDataObj) = val; break; case SQL_C_SHORT: case SQL_C_SSHORT: - *(short *)(colDefs[col].PtrDataObj) = val.GetLong(); + *(short *)(colDefs[colNo].PtrDataObj) = val.GetLong(); break; case SQL_C_ULONG: - *(unsigned long *)(colDefs[col].PtrDataObj) = val.GetLong(); + *(unsigned long *)(colDefs[colNo].PtrDataObj) = val.GetLong(); break; case SQL_C_TINYINT: - *(char *)(colDefs[col].PtrDataObj) = val.GetChar(); + *(char *)(colDefs[colNo].PtrDataObj) = val.GetChar(); break; case SQL_C_UTINYINT: - *(unsigned char *)(colDefs[col].PtrDataObj) = val.GetChar(); + *(unsigned char *)(colDefs[colNo].PtrDataObj) = val.GetChar(); break; case SQL_C_USHORT: - *(unsigned short *)(colDefs[col].PtrDataObj) = val.GetLong(); + *(unsigned short *)(colDefs[colNo].PtrDataObj) = val.GetLong(); break; //FIXME: Add proper wxDateTime support to wxVariant.. case SQL_C_DATE: { DATE_STRUCT *dataptr = - (DATE_STRUCT *)colDefs[col].PtrDataObj; + (DATE_STRUCT *)colDefs[colNo].PtrDataObj; dataptr->year = dateval.GetYear(); dataptr->month = dateval.GetMonth()+1; @@ -2602,7 +2649,7 @@ void wxDbTable::SetCol(const int col, const wxVariant val) case SQL_C_TIME: { TIME_STRUCT *dataptr = - (TIME_STRUCT *)colDefs[col].PtrDataObj; + (TIME_STRUCT *)colDefs[colNo].PtrDataObj; dataptr->hour = dateval.GetHour(); dataptr->minute = dateval.GetMinute(); @@ -2612,7 +2659,7 @@ void wxDbTable::SetCol(const int col, const wxVariant val) case SQL_C_TIMESTAMP: { TIMESTAMP_STRUCT *dataptr = - (TIMESTAMP_STRUCT *)colDefs[col].PtrDataObj; + (TIMESTAMP_STRUCT *)colDefs[colNo].PtrDataObj; dataptr->year = dateval.GetYear(); dataptr->month = dateval.GetMonth()+1; dataptr->day = dateval.GetDay(); @@ -2623,7 +2670,7 @@ void wxDbTable::SetCol(const int col, const wxVariant val) } break; case SQL_C_DOUBLE: - *(double *)(colDefs[col].PtrDataObj) = val; + *(double *)(colDefs[colNo].PtrDataObj) = val; break; default: assert(0); @@ -2635,10 +2682,10 @@ void wxDbTable::SetCol(const int col, const wxVariant val) GenericKey wxDbTable::GetKey() { void *blk; - char *blkptr; + wxChar *blkptr; blk = malloc(m_keysize); - blkptr = (char *) blk; + blkptr = (wxChar *) blk; int i; for (i=0; i < noCols; i++) @@ -2659,11 +2706,11 @@ GenericKey wxDbTable::GetKey() void wxDbTable::SetKey(const GenericKey& k) { - void *blk; - char *blkptr; + void *blk; + wxChar *blkptr; blk = k.GetBlk(); - blkptr = (char *)blk; + blkptr = (wxChar *)blk; int i; for (i=0; i < noCols; i++)