#include "wx/object.h"
#include "wx/list.h"
#include "wx/utils.h"
- #include "wx/msgdlg.h"
+ #if wxUSE_GUI
+ #include "wx/msgdlg.h"
+ #endif
#include "wx/log.h"
#endif
#include "wx/filefn.h"
UserID.Empty();
// dBase does not use user names, and some drivers fail if you try to pass one
- if (Dbms() == dbmsDBASE)
+ if ( Dbms() == dbmsDBASE
+ || Dbms() == dbmsXBASE_SEQUITER )
UserID.Empty();
// Oracle user names may only be in uppercase, so force
/********** wxDb::Open() **********/
-bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr)
+bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr, bool failOnDataTypeUnsupported)
{
wxASSERT(Dsn.Length());
dsn = Dsn;
(UCHAR FAR *) uid.c_str(), SQL_NTS,
(UCHAR FAR *) authStr.c_str(), SQL_NTS);
-/*
- if (retcode == SQL_SUCCESS_WITH_INFO)
- DispAllErrors(henv, hdbc);
- else if (retcode != SQL_SUCCESS)
- return(DispAllErrors(henv, hdbc));
-
- if (retcode == SQL_ERROR)
- return(DispAllErrors(henv, hdbc));
-*/
if ((retcode != SQL_SUCCESS) &&
(retcode != SQL_SUCCESS_WITH_INFO))
return(DispAllErrors(henv, hdbc));
if (!getDataTypeInfo(SQL_FLOAT,typeInfFloat))
if (!getDataTypeInfo(SQL_DECIMAL,typeInfFloat))
if (!getDataTypeInfo(SQL_NUMERIC,typeInfFloat))
- return(FALSE);
+ {
+ if (failOnDataTypeUnsupported)
+ return(FALSE);
+ }
else
typeInfFloat.FsqlType = SQL_NUMERIC;
else
// 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);
+ {
+ if (failOnDataTypeUnsupported)
+ return(FALSE);
+ }
else
typeInfInteger.FsqlType = typeInfFloat.FsqlType;
}
typeInfInteger.FsqlType = SQL_INTEGER;
// Date/Time
- if (Dbms() != dbmsDBASE)
- {
- if (!getDataTypeInfo(SQL_TIMESTAMP,typeInfDate))
- return(FALSE);
- else
- typeInfDate.FsqlType = SQL_TIMESTAMP;
- }
- else
+ if (!getDataTypeInfo(SQL_TIMESTAMP,typeInfDate))
{
if (!getDataTypeInfo(SQL_DATE,typeInfDate))
- return(FALSE);
+ {
+#ifdef SQL_DATETIME
+ if (getDataTypeInfo(SQL_DATETIME,typeInfDate))
+ {
+ typeInfDate.FsqlType = SQL_TIME;
+ }
+ else
+#endif // SQL_DATETIME defined
+ {
+ if (failOnDataTypeUnsupported)
+ return(FALSE);
+ }
+ }
else
typeInfDate.FsqlType = SQL_DATE;
}
+ else
+ typeInfDate.FsqlType = SQL_TIMESTAMP;
+
if (!getDataTypeInfo(SQL_LONGVARBINARY, typeInfBlob))
{
if (!getDataTypeInfo(SQL_VARBINARY,typeInfBlob))
- return(FALSE);
+ {
+ if (failOnDataTypeUnsupported)
+ return(FALSE);
+ }
else
typeInfBlob.FsqlType = SQL_VARBINARY;
}
// Get information about the data type specified
if (SQLGetTypeInfo(hstmt, fSqlType) != SQL_SUCCESS)
return(DispAllErrors(henv, hdbc, hstmt));
+
// Fetch the record
- if ((retcode = SQLFetch(hstmt)) != SQL_SUCCESS)
+ retcode = SQLFetch(hstmt);
+ if (retcode != SQL_SUCCESS)
{
#ifdef DBDEBUG_CONSOLE
if (retcode == SQL_NO_DATA_FOUND)
}
wxChar typeName[DB_TYPE_NAME_LEN+1];
+
// Obtain columns from the record
if (SQLGetData(hstmt, 1, SQL_C_CHAR, (UCHAR*) typeName, DB_TYPE_NAME_LEN, &cbRet) != SQL_SUCCESS)
return(DispAllErrors(henv, hdbc, hstmt));
}
sqlStmt += wxT(" ON ");
- sqlStmt += tableName;
+ sqlStmt += SQLTableName(tableName);
sqlStmt += wxT(" TO ");
sqlStmt += userList;
// Build a generic SELECT statement which returns 0 rows
wxString Stmt;
- Stmt.Printf(wxT("select * from %s where 0=1"), tableName);
+ Stmt.Printf(wxT("select * from \"%s\" where 0=1"), tableName);
// Execute query
if (SQLExecDirect(hstmt, (UCHAR FAR *) Stmt.c_str(), SQL_NTS) != SQL_SUCCESS)
wxChar colName[DB_MAX_COLUMN_NAME_LEN+1];
SWORD sqlDataType;
wxChar typeName[30+1];
- SWORD precision, length;
+ SDWORD precision, length;
FILE *fp = fopen(fileName.c_str(),wxT("wt"));
if (fp == NULL)
tblNameSave.Empty();
int cnt = 0;
- while ((retcode = SQLFetch(hstmt)) == SQL_SUCCESS)
+ while (TRUE)
{
+ retcode = SQLFetch(hstmt);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+ break;
+
if (wxStrcmp(tblName, tblNameSave.c_str()))
{
if (cnt)
tblNameSave = tblName;
}
- GetData(3,SQL_C_CHAR, (UCHAR *)tblName, DB_MAX_TABLE_NAME_LEN+1, &cb);
- GetData(4,SQL_C_CHAR, (UCHAR *)colName, DB_MAX_COLUMN_NAME_LEN+1,&cb);
- GetData(5,SQL_C_SSHORT,(UCHAR *)&sqlDataType,0, &cb);
- GetData(6,SQL_C_CHAR, (UCHAR *)typeName, sizeof(typeName), &cb);
- GetData(7,SQL_C_SSHORT,(UCHAR *)&precision, 0, &cb);
- GetData(8,SQL_C_SSHORT,(UCHAR *)&length, 0, &cb);
+ GetData(3,SQL_C_CHAR, (UCHAR *) tblName, DB_MAX_TABLE_NAME_LEN+1, &cb);
+ GetData(4,SQL_C_CHAR, (UCHAR *) colName, DB_MAX_COLUMN_NAME_LEN+1,&cb);
+ GetData(5,SQL_C_SSHORT,(UCHAR *)&sqlDataType, 0, &cb);
+ GetData(6,SQL_C_CHAR, (UCHAR *) typeName, sizeof(typeName), &cb);
+ GetData(7,SQL_C_SLONG, (UCHAR *)&precision, 0, &cb);
+ GetData(8,SQL_C_SLONG, (UCHAR *)&length, 0, &cb);
outStr.Printf(wxT("%-32s %-32s (%04d)%-15s %9d %9d\n"),
tblName, colName, sqlDataType, typeName, precision, length);
} // wxDb::TablePrivileges
+const wxString wxDb::SQLTableName(const wxChar *tableName)
+{
+ wxString TableName;
+
+ if (Dbms() == dbmsACCESS)
+ TableName = '"';
+ TableName += tableName;
+ if (Dbms() == dbmsACCESS)
+ TableName += '"';
+
+ return TableName;
+} // wxDb::SQLTableName()
+
+
+const wxString wxDb::SQLColumnName(const wxChar *colName)
+{
+ wxString ColName;
+
+ if (Dbms() == dbmsACCESS)
+ ColName = '"';
+ ColName += colName;
+ if (Dbms() == dbmsACCESS)
+ ColName += '"';
+
+ return ColName;
+} // wxDb::SQLColumnName()
+
+
/********** wxDb::SetSqlLogging() **********/
bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool append)
{
if (!wxStricmp(baseName,wxT("DBASE")))
return((wxDBMS)(dbmsType = dbmsDBASE));
+ if (!wxStricmp(baseName,wxT("xBase")))
+ return((wxDBMS)(dbmsType = dbmsXBASE_SEQUITER));
+
+ if (!wxStricmp(baseName,wxT("MySQL")))
+ return((wxDBMS)(dbmsType = dbmsMY_SQL));
+
baseName[3] = 0;
if (!wxStricmp(baseName,wxT("DB2")))
return((wxDBMS)(dbmsType = dbmsDBASE));
case dbmsPOSTGRES :
case dbmsACCESS :
case dbmsDBASE :
+ case dbmsXBASE_SEQUITER :
default :
alterSlashModify = "MODIFY";
break;
}
// create the SQL statement
- sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName.c_str(), alterSlashModify.c_str(),
+ 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)
+ if (dataType == DB_DATA_TYPE_VARCHAR &&
+ (Dbms() != dbmsMY_SQL || dataTypeName != "text"))
{
wxString s;
s.Printf(wxT("(%d)"), columnLength);
/********** wxDbLogExtendedErrorMsg() **********/
// DEBUG ONLY function
-const wxChar WXDLLEXPORT *wxDbLogExtendedErrorMsg(const wxChar *userText, wxDb *pDb,
- char *ErrFile, int ErrLine)
+const wxChar WXDLLEXPORT *wxDbLogExtendedErrorMsg(const wxChar *userText,
+ wxDb *pDb,
+ const wxChar *ErrFile,
+ int ErrLine)
{
static wxString msg;
msg = userText;
msg.Append (wxT("\nODBC errors:\n"));
msg += wxT("\n");
-
+
// Display errors for this connection
int i;
for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)