diff --git a/src/common/db.cpp b/src/common/db.cpp index 0c87c849c8..1dd06a445e 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -45,7 +45,7 @@ #if wxMAJOR_VERSION == 2 #ifdef __GNUG__ - #pragma implementation "db.h" + #pragma implementation "db.h" #endif #endif @@ -138,21 +138,22 @@ typedef struct } wxDbTablePrivilegeInfo; #endif + /********** wxDbColFor Constructor **********/ wxDbColFor::wxDbColFor() { - s_Field = ""; + s_Field = ""; int i; for (i=0;i<7;i++) { s_Format[i] = ""; - s_Amount[i] = ""; - i_Amount[i] = 0; + s_Amount[i] = ""; + i_Amount[i] = 0; } - i_Nation = 0; // 0=EU, 1=UK, 2=International, 3=US + 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 + Format(1,DB_DATA_TYPE_VARCHAR,0,0,0); // the Function that does the work } // wxDbColFor::wxDbColFor() @@ -167,19 +168,20 @@ int wxDbColFor::Format(int Nation,int dbDataType,SWORD sqlDataType,short columnS // -- 19991224 : mj10777@gmx.net : Create // There is still a lot of work to do here, but it is a start // It handles all the basic data-types that I have run into up to now - // The main work will have be with Dates and float Formatting (US 1,000.00 ; EU 1.000,00) - // There are wxWindow plans for locale support and the new wxDateTime. - // - if they define some constants (wxEUROPEAN) that can be gloably used, + // The main work will have be with Dates and float Formatting + // (US 1,000.00 ; EU 1.000,00) + // There are wxWindow plans for locale support and the new wxDateTime. If + // they define some constants (wxEUROPEAN) that can be gloably used, // they should be used here. // ---------------------------------------------------------------------------------------- - // There should also be a Function to scan in a string to fill the variable + // There should also be a function to scan in a string to fill the variable // ---------------------------------------------------------------------------------------- wxString Temp0; - i_Nation = Nation; // 0 = timestamp , 1=EU, 2=UK, 3=International, 4=US + i_Nation = Nation; // 0 = timestamp , 1=EU, 2=UK, 3=International, 4=US i_dbDataType = dbDataType; i_sqlDataType = sqlDataType; - s_Field.Printf(wxT("%s%d"),s_Amount[1].c_str(),i_Amount[1]); // OK for VARCHAR, INTEGER and FLOAT - if (i_dbDataType == 0) // Filter unsupported dbDataTypes + s_Field.Printf(wxT("%s%d"),s_Amount[1].c_str(),i_Amount[1]); // OK for VARCHAR, INTEGER and FLOAT + if (i_dbDataType == 0) // Filter unsupported dbDataTypes { if ((i_sqlDataType == SQL_VARCHAR) || (i_sqlDataType == SQL_LONGVARCHAR)) i_dbDataType = DB_DATA_TYPE_VARCHAR; @@ -199,17 +201,17 @@ int wxDbColFor::Format(int Nation,int dbDataType,SWORD sqlDataType,short columnS switch(i_dbDataType) // -A-> Still a lot of proper formatting to do { case DB_DATA_TYPE_VARCHAR: - s_Field = "%s"; // + s_Field = "%s"; break; case DB_DATA_TYPE_INTEGER: - s_Field = "%d"; // + s_Field = "%d"; break; case DB_DATA_TYPE_FLOAT: if (decimalDigits == 0) decimalDigits = 2; Temp0 = "%"; Temp0.Printf(wxT("%s%d.%d"),Temp0.c_str(),columnSize,decimalDigits); - s_Field.Printf(wxT("%sf"),Temp0.c_str()); // + s_Field.Printf(wxT("%sf"),Temp0.c_str()); break; case DB_DATA_TYPE_DATE: if (i_Nation == 0) // timestamp YYYY-MM-DD HH:MM:SS.SSS (tested for SYBASE) @@ -234,7 +236,7 @@ int wxDbColFor::Format(int Nation,int dbDataType,SWORD sqlDataType,short columnS } break; default: - s_Field.Printf(wxT("-E-> unknown Format(%d)-sql(%d)"),dbDataType,sqlDataType); // + s_Field.Printf(wxT("Unknown Format(%d)-SQL(%d)"),dbDataType,sqlDataType); // break; }; return TRUE; @@ -400,8 +402,8 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) // SQL_INTEGER type name = 'LONG', Precision = 10 // VARCHAR = Variable length character string - if (! getDataTypeInfo(SQL_VARCHAR, typeInfVarchar)) - if (! getDataTypeInfo(SQL_CHAR, typeInfVarchar)) + if (!getDataTypeInfo(SQL_VARCHAR, typeInfVarchar)) + if (!getDataTypeInfo(SQL_CHAR, typeInfVarchar)) return(FALSE); else typeInfVarchar.FsqlType = SQL_CHAR; @@ -409,12 +411,12 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) typeInfVarchar.FsqlType = SQL_VARCHAR; // Float - if (! getDataTypeInfo(SQL_DOUBLE, typeInfFloat)) + if (!getDataTypeInfo(SQL_DOUBLE,typeInfFloat)) - if (! getDataTypeInfo(SQL_REAL, typeInfFloat)) - if (! getDataTypeInfo(SQL_FLOAT, typeInfFloat)) - if (! getDataTypeInfo(SQL_DECIMAL, typeInfFloat)) - if (! getDataTypeInfo(SQL_NUMERIC, typeInfFloat)) + if (!getDataTypeInfo(SQL_REAL,typeInfFloat)) + if (!getDataTypeInfo(SQL_FLOAT,typeInfFloat)) + if (!getDataTypeInfo(SQL_DECIMAL,typeInfFloat)) + if (!getDataTypeInfo(SQL_NUMERIC,typeInfFloat)) return(FALSE); else typeInfFloat.FsqlType = SQL_NUMERIC; @@ -429,10 +431,10 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) // Integer - if (! getDataTypeInfo(SQL_INTEGER, typeInfInteger)) - // If SQL_INTEGER is not supported, use the floating point - // data type to store integers as well as floats - if (! getDataTypeInfo(typeInfFloat.FsqlType, typeInfInteger)) + if (!getDataTypeInfo(SQL_INTEGER, typeInfInteger)) + // If SQL_INTEGER is not supported, use the floating point + // data type to store integers as well as floats + if (!getDataTypeInfo(typeInfFloat.FsqlType, typeInfInteger)) return(FALSE); else typeInfInteger.FsqlType = typeInfFloat.FsqlType; @@ -442,14 +444,14 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) // Date/Time if (Dbms() != dbmsDBASE) { - if (! getDataTypeInfo(SQL_TIMESTAMP, typeInfDate)) + if (! getDataTypeInfo(SQL_TIMESTAMP,typeInfDate)) return(FALSE); else typeInfDate.FsqlType = SQL_TIMESTAMP; } else { - if (! getDataTypeInfo(SQL_DATE, typeInfDate)) + if (!getDataTypeInfo(SQL_DATE,typeInfDate)) return(FALSE); else typeInfDate.FsqlType = SQL_DATE; @@ -842,15 +844,15 @@ bool wxDb::getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo) return(DispAllErrors(henv, hdbc, hstmt)); // Fetch the record if ((retcode = SQLFetch(hstmt)) != SQL_SUCCESS) - { + { #ifdef DBDEBUG_CONSOLE - if (retcode == SQL_NO_DATA_FOUND) - cout << "SQL_NO_DATA_FOUND fetching inf. about data type." << endl; + if (retcode == SQL_NO_DATA_FOUND) + cout << "SQL_NO_DATA_FOUND fetching inf. about data type." << endl; #endif - DispAllErrors(henv, hdbc, hstmt); - SQLFreeStmt(hstmt, SQL_CLOSE); - return(FALSE); - } + DispAllErrors(henv, hdbc, hstmt); + SQLFreeStmt(hstmt, SQL_CLOSE); + return(FALSE); + } // Obtain columns from the record if (SQLGetData(hstmt, 1, SQL_C_CHAR, (UCHAR*) structSQLTypeInfo.TypeName, DB_TYPE_NAME_LEN, &cbRet) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc, hstmt)); @@ -860,19 +862,22 @@ bool wxDb::getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo) #if OLD_GETCOLUMNS // BJO 991209 if (Dbms() == dbmsMY_SQL) - { + { if (!wxStrcmp(structSQLTypeInfo.TypeName, "middleint")) wxStrcpy(structSQLTypeInfo.TypeName, "mediumint"); if (!wxStrcmp(structSQLTypeInfo.TypeName, "middleint unsigned")) wxStrcpy(structSQLTypeInfo.TypeName, "mediumint unsigned"); if (!wxStrcmp(structSQLTypeInfo.TypeName, "integer")) wxStrcpy(structSQLTypeInfo.TypeName, "int"); if (!wxStrcmp(structSQLTypeInfo.TypeName, "integer unsigned")) wxStrcpy(structSQLTypeInfo.TypeName, "int unsigned"); if (!wxStrcmp(structSQLTypeInfo.TypeName, "middleint")) wxStrcpy(structSQLTypeInfo.TypeName, "mediumint"); if (!wxStrcmp(structSQLTypeInfo.TypeName, "varchar")) wxStrcpy(structSQLTypeInfo.TypeName, "char"); - } + } // BJO 20000427 : OpenLink driver if (!wxStrncmp(dbInf.driverName, "oplodbc", 7) || - !wxStrncmp(dbInf.driverName, "OLOD", 4)) - if (!wxStrcmp(structSQLTypeInfo.TypeName, "double precision")) wxStrcpy(structSQLTypeInfo.TypeName, "real"); + !wxStrncmp(dbInf.driverName, "OLOD", 4)) + { + if (!wxStrcmp(structSQLTypeInfo.TypeName, "double precision")) + wxStrcpy(structSQLTypeInfo.TypeName, "real"); + } #endif if (SQLGetData(hstmt, 3, SQL_C_LONG, (UCHAR*) &structSQLTypeInfo.Precision, 0, &cbRet) != SQL_SUCCESS) @@ -1025,7 +1030,6 @@ bool wxDb::GetNextError(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) /********** wxDb::DispNextError() **********/ void wxDb::DispNextError(void) { -// char odbcErrMsg[DB_MAX_ERROR_MSG_LEN]; wxString odbcErrMsg; odbcErrMsg.sprintf("SQL State = %s\nNative Error Code = %li\nError Message = %s\n", sqlState, nativeError, errorMsg); @@ -1045,7 +1049,6 @@ void wxDb::DispNextError(void) wxLogDebug(odbcErrMsg,wxT("ODBC DEBUG MESSAGE")); #endif // __WXDEBUG__ - } // wxDb::DispNextError() @@ -1268,7 +1271,6 @@ int wxDb::TranslateSqlState(const wxChar *SQLState) /********** wxDb::Grant() **********/ bool wxDb::Grant(int privileges, const char *tableName, const char *userList) { -// char sqlStmt[DB_MAX_STATEMENT_LEN]; wxString sqlStmt; // Build the grant statement @@ -1322,7 +1324,6 @@ bool wxDb::Grant(int privileges, const char *tableName, const char *userList) /********** wxDb::CreateView() **********/ bool wxDb::CreateView(const char *viewName, const char *colList, const char *pSqlStmt, bool attemptDrop) { -// char sqlStmt[DB_MAX_STATEMENT_LEN]; wxString sqlStmt; // Drop the view first @@ -1495,8 +1496,8 @@ int wxDb::GetKeyFields(char *tableName, wxDbColInf* colInf, int noCols) for (i=0;iuid' - // userID != "" ... UserID set equal to 'userID' - // - // NOTE: ALL column bindings associated with this wxDb instance are unbound - // by this function. This function should use its own wxDb instance - // to avoid undesired unbinding of columns. - +// +// 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 +// columns stored in the returned wxDbColInf is set in '*numCols' +// +// userID is evaluated in the following manner: +// userID == NULL ... UserID is ignored +// userID == "" ... UserID set equal to 'this->uid' +// userID != "" ... UserID set equal to 'userID' +// +// NOTE: ALL column bindings associated with this wxDb instance are unbound +// by this function. This function should use its own wxDb instance +// to avoid undesired unbinding of columns. { - SWORD noCols = 0; - int colNo = 0; - wxDbColInf *colInf = 0; - - RETCODE retcode; - SDWORD cb; - - wxString UserID; - wxString TableName; - - if (userID) + SWORD noCols = 0; + int colNo = 0; + wxDbColInf *colInf = 0; + + RETCODE retcode; + SDWORD cb; + + wxString UserID; + wxString TableName; + + if (userID) { - if (!wxStrlen(userID)) - UserID = uid; - else - UserID = userID; + if (!wxStrlen(userID)) + UserID = uid; + else + UserID = userID; } - else - UserID = ""; - - // dBase does not use user names, and some drivers fail if you try to pass one - if (Dbms() == dbmsDBASE) - UserID = ""; - - // Oracle user names may only be in uppercase, so force - // the name to uppercase - if (Dbms() == dbmsORACLE) - UserID = UserID.Upper(); - - // Pass 1 - Determine how many columns there are. - // Pass 2 - Allocate the wxDbColInf array and fill in - // the array with the column information. - int pass; - for (pass = 1; pass <= 2; pass++) + else + UserID = ""; + + // dBase does not use user names, and some drivers fail if you try to pass one + if (Dbms() == dbmsDBASE) + UserID = ""; + + // Oracle user names may only be in uppercase, so force + // the name to uppercase + if (Dbms() == dbmsORACLE) + UserID = UserID.Upper(); + + // Pass 1 - Determine how many columns there are. + // Pass 2 - Allocate the wxDbColInf array and fill in + // the array with the column information. + int pass; + for (pass = 1; pass <= 2; pass++) { - if (pass == 2) + if (pass == 2) { - if (noCols == 0) // Probably a bogus table name(s) - break; - // Allocate n wxDbColInf objects to hold the column information - colInf = new wxDbColInf[noCols+1]; - if (!colInf) - break; - // Mark the end of the array - wxStrcpy(colInf[noCols].tableName, wxT("")); - wxStrcpy(colInf[noCols].colName, wxT("")); - colInf[noCols].sqlDataType = 0; + if (noCols == 0) // Probably a bogus table name(s) + break; + // Allocate n wxDbColInf objects to hold the column information + colInf = new wxDbColInf[noCols+1]; + if (!colInf) + break; + // Mark the end of the array + wxStrcpy(colInf[noCols].tableName, wxT("")); + wxStrcpy(colInf[noCols].colName, wxT("")); + colInf[noCols].sqlDataType = 0; } - - TableName = tableName; - // Oracle table names are uppercase only, so force - // the name to uppercase just in case programmer forgot to do this - if (Dbms() == dbmsORACLE) - TableName = TableName.Upper(); - - SQLFreeStmt(hstmt, SQL_CLOSE); - - // MySQL and Access cannot accept a user name when looking up column names, so we - // use the call below that leaves out the user name - if (wxStrcmp(UserID.c_str(),wxT("")) && - Dbms() != dbmsMY_SQL && - Dbms() != dbmsACCESS) + + TableName = tableName; + // Oracle table names are uppercase only, so force + // the name to uppercase just in case programmer forgot to do this + if (Dbms() == dbmsORACLE) + TableName = TableName.Upper(); + + SQLFreeStmt(hstmt, SQL_CLOSE); + + // MySQL and Access cannot accept a user name when looking up column names, so we + // use the call below that leaves out the user name + if (wxStrcmp(UserID.c_str(),wxT("")) && + Dbms() != dbmsMY_SQL && + Dbms() != dbmsACCESS) { - retcode = SQLColumns(hstmt, - NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, - NULL, 0); // All columns + retcode = SQLColumns(hstmt, + NULL, 0, // All qualifiers + (UCHAR *) UserID.c_str(), SQL_NTS, // Owner + (UCHAR *) TableName.c_str(), SQL_NTS, + NULL, 0); // All columns } - else + else { - retcode = SQLColumns(hstmt, - NULL, 0, // All qualifiers - NULL, 0, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, - NULL, 0); // All columns + retcode = SQLColumns(hstmt, + NULL, 0, // All qualifiers + NULL, 0, // Owner + (UCHAR *) TableName.c_str(), SQL_NTS, + NULL, 0); // All columns } - if (retcode != SQL_SUCCESS) + if (retcode != SQL_SUCCESS) { // Error occured, abort - DispAllErrors(henv, hdbc, hstmt); - if (colInf) - delete [] colInf; - SQLFreeStmt(hstmt, SQL_CLOSE); - if (numCols) - *numCols = 0; - return(0); + DispAllErrors(henv, hdbc, hstmt); + if (colInf) + delete [] colInf; + SQLFreeStmt(hstmt, SQL_CLOSE); + if (numCols) + *numCols = 0; + return(0); } - + while ((retcode = SQLFetch(hstmt)) == SQL_SUCCESS) { if (pass == 1) // First pass, just add up the number of columns @@ -2154,151 +2161,141 @@ wxDbColInf *wxDb::GetColumns(char *tableName, int *numCols, const char *userID) colInf[colNo].PkTableName[0] = 0; // Tablenames where Primary Key is used as a Foreign Key colInf[colNo].FkCol = 0; // Foreign key column 0=No; 1= First Key, 2 = Second Key etc. colInf[colNo].FkTableName[0] = 0; // Foreign key table name - -#ifdef _IODBC_ - // IODBC returns the columnSize in bufferLength.. (bug) - colInf[colNo].columnSize = colInf[colNo].bufferLength; + +#ifdef _IODBC_ + // IODBC returns the columnSize in bufferLength.. (bug) + colInf[colNo].columnSize = colInf[colNo].bufferLength; #endif - - // Determine the wxDb data type that is used to represent the native data type of this data source - colInf[colNo].dbDataType = 0; - // Get the intern datatype - switch (colInf[colNo].sqlDataType) - { - case SQL_VARCHAR: - case SQL_CHAR: - colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; - break; - - case SQL_TINYINT: - case SQL_SMALLINT: - case SQL_INTEGER: - colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER; - break; - case SQL_DOUBLE: - case SQL_DECIMAL: - case SQL_NUMERIC: - case SQL_FLOAT: - case SQL_REAL: - colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT; - break; - case SQL_DATE: - colInf[colNo].dbDataType = DB_DATA_TYPE_DATE; - break; - - + + // Determine the wxDb data type that is used to represent the native data type of this data source + colInf[colNo].dbDataType = 0; + // Get the intern datatype + switch (colInf[colNo].sqlDataType) + { + case SQL_VARCHAR: + case SQL_CHAR: + colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; + break; + + case SQL_TINYINT: + case SQL_SMALLINT: + case SQL_INTEGER: + colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER; + break; + case SQL_DOUBLE: + case SQL_DECIMAL: + case SQL_NUMERIC: + case SQL_FLOAT: + case SQL_REAL: + colInf[colNo].dbDataType = DB_DATA_TYPE_FLOAT; + break; + case SQL_DATE: + colInf[colNo].dbDataType = DB_DATA_TYPE_DATE; + break; #ifdef __WXDEBUG__ - default: - wxString errMsg; - errMsg.sprintf("SQL Data type %d currently not supported by wxWindows", colInf[colNo].sqlDataType); - wxLogDebug(errMsg,wxT("ODBC DEBUG MESSAGE")); -#endif - } - - - + default: + wxString errMsg; + errMsg.sprintf("SQL Data type %d currently not supported by wxWindows", colInf[colNo].sqlDataType); + wxLogDebug(errMsg,wxT("ODBC DEBUG MESSAGE")); +#endif + } colNo++; } } } if (retcode != SQL_NO_DATA_FOUND) - { // Error occured, abort + { // Error occured, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) - delete [] colInf; + delete [] colInf; SQLFreeStmt(hstmt, SQL_CLOSE); if (numCols) - *numCols = 0; + *numCols = 0; return(0); - } + } } - - SQLFreeStmt(hstmt, SQL_CLOSE); - - // Store Primary and Foreign Keys - GetKeyFields(tableName,colInf,noCols); - - - - /////////////////////////////////////////////////////////////////////////// - // Now sort the the columns in order to make them appear in the right order - /////////////////////////////////////////////////////////////////////////// - - // Build a generic SELECT statement which returns 0 rows - wxString Stmt; - - Stmt.sprintf("select * from %s where 0=1", tableName); - - // Execute query - if (SQLExecDirect(hstmt, (UCHAR FAR *) Stmt.c_str(), SQL_NTS) != SQL_SUCCESS) - { - DispAllErrors(henv, hdbc, hstmt); - return NULL; - } - - // Get the number of result columns - if (SQLNumResultCols (hstmt, &noCols) != SQL_SUCCESS) - { - DispAllErrors(henv, hdbc, hstmt); - return NULL; - } - - if (noCols == 0) // Probably a bogus table name - return NULL; + + SQLFreeStmt(hstmt, SQL_CLOSE); + + // Store Primary and Foreign Keys + GetKeyFields(tableName,colInf,noCols); - // Get the name - int i; - short colNum; - UCHAR name[100]; - SWORD Sword; - SDWORD Sdword; - for (colNum = 0; colNum < noCols; colNum++) + /////////////////////////////////////////////////////////////////////////// + // Now sort the the columns in order to make them appear in the right order + /////////////////////////////////////////////////////////////////////////// + + // Build a generic SELECT statement which returns 0 rows + wxString Stmt; + + Stmt.sprintf("select * from %s where 0=1", tableName); + + // Execute query + if (SQLExecDirect(hstmt, (UCHAR FAR *) Stmt.c_str(), SQL_NTS) != SQL_SUCCESS) + { + DispAllErrors(henv, hdbc, hstmt); + return NULL; + } + + // Get the number of result columns + if (SQLNumResultCols (hstmt, &noCols) != SQL_SUCCESS) + { + DispAllErrors(henv, hdbc, hstmt); + return NULL; + } + + if (noCols == 0) // Probably a bogus table name + return NULL; + + // Get the name + int i; + short colNum; + UCHAR name[100]; + SWORD Sword; + SDWORD Sdword; + for (colNum = 0; colNum < noCols; colNum++) { - if (SQLColAttributes(hstmt,colNum+1, SQL_COLUMN_NAME, - name, sizeof(name), - &Sword, &Sdword) != SQL_SUCCESS) - { - DispAllErrors(henv, hdbc, hstmt); - return NULL; - } - - wxString Name1 = name; - Name1 = Name1.Upper(); - - // Where is this name in the array ? - for (i = colNum ; i < noCols ; i++) - { - wxString Name2 = colInf[i].colName; - Name2 = Name2.Upper(); - if (Name2 == Name1) - { - if (colNum != i) // swap to sort - { - wxDbColInf tmpColInf = colInf[colNum]; - colInf[colNum] = colInf[i]; - colInf[i] = tmpColInf; - } - break; - } - } + if (SQLColAttributes(hstmt,colNum+1, SQL_COLUMN_NAME, + name, sizeof(name), + &Sword, &Sdword) != SQL_SUCCESS) + { + DispAllErrors(henv, hdbc, hstmt); + return NULL; + } + + wxString Name1 = name; + Name1 = Name1.Upper(); + + // Where is this name in the array ? + for (i = colNum ; i < noCols ; i++) + { + wxString Name2 = colInf[i].colName; + Name2 = Name2.Upper(); + if (Name2 == Name1) + { + if (colNum != i) // swap to sort + { + wxDbColInf tmpColInf = colInf[colNum]; + colInf[colNum] = colInf[i]; + colInf[i] = tmpColInf; + } + break; + } + } } - SQLFreeStmt(hstmt, SQL_CLOSE); + SQLFreeStmt(hstmt, SQL_CLOSE); - /////////////////////////////////////////////////////////////////////////// - // End sorting - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // End sorting + /////////////////////////////////////////////////////////////////////////// - - - - if (numCols) - *numCols = noCols; - return colInf; - + if (numCols) + *numCols = noCols; + return colInf; + } // wxDb::GetColumns() -#endif +#endif // #else OLD_GETCOLUMNS /********** wxDb::GetColumnCount() **********/ @@ -2363,7 +2360,7 @@ int wxDb::GetColumnCount(char *tableName, const char *userID) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // Owner + (UCHAR *) UserID.c_str(), SQL_NTS, // Owner (UCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } @@ -2430,7 +2427,6 @@ wxDbInf *wxDb::GetCatalog(char *userID) int pass; RETCODE retcode; SDWORD cb; -// char tblNameSave[DB_MAX_TABLE_NAME_LEN+1]; wxString tblNameSave; wxString UserID; @@ -2467,26 +2463,23 @@ wxDbInf *wxDb::GetCatalog(char *userID) // - Create the Cols array = NULL //------------------------------------------------------------- - for (pass = 1; pass <= 2; pass++) { SQLFreeStmt(hstmt, SQL_CLOSE); // Close if Open tblNameSave = wxT(""); if (wxStrcmp(UserID.c_str(),wxT("")) && - Dbms() != dbmsMY_SQL && - Dbms() != dbmsACCESS) + Dbms() != dbmsMY_SQL && + Dbms() != dbmsACCESS) { - retcode = SQLTables(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // User specified + (UCHAR *) UserID.c_str(), SQL_NTS, // User specified NULL, 0, // All tables NULL, 0); // All columns } else { - retcode = SQLTables(hstmt, NULL, 0, // All qualifiers NULL, 0, // User specified @@ -2501,10 +2494,9 @@ wxDbInf *wxDb::GetCatalog(char *userID) SQLFreeStmt(hstmt, SQL_CLOSE); return pDbInf; } - + while ((retcode = SQLFetch(hstmt)) == SQL_SUCCESS) // Table Information { - if (pass == 1) // First pass, just count the Tables { if (pDbInf->numTables == 0) @@ -2528,16 +2520,16 @@ wxDbInf *wxDb::GetCatalog(char *userID) (pDbInf->pTableInf+noTab)->pColInf = NULL; } noTab = 0; - } // if (pDbInf->pTableInf == NULL) // Has the Table Array been created + } // if (pDbInf->pTableInf == NULL) // Has the Table Array been created GetData( 3, SQL_C_CHAR, (UCHAR*) (pDbInf->pTableInf+noTab)->tableName, DB_MAX_TABLE_NAME_LEN+1, &cb); GetData( 4, SQL_C_CHAR, (UCHAR*) (pDbInf->pTableInf+noTab)->tableType, 30+1, &cb); GetData( 5, SQL_C_CHAR, (UCHAR*) (pDbInf->pTableInf+noTab)->tableRemarks, 254+1, &cb); - + noTab++; - } // if (pass == 2) We now know the amount of Tables - } // while ((retcode = SQLFetch(hstmt)) == SQL_SUCCESS) - } // for (pass = 1; pass <= 2; pass++) + } // if + } // while + } // for SQLFreeStmt(hstmt, SQL_CLOSE); // Query how many columns are in each table @@ -2545,7 +2537,9 @@ wxDbInf *wxDb::GetCatalog(char *userID) { (pDbInf->pTableInf+noTab)->numCols = GetColumnCount((pDbInf->pTableInf+noTab)->tableName,UserID); } + return pDbInf; + } // wxDb::GetCatalog() @@ -2610,7 +2604,7 @@ bool wxDb::Catalog(const char *userID, const char *fileName) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // User specified + (UCHAR *) UserID.c_str(), SQL_NTS, // User specified NULL, 0, // All tables NULL, 0); // All columns } @@ -2699,23 +2693,22 @@ bool wxDb::TableExists(const char *tableName, const char *userID, const char *ta { wxString UserID; wxString TableName; - + assert(tableName && wxStrlen(tableName)); - + if (Dbms() == dbmsDBASE) { - - wxString dbName; - if (tablePath && wxStrlen(tablePath)) - dbName.sprintf("%s\\%s.dbf",tablePath,tableName); - else - dbName.sprintf("%s.dbf",tableName); - - bool exists; - exists = wxFileExists(dbName.c_str()); - return exists; + wxString dbName; + if (tablePath && wxStrlen(tablePath)) + dbName.sprintf("%s\\%s.dbf",tablePath,tableName); + else + dbName.sprintf("%s.dbf",tableName); + + bool exists; + exists = wxFileExists(dbName.c_str()); + return exists; } - + if (userID) { if (!wxStrlen(userID)) @@ -2725,75 +2718,77 @@ bool wxDb::TableExists(const char *tableName, const char *userID, const char *ta } else UserID = ""; - + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); - + TableName = tableName; // Oracle table names are uppercase only, so force // the name to uppercase just in case programmer forgot to do this if (Dbms() == dbmsORACLE) TableName = TableName.Upper(); - + SQLFreeStmt(hstmt, SQL_CLOSE); RETCODE retcode; - + // MySQL and Access cannot accept a user name when looking up table names, so we // use the call below that leaves out the user name if (wxStrcmp(UserID,"") && - Dbms() != dbmsMY_SQL && - Dbms() != dbmsACCESS) + Dbms() != dbmsMY_SQL && + Dbms() != dbmsACCESS) { retcode = SQLTables(hstmt, - NULL, 0, // All qualifiers + NULL, 0, // All qualifiers (UCHAR *) UserID.c_str(), SQL_NTS, // All owners (UCHAR FAR *)TableName.c_str(), SQL_NTS, - NULL, 0); // All table types + NULL, 0); // All table types } else { retcode = SQLTables(hstmt, - NULL, 0, // All qualifiers - NULL, 0, // All owners + NULL, 0, // All qualifiers + NULL, 0, // All owners (UCHAR FAR *)TableName.c_str(), SQL_NTS, - NULL, 0); // All table types + NULL, 0); // All table types } if (retcode != SQL_SUCCESS) return(DispAllErrors(henv, hdbc, hstmt)); - + retcode = SQLFetch(hstmt); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { SQLFreeStmt(hstmt, SQL_CLOSE); return(DispAllErrors(henv, hdbc, hstmt)); } - + SQLFreeStmt(hstmt, SQL_CLOSE); - return(TRUE); + return(TRUE); + } // wxDb::TableExists() + #if EXPERIMENTAL_WXDB_FUNCTIONS // will be added in 2.4 /********** wxDB::TablePrivileges() **********/ bool wxDB::TablePrivileges(const char *tableName, const char* priv, const char *userID, const char *tablePath) { - wxDbTablePrivilegeInfo result; - SDWORD cbRetVal; - RETCODE retcode; - - //We probably need to be able to dynamically set this based on - //the driver type, and state. - char curRole[]="public"; - - //Prologue here similar to db::TableExists() + wxDbTablePrivilegeInfo result; + SDWORD cbRetVal; + RETCODE retcode; + + //We probably need to be able to dynamically set this based on + //the driver type, and state. + char curRole[]="public"; + + //Prologue here similar to db::TableExists() wxString UserID; wxString TableName; - + assert(tableName && wxStrlen(tableName)); - + if (userID) { if (!wxStrlen(userID)) @@ -2803,68 +2798,70 @@ bool wxDB::TablePrivileges(const char *tableName, const char* priv, } else UserID = ""; - + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); - + TableName = tableName; // Oracle table names are uppercase only, so force // the name to uppercase just in case programmer forgot to do this if (Dbms() == dbmsORACLE) TableName = TableName.Upper(); - + SQLFreeStmt(hstmt, SQL_CLOSE); - + retcode = SQLTablePrivileges(hstmt, NULL, 0, // All qualifiers NULL, 0, // All owners (UCHAR FAR *)TableName.GetData(), SQL_NTS); - + #ifdef DBDEBUG_CONSOLE fprintf(stderr ,"SQLTablePrivileges() returned %i \n",retcode); #endif retcode = SQLBindCol (hstmt, 1, SQL_C_CHAR , &result.tableQual, 128, &cbRetVal); - + retcode = SQLBindCol (hstmt, 2, SQL_C_CHAR , &result.tableOwner, 128, &cbRetVal); - + retcode = SQLBindCol (hstmt, 3, SQL_C_CHAR , &result.tableName, 128, &cbRetVal); - + retcode = SQLBindCol (hstmt, 4, SQL_C_CHAR , &result.grantor, 128, &cbRetVal); - + retcode = SQLBindCol (hstmt, 5, SQL_C_CHAR , &result.grantee, 128, &cbRetVal); - + retcode = SQLBindCol (hstmt, 6, SQL_C_CHAR , &result.privilege, 128, &cbRetVal); - + retcode = SQLBindCol (hstmt, 7, SQL_C_CHAR , &result.grantable, 3, &cbRetVal); - + retcode = SQLFetch(hstmt); while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) - { + { #ifdef DBDEBUG_CONSOLE - fprintf(stderr,"Scanning %s privilege on table %s.%s granted by %s to %s\n", - result.privilege,result.tabowner,result.tabname, - result.grantor, result.grantee); + fprintf(stderr,"Scanning %s privilege on table %s.%s granted by %s to %s\n", + result.privilege,result.tabowner,result.tabname, + result.grantor, result.grantee); #endif - if (UserID.IsSameAs(result.tableOwner,false) ) - return TRUE; - - if (UserID.IsSameAs(result.grantee,false) && - !strcmp(result.privilege,priv)) - return TRUE; - - if (!strcmp(result.grantee,curRole) && - !strcmp(result.privilege,priv)) - return TRUE; - - retcode = SQLFetch(hstmt); + if (UserID.IsSameAs(result.tableOwner,false) ) + return TRUE; + + if (UserID.IsSameAs(result.grantee,false) && + !strcmp(result.privilege,priv)) + return TRUE; + + if (!strcmp(result.grantee,curRole) && + !strcmp(result.privilege,priv)) + return TRUE; + + retcode = SQLFetch(hstmt); } - + return FALSE; + } // wxDB::TablePrivileges #endif + /********** wxDb::SetSqlLogging() **********/ bool wxDb::SetSqlLogging(wxDbSqlLogState state, const char *filename, bool append) { @@ -2948,6 +2945,7 @@ wxDBMS wxDb::Dbms(void) * * SYBASE (Enterprise) * - If a column is part of the Primary Key, the column cannot be NULL + * - Maximum row size is somewhere in the neighborhood of 1920 bytes * * MY_SQL * - If a column is part of the Primary Key, the column cannot be NULL @@ -2955,10 +2953,11 @@ wxDBMS wxDb::Dbms(void) * - Columns that are part of primary or secondary keys must be defined as being NOT NULL * when they are created. Some code is added in ::CreateIndex to try to adjust the * column definition if it is not defined correctly, but it is experimental + * - Does not support sub-queries in SQL statements * * POSTGRES * - Does not support the keywords 'ASC' or 'DESC' as of release v6.5.0 - * + * - Does not support sub-queries in SQL statements * */ { @@ -2977,12 +2976,13 @@ wxDBMS wxDb::Dbms(void) // BJO 20000427 : The "SQL Server" string is also returned by SQLServer when // connected through an OpenLink driver. // Is it also returned by Sybase Adapatitve server? - // OpenLink driver name is OLOD3032.DLL for msw and oplodbc.so for unix + // OpenLink driver name is OLOD3032.DLL for msw and oplodbc.so for unix if (!wxStricmp(dbInf.dbmsName,"SQL Server")) + { if (!wxStrncmp(dbInf.driverName, "oplodbc", 7) || !wxStrncmp(dbInf.driverName, "OLOD", 4)) - return dbmsMS_SQL_SERVER; else return dbmsSYBASE_ASE; - + return dbmsMS_SQL_SERVER; else return dbmsSYBASE_ASE; + } if (!wxStricmp(dbInf.dbmsName,"Microsoft SQL Server")) return(dbmsMS_SQL_SERVER); @@ -2995,7 +2995,6 @@ wxDBMS wxDb::Dbms(void) if (!wxStricmp(baseName,"Informix")) return(dbmsINFORMIX); - baseName[6] = 0; if (!wxStricmp(baseName,"Oracle")) return(dbmsORACLE); @@ -3011,6 +3010,7 @@ wxDBMS wxDb::Dbms(void) return(dbmsDBASE); return(dbmsUNIDENTIFIED); + } // wxDb::Dbms() @@ -3027,7 +3027,7 @@ 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->Dsn, pList->Dsn))) // Found a free connection { pList->Free = FALSE; return(pList->PtrDb); @@ -3045,7 +3045,7 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso pList->PtrNext->PtrPrev = pList; pList = pList->PtrNext; } - else // Empty list + else // Empty list { // Create the first node on the list pList = PtrBegDbList = new wxDbList; @@ -3088,7 +3088,7 @@ bool WXDLLEXPORT wxDbFreeConnection(wxDb *pDb) // Scan the linked list searching for the database connection for (pList = PtrBegDbList; pList; pList = pList->PtrNext) { - if (pList->PtrDb == pDb) // Found it, now free it!!! + if (pList->PtrDb == pDb) // Found it, now free it!!! return (pList->Free = TRUE); } @@ -3151,7 +3151,6 @@ bool wxDbSqlLog(wxDbSqlLogState state, const wxChar *filename) } SQLLOGstate = state; -// wxStrcpy(SQLLOGfn,filename); SQLLOGfn = filename; return(TRUE); diff --git a/src/common/dbtable.cpp b/src/common/dbtable.cpp index 8ad1e48b62..8681f40a62 100644 --- a/src/common/dbtable.cpp +++ b/src/common/dbtable.cpp @@ -32,9 +32,9 @@ #include "wx/version.h" #if wxMAJOR_VERSION == 2 -# ifdef __GNUG__ -# pragma implementation "dbtable.h" -# endif + #ifdef __GNUG__ + #pragma implementation "dbtable.h" + #endif #endif #ifdef DBDEBUG_CONSOLE @@ -131,21 +131,21 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, wxStrcpy(tableName, tblName); // Table Name if (tblPath) wxStrcpy(tablePath, tblPath); // Table Path - used for dBase files - + if (qryTblName) // Name of the table/view to query wxStrcpy(queryTableName, qryTblName); else wxStrcpy(queryTableName, tblName); - + if (!pDb) return; - + pDb->incrementTableCount(); - + wxString s; tableID = ++lastTableID; s.sprintf("wxDbTable constructor (%-20s) tableID:[%6lu] pDb:[%p]", tblName,tableID,pDb); - + #ifdef __WXDEBUG__ wxTablesInUse *tableInUse; tableInUse = new wxTablesInUse(); @@ -154,17 +154,17 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, tableInUse->pDb = pDb; TablesInUse.Append(tableInUse); #endif - + pDb->WriteSqlLog(s.c_str()); - + // Grab the HENV and HDBC from the wxDb object henv = pDb->GetHENV(); hdbc = pDb->GetHDBC(); - + // Allocate space for column definitions if (noCols) colDefs = new wxDbColDef[noCols]; // Points to the first column defintion - + // Allocate statement handles for the table if (!queryOnly) { @@ -181,62 +181,64 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, // Allocate a separate statement handle for internal use if (SQLAllocStmt(hdbc, &hstmtInternal) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc); - + // Set the cursor type for the statement handles cursorType = SQL_CURSOR_STATIC; - + if (SQLSetStmtOption(hstmtInternal, SQL_CURSOR_TYPE, cursorType) != SQL_SUCCESS) - { + { // Check to see if cursor type is supported pDb->GetNextError(henv, hdbc, hstmtInternal); if (! wxStrcmp(pDb->sqlState, "01S02")) // Option Value Changed - { - + { // Datasource does not support static cursors. Driver // will substitute a cursor type. Call SQLGetStmtOption() // to determine which cursor type was selected. if (SQLGetStmtOption(hstmtInternal, SQL_CURSOR_TYPE, &cursorType) != SQL_SUCCESS) - pDb->DispAllErrors(henv, hdbc, hstmtInternal); + pDb->DispAllErrors(henv, hdbc, hstmtInternal); #ifdef DBDEBUG_CONSOLE cout << "Static cursor changed to: "; switch(cursorType) - { - case SQL_CURSOR_FORWARD_ONLY: - cout << "Forward Only"; break; - case SQL_CURSOR_STATIC: - cout << "Static"; break; - case SQL_CURSOR_KEYSET_DRIVEN: - cout << "Keyset Driven"; break; - case SQL_CURSOR_DYNAMIC: - cout << "Dynamic"; break; - } + { + case SQL_CURSOR_FORWARD_ONLY: + cout << "Forward Only"; + break; + case SQL_CURSOR_STATIC: + cout << "Static"; + break; + case SQL_CURSOR_KEYSET_DRIVEN: + cout << "Keyset Driven"; + break; + case SQL_CURSOR_DYNAMIC: + cout << "Dynamic"; + break; + } cout << endl << endl; #endif - - // BJO20000425 - if (pDb->FwdOnlyCursors() && cursorType != SQL_CURSOR_FORWARD_ONLY) - { - // Force the use of a forward only cursor... - cursorType = SQL_CURSOR_FORWARD_ONLY; - if (SQLSetStmtOption(hstmtInternal, SQL_CURSOR_TYPE, cursorType) != SQL_SUCCESS) - { - // Should never happen - pDb->GetNextError(henv, hdbc, hstmtInternal); - return; - } - } - } - else - { + // BJO20000425 + if (pDb->FwdOnlyCursors() && cursorType != SQL_CURSOR_FORWARD_ONLY) + { + // Force the use of a forward only cursor... + cursorType = SQL_CURSOR_FORWARD_ONLY; + if (SQLSetStmtOption(hstmtInternal, SQL_CURSOR_TYPE, cursorType) != SQL_SUCCESS) + { + // Should never happen + pDb->GetNextError(henv, hdbc, hstmtInternal); + return; + } + } + } + else + { pDb->DispNextError(); pDb->DispAllErrors(henv, hdbc, hstmtInternal); - } + } } #ifdef DBDEBUG_CONSOLE else cout << "Cursor Type set to STATIC" << endl << endl; #endif - + if (!queryOnly) { // Set the cursor type for the INSERT statement handle @@ -249,12 +251,12 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, if (SQLSetStmtOption(hstmtUpdate, SQL_CURSOR_TYPE, SQL_CURSOR_FORWARD_ONLY) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc, hstmtUpdate); } - + // Make the default cursor the active cursor hstmtDefault = GetNewCursor(FALSE,FALSE); assert(hstmtDefault); hstmt = *hstmtDefault; - + } // wxDbTable::wxDbTable() @@ -317,7 +319,6 @@ wxDbTable::~wxDbTable() if (hstmtUpdate) if (SQLFreeStmt(hstmtUpdate, SQL_DROP) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc); - } if (hstmtInternal) @@ -331,7 +332,6 @@ wxDbTable::~wxDbTable() if (hstmtCount) DeleteCursor(hstmtCount); - } // wxDbTable::~wxDbTable() @@ -359,36 +359,35 @@ bool wxDbTable::bindInsertParams(void) continue; switch(colDefs[i].DbDataType) { - - case DB_DATA_TYPE_VARCHAR: - fSqlType = pDb->GetTypeInfVarchar().FsqlType; - precision = colDefs[i].SzDataObj; - scale = 0; - colDefs[i].CbValue = SQL_NTS; - break; - case DB_DATA_TYPE_INTEGER: - fSqlType = pDb->GetTypeInfInteger().FsqlType; - precision = pDb->GetTypeInfInteger().Precision; - scale = 0; - colDefs[i].CbValue = 0; - break; - case DB_DATA_TYPE_FLOAT: - fSqlType = pDb->GetTypeInfFloat().FsqlType; - precision = pDb->GetTypeInfFloat().Precision; - scale = pDb->GetTypeInfFloat().MaximumScale; - // SQL Sybase Anywhere v5.5 returned a negative number for the - // MaxScale. This caused ODBC to kick out an error on ibscale. - // I check for this here and set the scale = precision. - //if (scale < 0) - // scale = (short) precision; - colDefs[i].CbValue = 0; - break; - case DB_DATA_TYPE_DATE: - fSqlType = pDb->GetTypeInfDate().FsqlType; - precision = pDb->GetTypeInfDate().Precision; - scale = 0; - colDefs[i].CbValue = 0; - break; + case DB_DATA_TYPE_VARCHAR: + fSqlType = pDb->GetTypeInfVarchar().FsqlType; + precision = colDefs[i].SzDataObj; + scale = 0; + colDefs[i].CbValue = SQL_NTS; + break; + case DB_DATA_TYPE_INTEGER: + fSqlType = pDb->GetTypeInfInteger().FsqlType; + precision = pDb->GetTypeInfInteger().Precision; + scale = 0; + colDefs[i].CbValue = 0; + break; + case DB_DATA_TYPE_FLOAT: + fSqlType = pDb->GetTypeInfFloat().FsqlType; + precision = pDb->GetTypeInfFloat().Precision; + scale = pDb->GetTypeInfFloat().MaximumScale; + // SQL Sybase Anywhere v5.5 returned a negative number for the + // MaxScale. This caused ODBC to kick out an error on ibscale. + // I check for this here and set the scale = precision. + //if (scale < 0) + // scale = (short) precision; + colDefs[i].CbValue = 0; + break; + case DB_DATA_TYPE_DATE: + fSqlType = pDb->GetTypeInfDate().FsqlType; + precision = pDb->GetTypeInfDate().Precision; + scale = 0; + colDefs[i].CbValue = 0; + break; } // Null values if (colDefs[i].Null) @@ -397,10 +396,12 @@ bool wxDbTable::bindInsertParams(void) colDefs[i].Null = FALSE; } - if (SQLBindParameter(hstmtInsert, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, - fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, - precision+1,&colDefs[i].CbValue) != SQL_SUCCESS) - return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); + if (SQLBindParameter(hstmtInsert, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, + fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, + precision+1,&colDefs[i].CbValue) != SQL_SUCCESS) + { + return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); + } } // Completed successfully @@ -415,7 +416,7 @@ bool wxDbTable::bindUpdateParams(void) assert(!queryOnly); if (queryOnly) return(FALSE); - + SWORD fSqlType = 0; UDWORD precision = 0; SWORD scale = 0; @@ -428,43 +429,45 @@ bool wxDbTable::bindUpdateParams(void) continue; switch(colDefs[i].DbDataType) { - case DB_DATA_TYPE_VARCHAR: - fSqlType = pDb->GetTypeInfVarchar().FsqlType; - precision = colDefs[i].SzDataObj; - scale = 0; - colDefs[i].CbValue = SQL_NTS; - break; - case DB_DATA_TYPE_INTEGER: - fSqlType = pDb->GetTypeInfInteger().FsqlType; - precision = pDb->GetTypeInfInteger().Precision; - scale = 0; - colDefs[i].CbValue = 0; - break; - case DB_DATA_TYPE_FLOAT: - fSqlType = pDb->GetTypeInfFloat().FsqlType; - precision = pDb->GetTypeInfFloat().Precision; - scale = pDb->GetTypeInfFloat().MaximumScale; - // SQL Sybase Anywhere v5.5 returned a negative number for the - // MaxScale. This caused ODBC to kick out an error on ibscale. - // I check for this here and set the scale = precision. - //if (scale < 0) - // scale = (short) precision; - colDefs[i].CbValue = 0; - break; - case DB_DATA_TYPE_DATE: - fSqlType = pDb->GetTypeInfDate().FsqlType; - precision = pDb->GetTypeInfDate().Precision; - scale = 0; - colDefs[i].CbValue = 0; - break; + case DB_DATA_TYPE_VARCHAR: + fSqlType = pDb->GetTypeInfVarchar().FsqlType; + precision = colDefs[i].SzDataObj; + scale = 0; + colDefs[i].CbValue = SQL_NTS; + break; + case DB_DATA_TYPE_INTEGER: + fSqlType = pDb->GetTypeInfInteger().FsqlType; + precision = pDb->GetTypeInfInteger().Precision; + scale = 0; + colDefs[i].CbValue = 0; + break; + case DB_DATA_TYPE_FLOAT: + fSqlType = pDb->GetTypeInfFloat().FsqlType; + precision = pDb->GetTypeInfFloat().Precision; + scale = pDb->GetTypeInfFloat().MaximumScale; + // SQL Sybase Anywhere v5.5 returned a negative number for the + // MaxScale. This caused ODBC to kick out an error on ibscale. + // I check for this here and set the scale = precision. + //if (scale < 0) + // scale = (short) precision; + colDefs[i].CbValue = 0; + break; + case DB_DATA_TYPE_DATE: + fSqlType = pDb->GetTypeInfDate().FsqlType; + precision = pDb->GetTypeInfDate().Precision; + scale = 0; + colDefs[i].CbValue = 0; + break; + } + + if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, + fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, + precision+1, &colDefs[i].CbValue) != SQL_SUCCESS) + { + return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate)); } - - if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, - fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, - precision+1, &colDefs[i].CbValue) != SQL_SUCCESS) - return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate)); } - + // Completed successfully return(TRUE); @@ -479,11 +482,13 @@ bool wxDbTable::bindCols(HSTMT cursor) // Bind each column of the table to a memory address for fetching data int i; for (i = 0; i < noCols; i++) - { - if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj, - colDefs[i].SzDataObj, &cb) != SQL_SUCCESS) - return (pDb->DispAllErrors(henv, hdbc, cursor)); - } + { + if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj, + colDefs[i].SzDataObj, &cb) != SQL_SUCCESS) + { + return (pDb->DispAllErrors(henv, hdbc, cursor)); + } + } // Completed successfully return(TRUE); @@ -504,10 +509,12 @@ bool wxDbTable::getRec(UWORD fetchType) retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) + { if (retcode == SQL_NO_DATA_FOUND) return(FALSE); else return(pDb->DispAllErrors(henv, hdbc, hstmt)); + } } else { @@ -568,29 +575,31 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const char * // Set the SQL SELECT string if (queryType != DB_SELECT_STATEMENT) // A select statement was not passed in, - { // so generate a select statement. + { // so generate a select statement. BuildSelectStmt(sqlStmt, queryType, distinct); pDb->WriteSqlLog(sqlStmt); - } else wxStrcpy(sqlStmt, pSqlStmt); + } + else + wxStrcpy(sqlStmt, pSqlStmt); SQLFreeStmt(hstmt, SQL_CLOSE); if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt, SQL_NTS) == SQL_SUCCESS) - return(TRUE); + return(TRUE); else - { + { pDb->DispAllErrors(henv, hdbc, hstmt); return(FALSE); - } + } // Make sure the cursor is closed first if (! CloseCursor(hstmt)) - return(FALSE); + return(FALSE); // Execute the SQL SELECT statement int retcode; retcode = SQLExecDirect(hstmt, (UCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt : sqlStmt), SQL_NTS); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) - return(pDb->DispAllErrors(henv, hdbc, hstmt)); + return(pDb->DispAllErrors(henv, hdbc, hstmt)); // Completed successfully return(TRUE); @@ -639,10 +648,10 @@ bool wxDbTable::Open(void) if (!bindCols(*hstmtDefault)) // Selects return(FALSE); - + if (!bindCols(hstmtInternal)) // Internal use only return(FALSE); - + /* * Do NOT bind the hstmtCount cursor!!! */ @@ -664,7 +673,7 @@ bool wxDbTable::Open(void) needComma = FALSE; sqlStmt += ") VALUES ("; - int insertableCount = 0; + int insertableCount = 0; for (i = 0; i < noCols; i++) { @@ -674,17 +683,17 @@ bool wxDbTable::Open(void) sqlStmt += ","; sqlStmt += "?"; needComma = TRUE; - insertableCount++; + insertableCount++; } sqlStmt += ")"; - + // Prepare the insert statement for execution if (insertableCount) - { + { if (SQLPrepare(hstmtInsert, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); } - else + else insertable= FALSE; } @@ -741,6 +750,7 @@ bool wxDbTable::GetPrev(void) } else return(getRec(SQL_FETCH_PRIOR)); + } // wxDbTable::GetPrev() @@ -754,6 +764,7 @@ bool wxDbTable::operator--(int) } else return(getRec(SQL_FETCH_PRIOR)); + } // wxDbTable::operator-- @@ -767,6 +778,7 @@ bool wxDbTable::GetFirst(void) } else return(getRec(SQL_FETCH_FIRST)); + } // wxDbTable::GetFirst() @@ -780,6 +792,7 @@ bool wxDbTable::GetLast(void) } else return(getRec(SQL_FETCH_LAST)); + } // wxDbTable::GetLast() @@ -857,40 +870,40 @@ void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) // or build a where clause. The typeOfSelect determines this. switch(typeOfSelect) { - case DB_SELECT_WHERE: + case DB_SELECT_WHERE: #if wxODBC_BACKWARD_COMPATABILITY - if (where && wxStrlen(where)) // May not want a where clause!!! + if (where && wxStrlen(where)) // May not want a where clause!!! #else - if (where.Length()) // May not want a where clause!!! + if (where.Length()) // May not want a where clause!!! #endif - { - wxStrcat(pSqlStmt, " WHERE "); - wxStrcat(pSqlStmt, where); - } - break; - case DB_SELECT_KEYFIELDS: - BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); - if (wxStrlen(whereClause)) - { - wxStrcat(pSqlStmt, " WHERE "); - wxStrcat(pSqlStmt, whereClause); - } - break; - case DB_SELECT_MATCHING: - BuildWhereClause(whereClause, DB_WHERE_MATCHING); - if (wxStrlen(whereClause)) - { - wxStrcat(pSqlStmt, " WHERE "); - wxStrcat(pSqlStmt, whereClause); - } - break; + { + wxStrcat(pSqlStmt, " WHERE "); + wxStrcat(pSqlStmt, where); + } + break; + case DB_SELECT_KEYFIELDS: + BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); + if (wxStrlen(whereClause)) + { + wxStrcat(pSqlStmt, " WHERE "); + wxStrcat(pSqlStmt, whereClause); + } + break; + case DB_SELECT_MATCHING: + BuildWhereClause(whereClause, DB_WHERE_MATCHING); + if (wxStrlen(whereClause)) + { + wxStrcat(pSqlStmt, " WHERE "); + wxStrcat(pSqlStmt, whereClause); + } + break; } // Append the ORDER BY clause #if wxODBC_BACKWARD_COMPATABILITY if (orderBy && wxStrlen(orderBy)) #else - if (orderBy.Length()) + if (orderBy.Length()) #endif { wxStrcat(pSqlStmt, " ORDER BY "); @@ -942,7 +955,6 @@ bool wxDbTable::CreateTable(bool attemptDrop) return FALSE; int i, j; -// char sqlStmt[DB_MAX_STATEMENT_LEN]; wxString sqlStmt; #ifdef DBDEBUG_CONSOLE @@ -991,7 +1003,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) continue; // Comma Delimiter if (needComma) - sqlStmt += ","; + sqlStmt += ","; // Column Name sqlStmt += colDefs[i].ColName; sqlStmt += " "; @@ -999,13 +1011,17 @@ bool wxDbTable::CreateTable(bool attemptDrop) switch(colDefs[i].DbDataType) { case DB_DATA_TYPE_VARCHAR: - sqlStmt += pDb->GetTypeInfVarchar().TypeName; break; + sqlStmt += pDb->GetTypeInfVarchar().TypeName; + break; case DB_DATA_TYPE_INTEGER: - sqlStmt += pDb->GetTypeInfInteger().TypeName; break; + sqlStmt += pDb->GetTypeInfInteger().TypeName; + break; case DB_DATA_TYPE_FLOAT: - sqlStmt += pDb->GetTypeInfFloat().TypeName; break; + sqlStmt += pDb->GetTypeInfFloat().TypeName; + break; case DB_DATA_TYPE_DATE: - sqlStmt += pDb->GetTypeInfDate().TypeName; break; + sqlStmt += pDb->GetTypeInfDate().TypeName; + break; } // For varchars, append the size of the string if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR) @@ -1083,9 +1099,9 @@ bool wxDbTable::CreateTable(bool attemptDrop) } // Commit the transaction and close the cursor - if (! pDb->CommitTrans()) - return(FALSE); - if (! CloseCursor(hstmt)) + if (!pDb->CommitTrans()) + rEturn(FALSE); + if (!CloseCursor(hstmt)) return(FALSE); // Database table created successfully @@ -1115,13 +1131,13 @@ bool wxDbTable::DropTable() if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) { // Check for "Base table not found" error and ignore - pDb->GetNextError(henv, hdbc, hstmt); + pDb->GetNextError(henv, hdbc, hstmt); if (wxStrcmp(pDb->sqlState,"S0002") && wxStrcmp(pDb->sqlState, "S1000")) // "Base table not found" - { + { // Check for product specific error codes - if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,"42000")) || // 5.x (and lower?) - (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,"37000")) || - (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,"08S01")))) + if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,"42000")) || // 5.x (and lower?) + (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,"37000")) || + (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,"08S01")))) { pDb->DispNextError(); pDb->DispAllErrors(henv, hdbc, hstmt); @@ -1161,84 +1177,88 @@ bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wx // defined with the "NOT NULL" qualifier. if (pDb->Dbms() == dbmsMY_SQL) { - wxString sqlStmt; - int i; - bool ok = TRUE; - for (i = 0; i < noIdxCols && ok; i++) - { - int j = 0; - bool found = FALSE; - // Find the column definition that has the ColName that matches the - // index column name. We need to do this to get the DB_DATA_TYPE of - // the index column, as MySQL's syntax for the ALTER column requires - // this information - while (!found && (j < this->noCols)) - { - if (wxStrcmp(colDefs[j].ColName,pIdxDefs[i].ColName) == 0) - found = TRUE; - if (!found) - j++; - } - - if (found) - { - wxString typeNameAndSize; - - switch(colDefs[j].DbDataType) + wxString sqlStmt; + int i; + bool ok = TRUE; + for (i = 0; i < noIdxCols && ok; i++) + { + int j = 0; + bool found = FALSE; + // Find the column definition that has the ColName that matches the + // index column name. We need to do this to get the DB_DATA_TYPE of + // the index column, as MySQL's syntax for the ALTER column requires + // this information + while (!found && (j < this->noCols)) { - case DB_DATA_TYPE_VARCHAR: - typeNameAndSize = pDb->GetTypeInfVarchar().TypeName; break; - case DB_DATA_TYPE_INTEGER: - typeNameAndSize = pDb->GetTypeInfInteger().TypeName; break; - case DB_DATA_TYPE_FLOAT: - typeNameAndSize = pDb->GetTypeInfFloat().TypeName; break; - case DB_DATA_TYPE_DATE: - typeNameAndSize = pDb->GetTypeInfDate().TypeName; break; + if (wxStrcmp(colDefs[j].ColName,pIdxDefs[i].ColName) == 0) + found = TRUE; + if (!found) + j++; } - - // For varchars, append the size of the string - if (colDefs[j].DbDataType == DB_DATA_TYPE_VARCHAR) + + if (found) { - wxString s; - s.sprintf("(%d)", colDefs[i].SzDataObj); - typeNameAndSize += s.c_str(); + wxString typeNameAndSize; + + switch(colDefs[j].DbDataType) + { + case DB_DATA_TYPE_VARCHAR: + typeNameAndSize = pDb->GetTypeInfVarchar().TypeName; + break; + case DB_DATA_TYPE_INTEGER: + typeNameAndSize = pDb->GetTypeInfInteger().TypeName; + break; + case DB_DATA_TYPE_FLOAT: + typeNameAndSize = pDb->GetTypeInfFloat().TypeName; + break; + case DB_DATA_TYPE_DATE: + typeNameAndSize = pDb->GetTypeInfDate().TypeName; + break; + } + + // For varchars, append the size of the string + if (colDefs[j].DbDataType == DB_DATA_TYPE_VARCHAR) + { + wxString s; + s.sprintf("(%d)", colDefs[i].SzDataObj); + typeNameAndSize += s.c_str(); + } + + sqlStmt.sprintf("ALTER TABLE %s MODIFY %s %s NOT NULL",tableName,pIdxDefs[i].ColName,typeNameAndSize.c_str()); + ok = pDb->ExecSql(sqlStmt.c_str()); + + if (!ok) + { + wxODBC_ERRORS retcode; + // Oracle returns a DB_ERR_GENERAL_ERROR if the column is already + // defined to be NOT NULL, but reportedly MySQL doesn't mind. + // This line is just here for debug checking of the value + retcode = (wxODBC_ERRORS)pDb->DB_STATUS; + } } - - sqlStmt.sprintf("ALTER TABLE %s MODIFY %s %s NOT NULL",tableName,pIdxDefs[i].ColName,typeNameAndSize.c_str()); - ok = pDb->ExecSql(sqlStmt.c_str()); - - if (!ok) - { - wxODBC_ERRORS retcode; - // Oracle returns a DB_ERR_GENERAL_ERROR if the column is already - // defined to be NOT NULL, but reportedly MySQL doesn't mind. - // This line is just here for debug checking of the value - retcode = (wxODBC_ERRORS)pDb->DB_STATUS; - } - } - else - ok = FALSE; - } - if (ok) - pDb->CommitTrans(); - else - { - pDb->RollbackTrans(); - return(FALSE); - } + else + ok = FALSE; + } + if (ok) + pDb->CommitTrans(); + else + { + pDb->RollbackTrans(); + return(FALSE); + } } - + // Build a CREATE INDEX statement sqlStmt = "CREATE "; if (unique) sqlStmt += "UNIQUE "; - + sqlStmt += "INDEX "; sqlStmt += idxName; sqlStmt += " ON "; sqlStmt += tableName; sqlStmt += " ("; - + // Append list of columns making up index int i; for (i = 0; i < noIdxCols; i++) @@ -1531,34 +1551,34 @@ void wxDbTable::BuildUpdateStmt(char *pSqlStmt, int typeOfUpd, const char *pWher wxStrcat(pSqlStmt, " WHERE "); switch(typeOfUpd) { - case DB_UPD_KEYFIELDS: - // If the datasource supports the ROWID column, build - // the where on ROWID for efficiency purposes. - // e.g. UPDATE PARTS SET Col1 = ?, Col2 = ? WHERE ROWID = '111.222.333' - if (CanUpdByROWID()) - { - SDWORD cb; - char rowid[wxDB_ROWID_LEN]; - - // 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) + case DB_UPD_KEYFIELDS: + // If the datasource supports the ROWID column, build + // the where on ROWID for efficiency purposes. + // e.g. UPDATE PARTS SET Col1 = ?, Col2 = ? WHERE ROWID = '111.222.333' + if (CanUpdByROWID()) { - wxStrcat(pSqlStmt, "ROWID = '"); - wxStrcat(pSqlStmt, rowid); - wxStrcat(pSqlStmt, "'"); - break; + SDWORD cb; + char rowid[wxDB_ROWID_LEN]; + + // 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) + { + wxStrcat(pSqlStmt, "ROWID = '"); + wxStrcat(pSqlStmt, rowid); + wxStrcat(pSqlStmt, "'"); + break; + } } - } - // Unable to delete by ROWID, so build a WHERE - // clause based on the keyfields. - BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); - wxStrcat(pSqlStmt, whereClause); - break; - case DB_UPD_WHERE: - wxStrcat(pSqlStmt, pWhereClause); - break; + // Unable to delete by ROWID, so build a WHERE + // clause based on the keyfields. + BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); + wxStrcat(pSqlStmt, whereClause); + break; + case DB_UPD_WHERE: + wxStrcat(pSqlStmt, pWhereClause); + break; } } // BuildUpdateStmt() @@ -1587,38 +1607,38 @@ void wxDbTable::BuildDeleteStmt(char *pSqlStmt, int typeOfDel, const char *pWher // Append the WHERE clause to the SQL DELETE statement switch(typeOfDel) { - case DB_DEL_KEYFIELDS: - // If the datasource supports the ROWID column, build - // the where on ROWID for efficiency purposes. - // e.g. DELETE FROM PARTS WHERE ROWID = '111.222.333' - if (CanUpdByROWID()) - { - SDWORD cb; - char rowid[wxDB_ROWID_LEN]; - - // 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) + case DB_DEL_KEYFIELDS: + // If the datasource supports the ROWID column, build + // the where on ROWID for efficiency purposes. + // e.g. DELETE FROM PARTS WHERE ROWID = '111.222.333' + if (CanUpdByROWID()) { - wxStrcat(pSqlStmt, "ROWID = '"); - wxStrcat(pSqlStmt, rowid); - wxStrcat(pSqlStmt, "'"); - break; + SDWORD cb; + char rowid[wxDB_ROWID_LEN]; + + // 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) + { + wxStrcat(pSqlStmt, "ROWID = '"); + wxStrcat(pSqlStmt, rowid); + wxStrcat(pSqlStmt, "'"); + break; + } } - } - // Unable to delete by ROWID, so build a WHERE - // clause based on the keyfields. - BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); - wxStrcat(pSqlStmt, whereClause); - break; - case DB_DEL_WHERE: - wxStrcat(pSqlStmt, pWhereClause); - break; - case DB_DEL_MATCHING: - BuildWhereClause(whereClause, DB_WHERE_MATCHING); - wxStrcat(pSqlStmt, whereClause); - break; + // Unable to delete by ROWID, so build a WHERE + // clause based on the keyfields. + BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); + wxStrcat(pSqlStmt, whereClause); + break; + case DB_DEL_WHERE: + wxStrcat(pSqlStmt, pWhereClause); + break; + case DB_DEL_MATCHING: + BuildWhereClause(whereClause, DB_WHERE_MATCHING); + wxStrcat(pSqlStmt, whereClause); + break; } } // BuildDeleteStmt() @@ -1664,27 +1684,27 @@ void wxDbTable::BuildWhereClause(char *pWhereClause, int typeOfWhere, wxStrcat(pWhereClause, " = "); switch(colDefs[i].SqlCtype) { - case SQL_C_CHAR: - sprintf(colValue, "'%s'", (UCHAR FAR *) colDefs[i].PtrDataObj); - break; - case SQL_C_SSHORT: - sprintf(colValue, "%hi", *((SWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_USHORT: - sprintf(colValue, "%hu", *((UWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_SLONG: - sprintf(colValue, "%li", *((SDWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_ULONG: - sprintf(colValue, "%lu", *((UDWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_FLOAT: - sprintf(colValue, "%.6f", *((SFLOAT *) colDefs[i].PtrDataObj)); - break; - case SQL_C_DOUBLE: - sprintf(colValue, "%.6f", *((SDOUBLE *) colDefs[i].PtrDataObj)); - break; + case SQL_C_CHAR: + sprintf(colValue, "'%s'", (UCHAR FAR *) colDefs[i].PtrDataObj); + break; + case SQL_C_SSHORT: + sprintf(colValue, "%hi", *((SWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_USHORT: + sprintf(colValue, "%hu", *((UWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_SLONG: + sprintf(colValue, "%li", *((SDWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_ULONG: + sprintf(colValue, "%lu", *((UDWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_FLOAT: + sprintf(colValue, "%.6f", *((SFLOAT *) colDefs[i].PtrDataObj)); + break; + case SQL_C_DOUBLE: + sprintf(colValue, "%.6f", *((SDOUBLE *) colDefs[i].PtrDataObj)); + break; } wxStrcat(pWhereClause, colValue); } @@ -1697,29 +1717,29 @@ bool wxDbTable::IsColNull(int colNo) { switch(colDefs[colNo].SqlCtype) { - case SQL_C_CHAR: - return(((UCHAR FAR *) colDefs[colNo].PtrDataObj)[0] == 0); - case SQL_C_SSHORT: - return(( *((SWORD *) colDefs[colNo].PtrDataObj)) == 0); - case SQL_C_USHORT: - return(( *((UWORD*) colDefs[colNo].PtrDataObj)) == 0); - case SQL_C_SLONG: - return(( *((SDWORD *) colDefs[colNo].PtrDataObj)) == 0); - case SQL_C_ULONG: - return(( *((UDWORD *) colDefs[colNo].PtrDataObj)) == 0); - case SQL_C_FLOAT: - return(( *((SFLOAT *) colDefs[colNo].PtrDataObj)) == 0); - case SQL_C_DOUBLE: - return((*((SDOUBLE *) colDefs[colNo].PtrDataObj)) == 0); - case SQL_C_TIMESTAMP: - TIMESTAMP_STRUCT *pDt; - pDt = (TIMESTAMP_STRUCT *) colDefs[colNo].PtrDataObj; - if (pDt->year == 0 && pDt->month == 0 && pDt->day == 0) + case SQL_C_CHAR: + return(((UCHAR FAR *) colDefs[colNo].PtrDataObj)[0] == 0); + case SQL_C_SSHORT: + return(( *((SWORD *) colDefs[colNo].PtrDataObj)) == 0); + case SQL_C_USHORT: + return(( *((UWORD*) colDefs[colNo].PtrDataObj)) == 0); + case SQL_C_SLONG: + return(( *((SDWORD *) colDefs[colNo].PtrDataObj)) == 0); + case SQL_C_ULONG: + return(( *((UDWORD *) colDefs[colNo].PtrDataObj)) == 0); + case SQL_C_FLOAT: + return(( *((SFLOAT *) colDefs[colNo].PtrDataObj)) == 0); + case SQL_C_DOUBLE: + return((*((SDOUBLE *) colDefs[colNo].PtrDataObj)) == 0); + case SQL_C_TIMESTAMP: + TIMESTAMP_STRUCT *pDt; + pDt = (TIMESTAMP_STRUCT *) colDefs[colNo].PtrDataObj; + if (pDt->year == 0 && pDt->month == 0 && pDt->day == 0) + return(TRUE); + else + return(FALSE); + default: return(TRUE); - else - return(FALSE); - default: - return(TRUE); } } // wxDbTable::IsColNull() @@ -1775,39 +1795,38 @@ void wxDbTable::ClearMemberVars(void) { switch(colDefs[i].SqlCtype) { - case SQL_C_CHAR: - ((UCHAR FAR *) colDefs[i].PtrDataObj)[0] = 0; - break; - case SQL_C_SSHORT: - *((SWORD *) colDefs[i].PtrDataObj) = 0; - break; - case SQL_C_USHORT: - *((UWORD*) colDefs[i].PtrDataObj) = 0; - break; - case SQL_C_SLONG: - *((SDWORD *) colDefs[i].PtrDataObj) = 0; - break; - case SQL_C_ULONG: - *((UDWORD *) colDefs[i].PtrDataObj) = 0; - break; - case SQL_C_FLOAT: - *((SFLOAT *) colDefs[i].PtrDataObj) = 0.0f; - break; - case SQL_C_DOUBLE: - *((SDOUBLE *) colDefs[i].PtrDataObj) = 0.0f; - break; - case SQL_C_TIMESTAMP: - TIMESTAMP_STRUCT *pDt; - pDt = (TIMESTAMP_STRUCT *) colDefs[i].PtrDataObj; - pDt->year = 0; - pDt->month = 0; - pDt->day = 0; - pDt->hour = 0; - pDt->minute = 0; - pDt->second = 0; - pDt->fraction = 0; - break; - + case SQL_C_CHAR: + ((UCHAR FAR *) colDefs[i].PtrDataObj)[0] = 0; + break; + case SQL_C_SSHORT: + *((SWORD *) colDefs[i].PtrDataObj) = 0; + break; + case SQL_C_USHORT: + *((UWORD*) colDefs[i].PtrDataObj) = 0; + break; + case SQL_C_SLONG: + *((SDWORD *) colDefs[i].PtrDataObj) = 0; + break; + case SQL_C_ULONG: + *((UDWORD *) colDefs[i].PtrDataObj) = 0; + break; + case SQL_C_FLOAT: + *((SFLOAT *) colDefs[i].PtrDataObj) = 0.0f; + break; + case SQL_C_DOUBLE: + *((SDOUBLE *) colDefs[i].PtrDataObj) = 0.0f; + break; + case SQL_C_TIMESTAMP: + TIMESTAMP_STRUCT *pDt; + pDt = (TIMESTAMP_STRUCT *) colDefs[i].PtrDataObj; + pDt->year = 0; + pDt->month = 0; + pDt->day = 0; + pDt->hour = 0; + pDt->minute = 0; + pDt->second = 0; + pDt->fraction = 0; + break; } } @@ -1834,8 +1853,8 @@ bool wxDbTable::SetQueryTimeout(UDWORD nSeconds) /********** wxDbTable::SetColDefs() **********/ void wxDbTable::SetColDefs (int index, const char *fieldName, int dataType, void *pData, - int cType, int size, bool keyField, bool upd, - bool insAllow, bool derivedCol) + int cType, int size, bool keyField, bool upd, + bool insAllow, bool derivedCol) { if (!colDefs) // May happen if the database connection fails return; @@ -1889,14 +1908,11 @@ wxDbColDataPtr* wxDbTable::SetColDefs (wxDbColInf *pColInfs, ULONG numCols) switch (pColInfs[index].dbDataType) { case DB_DATA_TYPE_VARCHAR: - { pColDataPtrs[index].PtrDataObj = new char[pColInfs[index].bufferLength+1]; pColDataPtrs[index].SzDataObj = pColInfs[index].columnSize; pColDataPtrs[index].SqlCtype = SQL_C_CHAR; break; - } case DB_DATA_TYPE_INTEGER: - { // Can be long or short if (pColInfs[index].bufferLength == sizeof(long)) { @@ -1911,9 +1927,7 @@ wxDbColDataPtr* wxDbTable::SetColDefs (wxDbColInf *pColInfs, ULONG numCols) pColDataPtrs[index].SqlCtype = SQL_C_SSHORT; } break; - } case DB_DATA_TYPE_FLOAT: - { // Can be float or double if (pColInfs[index].bufferLength == sizeof(float)) { @@ -1928,20 +1942,18 @@ wxDbColDataPtr* wxDbTable::SetColDefs (wxDbColInf *pColInfs, ULONG numCols) pColDataPtrs[index].SqlCtype = SQL_C_DOUBLE; } break; - } case DB_DATA_TYPE_DATE: - { pColDataPtrs[index].PtrDataObj = new TIMESTAMP_STRUCT; pColDataPtrs[index].SzDataObj = sizeof(TIMESTAMP_STRUCT); pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP; break; - } } - - SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj); + SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj); } } + return (pColDataPtrs); + } // wxDbTable::SetColDef()