X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4fdae9972d39fbe62adaa1c1d721ba1762cd8950..353327844e319db755c2e7a07a4cf5b53cef35c4:/src/common/db.cpp?ds=sidebyside diff --git a/src/common/db.cpp b/src/common/db.cpp index 21c1313c12..b075f92a59 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -135,100 +135,158 @@ typedef struct } wxDbTablePrivilegeInfo; -/********** wxDbColFor Constructor **********/ -wxDbColFor::wxDbColFor() +/********** wxDbConnectInf Constructor - form 1 **********/ +wxDbConnectInf::wxDbConnectInf() { - s_Field.Empty(); - int i; - for (i=0; i<7; i++) + Henv = 0; + freeHenvOnDestroy = FALSE; + + Initialize(); +} // Constructor + + +/********** wxDbConnectInf Constructor - form 2 **********/ +wxDbConnectInf::wxDbConnectInf(HENV henv, const wxString &dsn, const wxString &userID, + const wxString &password, const wxString &defaultDir, + const wxString &fileType, const wxString &description) +{ + Henv = 0; + freeHenvOnDestroy = FALSE; + + Initialize(); + + if (henv) + SetHenv(henv); + else + AllocHenv(); + + SetDsn(dsn); + SetUserID(userID); + SetPassword(password); + SetDescription(description); + SetFileType(fileType); + SetDefaultDir(defaultDir); +} // wxDbConnectInf Constructor + + +wxDbConnectInf::~wxDbConnectInf() +{ + if (freeHenvOnDestroy) { - s_Format[i].Empty(); - s_Amount[i].Empty(); - i_Amount[i] = 0; + FreeHenv(); } - i_Nation = 0; // 0=EU, 1=UK, 2=International, 3=US - i_dbDataType = 0; - i_sqlDataType = 0; - Format(1,DB_DATA_TYPE_VARCHAR,0,0,0); // the Function that does the work -} // wxDbColFor::wxDbColFor() +} // wxDbConnectInf Destructor -wxDbColFor::~wxDbColFor() + +/********** wxDbConnectInf::Initialize() **********/ +bool wxDbConnectInf::Initialize() { -} // wxDbColFor::~wxDbColFor() + freeHenvOnDestroy = FALSE; + if (freeHenvOnDestroy && Henv) + FreeHenv(); -/********** wxDbColInf Con / Destructor **********/ -wxDbColInf::wxDbColInf() + Henv = 0; + Dsn[0] = 0; + Uid[0] = 0; + AuthStr[0] = 0; + Description.Empty(); + FileType.Empty(); + DefaultDir.Empty(); + + return TRUE; +} // wxDbConnectInf::Initialize() + + +/********** wxDbConnectInf::AllocHenv() **********/ +bool wxDbConnectInf::AllocHenv() { - catalog[0] = 0; - schema[0] = 0; - tableName[0] = 0; - colName[0] = 0; - sqlDataType = 0; - typeName[0] = 0; - columnSize = 0; - bufferLength = 0; - decimalDigits = 0; - numPrecRadix = 0; - nullable = 0; - remarks[0] = 0; - dbDataType = 0; - PkCol = 0; - PkTableName[0] = 0; - FkCol = 0; - FkTableName[0] = 0; - pColFor = NULL; -} // wxDbColInf::wxDbColFor() + // This is here to help trap if you are getting a new henv + // without releasing an existing henv + wxASSERT(!Henv); + // Initialize the ODBC Environment for Database Operations + if (SQLAllocEnv(&Henv) != SQL_SUCCESS) + { + wxLogDebug(wxT("A problem occured while trying to get a connection to the data source")); + return FALSE; + } -wxDbColInf::~wxDbColInf() + freeHenvOnDestroy = TRUE; + + return TRUE; +} // wxDbConnectInf::AllocHenv() + + +void wxDbConnectInf::FreeHenv() { - if (pColFor) - delete pColFor; - pColFor = NULL; -} // wxDbColInf::~wxDbColInf() + wxASSERT(Henv); + if (Henv) + SQLFreeEnv(Henv); -/********** wxDbTableInf Constructor ********/ -wxDbTableInf::wxDbTableInf() + Henv = 0; + freeHenvOnDestroy = FALSE; + +} // wxDbConnectInf::FreeHenv() + + +void wxDbConnectInf::SetDsn(const wxString &dsn) { - tableName[0] = 0; - tableType[0] = 0; - tableRemarks[0] = 0; - numCols = 0; - pColInf = NULL; -} // wxDbTableInf::wxDbTableFor() + wxASSERT(dsn.Length() < sizeof(Dsn)); + wxStrcpy(Dsn,dsn); +} // wxDbConnectInf::SetDsn() -/********** wxDbTableInf Constructor ********/ -wxDbTableInf::~wxDbTableInf() + +void wxDbConnectInf::SetUserID(const wxString &uid) { - if (pColInf) - delete [] pColInf; - pColInf = NULL; -} // wxDbTableInf::~wxDbTableInf() + wxASSERT(uid.Length() < sizeof(Uid)); + wxStrcpy(Uid,uid); +} // wxDbConnectInf::SetUserID() -/********** wxDbInf Constructor *************/ -wxDbInf::wxDbInf() +void wxDbConnectInf::SetPassword(const wxString &password) { - catalog[0] = 0; - schema[0] = 0; - numTables = 0; - pTableInf = NULL; -} // wxDbInf::wxDbFor() + wxASSERT(password.Length() < sizeof(AuthStr)); + + wxStrcpy(AuthStr,password); +} // wxDbConnectInf::SetPassword() -/********** wxDbInf Destructor *************/ -wxDbInf::~wxDbInf() + +/********** wxDbColFor Constructor **********/ +wxDbColFor::wxDbColFor() { - if (pTableInf) - delete [] pTableInf; - pTableInf = NULL; -} // wxDbInf::~wxDbInf() + Initialize(); +} // wxDbColFor::wxDbColFor() + + +wxDbColFor::~wxDbColFor() +{ +} // wxDbColFor::~wxDbColFor() + + +/********** wxDbColFor::Initialize() **********/ +void wxDbColFor::Initialize() +{ + s_Field.Empty(); + int i; + for (i=0; i<7; i++) + { + s_Format[i].Empty(); + s_Amount[i].Empty(); + i_Amount[i] = 0; + } + i_Nation = 0; // 0=EU, 1=UK, 2=International, 3=US + i_dbDataType = 0; + i_sqlDataType = 0; + Format(1,DB_DATA_TYPE_VARCHAR,0,0,0); // the Function that does the work +} // wxDbColFor::Initialize() +/********** wxDbColFor::Format() **********/ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, short columnSize, short decimalDigits) { @@ -262,6 +320,8 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, i_dbDataType = DB_DATA_TYPE_VARCHAR; if (i_sqlDataType == SQL_REAL) i_dbDataType = DB_DATA_TYPE_FLOAT; + if (i_sqlDataType == SQL_C_BINARY) + i_dbDataType = DB_DATA_TYPE_BLOB; } if ((i_dbDataType == DB_DATA_TYPE_INTEGER) && (i_sqlDataType == SQL_C_DOUBLE)) @@ -306,6 +366,9 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, s_Field = wxT("%02d/%02d/%04d %02d:%02d:%02d.%03d"); } break; + case DB_DATA_TYPE_BLOB: + s_Field.Printf(wxT("Unable to format(%d)-SQL(%d)"),dbDataType,sqlDataType); // + break; default: s_Field.Printf(wxT("Unknown Format(%d)-SQL(%d)"),dbDataType,sqlDataType); // break; @@ -314,17 +377,117 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, } // wxDbColFor::Format() + +/********** wxDbColInf Constructor **********/ +wxDbColInf::wxDbColInf() +{ + Initialize(); +} // wxDbColInf::wxDbColInf() + + +/********** wxDbColInf Destructor ********/ +wxDbColInf::~wxDbColInf() +{ + if (pColFor) + delete pColFor; + pColFor = NULL; +} // wxDbColInf::~wxDbColInf() + + +bool wxDbColInf::Initialize() +{ + catalog[0] = 0; + schema[0] = 0; + tableName[0] = 0; + colName[0] = 0; + sqlDataType = 0; + typeName[0] = 0; + columnSize = 0; + bufferLength = 0; + decimalDigits = 0; + numPrecRadix = 0; + nullable = 0; + remarks[0] = 0; + dbDataType = 0; + PkCol = 0; + PkTableName[0] = 0; + FkCol = 0; + FkTableName[0] = 0; + pColFor = NULL; + + return TRUE; +} // wxDbColInf::Initialize() + + +/********** wxDbTableInf Constructor ********/ +wxDbTableInf::wxDbTableInf() +{ + Initialize(); +} // wxDbTableInf::wxDbTableInf() + + +/********** wxDbTableInf Constructor ********/ +wxDbTableInf::~wxDbTableInf() +{ + if (pColInf) + delete [] pColInf; + pColInf = NULL; +} // wxDbTableInf::~wxDbTableInf() + + +bool wxDbTableInf::Initialize() +{ + tableName[0] = 0; + tableType[0] = 0; + tableRemarks[0] = 0; + numCols = 0; + pColInf = NULL; + + return TRUE; +} // wxDbTableInf::Initialize() + + +/********** wxDbInf Constructor *************/ +wxDbInf::wxDbInf() +{ + Initialize(); +} // wxDbInf::wxDbInf() + + +/********** wxDbInf Destructor *************/ +wxDbInf::~wxDbInf() +{ + if (pTableInf) + delete [] pTableInf; + pTableInf = NULL; +} // wxDbInf::~wxDbInf() + + +/********** wxDbInf::Initialize() *************/ +bool wxDbInf::Initialize() +{ + catalog[0] = 0; + schema[0] = 0; + numTables = 0; + pTableInf = NULL; + + return TRUE; +} // wxDbInf::Initialize() + + /********** wxDb Constructors **********/ -wxDb::wxDb(HENV &aHenv, bool FwdOnlyCursors) +wxDb::wxDb(const HENV &aHenv, bool FwdOnlyCursors) { // Copy the HENV into the db class henv = aHenv; fwdOnlyCursors = FwdOnlyCursors; + initialize(); } // wxDb::wxDb() /********** PRIVATE! wxDb::initialize PRIVATE! **********/ +/********** wxDb::initialize() **********/ void wxDb::initialize() /* * Private member function that sets all wxDb member variables to @@ -338,11 +501,11 @@ void wxDb::initialize() nTables = 0; dbmsType = dbmsUNIDENTIFIED; - wxStrcpy(sqlState,wxT("")); - wxStrcpy(errorMsg,wxT("")); + wxStrcpy(sqlState,wxEmptyString); + wxStrcpy(errorMsg,wxEmptyString); nativeError = cbErrorMsg = 0; for (i = 0; i < DB_MAX_ERROR_HISTORY; i++) - wxStrcpy(errorList[i], wxT("")); + wxStrcpy(errorList[i], wxEmptyString); // Init typeInf structures typeInfVarchar.TypeName.Empty(); @@ -369,6 +532,12 @@ void wxDb::initialize() typeInfDate.CaseSensitive = 0; typeInfDate.MaximumScale = 0; + typeInfBlob.TypeName.Empty(); + typeInfBlob.FsqlType = 0; + typeInfBlob.Precision = 0; + typeInfBlob.CaseSensitive = 0; + typeInfBlob.MaximumScale = 0; + // Error reporting is turned OFF by default silent = TRUE; @@ -384,7 +553,7 @@ void wxDb::initialize() } // wxDb::initialize() -/********** PRIVATE! wxDb::initialize PRIVATE! **********/ +/********** PRIVATE! wxDb::convertUserID PRIVATE! **********/ // // NOTE: Return value from this function MUST be copied // immediately, as the value is not good after @@ -461,8 +630,8 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt If using Intersolv branded ODBC drivers, this is the place where you would substitute your branded driver license information - SQLSetConnectOption(hdbc, 1041, (UDWORD) wxT("")); - SQLSetConnectOption(hdbc, 1042, (UDWORD) wxT("")); + SQLSetConnectOption(hdbc, 1041, (UDWORD) wxEmptyString); + SQLSetConnectOption(hdbc, 1042, (UDWORD) wxEmptyString); */ // Mark database as open @@ -483,7 +652,7 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt // Query the data source regarding data type information // - // The way I determined which SQL data types to use was by calling SQLGetInfo + // The way it was determined which SQL data types to use was by calling SQLGetInfo // for all of the possible SQL data types to see which ones were supported. If // a type is not supported, the SQLFetch() that's called from getDataTypeInfo() // fails with SQL_NO_DATA_FOUND. This is ugly because I'm sure the three SQL data @@ -532,7 +701,6 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt // Float if (!getDataTypeInfo(SQL_DOUBLE,typeInfFloat)) - if (!getDataTypeInfo(SQL_REAL,typeInfFloat)) if (!getDataTypeInfo(SQL_FLOAT,typeInfFloat)) if (!getDataTypeInfo(SQL_DECIMAL,typeInfFloat)) @@ -578,11 +746,24 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt typeInfDate.FsqlType = SQL_DATE; } + if (!getDataTypeInfo(SQL_LONGVARBINARY, typeInfBlob)) + { + if (!getDataTypeInfo(SQL_VARBINARY,typeInfBlob)) + return(FALSE); + else + typeInfBlob.FsqlType = SQL_VARBINARY; + } + else + typeInfBlob.FsqlType = SQL_LONGVARBINARY; + +//typeInfBlob.TypeName = "BLOB"; + #ifdef DBDEBUG_CONSOLE cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl; cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl; cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl; cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl; + cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl; cout << endl; #endif @@ -592,6 +773,13 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt } // wxDb::Open() +bool wxDb::Open(wxDbConnectInf *dbConnectInf) +{ + return Open(dbConnectInf->GetDsn(), dbConnectInf->GetUserID(), + dbConnectInf->GetPassword()); +} // wxDb::Open() + + bool wxDb::Open(wxDb *copyDb) { dsn = copyDb->GetDatasourceName(); @@ -626,8 +814,8 @@ bool wxDb::Open(wxDb *copyDb) If using Intersolv branded ODBC drivers, this is the place where you would substitute your branded driver license information - SQLSetConnectOption(hdbc, 1041, (UDWORD) wxT("")); - SQLSetConnectOption(hdbc, 1042, (UDWORD) wxT("")); + SQLSetConnectOption(hdbc, 1041, (UDWORD) wxEmptyString); + SQLSetConnectOption(hdbc, 1042, (UDWORD) wxEmptyString); */ // Mark database as open @@ -703,11 +891,19 @@ bool wxDb::Open(wxDb *copyDb) typeInfDate.CaseSensitive = copyDb->typeInfDate.CaseSensitive; typeInfDate.MaximumScale = copyDb->typeInfDate.MaximumScale; + // Blob + typeInfBlob.FsqlType = copyDb->typeInfBlob.FsqlType; + typeInfBlob.TypeName = copyDb->typeInfBlob.TypeName; + typeInfBlob.Precision = copyDb->typeInfBlob.Precision; + typeInfBlob.CaseSensitive = copyDb->typeInfBlob.CaseSensitive; + typeInfBlob.MaximumScale = copyDb->typeInfBlob.MaximumScale; + #ifdef DBDEBUG_CONSOLE cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl; cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl; cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl; cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl; + cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl; cout << endl; #endif @@ -1228,7 +1424,7 @@ void wxDb::Close(void) // Copy the error messages to a global variable int i; for (i = 0; i < DB_MAX_ERROR_HISTORY; i++) - wxStrcpy(DBerrorList[i],errorList[i]); + wxStrcpy(DBerrorList[i], errorList[i]); dbmsType = dbmsUNIDENTIFIED; dbIsOpen = FALSE; @@ -1659,7 +1855,7 @@ bool wxDb::DropView(const wxString &viewName) */ wxString sqlStmt; - sqlStmt.Printf(wxT("DROP VIEW %s"), viewName); + sqlStmt.Printf(wxT("DROP VIEW %s"), viewName.c_str()); WriteSqlLog(sqlStmt); @@ -1696,9 +1892,16 @@ bool wxDb::DropView(const wxString &viewName) /********** wxDb::ExecSql() **********/ bool wxDb::ExecSql(const wxString &pSqlStmt) { + RETCODE retcode; + 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); + } else { DispAllErrors(henv, hdbc, hstmt); @@ -1740,7 +1943,7 @@ bool wxDb::GetData(UWORD colNo, SWORD cType, PTR pData, SDWORD maxLen, SDWORD FA /********** wxDb::GetKeyFields() **********/ -int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, int noCols) +int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCols) { wxChar szPkTable[DB_MAX_TABLE_NAME_LEN+1]; /* Primary key table name */ wxChar szFkTable[DB_MAX_TABLE_NAME_LEN+1]; /* Foreign key table name */ @@ -1750,7 +1953,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, int noCols wxChar szFkCol[DB_MAX_COLUMN_NAME_LEN+1]; /* Foreign key column */ SQLRETURN retcode; SDWORD cb; - int i; + SWORD i; wxString tempStr; /* * ----------------------------------------------------------------------- @@ -1908,8 +2111,8 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) * to avoid undesired unbinding of columns. */ { - int noCols = 0; - int colNo = 0; + UWORD noCols = 0; + UWORD colNo = 0; wxDbColInf *colInf = 0; RETCODE retcode; @@ -1935,8 +2138,8 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) if (!colInf) break; // Mark the end of the array - wxStrcpy(colInf[noCols].tableName,wxT("")); - wxStrcpy(colInf[noCols].colName,wxT("")); + wxStrcpy(colInf[noCols].tableName,wxEmptyString); + wxStrcpy(colInf[noCols].colName,wxEmptyString); colInf[noCols].sqlDataType = 0; } // Loop through each table name @@ -2019,13 +2222,14 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) #endif colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; } - else if (!wxStricmp(typeInfInteger.TypeName,colInf[colNo].typeName)) + else if (!wxStricmp(typeInfInteger.TypeName, colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER; - else if (!wxStricmp(typeInfFloat.TypeName,colInf[colNo].typeName)) + else if (!wxStricmp(typeInfFloat.TypeName, colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT; - else if (!wxStricmp(typeInfDate.TypeName,colInf[colNo].typeName)) + else if (!wxStricmp(typeInfDate.TypeName, colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_DATE; - + else if (!wxStricmp(typeInfBlob.TypeName, colInf[colNo].typeName)) + colInf[colNo].dbDataType = DB_DATA_TYPE_BLOB; colNo++; } } @@ -2049,7 +2253,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) /********** wxDb::GetColumns() **********/ -wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxChar *userID) +wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wxChar *userID) // // Same as the above GetColumns() function except this one gets columns // only for a single table, and if 'numCols' is not NULL, the number of @@ -2065,8 +2269,8 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh // to avoid undesired unbinding of columns. { - int noCols = 0; - int colNo = 0; + UWORD noCols = 0; + UWORD colNo = 0; wxDbColInf *colInf = 0; RETCODE retcode; @@ -2092,8 +2296,8 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh if (!colInf) break; // Mark the end of the array - wxStrcpy(colInf[noCols].tableName, wxT("")); - wxStrcpy(colInf[noCols].colName, wxT("")); + wxStrcpy(colInf[noCols].tableName, wxEmptyString); + wxStrcpy(colInf[noCols].colName, wxEmptyString); colInf[noCols].sqlDataType = 0; } @@ -2176,7 +2380,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh // Determine the wxDb data type that is used to represent the native data type of this data source colInf[colNo].dbDataType = 0; - if (!wxStricmp(typeInfVarchar.TypeName,colInf[colNo].typeName)) + if (!wxStricmp(typeInfVarchar.TypeName, colInf[colNo].typeName)) { #ifdef _IODBC_ // IODBC does not return a correct columnSize, so we set @@ -2190,12 +2394,14 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; } - else if (!wxStricmp(typeInfInteger.TypeName,colInf[colNo].typeName)) + else if (!wxStricmp(typeInfInteger.TypeName, colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER; - else if (!wxStricmp(typeInfFloat.TypeName,colInf[colNo].typeName)) + else if (!wxStricmp(typeInfFloat.TypeName, colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT; - else if (!wxStricmp(typeInfDate.TypeName,colInf[colNo].typeName)) + else if (!wxStricmp(typeInfDate.TypeName, colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_DATE; + else if (!wxStricmp(typeInfBlob.TypeName, colInf[colNo].typeName)) + colInf[colNo].dbDataType = DB_DATA_TYPE_BLOB; colNo++; } @@ -2248,7 +2454,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh typedef struct { - int noCols; + UWORD noCols; wxDbColInf *colInf; } _TableColumns; @@ -2259,7 +2465,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) // The last array element of the tableName[] argument must be zero (null). // This is how the end of the array is detected. - int noCols = 0; + UWORD noCols = 0; // How many tables ? int tbl; @@ -2282,8 +2488,8 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) wxDbColInf *colInf = new wxDbColInf[noCols+1]; // Mark the end of the array - wxStrcpy(colInf[noCols].tableName, wxT("")); - wxStrcpy(colInf[noCols].colName, wxT("")); + wxStrcpy(colInf[noCols].tableName, wxEmptyString); + wxStrcpy(colInf[noCols].colName, wxEmptyString); colInf[noCols].sqlDataType = 0; // Merge ... @@ -2318,8 +2524,8 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh // by this function. This function should use its own wxDb instance // to avoid undesired unbinding of columns. { - SWORD noCols = 0; - int colNo = 0; + UWORD noCols = 0; + UWORD colNo = 0; wxDbColInf *colInf = 0; RETCODE retcode; @@ -2345,8 +2551,8 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh if (!colInf) break; // Mark the end of the array - wxStrcpy(colInf[noCols].tableName, wxT("")); - wxStrcpy(colInf[noCols].colName, wxT("")); + wxStrcpy(colInf[noCols].tableName, wxEmptyString); + wxStrcpy(colInf[noCols].colName, wxEmptyString); colInf[noCols].sqlDataType = 0; } @@ -2453,6 +2659,9 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh case SQL_DATE: colInf[colNo].dbDataType = DB_DATA_TYPE_DATE; break; + case SQL_BINARY: + colInf[colNo].dbDataType = DB_DATA_TYPE_BLOB; + break; #ifdef __WXDEBUG__ default: wxString errMsg; @@ -2560,7 +2769,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh /********** wxDb::GetColumnCount() **********/ -int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) +UWORD wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) /* * Returns a count of how many columns are in a table. * If an error occurs in computing the number of columns @@ -2576,7 +2785,7 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) * to avoid undesired unbinding of columns. */ { - int noCols = 0; + UWORD noCols = 0; RETCODE retcode; @@ -2894,9 +3103,9 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx { wxString dbName; if (tablePath.Length()) - dbName.Printf(wxT("%s/%s.dbf"),tablePath,tableName); + dbName.Printf(wxT("%s/%s.dbf"), tablePath.c_str(), tableName.c_str()); else - dbName.Printf(wxT("%s.dbf"),tableName); + dbName.Printf(wxT("%s.dbf"), tableName.c_str()); bool exists; exists = wxFileExists(dbName); @@ -2921,7 +3130,9 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx if (!UserID.IsEmpty() && Dbms() != dbmsMY_SQL && Dbms() != dbmsACCESS && - Dbms() != dbmsMS_SQL_SERVER) + Dbms() != dbmsMS_SQL_SERVER && + Dbms() != dbmsDB2 && + Dbms() != dbmsPERVASIVE_SQL) { retcode = SQLTables(hstmt, NULL, 0, // All qualifiers @@ -2970,8 +3181,9 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons wxString TableName; - wxString UserID; + wxString UserID,Schema; convertUserID(userID,UserID); + convertUserID(schema,Schema); TableName = tableName; // Oracle and Interbase table names are uppercase only, so force @@ -2982,18 +3194,23 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons SQLFreeStmt(hstmt, SQL_CLOSE); - if (!schema) + // Some databases cannot accept a user name when looking up table names, + // so we use the call below that leaves out the user name + if (!Schema.IsEmpty() && + Dbms() != dbmsMY_SQL && + Dbms() != dbmsACCESS && + Dbms() != dbmsMS_SQL_SERVER) { retcode = SQLTablePrivileges(hstmt, NULL, 0, // Catalog - NULL, 0, // Schema + (UCHAR FAR *)Schema.c_str(), SQL_NTS, // Schema (UCHAR FAR *)TableName.c_str(), SQL_NTS); } else { retcode = SQLTablePrivileges(hstmt, NULL, 0, // Catalog - (UCHAR FAR *)schema, SQL_NTS, // Schema + NULL, 0, // Schema (UCHAR FAR *)TableName.c_str(), SQL_NTS); } @@ -3004,30 +3221,35 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) return(DispAllErrors(henv, hdbc, hstmt)); + bool failed = FALSE; retcode = SQLFetch(hstmt); while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { if (SQLGetData(hstmt, 1, SQL_C_CHAR, (UCHAR*) result.tableQual, sizeof(result.tableQual), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + failed = true; - if (SQLGetData(hstmt, 2, SQL_C_CHAR, (UCHAR*) result.tableOwner, sizeof(result.tableOwner), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + if (!failed && SQLGetData(hstmt, 2, SQL_C_CHAR, (UCHAR*) result.tableOwner, sizeof(result.tableOwner), &cbRetVal) != SQL_SUCCESS) + failed = true; - if (SQLGetData(hstmt, 3, SQL_C_CHAR, (UCHAR*) result.tableName, sizeof(result.tableName), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + if (!failed && SQLGetData(hstmt, 3, SQL_C_CHAR, (UCHAR*) result.tableName, sizeof(result.tableName), &cbRetVal) != SQL_SUCCESS) + failed = true; - if (SQLGetData(hstmt, 4, SQL_C_CHAR, (UCHAR*) result.grantor, sizeof(result.grantor), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + if (!failed && SQLGetData(hstmt, 4, SQL_C_CHAR, (UCHAR*) result.grantor, sizeof(result.grantor), &cbRetVal) != SQL_SUCCESS) + failed = true; - if (SQLGetData(hstmt, 5, SQL_C_CHAR, (UCHAR*) result.grantee, sizeof(result.grantee), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + if (!failed && SQLGetData(hstmt, 5, SQL_C_CHAR, (UCHAR*) result.grantee, sizeof(result.grantee), &cbRetVal) != SQL_SUCCESS) + failed = true; - if (SQLGetData(hstmt, 6, SQL_C_CHAR, (UCHAR*) result.privilege, sizeof(result.privilege), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + if (!failed && SQLGetData(hstmt, 6, SQL_C_CHAR, (UCHAR*) result.privilege, sizeof(result.privilege), &cbRetVal) != SQL_SUCCESS) + failed = true; - if (SQLGetData(hstmt, 7, SQL_C_CHAR, (UCHAR*) result.grantable, sizeof(result.grantable), &cbRetVal) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc, hstmt)); + if (!failed && SQLGetData(hstmt, 7, SQL_C_CHAR, (UCHAR*) result.grantable, sizeof(result.grantable), &cbRetVal) != SQL_SUCCESS) + failed = true; + if (failed) + { + return(DispAllErrors(henv, hdbc, hstmt)); + } #ifdef DBDEBUG_CONSOLE fprintf(stderr,wxT("Scanning %s privilege on table %s.%s granted by %s to %s\n"), result.privilege,result.tableOwner,result.tableName, @@ -3165,6 +3387,11 @@ wxDBMS wxDb::Dbms(void) * * DB2 * - 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 * */ { @@ -3210,6 +3437,10 @@ wxDBMS wxDb::Dbms(void) if (!wxStricmp(dbInf.dbmsName,wxT("PostgreSQL"))) // v6.5.0 return((wxDBMS)(dbmsType = dbmsPOSTGRES)); + baseName[9] = 0; + if (!wxStricmp(dbInf.dbmsName,wxT("Pervasive"))) + return((wxDBMS)(dbmsType = dbmsPERVASIVE_SQL)); + baseName[8] = 0; if (!wxStricmp(baseName,wxT("Informix"))) return((wxDBMS)(dbmsType = dbmsINFORMIX)); @@ -3268,6 +3499,9 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, case DB_DATA_TYPE_DATE : dataTypeName = typeInfDate.TypeName; break; + case DB_DATA_TYPE_BLOB : + dataTypeName = typeInfBlob.TypeName; + break; default: return FALSE; } @@ -3295,8 +3529,8 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, } // create the SQL statement - sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName, alterSlashModify, - columnName, dataTypeName); + sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName.c_str(), alterSlashModify.c_str(), + columnName.c_str(), dataTypeName.c_str()); // For varchars only, append the size of the column if (dataType == DB_DATA_TYPE_VARCHAR) @@ -3338,15 +3572,15 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso // name and must currently not be in use. if (pList->Free && (pList->PtrDb->FwdOnlyCursors() == FwdOnlyCursors) && - (!wxStrcmp(pDbConfig->Dsn, pList->Dsn))) // Found a free connection + (!wxStrcmp(pDbConfig->GetDsn(), pList->Dsn))) // Found a free connection { pList->Free = FALSE; return(pList->PtrDb); } - if (!wxStrcmp(pDbConfig->Dsn, pList->Dsn) && - !wxStrcmp(pDbConfig->Uid, pList->Uid) && - !wxStrcmp(pDbConfig->AuthStr, pList->AuthStr)) + if (!wxStrcmp(pDbConfig->GetDsn(), pList->Dsn) && + !wxStrcmp(pDbConfig->GetUserID(), pList->Uid) && + !wxStrcmp(pDbConfig->GetPassword(), pList->AuthStr)) matchingDbConnection = pList->PtrDb; } @@ -3371,16 +3605,16 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso // Initialize new node in the linked list pList->PtrNext = 0; pList->Free = FALSE; - pList->Dsn = pDbConfig->Dsn; - pList->Uid = pDbConfig->Uid; - pList->AuthStr = pDbConfig->AuthStr; + pList->Dsn = pDbConfig->GetDsn(); //glt - will this assignment work? + pList->Uid = pDbConfig->GetUserID(); + pList->AuthStr = pDbConfig->GetPassword(); - pList->PtrDb = new wxDb(pDbConfig->Henv,FwdOnlyCursors); + pList->PtrDb = new wxDb(pDbConfig->GetHenv(), FwdOnlyCursors); bool opened = FALSE; if (!matchingDbConnection) - opened = pList->PtrDb->Open(pDbConfig->Dsn, pDbConfig->Uid, pDbConfig->AuthStr); + opened = pList->PtrDb->Open(pDbConfig->GetDsn(), pDbConfig->GetUserID(), pDbConfig->GetPassword()); else opened = pList->PtrDb->Open(matchingDbConnection);