2014-06-24 12:45:40 +00:00
|
|
|
#include "wxinc.h"
|
|
|
|
#include "xvt.h"
|
|
|
|
|
|
|
|
#include "../wxSqlite3/wxSqlite3.h"
|
|
|
|
|
|
|
|
class XVT_SQLDataBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual bool Open(const char* dsn, const char* usr, const char* pwd, const char* dir) = 0;
|
|
|
|
virtual bool Close() = 0 { return false; }
|
|
|
|
virtual bool IsOk() const = 0 { return false; }
|
|
|
|
virtual ULONG Execute(const char* sql, ODBC_CALLBACK cb, void* jolly) = 0;
|
|
|
|
virtual SLIST ListFields(const char* table) const = 0;
|
|
|
|
virtual SLIST ListTables() const = 0;
|
|
|
|
virtual bool TableExists(const char* name) const;
|
|
|
|
|
2014-07-30 13:01:24 +00:00
|
|
|
virtual bool Begin() const { return false; }
|
|
|
|
virtual bool Commit() const { return false; }
|
|
|
|
virtual bool Rollback() const { return false; }
|
|
|
|
|
2014-06-24 12:45:40 +00:00
|
|
|
virtual ~XVT_SQLDataBase() { Close(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
bool XVT_SQLDataBase::TableExists(const char* name) const
|
|
|
|
{
|
|
|
|
bool yes = false;
|
|
|
|
SLIST list = ListTables();
|
|
|
|
for (SLIST_ELT e = xvt_slist_get_first(list); e != NULL && !yes; e = xvt_slist_get_next(list, e))
|
|
|
|
{
|
|
|
|
const char* table = xvt_slist_get(list, e, NULL);
|
|
|
|
yes = xvt_str_compare_ignoring_case(name, table) == 0;
|
|
|
|
}
|
|
|
|
xvt_slist_destroy(list);
|
|
|
|
|
|
|
|
return yes;
|
|
|
|
}
|
|
|
|
|
|
|
|
class XVT_SQLDB_SQLite3 : public XVT_SQLDataBase
|
|
|
|
{
|
|
|
|
wxSQLite3Database* m_pDB;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual bool Open(const char* dsn, const char* usr, const char* pwd, const char* dir);
|
|
|
|
virtual bool Close();
|
|
|
|
virtual bool IsOk() const { return m_pDB != NULL && m_pDB->IsOpen(); }
|
|
|
|
virtual ULONG Execute(const char* sql, ODBC_CALLBACK cb, void* jolly);
|
|
|
|
virtual SLIST ListFields(const char* table) const;
|
|
|
|
virtual SLIST ListTables() const;
|
|
|
|
virtual bool TableExists(const char* name) const;
|
|
|
|
|
|
|
|
public:
|
2014-07-30 13:01:24 +00:00
|
|
|
virtual bool Begin() const;
|
|
|
|
virtual bool Commit() const;
|
|
|
|
virtual bool Rollback() const;
|
|
|
|
|
2014-06-24 12:45:40 +00:00
|
|
|
XVT_SQLDB_SQLite3() : m_pDB(NULL) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool XVT_SQLDB_SQLite3::Open(const char* dsn, const char*, const char*, const char*)
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
m_pDB = new wxSQLite3Database;
|
|
|
|
if (dsn == NULL || *dsn <= ' ')
|
|
|
|
dsn = ":memory:";
|
|
|
|
try
|
|
|
|
{
|
|
|
|
m_pDB->Open(dsn);
|
|
|
|
}
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XVT_SQLDB_SQLite3::Close()
|
|
|
|
{
|
|
|
|
if (IsOk())
|
|
|
|
{
|
|
|
|
delete m_pDB;
|
|
|
|
m_pDB = NULL;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-07-30 13:01:24 +00:00
|
|
|
bool XVT_SQLDB_SQLite3::Begin() const
|
|
|
|
{
|
|
|
|
bool bDone = IsOk();
|
|
|
|
if (bDone)
|
|
|
|
{
|
|
|
|
try { m_pDB->Begin(); }
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage());
|
|
|
|
bDone = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bDone;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XVT_SQLDB_SQLite3::Commit() const
|
|
|
|
{
|
|
|
|
bool bDone = IsOk();
|
|
|
|
if (bDone)
|
|
|
|
{
|
|
|
|
try { m_pDB->Commit(); }
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage());
|
|
|
|
bDone = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bDone;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XVT_SQLDB_SQLite3::Rollback() const
|
|
|
|
{
|
|
|
|
bool bDone = IsOk();
|
|
|
|
if (bDone)
|
|
|
|
{
|
|
|
|
try { m_pDB->Rollback(); }
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage());
|
|
|
|
bDone = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bDone;
|
|
|
|
}
|
|
|
|
|
2014-06-24 12:45:40 +00:00
|
|
|
ULONG XVT_SQLDB_SQLite3::Execute(const char* sql, ODBC_CALLBACK cb, void* jolly)
|
|
|
|
{
|
|
|
|
ULONG nRows = 0;
|
|
|
|
if (!IsOk())
|
|
|
|
return nRows;
|
|
|
|
|
|
|
|
if (cb != NULL) // Ho una vera callback?
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
wxSQLite3ResultSet rs = m_pDB->ExecuteQuery(sql);
|
2014-07-30 13:01:24 +00:00
|
|
|
short numcols = rs.GetColumnCount();
|
2014-06-24 12:45:40 +00:00
|
|
|
|
|
|
|
if (numcols > 0)
|
|
|
|
{
|
2014-07-30 13:01:24 +00:00
|
|
|
wxArrayString aNames, aValues;
|
|
|
|
|
|
|
|
const short nMaxCols = 256;
|
|
|
|
char* values[nMaxCols]; // Lista dei valori del record corrente
|
|
|
|
memset(values, 0, sizeof(values));
|
2014-06-24 12:45:40 +00:00
|
|
|
|
2014-07-30 13:01:24 +00:00
|
|
|
char* names[2*nMaxCols]; // Lista dei nomi dei campi e dei tipi
|
|
|
|
memset(names, 0, sizeof(names));
|
|
|
|
|
|
|
|
if (numcols > nMaxCols)
|
|
|
|
numcols = nMaxCols;
|
2014-06-24 12:45:40 +00:00
|
|
|
|
|
|
|
short c;
|
|
|
|
for (c = 0; c < numcols; c++)
|
|
|
|
{
|
2014-07-30 13:01:24 +00:00
|
|
|
aNames.Add(rs.GetColumnName(c));
|
|
|
|
names[c] = (char*)(const char*)aNames[c];
|
2014-06-24 12:45:40 +00:00
|
|
|
switch (rs.GetColumnType(c))
|
|
|
|
{
|
|
|
|
case WXSQLITE_INTEGER:
|
|
|
|
case WXSQLITE_FLOAT:
|
|
|
|
names[c+numcols] = "NUMERIC"; break;
|
|
|
|
default:
|
|
|
|
names[c+numcols] = "VARCHAR"; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (rs.NextRow())
|
|
|
|
{
|
2014-07-30 13:01:24 +00:00
|
|
|
aValues.Empty();
|
2014-06-24 12:45:40 +00:00
|
|
|
for (c = 0; c < numcols; c++)
|
2014-07-30 13:01:24 +00:00
|
|
|
{
|
|
|
|
aValues.Add(rs.GetAsString(c));
|
|
|
|
values[c] = (char*)(const char*)aValues[c];
|
|
|
|
}
|
2014-06-24 12:45:40 +00:00
|
|
|
if (cb(jolly, numcols, values, names) != 0)
|
|
|
|
break;
|
|
|
|
nRows++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage() + "\n" + sql);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nRows = m_pDB->ExecuteUpdate(sql);
|
|
|
|
|
|
|
|
return nRows;
|
|
|
|
}
|
|
|
|
|
|
|
|
SLIST XVT_SQLDB_SQLite3::ListTables() const
|
|
|
|
{
|
|
|
|
wxASSERT(m_pDB != NULL);
|
|
|
|
SLIST list = xvt_slist_create();
|
|
|
|
const wxString strQuery = wxT("SELECT name FROM sqlite_master WHERE type = 'table'");
|
|
|
|
try
|
|
|
|
{
|
|
|
|
wxSQLite3ResultSet rs = m_pDB->ExecuteQuery(strQuery);
|
|
|
|
while (rs.NextRow())
|
|
|
|
xvt_slist_add_at_elt(list, NULL, rs.GetAsString(0), 0L);
|
|
|
|
}
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage() + "\n" + strQuery);
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
SLIST XVT_SQLDB_SQLite3::ListFields(const char* strTable) const
|
|
|
|
{
|
|
|
|
SLIST list = NULL;
|
|
|
|
if (TableExists(strTable))
|
|
|
|
{
|
|
|
|
list = xvt_slist_create();
|
|
|
|
wxString strQuery; strQuery << "PRAGMA table_info(" << (const char*)strTable << ");";
|
|
|
|
try
|
|
|
|
{
|
|
|
|
wxSQLite3ResultSet rs = m_pDB->ExecuteQuery(strQuery);
|
|
|
|
while (rs.NextRow())
|
|
|
|
{
|
|
|
|
const wxString strField = rs.GetAsString(1);
|
|
|
|
const wxString strType = rs.GetAsString(2);
|
|
|
|
if (strType == "INTEGER")
|
|
|
|
xvt_slist_add_at_elt(list, NULL, strField, 2L); // intfld
|
|
|
|
if (strType == "NUMERIC")
|
|
|
|
xvt_slist_add_at_elt(list, NULL, strField, 5L); // realfld
|
|
|
|
else
|
|
|
|
xvt_slist_add_at_elt(list, NULL, strField, 1L); // alfafld
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage() + "\n" + strQuery);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XVT_SQLDB_SQLite3::TableExists(const char* name) const
|
|
|
|
{
|
|
|
|
return m_pDB != NULL && name && *name && m_pDB->TableExists(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// xvt_sql_...
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
XVT_SQLDB xvt_sql_open(const char* dsn, const char* usr, const char* pwd, const char* dir)
|
|
|
|
{
|
|
|
|
XVT_SQLDataBase* db = new XVT_SQLDB_SQLite3;
|
|
|
|
db->Open(dsn, usr, pwd, dir);
|
|
|
|
return (XVT_SQLDB)db;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN xvt_sql_close(XVT_SQLDB handle)
|
|
|
|
{
|
|
|
|
BOOLEAN ok = handle != NULL;
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db != NULL)
|
|
|
|
delete db;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2014-07-30 13:01:24 +00:00
|
|
|
BOOLEAN xvt_sql_begin(XVT_SQLDB handle)
|
|
|
|
{
|
|
|
|
BOOLEAN ok = handle != NULL;
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db != NULL)
|
|
|
|
ok = db->Begin();
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN xvt_sql_commit(XVT_SQLDB handle)
|
|
|
|
{
|
|
|
|
BOOLEAN ok = handle != NULL;
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db != NULL)
|
|
|
|
ok = db->Commit();
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN xvt_sql_rollback(XVT_SQLDB handle)
|
|
|
|
{
|
|
|
|
BOOLEAN ok = handle != NULL;
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db != NULL)
|
|
|
|
ok = db->Rollback();
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2014-06-24 12:45:40 +00:00
|
|
|
ULONG xvt_sql_execute(XVT_SQLDB handle, const char* sql, ODBC_CALLBACK cb, void* jolly)
|
|
|
|
{
|
|
|
|
ULONG n = 0;
|
|
|
|
if (handle && sql && *sql)
|
|
|
|
{
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db->IsOk())
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
n = db->Execute(sql, cb, jolly);
|
|
|
|
}
|
|
|
|
catch(wxSQLite3Exception& e)
|
|
|
|
{
|
|
|
|
xvt_dm_post_error(e.GetMessage() + "\n" + sql);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
SLIST xvt_sql_list_fields(XVT_SQLDB handle, const char* table)
|
|
|
|
{
|
|
|
|
SLIST list = NULL;
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (table && *table && db != NULL && db->IsOk())
|
|
|
|
list = db->ListFields(table);
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
SLIST xvt_sql_list_tables(XVT_SQLDB handle)
|
|
|
|
{
|
|
|
|
SLIST list = NULL;
|
|
|
|
XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db != NULL && db->IsOk())
|
|
|
|
list = db->ListTables();
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN xvt_sql_table_exists(XVT_SQLDB handle, const char* name)
|
|
|
|
{
|
|
|
|
BOOLEAN yes = FALSE;
|
|
|
|
if (handle && name && *name)
|
|
|
|
{
|
|
|
|
const XVT_SQLDataBase* db = (XVT_SQLDataBase*)handle;
|
|
|
|
if (db->IsOk())
|
|
|
|
yes = db->TableExists(name);
|
|
|
|
}
|
|
|
|
return yes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN xvt_sql_driver(XVT_SQLDB handle, char* str, int max_size)
|
|
|
|
{
|
|
|
|
if (str != NULL && max_size > 8)
|
|
|
|
{
|
|
|
|
if (handle != NULL)
|
|
|
|
wxStrncpy(str, "SQLite 3", max_size);
|
|
|
|
else
|
|
|
|
wxStrncpy(str, "ODBC 2.0", max_size);
|
|
|
|
}
|
|
|
|
return handle != NULL;
|
|
|
|
}
|