From: George Tasker Date: Wed, 11 Apr 2001 14:20:56 +0000 (+0000) Subject: Experimental BLOB code added - set wxODBC_BLOB_EXPERIMENT to 1 in dbtest.h if you... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/3fe813a9ad3fdc05006bd3a3fd75b49291251f3e Experimental BLOB code added - set wxODBC_BLOB_EXPERIMENT to 1 in dbtest.h if you want to help work on this Added some more test functions that have no GUI hook yet, but will be used in wxBase buidls eventually Fixed handling of checks for TableExists() and TablePrivileges() to use the (HOPEFULLY) now working functions. Better exception handling when the .CFG file does not exist Better reporting of database errors shown by example git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9719 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/samples/db/dbtest.cpp b/samples/db/dbtest.cpp index 532b4bbf20..4bbb8474ef 100644 --- a/samples/db/dbtest.cpp +++ b/samples/db/dbtest.cpp @@ -41,10 +41,10 @@ #include /* Included strictly for reading the text file with the database parameters */ -#include /* Required in the file which will get the data source connection */ -#include /* Has the wxDbTable object from which all data objects will inherit their data table functionality */ +//#include /* Required in the file which will get the data source connection */ +//#include /* Has the wxDbTable object from which all data objects will inherit their data table functionality */ -extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */ +//extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */ #include "dbtest.h" /* Header file for this demonstration program */ #include "listdb.h" /* Code to support the "Lookup" button on the editor dialog */ @@ -94,6 +94,222 @@ const char *GetExtendedDBErrorMsg(wxDb *pDb, char *ErrFile, int ErrLine) } // GetExtendedDBErrorMsg +bool DataTypeSupported(wxDb *pDb, SWORD datatype) +{ + wxDbSqlTypeInfo sqlTypeInfo; + + bool breakpoint = FALSE; + + if (pDb->GetDataTypeInfo(datatype, sqlTypeInfo)) + breakpoint = TRUE; + + return breakpoint; + +} // GetDataTypesSupported(); + + + +void CheckSupportForAllDataTypes(wxDb *pDb) +{ + bool supported; +#ifdef SQL_C_BINARY + supported = DataTypeSupported(pDb,SQL_C_BINARY); +#endif +#ifdef SQL_C_BIT + supported = DataTypeSupported(pDb,SQL_C_BIT); +#endif +#ifdef SQL_C_BOOKMARK + supported = DataTypeSupported(pDb,SQL_C_BOOKMARK); +#endif +#ifdef SQL_C_CHAR + supported = DataTypeSupported(pDb,SQL_C_CHAR); +#endif +#ifdef SQL_C_DATE + supported = DataTypeSupported(pDb,SQL_C_DATE); +#endif +#ifdef SQL_C_DEFAULT + supported = DataTypeSupported(pDb,SQL_C_DEFAULT); +#endif +#ifdef SQL_C_DOUBLE + supported = DataTypeSupported(pDb,SQL_C_DOUBLE); +#endif +#ifdef SQL_C_FLOAT + supported = DataTypeSupported(pDb,SQL_C_FLOAT); +#endif +#ifdef SQL_C_GUID + supported = DataTypeSupported(pDb,SQL_C_GUID); +#endif +#ifdef SQL_C_INTERVAL_DAY + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_DAY); +#endif +#ifdef SQL_C_INTERVAL_DAY_TO_HOUR + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_HOUR); +#endif +#ifdef SQL_C_INTERVAL_DAY_TO_MINUTE + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_MINUTE); +#endif +#ifdef SQL_C_INTERVAL_DAY_TO_SECOND + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_SECOND); +#endif +#ifdef SQL_C_INTERVAL_HOUR + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR); +#endif +#ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_MINUTE); +#endif +#ifdef SQL_C_INTERVAL_HOUR_TO_SECOND + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_SECOND); +#endif +#ifdef SQL_C_INTERVAL_MINUTE + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE); +#endif +#ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE_TO_SECOND); +#endif +#ifdef SQL_C_INTERVAL_MONTH + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_MONTH); +#endif +#ifdef SQL_C_INTERVAL_SECOND + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_SECOND); +#endif +#ifdef SQL_C_INTERVAL_YEAR + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR); +#endif +#ifdef SQL_C_INTERVAL_YEAR_TO_MONTH + supported = DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR_TO_MONTH); +#endif +#ifdef SQL_C_LONG + supported = DataTypeSupported(pDb,SQL_C_LONG); +#endif +#ifdef SQL_C_NUMERIC + supported = DataTypeSupported(pDb,SQL_C_NUMERIC); +#endif +#ifdef SQL_C_SBIGINT + supported = DataTypeSupported(pDb,SQL_C_SBIGINT); +#endif +#ifdef SQL_C_SHORT + supported = DataTypeSupported(pDb,SQL_C_SHORT); +#endif +#ifdef SQL_C_SLONG + supported = DataTypeSupported(pDb,SQL_C_SLONG); +#endif +#ifdef SQL_C_SSHORT + supported = DataTypeSupported(pDb,SQL_C_SSHORT); +#endif +#ifdef SQL_C_STINYINT + supported = DataTypeSupported(pDb,SQL_C_STINYINT); +#endif +#ifdef SQL_C_TIME + supported = DataTypeSupported(pDb,SQL_C_TIME); +#endif +#ifdef SQL_C_TIMESTAMP + supported = DataTypeSupported(pDb,SQL_C_TIMESTAMP); +#endif +#ifdef SQL_C_TINYINT + supported = DataTypeSupported(pDb,SQL_C_TINYINT); +#endif +#ifdef SQL_C_TYPE_DATE + supported = DataTypeSupported(pDb,SQL_C_TYPE_DATE); +#endif +#ifdef SQL_C_TYPE_TIME + supported = DataTypeSupported(pDb,SQL_C_TYPE_TIME); +#endif +#ifdef SQL_C_TYPE_TIMESTAMP + supported = DataTypeSupported(pDb,SQL_C_TYPE_TIMESTAMP); +#endif +#ifdef SQL_C_UBIGINT + supported = DataTypeSupported(pDb,SQL_C_UBIGINT); +#endif +#ifdef SQL_C_ULONG + supported = DataTypeSupported(pDb,SQL_C_ULONG); +#endif +#ifdef SQL_C_USHORT + supported = DataTypeSupported(pDb,SQL_C_USHORT); +#endif +#ifdef SQL_C_UTINYINT + supported = DataTypeSupported(pDb,SQL_C_UTINYINT); +#endif +#ifdef SQL_C_VARBOOKMARK + supported = DataTypeSupported(pDb,SQL_C_VARBOOKMARK); +#endif + +// Extended SQL types +#ifdef SQL_DATE + supported = DataTypeSupported(pDb,SQL_DATE); +#endif +#ifdef SQL_INTERVAL + supported = DataTypeSupported(pDb,SQL_INTERVAL); +#endif +#ifdef SQL_TIME + supported = DataTypeSupported(pDb,SQL_TIME); +#endif +#ifdef SQL_TIMESTAMP + supported = DataTypeSupported(pDb,SQL_TIMESTAMP); +#endif +#ifdef SQL_LONGVARCHAR + supported = DataTypeSupported(pDb,SQL_LONGVARCHAR); +#endif +#ifdef SQL_BINARY + supported = DataTypeSupported(pDb,SQL_BINARY); +#endif +#ifdef SQL_VARBINARY + supported = DataTypeSupported(pDb,SQL_VARBINARY); +#endif +#ifdef SQL_LONGVARBINARY + supported = DataTypeSupported(pDb,SQL_LONGVARBINARY); +#endif +#ifdef SQL_BIGINT + supported = DataTypeSupported(pDb,SQL_BIGINT); +#endif +#ifdef SQL_TINYINT + supported = DataTypeSupported(pDb,SQL_TINYINT); +#endif +#ifdef SQL_BIT + supported = DataTypeSupported(pDb,SQL_BIT); +#endif +#ifdef SQL_GUID + supported = DataTypeSupported(pDb,SQL_GUID); +#endif + +#ifdef SQL_CHAR + supported = DataTypeSupported(pDb,SQL_CHAR); +#endif +#ifdef SQL_INTEGER + supported = DataTypeSupported(pDb,SQL_INTEGER); +#endif +#ifdef SQL_SMALLINT + supported = DataTypeSupported(pDb,SQL_SMALLINT); +#endif +#ifdef SQL_REAL + supported = DataTypeSupported(pDb,SQL_REAL); +#endif +#ifdef SQL_DOUBLE + supported = DataTypeSupported(pDb,SQL_DOUBLE); +#endif +#ifdef SQL_NUMERIC + supported = DataTypeSupported(pDb,SQL_NUMERIC); +#endif +#ifdef SQL_DATE + supported = DataTypeSupported(pDb,SQL_DATE); +#endif +#ifdef SQL_TIME + supported = DataTypeSupported(pDb,SQL_TIME); +#endif +#ifdef SQL_TIMESTAMP + supported = DataTypeSupported(pDb,SQL_TIMESTAMP); +#endif +#ifdef SQL_VARCHAR + supported = DataTypeSupported(pDb,SQL_VARCHAR); +#endif + + +// UNICODE +#ifdef SQL_C_TCHAR + supported = DataTypeSupported(pDb,SQL_C_TCHAR); +#endif +} // CheckSupportForAllDataTypes() + + bool DatabaseDemoApp::OnInit() { DbConnectInf = NULL; @@ -131,8 +347,6 @@ bool DatabaseDemoApp::OnInit() // Show the frame DemoFrame->Show(TRUE); - ReadParamFile(params); - // Passing NULL for the SQL environment handle causes // the wxDbConnectInf constructor to obtain a handle // for you. @@ -149,6 +363,20 @@ bool DatabaseDemoApp::OnInit() delete DbConnectInf; } + if (!ReadParamFile(params)) + DemoFrame->BuildParameterDialog(NULL); + + if (!wxStrlen(params.ODBCSource)) + { + delete DbConnectInf; + return(FALSE); + } + + DbConnectInf->SetDsn(params.ODBCSource); + DbConnectInf->SetUserID(params.UserName); + DbConnectInf->SetPassword(params.Password); + DbConnectInf->SetDefaultDir(params.DirPath); + READONLY_DB = wxDbGetConnection(DbConnectInf); if (READONLY_DB == 0) { @@ -177,9 +405,7 @@ bool DatabaseDemoApp::ReadParamFile(Cparameters ¶ms) tStr.Printf(wxT("Unable to open the parameter file '%s' for reading.\n\nYou must specify the data source, user name, and\npassword that will be used and save those settings."),PARAM_FILENAME); wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION); - DemoFrame->BuildParameterDialog(NULL); - if ((paramFile = fopen(PARAM_FILENAME, wxT("r"))) == NULL) - return FALSE; + return FALSE; } wxChar buffer[1000+1]; @@ -452,6 +678,9 @@ Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(w // released when the last database instance using the connection is deleted freeDbConn = !pwxDb; + if (GetDb()) + GetDb()->SetSqlLogging(sqlLogON); + SetupColumns(); } // Ccontact Constructor @@ -516,6 +745,9 @@ void Ccontact::SetupColumns() SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER, &Contributions, SQL_C_USHORT, sizeof(Contributions), FALSE,TRUE); SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER, &LinesOfCode, SQL_C_ULONG, sizeof(LinesOfCode), FALSE,TRUE); SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER, &NativeLanguage, SQL_C_ENUM, sizeof(NativeLanguage), FALSE,TRUE); +#if wxODBC_BLOB_EXPERIMENT > 0 + SetColDefs (12,wxT("PICTURE"), DB_DATA_TYPE_BLOB, Picture, SQL_LONGVARBINARY, sizeof(Picture), FALSE,TRUE); +#endif } // Ccontact::SetupColumns @@ -592,6 +824,8 @@ CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 0, 0, 537, 480) initialized = FALSE; + SetMode(mView); + Contact = NULL; Show(FALSE); @@ -654,10 +888,13 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event) if (widgetName == pCopyBtn->GetName()) { + + CheckSupportForAllDataTypes(wxGetApp().READONLY_DB); +/* SetMode(mCreate); pNameTxt->SetValue(wxT("")); pNameTxt->SetFocus(); - +*/ return; } @@ -929,25 +1166,29 @@ bool CeditorDlg::Initialize() // Table does exist, or there was some problem opening it. Currently this should // never fail, except in the case of the table not exisiting or the current // user has insufficent privileges to access the table -#if 0 +#if 1 // This code is experimenting with a new function that will hopefully be available // in the 2.4 release. This check will determine whether the open failing was due // to the table not existing, or the users privileges being insufficient to // open the table. - if (!Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME,wxT("SELECT"),Contact->GetDb()->GetUsername(),Contact->GetDb()->GetUsername(),DbConnectInf->GetDefaultDir())) + if (!Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME, wxT("SELECT"), + Contact->GetDb()->GetUsername(), + Contact->GetDb()->GetUsername(), + wxGetApp().DbConnectInf->GetDefaultDir())) { wxString tStr; - tStr.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME); + tStr.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME); tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__); wxMessageBox(tStr,wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION); } else #endif - if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME, Contact->GetDb()->GetUsername(), - wxGetApp().DbConnectInf->GetDefaultDir())) + if (!Contact->GetDb()->TableExists(CONTACT_TABLE_NAME, + Contact->GetDb()->GetUsername(), + wxGetApp().DbConnectInf->GetDefaultDir())) { wxString tStr; - tStr.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME); + tStr.Printf(wxT("Unable to open the table '%s' as the table\ndoes not appear to exist in the tablespace available\nto the currently logged in user.\n\n"),CONTACT_TABLE_NAME); tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__); wxMessageBox(tStr,wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION); } @@ -1066,6 +1307,9 @@ bool CeditorDlg::Initialize() void CeditorDlg::FieldsEditable() { + if (!widgetPtrsSet) + return; + pNameTxt->Enable((mode == mCreate) || (mode == mEdit)); pAddress1Txt->Enable((mode == mCreate) || (mode == mEdit)); pAddress2Txt->Enable((mode == mCreate) || (mode == mEdit)); @@ -1643,7 +1887,7 @@ void CparameterDlg::FillDataSourceList() pParamODBCSourceList->Append(p[i]); delete [] p; -} // CparameterDlg::CparameterDlg::FillDataSourceList() +} // CparameterDlg::FillDataSourceList() BEGIN_EVENT_TABLE(CqueryDlg, wxDialog) @@ -2121,11 +2365,12 @@ void CqueryDlg::ProcessCountBtn() if (!ValidateWhereClause()) return; - if (dbTable == 0) // wxDbTable object needs to be created and opened + if (!dbTable) // wxDbTable object needs to be created and opened { - if (!(dbTable = new wxDbTable(pDB, masterTableName, 0, wxT(""), - !wxDB_QUERY_ONLY, - wxGetApp().DbConnectInf->GetDefaultDir()))) + dbTable = new wxDbTable(pDB, masterTableName, 0, wxT(""), + !wxDB_QUERY_ONLY, + wxGetApp().DbConnectInf->GetDefaultDir()); + if (!dbTable) { wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK | wxICON_EXCLAMATION); return; diff --git a/samples/db/dbtest.h b/samples/db/dbtest.h index 87911415e9..754516b048 100644 --- a/samples/db/dbtest.h +++ b/samples/db/dbtest.h @@ -14,7 +14,6 @@ #endif #include -#include #include enum DialogModes {mView,mCreate,mEdit,mSearch}; @@ -39,10 +38,17 @@ enum DialogModes {mView,mCreate,mEdit,mSearch}; // Name of the table to be created/opened const wxChar CONTACT_TABLE_NAME[] = "contacts"; + +#define wxODBC_BLOB_EXPERIMENT 0 + // Number of columns in the CONTACT table +#if wxODBC_BLOB_EXPERIMENT > 0 +const int CONTACT_NO_COLS = 13; // 0-12 +#else const int CONTACT_NO_COLS = 12; // 0-11 +#endif -const wxChar PARAM_FILENAME[] = "dbtest.cfg"; +const wxChar PARAM_FILENAME[] = "dbtest.cfg"; enum Language {langENGLISH, langFRENCH, langGERMAN, langSPANISH, langOTHER}; @@ -70,6 +76,9 @@ class CstructContact : public wxObject wxChar Country[20+1]; TIMESTAMP_STRUCT JoinDate; // Date on which this person joined the wxWindows project Language NativeLanguage; // Enumerated type indicating person's native language +#if wxODBC_BLOB_EXPERIMENT > 0 + wxChar Picture[50000]; +#endif bool IsDeveloper; // Is this person a developer for wxWindows, or just a subscriber UCHAR Contributions; // Something to show off an integer field ULONG LinesOfCode; // Something to show off a 'long' field diff --git a/samples/db/listdb.cpp b/samples/db/listdb.cpp index e5959ab255..163a0ae414 100644 --- a/samples/db/listdb.cpp +++ b/samples/db/listdb.cpp @@ -89,10 +89,10 @@ extern wxApp *DatabaseDemoApp; * NOTE: The value returned by this function is for temporary use only and * should be copied for long term use */ -const wxChar *GetExtendedDBErrorMsg2(wxChar *ErrFile, int ErrLine) +const char *GetExtendedDBErrorMsg2(wxDb *pDb, char *ErrFile, int ErrLine) { static wxString msg; - msg.Empty(); + msg = wxT(""); wxString tStr; @@ -102,42 +102,33 @@ const wxChar *GetExtendedDBErrorMsg2(wxChar *ErrFile, int ErrLine) msg += ErrFile; msg += wxT(" Line: "); tStr.Printf(wxT("%d"),ErrLine); - msg += tStr; + msg += tStr.c_str(); msg += wxT("\n"); } msg.Append (wxT("\nODBC errors:\n")); msg += wxT("\n"); - /* Scan through each database connection displaying - * any ODBC errors that have occured. */ - wxDbList *pDbList; - for (pDbList = PtrBegDbList; pDbList; pDbList = pDbList->PtrNext) + // Display errors for this connection + int i; + for (i = 0; i < DB_MAX_ERROR_HISTORY; i++) { - // Skip over any free connections - if (pDbList->Free) - continue; - // Display errors for this connection - for (int i = 0; i < DB_MAX_ERROR_HISTORY; i++) + if (pDb->errorList[i]) { - if (pDbList->PtrDb->errorList[i]) - { - msg.Append(pDbList->PtrDb->errorList[i]); - if (wxStrcmp(pDbList->PtrDb->errorList[i],wxT("")) != 0) - msg.Append(wxT("\n")); - // Clear the errmsg buffer so the next error will not - // end up showing the previous error that have occurred - wxStrcpy(pDbList->PtrDb->errorList[i],wxT("")); - } + msg.Append(pDb->errorList[i]); + if (wxStrcmp(pDb->errorList[i],wxT("")) != 0) + msg.Append(wxT("\n")); + // Clear the errmsg buffer so the next error will not + // end up showing the previous error that have occurred + wxStrcpy(pDb->errorList[i],wxT("")); } } msg += wxT("\n"); - return /*(wxChar*) (const wxChar*) msg*/msg.c_str(); + return msg.c_str(); } // GetExtendedDBErrorMsg - // Clookup constructor Clookup::Clookup(wxChar *tblName, wxChar *colName, wxDb *pDb, const wxString &defDir) : wxDbTable(pDb, tblName, 1, wxT(""), !wxDB_QUERY_ONLY, @@ -199,7 +190,8 @@ ClookUpDlg::ClookUpDlg(wxWindow *parent, wxChar *windowTitle, wxChar *tableName, widgetPtrsSet = TRUE; // Query the lookup table and display the result set - if (!(lookup = new Clookup(tableName, colName, pDb, defDir))) + lookup = new Clookup(tableName, colName, pDb, defDir); + if (!lookup) { wxMessageBox(wxT("Error allocating memory for 'Clookup'object."),wxT("Error...")); Close(); @@ -303,7 +295,8 @@ ClookUpDlg::ClookUpDlg(wxWindow *parent, wxChar *windowTitle, wxChar *tableName, widgetPtrsSet = TRUE; // Query the lookup table and display the result set - if (!(lookup2 = new Clookup2(tableName, dispCol1, dispCol2, pDb, defDir))) + lookup2 = new Clookup2(tableName, dispCol1, dispCol2, pDb, defDir); + if (!lookup2) { wxMessageBox(wxT("Error allocating memory for 'Clookup2' object."),wxT("Error...")); Close(); @@ -314,7 +307,7 @@ ClookUpDlg::ClookUpDlg(wxWindow *parent, wxChar *windowTitle, wxChar *tableName, { wxString tStr; tStr.Printf(wxT("Unable to open the table '%s'."),tableName); - tStr += GetExtendedDBErrorMsg2(__FILE__,__LINE__); + tStr += GetExtendedDBErrorMsg2(pDb,__FILE__,__LINE__); wxMessageBox(tStr,wxT("ODBC Error...")); Close(); return;