campo-sirio/xvaga/xvtodbc.cpp
guy 07a1b81dad Aggiunto supporto logging transazioni ODBC
git-svn-id: svn://10.65.10.50/branches/R_10_00@23026 c028cbd2-c16b-5b4b-a496-9718f37d4682
2014-12-10 16:17:23 +00:00

261 lines
7.2 KiB
C++
Executable File

#include "wxinc.h"
#include "xvt.h"
#include <wx/db.h>
///////////////////////////////////////////////////////////
// TwxConnectionDlg
///////////////////////////////////////////////////////////
class TwxConnectionDlg : public wxDialog
{
protected:
wxTextCtrl* AddString(wxSizer* ctlSizer, int id, const char* label, wxString* str);
public:
wxString _strDsn, _strUsr, _strPwd, _strDir;
TwxConnectionDlg();
};
wxTextCtrl* TwxConnectionDlg::AddString(wxSizer* ctlSizer, int id, const char* label, wxString* str)
{
wxStaticText* lbl = new wxStaticText(this, wxID_ANY, label);
const int k = 20, b = k/10;
wxTextCtrl* txt = new wxTextCtrl(this, id, wxEmptyString, wxDefaultPosition, wxSize(20*k, k),
0, wxTextValidator(wxFILTER_ASCII, str));
ctlSizer->Add(lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, b);
ctlSizer->Add(txt, 1, wxALIGN_LEFT | wxALL, b);
return txt;
}
TwxConnectionDlg::TwxConnectionDlg() : wxDialog(NULL, wxID_ANY, "ODBC",
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE)
{
wxSizer* ctlTextSizer = new wxFlexGridSizer(4, 2, 8, 8);
AddString(ctlTextSizer, 1001, "Dsn", &_strDsn);
AddString(ctlTextSizer, 1002, "User", &_strUsr);
AddString(ctlTextSizer, 1003, "Password", &_strPwd);
AddString(ctlTextSizer, 1004, "Directory", &_strDir);
wxSizer* ctlButtonSizer = CreateButtonSizer(wxOK | wxCANCEL);
wxBoxSizer* ctlTopSizer = new wxBoxSizer(wxVERTICAL);
ctlTopSizer->Add(ctlTextSizer, 0, wxALIGN_CENTER);
ctlTopSizer->Add(ctlButtonSizer, 0, wxALIGN_CENTER);
SetSizer(ctlTopSizer);
ctlTopSizer->SetSizeHints(this);
}
///////////////////////////////////////////////////////////
// xvt_odbc_...
///////////////////////////////////////////////////////////
XVT_ODBC xvt_odbc_get_connection(const char* dsn, const char* usr, const char* pwd, const char* dir)
{
static wxDbConnectInf* ci = NULL;
if (ci == NULL)
{
ci = new wxDbConnectInf;
ci->AllocHenv();
}
wxString strDsn(dsn), strUsr(usr), strPwd(pwd), strDir(dir);
if (strDsn.IsEmpty())
{
TwxConnectionDlg* dlg = new TwxConnectionDlg;
if (dlg->ShowModal() == wxID_OK)
{
strDsn = dlg->_strDsn;
strUsr = dlg->_strUsr;
strPwd = dlg->_strPwd;
strDir = dlg->_strDir;
}
dlg->Destroy();
if (strDsn.IsEmpty())
return NULL;
}
bool bSuccess = false;
wxDb* db = new wxDb(ci->GetHenv(), true);
if (strDsn.Find(';') > 0)
bSuccess = db->Open(strDsn); // Use connection string
else
bSuccess = db->Open(strDsn, strUsr, strPwd, true); // Use DSN, user and password
if (!bSuccess)
{
delete db;
db = NULL;
}
return (XVT_ODBC)db;
}
BOOLEAN xvt_odbc_free_connection(XVT_ODBC handle)
{
BOOLEAN ok = handle != NULL;
if (ok)
{
wxDb* db = (wxDb*)handle;
db->CommitTrans();
db->Close();
delete db;
}
return ok;
}
BOOLEAN xvt_odbc_log_file(XVT_ODBC handle, const char* str)
{
BOOLEAN ok = handle != NULL;
if (ok)
{
wxDb* db = (wxDb*)handle;
if (str && *str)
ok = db->SetSqlLogging(sqlLogON, wxString(str));
else
db->SetSqlLogging(sqlLogOFF, wxEmptyString);
}
return ok;
}
ULONG xvt_odbc_execute(XVT_ODBC handle, const char* sql, ODBC_CALLBACK cb, void* jolly)
{
ULONG nCount = 0;
if (handle && sql && *sql)
{
wxDb* db = (wxDb*)handle;
if (cb != NULL) // Ho una vera callback?
{
wxDbColInf* columns = NULL;
short numcols = 0;
if (db->ExecSql(sql, &columns, numcols) && numcols > 0)
{
const size_t BUF_SIZE = 1024*64;
char* buffer = new char[BUF_SIZE]; // Valore di un singolo campo
char** values = new char*[numcols]; // Lista dei valori del record corrente
memset(values, 0, numcols*sizeof(char*));
char** names = new char*[numcols*2]; // Lista dei nomi dei campi e dei tipi
memset(names, 0, numcols*2*sizeof(char*));
short c;
for (c = 0; c < numcols; c++)
{
const wxDbColInf& info = columns[c];
names[c] = (char*)info.colName;
switch (info.dbDataType)
{
case DB_DATA_TYPE_INTEGER:
case DB_DATA_TYPE_FLOAT:
names[c+numcols] = "NUMERIC"; break;
case DB_DATA_TYPE_DATE:
names[c+numcols] = "DATE"; break;
default:
names[c+numcols] = "VARCHAR"; break;
}
}
wxArrayString data;
for (nCount = 0; db->GetNext(); nCount++)
{
data.Empty(); // Svuota l'array
for (c = 0; c < numcols; c++)
{
const wxDbColInf& info = columns[c];
try
{
SDWORD cbReturned = SQL_NULL_DATA;
switch (info.dbDataType)
{
case DB_DATA_TYPE_DATE:
{
db->GetData(c+1, SQL_C_CHAR, buffer, BUF_SIZE, &cbReturned);
int d = 0, m = 0, y = 0;
int n = sscanf(buffer, "%04d-%02d-%02d", &y, &m, &d);
if (n == 3 && d > 0)
sprintf(buffer, "%04d%02d%02d", y, m, d);
else
buffer[0] = '\0';
}
break;
default:
db->GetData(c+1, SQL_C_CHAR, buffer, BUF_SIZE, &cbReturned);
break;
}
if (cbReturned == SQL_NULL_DATA)
buffer[0] = '\0';
data.Add(buffer);
}
catch (...)
{
break;
}
}
for (c = 0; c < (short)data.GetCount(); c++)
values[c] = (char*)data[c].c_str();
const int err = cb(jolly, numcols, values, names);
if (err != 0)
break;
}
delete values; // butta la lista dei valori
delete names; // butta la lista dei nomi
delete buffer; // butta il buffer temporaneo
}
}
else
{
wxString cmd(sql); cmd.MakeUpper();
if (cmd.StartsWith("BEGIN"))
/* DO NOTHING! */; else
if (cmd.StartsWith("COMMIT"))
db->CommitTrans(); else
if (cmd.StartsWith("SELECT"))
{
// Senza callback mi limito a contare i records
if (db->ExecSql(sql))
for (nCount = 0; db->GetNext(); nCount++);
}
else
{
db->SetDebugErrorMessages(true);
if (db->ExecSql(sql))
nCount = 1;
else
nCount = -db->nativeError;
db->SetDebugErrorMessages(false);
}
}
}
return nCount;
}
BOOLEAN xvt_odbc_driver(XVT_ODBC handle, char* str, int max_size)
{
if (str != NULL && max_size > 8)
{
if (handle != NULL)
{
const wxDb* db = (const wxDb*)handle;
wxStrncpy(str, db->dbInf.driverName, max_size);
}
else
wxStrncpy(str, "ODBC 2.0", max_size);
}
return handle != NULL;
}