From 07a1b81dadaceb46f1e25adbb25f610d9a4f80b5 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 10 Dec 2014 16:17:23 +0000 Subject: [PATCH] Aggiunto supporto logging transazioni ODBC git-svn-id: svn://10.65.10.50/branches/R_10_00@23026 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- xvaga/xvt.h | 1 + xvaga/xvtodbc.cpp | 489 ++++++++++++++++++++++++---------------------- 2 files changed, 261 insertions(+), 229 deletions(-) diff --git a/xvaga/xvt.h b/xvaga/xvt.h index 75a448050..916cb4f00 100755 --- a/xvaga/xvt.h +++ b/xvaga/xvt.h @@ -498,6 +498,7 @@ XVTDLL XVT_ODBC xvt_odbc_get_connection(const char* dsn, const char* usr, const XVTDLL BOOLEAN xvt_odbc_free_connection(XVT_ODBC handle); XVTDLL ULONG xvt_odbc_execute(XVT_ODBC handle, const char* sql, ODBC_CALLBACK cb, void* jolly); XVTDLL BOOLEAN xvt_odbc_driver(XVT_ODBC handle, char* str, int max_size); +XVTDLL BOOLEAN xvt_odbc_log_file(XVT_ODBC handle, const char* str); XVTDLL BOOLEAN xvt_sql_begin(XVT_SQLDB handle); XVTDLL BOOLEAN xvt_sql_close(XVT_SQLDB handle); diff --git a/xvaga/xvtodbc.cpp b/xvaga/xvtodbc.cpp index 2fdeb9057..11401173b 100755 --- a/xvaga/xvtodbc.cpp +++ b/xvaga/xvtodbc.cpp @@ -1,229 +1,260 @@ -#include "wxinc.h" -#include "xvt.h" - -#include - -/////////////////////////////////////////////////////////// -// 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; -} - -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 - { - // Senza callback mi limito a contare i records - if (db->ExecSql(sql)) - { - for (nCount = 0; db->GetNext(); nCount++); - } - } - } - - 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; -} +#include "wxinc.h" +#include "xvt.h" + +#include + +/////////////////////////////////////////////////////////// +// 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; +}