wxcore-0.10.3: wxc/src/db.cpp
#include "wrapper.h"
#if wxUSE_ODBC
# include "wx/db.h"
#else
class wxDb;
class wxDbColInf;
class wxDbInf;
class wxDbTableInf;
typedef void* HENV;
#endif
/* testing */
// #define wxUSE_ODBC 0
/*-----------------------------------------------------------------------------
We want to include the function signatures always -- even on
systems that don't support ODBC. This means that every function body is
surrounded by #ifdef wxUSE_ODBC directives :-(
-----------------------------------------------------------------------------*/
#if defined(wxUSE_ODBC) && (wxUSE_ODBC==0)
# undef wxUSE_ODBC
#endif
#ifndef wxUSE_ODBC
# define wxDb void
# define wxDbConnectInf void
#endif
#if defined(wxUSE_UNICODE) && (wxUSE_UNICODE==0)
# undef wxUSE_UNICODE
#endif
/* used for easy marshalling in Haskell */
enum StandardSqlType {
SqlUnknown
,SqlChar
,SqlNumeric
,SqlDecimal
,SqlInteger
,SqlSmallInt
,SqlFloat
,SqlReal
,SqlDouble
,SqlDate
,SqlTime
,SqlTimeStamp
,SqlVarChar
,SqlBit
,SqlBinary
,SqlVarBinary
,SqlBigInt
,SqlTinyInt
};
#ifndef SQL_DEFAULT
# define SQL_DEFAULT SQL_CHAR
#endif
extern "C" {
/*-----------------------------------------------------------------------------
HENV, HDBC, HSTMT
-----------------------------------------------------------------------------*/
EWXWEXPORT(void*,Null_HENV)()
{
#ifdef wxUSE_ODBC
return (void*)(SQL_NULL_HENV);
#else
return NULL;
#endif
}
EWXWEXPORT(void*,Null_HDBC)()
{
#ifdef wxUSE_ODBC
return (void*)(SQL_NULL_HDBC);
#else
return NULL;
#endif
}
EWXWEXPORT(void*,Null_HSTMT)()
{
#ifdef wxUSE_ODBC
return (void*)(SQL_NULL_HSTMT);
#else
return NULL;
#endif
}
/*-----------------------------------------------------------------------------
DbConnectInf
-----------------------------------------------------------------------------*/
EWXWEXPORT(wxDbConnectInf*,wxDbConnectInf_Create)(void* henv, wxString* dsn, wxString* userID, wxString* password, wxString* defaultDir, wxString* description, wxString* fileType)
{
#ifdef wxUSE_ODBC
return new wxDbConnectInf( (HENV)(henv), *dsn, *userID, *password, *defaultDir, *description, *fileType);
#else
return NULL;
#endif
}
EWXWEXPORT(void,wxDbConnectInf_AllocHenv)(wxDbConnectInf* self)
{
#ifdef wxUSE_ODBC
self->AllocHenv();
#endif
}
EWXWEXPORT(void,wxDbConnectInf_FreeHenv)(wxDbConnectInf* self)
{
#ifdef wxUSE_ODBC
self->FreeHenv();
#endif
}
EWXWEXPORT(void*,wxDbConnectInf_GetHenv)(wxDbConnectInf* self)
{
#ifdef wxUSE_ODBC
return (void*)(self->GetHenv());
#else
return NULL;
#endif
}
EWXWEXPORT(void,wxDbConnectInf_Delete)(wxDbConnectInf* self)
{
#ifdef wxUSE_ODBC
if (self != NULL) delete self;
#endif
}
/*-----------------------------------------------------------------------------
Global functions
-----------------------------------------------------------------------------*/
EWXWEXPORT(int,wxDb_IsSupported)()
{
#ifdef wxUSE_ODBC
return true;
#else
return false;
#endif
}
EWXWEXPORT(void,wxDb_CloseConnections)()
{
#ifdef wxUSE_ODBC
wxDbCloseConnections();
#endif
}
EWXWEXPORT(int,wxDb_ConnectionsInUse)()
{
#ifdef wxUSE_ODBC
return wxDbConnectionsInUse();
#else
return 0;
#endif
}
EWXWEXPORT(int,wxDb_FreeConnection)( wxDb* db)
{
#ifdef wxUSE_ODBC
return wxDbFreeConnection(db);
#else
return false;
#endif
}
EWXWEXPORT(wxDb*,wxDb_GetConnection)( wxDbConnectInf* connectInf, bool fwdCursorsOnly )
{
#ifdef wxUSE_ODBC
return wxDbGetConnection(connectInf,fwdCursorsOnly);
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDb_GetDataSource)( void* henv, wxChar* dsn, int dsnLen, wxChar* description, int descLen, int direction)
{
if (dsn && dsnLen > 0) *dsn = '\0';
if (description && descLen > 0) *description = '\0';
#ifdef wxUSE_ODBC
return wxDbGetDataSource( (HENV)(henv), dsn, dsnLen, description, descLen, direction);
#else
return 0;
#endif
}
/* translate a system sql type to standard range of enumerations */
EWXWEXPORT(int,wxDb_SqlTypeToStandardSqlType)( int sqlType )
{
#ifdef wxUSE_ODBC
switch (sqlType) {
#if defined(wxUSE_UNICODE) && defined(SQL_WCHAR)
case SQL_WCHAR: return SqlChar;
#endif
case SQL_CHAR: return SqlChar;
case SQL_NUMERIC: return SqlNumeric;
case SQL_DECIMAL: return SqlDecimal;
case SQL_INTEGER: return SqlInteger;
case SQL_SMALLINT: return SqlSmallInt;
case SQL_FLOAT: return SqlFloat;
case SQL_REAL: return SqlReal;
case SQL_DOUBLE: return SqlDouble;
#ifdef SQL_DATE
case SQL_DATE: return SqlDate;
case SQL_TIME: return SqlTime;
case SQL_TIMESTAMP: return SqlTimeStamp;
#endif
#if defined(wxUSE_UNICODE) && defined(SQL_WVARCHAR)
case SQL_WVARCHAR: return SqlVarChar;
#endif
case SQL_VARCHAR: return SqlVarChar;
#ifdef SQL_BIT
case SQL_BIT: return SqlBit;
#endif
#ifdef SQL_BINARY
case SQL_BINARY: return SqlBinary;
case SQL_VARBINARY: return SqlVarBinary;
#endif
#ifdef SQL_BIGINT
case SQL_BIGINT: return SqlBigInt;
case SQL_TINYINT: return SqlTinyInt;
#endif
default: return SqlUnknown;
}
#else
return SqlUnknown;
#endif
}
EWXWEXPORT(int,wxDb_StandardSqlTypeToSqlType)( int sqlType )
{
#ifdef wxUSE_ODBC
switch (sqlType) {
#if defined(wxUSE_UNICODE) && defined(SQL_WCHAR)
case SqlChar : return SQL_WCHAR;
#else
case SqlChar : return SQL_CHAR;
#endif
case SqlNumeric : return SQL_NUMERIC;
case SqlDecimal : return SQL_DECIMAL;
case SqlInteger : return SQL_INTEGER;
case SqlSmallInt : return SQL_SMALLINT;
case SqlFloat : return SQL_FLOAT;
case SqlReal : return SQL_REAL;
case SqlDouble : return SQL_DOUBLE;
#ifdef SQL_DATE
case SqlDate : return SQL_DATE;
case SqlTime : return SQL_TIME;
case SqlTimeStamp : return SQL_TIMESTAMP;
#endif
#if defined(wxUSE_UNICODE) && defined(SQL_WVARCHAR)
case SqlVarChar : return SQL_WVARCHAR;
#else
case SqlVarChar : return SQL_VARCHAR;
#endif
#ifdef SQL_BIT
case SqlBit : return SQL_BIT;
#endif
#ifdef SQL_BINARY
case SqlBinary : return SQL_BINARY;
case SqlVarBinary : return SQL_VARBINARY;
#endif
#ifdef SQL_BIGINT
case SqlBigInt : return SQL_BIGINT;
case SqlTinyInt : return SQL_TINYINT;
#endif
case SqlUnknown : return SQL_DEFAULT;
default : return SQL_DEFAULT;
}
#else
return 0;
#endif
}
/*-----------------------------------------------------------------------------
Db
-----------------------------------------------------------------------------*/
EWXWEXPORT(int,wxDb_GetStatus)(wxDb* db)
{
#ifdef wxUSE_ODBC
if (db==NULL)
return DB_ERR_GENERAL_ERROR;
else
return db->DB_STATUS;
#else
return (-1);
#endif
}
EWXWEXPORT(wxString*,wxDb_GetErrorMsg)(wxDb* db)
{
#ifdef wxUSE_ODBC
if (db==NULL)
return new wxString(wxT("unconnected database (is NULL)"));
else
return new wxString(db->errorMsg,db->cbErrorMsg);
#else
return new wxString(wxT("ODBC is not supported on this platform (recompile with ODBC support)"));
#endif
}
EWXWEXPORT(int,wxDb_GetNumErrorMessages)( wxDb* db)
{
#ifdef wxUSE_ODBC
int n;
/* find the last non-empty entry */
for( n = DB_MAX_ERROR_HISTORY; n > 0; n-- ) {
if (db->errorList[n-1] != NULL && db->errorList[n-1][0] != 0) return n;
}
/* hmm, nothing found, return the last non-null entry instead */
for( n = DB_MAX_ERROR_HISTORY; n > 0; n-- ) {
if (db->errorList[n-1] != NULL) return n;
}
return 0;
#else
return 0;
#endif
}
EWXWEXPORT(wxString*,wxDb_GetErrorMessage)(wxDb* db, int index)
{
#ifdef wxUSE_ODBC
int n,idx;
if (db==NULL) return new wxString(wxT(""));
n = wxDb_GetNumErrorMessages(db);
if (index >= n) index = n-1;
if (index < 0) index = 0;
idx = n - index - 1;
if (idx < 0 || idx >= DB_MAX_ERROR_HISTORY)
return new wxString(wxT("unknown error"));
else
return new wxString(db->errorList[n - index - 1]);
#else
return new wxString(wxT("ODBC is not supported on this platform (recompile with ODBC support)"));
#endif
}
EWXWEXPORT(int,wxDb_GetNativeError)(wxDb* db)
{
#ifdef wxUSE_ODBC
if (db==NULL)
return (-1);
else
return db->nativeError;
#else
return (-1);
#endif
}
EWXWEXPORT(int,wxDb_IsOpen)(wxDb* db)
{
#ifdef wxUSE_ODBC
if (db==NULL)
return false;
else
return db->IsOpen();
#else
return false;
#endif
}
EWXWEXPORT(void,wxDb_Close)(wxDb* db)
{
#ifdef wxUSE_ODBC
db->Close();
#endif
}
EWXWEXPORT(int,wxDb_CommitTrans)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->CommitTrans();
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_RollbackTrans)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->RollbackTrans();
#else
return false;
#endif
}
EWXWEXPORT(void*,wxDb_GetHENV)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->GetHENV();
#else
return Null_HENV();
#endif
}
EWXWEXPORT(void*,wxDb_GetHDBC)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->GetHDBC();
#else
return Null_HDBC();
#endif
}
EWXWEXPORT(void*,wxDb_GetHSTMT)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->GetHSTMT();
#else
return Null_HSTMT();
#endif
}
EWXWEXPORT(int,wxDb_GetNextError)(wxDb* db, void* henv, void* hdbc, void* hstmt)
{
#ifdef wxUSE_ODBC
return db->GetNextError( (HENV)(henv), (HDBC)(hdbc), (HSTMT)(hstmt) );
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_ExecSql)(wxDb* db, wxString* sql)
{
#ifdef wxUSE_ODBC
return db->ExecSql(*sql);
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetNext)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->GetNext();
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetData)(wxDb* db, int column, int ctype, void* data, int dataLen, int* usedLen )
{
#ifdef wxUSE_ODBC
long used;
bool result = db->GetData( column, ctype, data, dataLen, &used );
if (usedLen) *usedLen = used;
return result;
#else
if (usedLen) *usedLen = 0;
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetDataInt)(wxDb* db, int column, int* i, int* usedLen )
{
#ifdef wxUSE_ODBC
long used;
long value = 0;
bool result = db->GetData( column, SQL_C_LONG, &value, sizeof(value), &used );
if (usedLen) *usedLen = used;
if (i) *i = value;
return result;
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetDataDouble)(wxDb* db, int column, double* d, int* usedLen )
{
#ifdef wxUSE_ODBC
long used;
double value = 0;
bool result = db->GetData( column, SQL_C_DOUBLE, &value, sizeof(value), &used );
if (usedLen) *usedLen = used;
if (d) *d = value;
return result;
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetDataBinary)(wxDb* db, int column, bool asChars, char** pbuf, int* plen )
{
/* DAAN: A rather complicated procedure to retrieve SQL data as a string or
binary value. Since there is no trustworthy way to retrieve the size of
the returned data beforehand, we start with a static buffer that is at
least large enough to hold all basic data types. We than allocate the
correct size in the heap, or when the data buffer was too small, we
repetively call GetData to retrieve the rest of the data.
*/
#ifdef wxUSE_ODBC
#define STATICBUF_LEN 512
long needed = 0;
bool ok = false;
int sqlType = (asChars ? SQL_C_CHAR : SQL_C_BINARY);
char staticBuf[STATICBUF_LEN+1];
/* init args */
*pbuf = NULL;
*plen = 0;
/* get data */
ok = db->GetData( column, sqlType, staticBuf, STATICBUF_LEN, &needed );
/* case 1: no error and data is in 'staticBuf' */
if (ok) {
if (needed > 0 && needed != SQL_NULL_DATA) {
*pbuf = (char*)malloc( needed );
if (*pbuf==NULL) return false;
memcpy( *pbuf, staticBuf, needed );
}
*plen = needed;
return ok;
}
/* case 2: buffer was too small, repetitively read data */
else if (db->DB_STATUS == DB_ERR_DATA_TRUNCATED)
{
char* buf = NULL;
long bufLen = 0;
long totalLen = (asChars ? STATICBUF_LEN-1 : STATICBUF_LEN); /* less the terminating 0 ? */
/* try to allocate correct length */
if (needed > totalLen && needed != SQL_NO_TOTAL)
bufLen = needed + 16; /* DAAN: somehow, we need at least 2 more items to prevent reallocs */
else
bufLen = 2*STATICBUF_LEN;
buf = (char*)malloc( bufLen );
if (buf==NULL) return false;
memcpy( buf, staticBuf, totalLen );
ok = db->GetData( column, sqlType, buf+totalLen, bufLen-totalLen, &needed );
while (!ok && db->DB_STATUS == DB_ERR_DATA_TRUNCATED)
{
char* newbuf;
totalLen = (asChars ? bufLen-1 : bufLen); /* less the terminating 0 ? */
/* realloc the buffer exponentially */
newbuf = (char*)realloc( buf, 2*bufLen );
if (newbuf == NULL) {
free(buf);
return false;
}
buf = newbuf;
bufLen = 2*bufLen;
/* add more data */
ok = db->GetData( column, sqlType, buf+totalLen, bufLen-totalLen, &needed );
}
/* check for errors */
if (!ok || needed == SQL_NO_TOTAL) {
free(buf);
return false;
}
/* add the last added data length to the total length */
totalLen += needed;
/* set results */
*pbuf = buf;
*plen = totalLen;
return ok;
}
/* case 3: real error */
else {
*plen = needed; /* could contain error code */
return ok;
}
#else
if (pbuf) *pbuf = NULL;
if (plen) *plen = 0;
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetDataDate)(wxDb* db, int column, int* ctime, int* usedLen )
{
#if defined(wxUSE_ODBC) && defined(SQL_C_TYPE_DATE)
SQL_DATE_STRUCT date;
long used;
bool ok;
if (ctime) *ctime = -1;
ok = db->GetData( column, SQL_C_TYPE_DATE, &date, sizeof(date), &used );
if (usedLen) *usedLen = used;
if (ok && used != SQL_NULL_DATA) {
struct tm datetm;
time_t secs;
memset(&datetm,0,sizeof(datetm));
datetm.tm_year = date.year - 1900;
datetm.tm_mon = date.month - 1;
datetm.tm_mday = date.day;
datetm.tm_isdst = -1;
secs = mktime(&datetm);
if (ctime) *ctime = secs;
}
return ok;
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetDataTimeStamp)(wxDb* db, int column, int* ctime, int* fraction, int* usedLen )
{
#if defined(wxUSE_ODBC) && defined(SQL_C_TYPE_TIMESTAMP)
SQL_TIMESTAMP_STRUCT date;
long used;
bool ok;
if (ctime) *ctime = -1;
if (fraction) *fraction = -1;
ok = db->GetData( column, SQL_C_TYPE_TIMESTAMP, &date, sizeof(date), &used );
if (usedLen) *usedLen = used;
if (ok && used != SQL_NULL_DATA) {
struct tm datetm;
time_t secs;
memset(&datetm,0,sizeof(datetm));
datetm.tm_year = date.year - 1900;
datetm.tm_mon = date.month - 1;
datetm.tm_mday = date.day;
datetm.tm_hour = date.hour;
datetm.tm_min = date.minute;
datetm.tm_sec = date.second;
datetm.tm_isdst = -1;
secs = mktime(&datetm);
if (ctime) *ctime = secs;
if (fraction) *fraction = date.fraction;
}
return ok;
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetDataTime)(wxDb* db, int column, int* secs, int* usedLen )
{
#if defined(wxUSE_ODBC) && defined(SQL_C_TYPE_TIME)
SQL_TIME_STRUCT sqltime;
long used;
bool ok;
if (secs) *secs = -1;
ok = db->GetData( column, SQL_C_TYPE_TIME, &sqltime, sizeof(sqltime), &used );
if (usedLen) *usedLen = used;
if (ok && used != SQL_NULL_DATA) {
if (secs) *secs = 3600*sqltime.hour + 60*sqltime.minute + sqltime.second;
}
return ok;
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_Dbms)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->Dbms();
#else
return 0;
#endif
}
EWXWEXPORT(wxString*,wxDb_GetDatabaseName)(wxDb* db)
{
#ifdef wxUSE_ODBC
return new wxString(db->GetDatabaseName());
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDb_GetDatasourceName)(wxDb* db)
{
#ifdef wxUSE_ODBC
return new wxString(db->GetDatasourceName());
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDb_GetPassword)(wxDb* db)
{
#ifdef wxUSE_ODBC
return new wxString(db->GetPassword());
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDb_GetUsername)(wxDb* db)
{
#ifdef wxUSE_ODBC
return new wxString(db->GetUsername());
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDb_Grant)(wxDb* db, int privileges, wxString* tableName, wxString* userList )
{
#ifdef wxUSE_ODBC
return db->Grant(privileges, *tableName, *userList);
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_GetTableCount)(wxDb* db)
{
#ifdef wxUSE_ODBC
return db->GetTableCount();
#else
return 0;
#endif
}
EWXWEXPORT(wxDbInf*,wxDb_GetCatalog)( wxDb* db, wxString* userName )
{
#ifdef wxUSE_ODBC
if (userName!=NULL && userName->IsEmpty()) {
userName=NULL;
}
return db->GetCatalog((userName ? userName->c_str() : NULL));
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDb_GetColumnCount)(wxDb* db, wxString* tableName, wxString* userName )
{
#ifdef wxUSE_ODBC
if (userName!=NULL && userName->IsEmpty()) {
userName=NULL;
}
return db->GetColumnCount((userName ? userName->c_str() : NULL));
#else
return 0;
#endif
}
EWXWEXPORT(wxDbColInf*,wxDb_GetColumns)(wxDb* db, wxString* tableName, int* columnCount, wxString* userName)
{
#ifdef wxUSE_ODBC
UWORD count = 0;
wxDbColInf* result = NULL;
if (userName!=NULL && userName->IsEmpty()) {
userName=NULL;
}
result = db->GetColumns(*tableName,&count,(userName ? userName->c_str() : NULL));
if (columnCount) *columnCount = count;
return result;
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDb_Open)(wxDb* db, wxString* dsn, wxString* userId, wxString* password)
{
#ifdef wxUSE_ODBC
return db->Open(*dsn,*userId,*password);
#else
return false;
#endif
}
EWXWEXPORT(wxString*,wxDb_SQLColumnName)(wxDb* db, wxString* columnName)
{
#ifdef wxUSE_ODBC
return new wxString(db->SQLColumnName(*columnName));
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDb_SQLTableName)(wxDb* db, wxString* tableName)
{
#ifdef wxUSE_ODBC
return new wxString(db->SQLTableName(*tableName));
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDb_TableExists)(wxDb* db, wxString* tableName, wxString* userName, wxString* path )
{
#ifdef wxUSE_ODBC
if (userName!=NULL && userName->IsEmpty()) {
userName=NULL;
}
return db->TableExists(*tableName,(userName ? userName->c_str() : NULL),*path);
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_TablePrivileges)(wxDb* db, wxString* tableName, wxString* privileges, wxString* userName, wxString* schema, wxString* path )
{
#ifdef wxUSE_ODBC
if (schema!=NULL && schema->IsEmpty()) {
schema=NULL;
}
return db->TablePrivileges(*tableName,*privileges,(userName==NULL ? wxT("") : userName->c_str()),(schema ? schema->c_str() : NULL),*path);
#else
return false;
#endif
}
EWXWEXPORT(int,wxDb_TranslateSqlState)(wxDb* db, wxString* sqlState)
{
#ifdef wxUSE_ODBC
return db->TranslateSqlState(*sqlState);
#else
return 0;
#endif
}
EWXWEXPORT(wxDb*,wxDb_Create)( HENV henv, bool fwdOnlyCursors )
{
#ifdef wxUSE_ODBC
return new wxDb(henv,fwdOnlyCursors);
#else
return NULL;
#endif
}
EWXWEXPORT(void,wxDb_Delete)( wxDb* db )
{
#ifdef wxUSE_ODBC
if (db!=NULL) delete db;
#endif
}
/*-----------------------------------------------------------------------------
DbInf
-----------------------------------------------------------------------------*/
EWXWEXPORT(wxString*,wxDbInf_GetCatalogName)( wxDbInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->catalog);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbInf_GetSchemaName)( wxDbInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->schema);
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDbInf_GetNumTables)( wxDbInf* self )
{
#ifdef wxUSE_ODBC
return (self->numTables);
#else
return 0;
#endif
}
EWXWEXPORT(wxDbTableInf*,wxDbInf_GetTableInf)( wxDbInf* self, int index )
{
#ifdef wxUSE_ODBC
if (self && self->pTableInf && index >= 0 && index < self->numTables)
return &self->pTableInf[index];
else
return NULL;
#else
return NULL;
#endif
}
EWXWEXPORT(void,wxDbInf_Delete)( wxDbInf* self )
{
#ifdef wxUSE_ODBC
if (self!=NULL) delete self;
#endif
}
/*-----------------------------------------------------------------------------
DbTableInf
-----------------------------------------------------------------------------*/
EWXWEXPORT(wxString*,wxDbTableInf_GetTableName)( wxDbTableInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->tableName);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbTableInf_GetTableType)( wxDbTableInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->tableType);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbTableInf_GetTableRemarks)( wxDbTableInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->tableRemarks);
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDbTableInf_GetNumCols)( wxDbTableInf* self )
{
#ifdef wxUSE_ODBC
return (self->numCols);
#else
return 0;
#endif
}
/*-----------------------------------------------------------------------------
DbColInfArray
-----------------------------------------------------------------------------*/
EWXWEXPORT(wxDbColInf*,wxDbColInfArray_GetColInf)( wxDbColInf* self, int index )
{
#ifdef wxUSE_ODBC
return &self[index];
#else
return NULL;
#endif
}
EWXWEXPORT(void,wxDbColInfArray_Delete)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
if (self!=NULL) delete [] self;
#endif
}
/*-----------------------------------------------------------------------------
DbColInf
-----------------------------------------------------------------------------*/
EWXWEXPORT(wxString*,wxDbColInf_GetCatalog)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->catalog);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetSchema)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->schema);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetTableName)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->tableName);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetColName)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->colName);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetTypeName)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->typeName);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetRemarks)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->remarks);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetPkTableName)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->PkTableName);
#else
return NULL;
#endif
}
EWXWEXPORT(wxString*,wxDbColInf_GetFkTableName)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return new wxString(self->FkTableName);
#else
return NULL;
#endif
}
EWXWEXPORT(int,wxDbColInf_GetSqlDataType)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return self->sqlDataType;
#else
return (-1);
#endif
}
EWXWEXPORT(int,wxDbColInf_GetColumnSize)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
#if (wxVERSION_NUMBER <= 2500)
return self->columnSize;
#else /* wxVERSION_NUMBER */
return self->columnLength;
#endif /* wxVERSION_NUMBER */
#else /* wxUSE_ODBC */
return (-1);
#endif /* wxUSE_ODBC */
}
EWXWEXPORT(int,wxDbColInf_GetBufferLength)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
#if (wxVERSION_NUMBER <= 2500)
return self->bufferLength;
#else /* wxVERSION_NUMBER */
return self->bufferSize;
#endif /* wxVERSION_NUMBER */
#else /* wxUSE_ODBC */
return (-1);
#endif /* wxUSE_ODBC */
}
EWXWEXPORT(int,wxDbColInf_GetDecimalDigits)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return self->decimalDigits;
#else
return (-1);
#endif
}
EWXWEXPORT(int,wxDbColInf_GetNumPrecRadix)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return self->numPrecRadix;
#else
return (-1);
#endif
}
EWXWEXPORT(int,wxDbColInf_GetDbDataType)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return self->dbDataType;
#else
return (-1);
#endif
}
EWXWEXPORT(int,wxDbColInf_GetPkCol)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return self->PkCol;
#else
return 0;
#endif
}
EWXWEXPORT(int,wxDbColInf_GetFkCol)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return self->FkCol;
#else
return 0;
#endif
}
EWXWEXPORT(int,wxDbColInf_IsNullable)( wxDbColInf* self )
{
#ifdef wxUSE_ODBC
return (self->nullable != 0);
#else
return false;
#endif
}
/*-----------------------------------------------------------------------------
Result set information.
Unfortunately, the wxWindows standard interface doesn't have a way
to retrieve column information for a query result -- so we add it
here ourselves.
-----------------------------------------------------------------------------*/
EWXWEXPORT(wxDbColInf*, wxDb_GetResultColumns)( wxDb* db, int* pnumCols )
{
#ifndef wxUSE_ODBC
if (pnumCols) *pnumCols = 0;
return NULL;
#else
RETCODE retcode = 0;
HSTMT hstmt = SQL_NULL_HSTMT;
SWORD numCols = 0;
UWORD column = 0;
wxDbColInf* colInf = NULL;
if (pnumCols) *pnumCols = 0;
if (db==NULL) return NULL;
/* allocate column info's */
hstmt = db->GetHSTMT();
retcode = SQLNumResultCols(hstmt,&numCols);
if (retcode != SQL_SUCCESS) {
db->DispAllErrors(db->GetHENV(), db->GetHDBC(), hstmt);
return NULL;
}
if (numCols==0) return NULL;
colInf = new wxDbColInf[numCols+1];
if (!colInf) return NULL;
/* mark the end of the array */
wxStrcpy(colInf[numCols].tableName, wxEmptyString);
wxStrcpy(colInf[numCols].colName, wxEmptyString);
colInf[numCols].sqlDataType = 0;
/* initialize all column infos */
for( column = 0; column < numCols; column++)
{
SWORD colNameLen = 0;
SWORD typeNameLen = 0;
UDWORD colSize = 0;
/* get the column information */
retcode = SQLDescribeCol(hstmt, column+1,
#ifndef wxUSE_UNICODE
(SQLCHAR*) colInf[column].colName,
#else
(SQLWCHAR*) colInf[column].colName,
#endif
DB_MAX_COLUMN_NAME_LEN+1, &colNameLen,
&colInf[column].sqlDataType,
&colSize,
&colInf[column].decimalDigits,
&colInf[column].nullable );
#if (wxVERSION_NUMBER <= 2500)
colInf[column].columnSize = colSize;
#else /* (wxVERSION_NUMBER <= 2500) */
colInf[column].columnLength = colSize;
#endif /* (wxVERSION_NUMBER <= 2500) */
/* check for errors */
if (retcode != SQL_SUCCESS) {
db->DispAllErrors(db->GetHENV(), db->GetHDBC(), hstmt);
delete [] colInf;
return NULL;
}
#ifdef SQL_DESC_TYPE_NAME
/* try to get type name too (errors are no problem) */
SQLColAttribute( hstmt, column+1, SQL_DESC_TYPE_NAME,
colInf[column].typeName, 128+1,
&typeNameLen, NULL );
#endif
/* for compatibilty with the wxWindows GetColumns, we set the dbDataType too */
colInf[column].dbDataType = 0;
switch (colInf[column].sqlDataType)
{
#ifndef wxUSE_UNICODE
#if defined(SQL_WVARCHAR)
case SQL_WVARCHAR:
#endif
#if defined(SQL_WCHAR)
case SQL_WCHAR:
#endif
#endif
case SQL_VARCHAR:
case SQL_CHAR:
colInf[column].dbDataType = DB_DATA_TYPE_VARCHAR;
break;
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
#ifdef SQL_BIGINT
case SQL_BIGINT:
#endif
#ifdef SQL_BIT
case SQL_BIT:
#endif
colInf[column].dbDataType = DB_DATA_TYPE_INTEGER;
break;
case SQL_DOUBLE:
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_FLOAT:
case SQL_REAL:
colInf[column].dbDataType = DB_DATA_TYPE_FLOAT;
break;
#ifdef SQL_DATE
case SQL_DATE:
colInf[column].dbDataType = DB_DATA_TYPE_DATE;
break;
#endif
#ifdef SQL_BINARY
case SQL_BINARY:
colInf[column].dbDataType = DB_DATA_TYPE_BLOB;
break;
#endif
#ifdef __WXDEBUG__
default:
wxString errMsg;
errMsg.Printf(wxT("SQL Data type %d currently not supported by wxWindows"), colInf[column].sqlDataType);
wxLogDebug(errMsg,wxT("ODBC DEBUG MESSAGE"));
#endif
}
} /* for columns */
if (pnumCols) *pnumCols = numCols;
return colInf;
#endif
}
}