///////////////////////////////////////////////////////////////////////////////
-// Name: db.cpp
+// Name: src/common/db.cpp
// Purpose: Implementation of the wxDb class. The wxDb class represents a connection
// to an ODBC data source. The wxDb class allows operations on the data
// source such as opening and closing the data source.
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
-/*
-// SYNOPSIS START
-// SYNOPSIS STOP
-*/
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "db.h"
-#endif
-
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
-#ifdef DBDEBUG_CONSOLE
- #include "wx/ioswrap.h"
-#endif
+#if wxUSE_ODBC
#ifndef WX_PRECOMP
- #include "wx/string.h"
#include "wx/object.h"
#include "wx/list.h"
+ #include "wx/string.h"
#include "wx/utils.h"
#include "wx/log.h"
+ #include "wx/app.h"
+#endif
+
+#ifdef DBDEBUG_CONSOLE
+ #include "wx/ioswrap.h"
#endif
+
#include "wx/filefn.h"
#include "wx/wxchar.h"
-#if wxUSE_ODBC
-
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "wx/db.h"
// DLL options compatibility check:
-#include "wx/app.h"
WX_CHECK_BUILD_OPTIONS("wxODBC")
WXDLLIMPEXP_DATA_ODBC(wxDbList*) PtrBegDbList = 0;
void wxDbConnectInf::SetDsn(const wxString &dsn)
{
- wxASSERT(dsn.Length() < sizeof(Dsn));
+ wxASSERT(dsn.length() < WXSIZEOF(Dsn));
- wxStrncpy(Dsn, dsn, sizeof(Dsn)-1);
- Dsn[sizeof(Dsn)-1] = 0; // Prevent buffer overrun
+ wxStrncpy(Dsn, dsn, WXSIZEOF(Dsn)-1);
+ Dsn[WXSIZEOF(Dsn)-1] = 0; // Prevent buffer overrun
} // wxDbConnectInf::SetDsn()
void wxDbConnectInf::SetUserID(const wxString &uid)
{
- wxASSERT(uid.Length() < sizeof(Uid));
- wxStrncpy(Uid, uid, sizeof(Uid)-1);
- Uid[sizeof(Uid)-1] = 0; // Prevent buffer overrun
+ wxASSERT(uid.length() < WXSIZEOF(Uid));
+ wxStrncpy(Uid, uid, WXSIZEOF(Uid)-1);
+ Uid[WXSIZEOF(Uid)-1] = 0; // Prevent buffer overrun
} // wxDbConnectInf::SetUserID()
void wxDbConnectInf::SetPassword(const wxString &password)
{
- wxASSERT(password.Length() < sizeof(AuthStr));
+ wxASSERT(password.length() < WXSIZEOF(AuthStr));
- wxStrncpy(AuthStr, password, sizeof(AuthStr)-1);
- AuthStr[sizeof(AuthStr)-1] = 0; // Prevent buffer overrun
+ wxStrncpy(AuthStr, password, WXSIZEOF(AuthStr)-1);
+ AuthStr[WXSIZEOF(AuthStr)-1] = 0; // Prevent buffer overrun
} // wxDbConnectInf::SetPassword()
void wxDbConnectInf::SetConnectionStr(const wxString &connectStr)
{
- wxASSERT(connectStr.Length() < sizeof(ConnectionStr));
+ wxASSERT(connectStr.length() < WXSIZEOF(ConnectionStr));
useConnectionStr = wxStrlen(connectStr) > 0;
- wxStrncpy(ConnectionStr, connectStr, sizeof(ConnectionStr)-1);
- ConnectionStr[sizeof(ConnectionStr)-1] = 0; // Prevent buffer overrun
+ wxStrncpy(ConnectionStr, connectStr, WXSIZEOF(ConnectionStr)-1);
+ ConnectionStr[WXSIZEOF(ConnectionStr)-1] = 0; // Prevent buffer overrun
} // wxDbConnectInf::SetConnectionStr()
if ((i_sqlDataType == SQL_VARCHAR)
#if wxUSE_UNICODE
#if defined(SQL_WCHAR)
- || (i_sqlDataType == SQL_WCHAR)
+ || (i_sqlDataType == SQL_WCHAR)
#endif
#if defined(SQL_WVARCHAR)
|| (i_sqlDataType == SQL_WVARCHAR)
typeInfBlob.CaseSensitive = 0;
typeInfBlob.MaximumScale = 0;
+ typeInfMemo.TypeName.Empty();
+ typeInfMemo.FsqlType = 0;
+ typeInfMemo.Precision = 0;
+ typeInfMemo.CaseSensitive = 0;
+ typeInfMemo.MaximumScale = 0;
+
// Error reporting is turned OFF by default
silent = true;
SQL_VARBINARY
};
+ // These are the possible SQL types we check for use agains the datasource we are connected
+ // to for the purpose of determining which data type to use for the MEMO column types
+ // (a type which allow to store large strings; like VARCHAR just with a bigger precision)
+ //
+ // NOTE: The first type in this enumeration that is determined to be supported by the
+ // datasource/driver is the one that will be used.
+ SWORD PossibleSqlMemoTypes[] = {
+ SQL_LONGVARCHAR,
+ };
+
// Query the data source regarding data type information
else if (failOnDataTypeUnsupported)
return false;
+ // --------------- MEMO ---------------
+ for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlMemoTypes) &&
+ !getDataTypeInfo(PossibleSqlMemoTypes[iIndex], typeInfMemo); ++iIndex)
+ {}
+
+ if (iIndex < WXSIZEOF(PossibleSqlMemoTypes))
+ typeInfMemo.FsqlType = PossibleSqlMemoTypes[iIndex];
+ else if (failOnDataTypeUnsupported)
+ return false;
+
return true;
} // wxDb::determineDataTypes
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 << wxT("MEMO DATA TYPE: ") << typeInfMemo.TypeName << endl;
cout << endl;
#endif
bool wxDb::Open(const wxString& inConnectStr, bool failOnDataTypeUnsupported)
{
- wxASSERT(inConnectStr.Length());
+ wxASSERT(inConnectStr.length());
return Open(inConnectStr, NULL, failOnDataTypeUnsupported);
}
bool wxDb::Open(const wxString& inConnectStr, SQLHWND parentWnd, bool failOnDataTypeUnsupported)
{
- dsn = wxT("");
- uid = wxT("");
- authStr = wxT("");
+ dsn = wxEmptyString;
+ uid = wxEmptyString;
+ authStr = wxEmptyString;
RETCODE retcode;
inConnectionStr = inConnectStr;
retcode = SQLDriverConnect(hdbc, parentWnd, (SQLTCHAR FAR *)inConnectionStr.c_str(),
- (SWORD)inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer,
+ (SWORD)inConnectionStr.length(), (SQLTCHAR FAR *)outConnectBuffer,
sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE );
if ((retcode != SQL_SUCCESS) &&
/********** wxDb::Open() **********/
bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr, bool failOnDataTypeUnsupported)
{
- wxASSERT(Dsn.Length());
+ wxASSERT(!Dsn.empty());
dsn = Dsn;
uid = Uid;
authStr = AuthStr;
- inConnectionStr = wxT("");
- outConnectionStr = wxT("");
+ inConnectionStr = wxEmptyString;
+ outConnectionStr = wxEmptyString;
RETCODE retcode;
inConnectionStr = copyDb->GetConnectionInStr();
retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(),
- (SWORD)inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer,
+ (SWORD)inConnectionStr.length(), (SQLTCHAR FAR *)outConnectBuffer,
sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE);
if ((retcode != SQL_SUCCESS) &&
typeInfBlob.CaseSensitive = copyDb->typeInfBlob.CaseSensitive;
typeInfBlob.MaximumScale = copyDb->typeInfBlob.MaximumScale;
+ // Memo
+ typeInfMemo.FsqlType = copyDb->typeInfMemo.FsqlType;
+ typeInfMemo.TypeName = copyDb->typeInfMemo.TypeName;
+ typeInfMemo.Precision = copyDb->typeInfMemo.Precision;
+ typeInfMemo.CaseSensitive = copyDb->typeInfMemo.CaseSensitive;
+ typeInfMemo.MaximumScale = copyDb->typeInfMemo.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 << wxT("MEMO DATA TYPE: ") << typeInfMemo.TypeName << endl;
cout << endl;
#endif
/********** wxDb::logError() **********/
void wxDb::logError(const wxString &errMsg, const wxString &SQLState)
{
- wxASSERT(errMsg.Length());
+ wxASSERT(errMsg.length());
static int pLast = -1;
int dbStatus;
wxStrncpy(errorList[pLast], errMsg, DB_MAX_ERROR_MSG_LEN);
errorList[pLast][DB_MAX_ERROR_MSG_LEN] = 0;
- if (SQLState.Length())
+ if (SQLState.length())
if ((dbStatus = TranslateSqlState(SQLState)) != DB_ERR_FUNCTION_SEQUENCE_ERROR)
DB_STATUS = dbStatus;
sqlStmt = wxT("CREATE VIEW ");
sqlStmt += viewName;
- if (colList.Length())
+ if (colList.length())
{
sqlStmt += wxT(" (");
sqlStmt += colList;
case SQL_CHAR:
pColInf[colNum].dbDataType = DB_DATA_TYPE_VARCHAR;
break;
+ case SQL_LONGVARCHAR:
+ pColInf[colNum].dbDataType = DB_DATA_TYPE_MEMO;
+ break;
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
case SQL_CHAR:
colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR;
break;
+ case SQL_LONGVARCHAR:
+ colInf[colNo].dbDataType = DB_DATA_TYPE_MEMO;
+ break;
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
* to avoid undesired unbinding of columns.
*/
{
- wxASSERT(fileName.Length());
+ wxASSERT(fileName.length());
RETCODE retcode;
SQLLEN cb;
* userID != "" ... UserID set equal to 'userID'
*/
{
- wxASSERT(tableName.Length());
+ wxASSERT(tableName.length());
wxString TableName;
if (Dbms() == dbmsDBASE)
{
wxString dbName;
- if (tablePath.Length())
+ if (tablePath.length())
dbName.Printf(wxT("%s/%s.dbf"), tablePath.c_str(), tableName.c_str());
else
dbName.Printf(wxT("%s.dbf"), tableName.c_str());
bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, const wxChar *userID,
const wxChar *schema, const wxString &WXUNUSED(tablePath))
{
- wxASSERT(tableName.Length());
+ wxASSERT(tableName.length());
wxDbTablePrivilegeInfo result;
SQLLEN cbRetVal;
bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool append)
{
wxASSERT(state == sqlLogON || state == sqlLogOFF);
- wxASSERT(state == sqlLogOFF || filename.Length());
+ wxASSERT(state == sqlLogOFF || filename.length());
if (state == sqlLogON)
{
/********** wxDb::WriteSqlLog() **********/
bool wxDb::WriteSqlLog(const wxString &logMsg)
{
- wxASSERT(logMsg.Length());
+ wxASSERT(logMsg.length());
if (fpSqlLog == 0 || sqlLogState == sqlLogOFF)
return false;
baseName[3] = 0;
if (!wxStricmp(baseName,wxT("DB2")))
- return((wxDBMS)(dbmsType = dbmsDBASE));
+ return((wxDBMS)(dbmsType = dbmsDB2));
return((wxDBMS)(dbmsType = dbmsUNIDENTIFIED));
int dataType, ULONG columnLength,
const wxString &optionalParam)
{
- wxASSERT(tableName.Length());
- wxASSERT(columnName.Length());
+ wxASSERT(tableName.length());
+ wxASSERT(columnName.length());
wxASSERT((dataType == DB_DATA_TYPE_VARCHAR && columnLength > 0) ||
dataType != DB_DATA_TYPE_VARCHAR);
}
// for passing things like "NOT NULL"
- if (optionalParam.Length())
+ if (optionalParam.length())
{
sqlStmt += wxT(" ");
sqlStmt += optionalParam;