Patch level : 12.0 no-patch
Files correlati : Commento : - Aggiunta la possibilità di generare DLL o libreria - tolti identificatori che generavano warnings per TT_driver e isoLvl - tolta xvt_create_connection, la connection viene creata nella classe e non più condivisa - Disabilitato il copy contructor: se quelli di sqlapi li hanno fatto avranno le loro buone ragioni - rese const isConnect() e isAlive() - Creato files per contenere i codici di errore git-svn-id: svn://10.65.10.50/branches/R_10_00@24361 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
dbbd6bddcc
commit
34ceaffc52
@ -1,46 +1,13 @@
|
||||
#include "xvtdb.h"
|
||||
#include <sqlapi.h>
|
||||
#include <string> // sprintf_s
|
||||
|
||||
#define _CON(a) ((SAConnection *)a)
|
||||
#define _RCS(a) ((SACommand *)a)
|
||||
#define _ERR(a) ((SAException *)a)
|
||||
|
||||
// Funzione per la connessione, utilizzando un DBMS devo controllare sempre
|
||||
int xvt_create_connection(P_CONN_VOID con, const char* db, const char* user, const char* pass, TT_driver tipoDb)
|
||||
{
|
||||
if(con != NULL)
|
||||
{
|
||||
// Se è già connesso lo scollego
|
||||
if(_CON(con)->isConnected())
|
||||
_CON(con)->Disconnect();
|
||||
|
||||
SAString dbAddress = db;
|
||||
SAString usr = user;
|
||||
SAString psw = pass;
|
||||
SAClient_t dbDriver = (SAClient_t)tipoDb;
|
||||
if (dbAddress.IsEmpty() || usr.IsEmpty())
|
||||
{
|
||||
return NOT_INITIALIZED;
|
||||
}
|
||||
try
|
||||
{
|
||||
// Mi collego
|
||||
_CON(con)->Connect(dbAddress, usr, psw, dbDriver);
|
||||
// Imposto che non si possono vedere i record non committati
|
||||
_CON(con)->setIsolationLevel(SA_ReadCommitted);
|
||||
}
|
||||
catch (SAException &x)
|
||||
{
|
||||
return x.ErrNativeCode();
|
||||
}
|
||||
return NOERR;
|
||||
}
|
||||
return NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* TXvt_recordset *
|
||||
* TXvt_recordset *
|
||||
* Classe per esecuzioni di query temporanee (wrapper semplice per SACommand) *
|
||||
******************************************************************************/
|
||||
|
||||
@ -61,9 +28,10 @@ TXvt_recordset::TXvt_recordset()
|
||||
|
||||
|
||||
TXvt_recordset::TXvt_recordset(const char* db, const char* user, const char* pass, TT_driver tipoDb, const char * query, const bool ex, const bool freezed)
|
||||
: _db(db), _usr(user), _psw(pass), _drv(tipoDb)
|
||||
{
|
||||
_con = new SAConnection;
|
||||
if(xvt_create_connection(_con, db, user, pass, tipoDb) == NOERR)
|
||||
if(connect(db, user, pass, tipoDb) == NOERR)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -90,59 +58,27 @@ TXvt_recordset::TXvt_recordset(const char* db, const char* user, const char* pas
|
||||
}
|
||||
}
|
||||
|
||||
TXvt_recordset::TXvt_recordset(P_CONN_VOID c, const char * query, bool ex)
|
||||
{
|
||||
_toDisconnect = true;
|
||||
//_con = c;
|
||||
memcpy(_con, c, sizeof(c));
|
||||
if (!_CON(_con)->isConnected())
|
||||
bool tolla = true;
|
||||
_recno = -1;
|
||||
try
|
||||
{
|
||||
_recset = new SACommand;
|
||||
_RCS(_recset)->setConnection(_CON(_con));
|
||||
// if (query[0] != '\0')
|
||||
if (query && *query)
|
||||
{
|
||||
set(query);
|
||||
if (ex)
|
||||
{
|
||||
exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SAException &x)
|
||||
{
|
||||
_codeError = x.ErrNativeCode();
|
||||
_stringError = x.ErrMessage();
|
||||
}
|
||||
}
|
||||
|
||||
TXvt_recordset::~TXvt_recordset()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(_toDisconnect && _CON(_con)->isConnected())
|
||||
if(_CON(_con)->isConnected())
|
||||
_CON(_con)->Disconnect();
|
||||
if(_con != NULL)
|
||||
delete _con;
|
||||
if(_recset != NULL)
|
||||
delete _recset;
|
||||
}
|
||||
catch(...){}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
/* PRIVATE FUNCTIONS **************************************************************************************************/
|
||||
|
||||
const bool TXvt_recordset::checkPermission()
|
||||
{
|
||||
bool err = isFreezed();
|
||||
if(err)
|
||||
{
|
||||
_codeError = ERROR_FREEZED;
|
||||
_stringError = "Il recordset è bloccato";
|
||||
}
|
||||
bool err = is_freezed();
|
||||
if (err)
|
||||
setErrorFreezed();
|
||||
return !err;
|
||||
}
|
||||
|
||||
@ -154,7 +90,44 @@ const bool TXvt_recordset::checkPermission()
|
||||
|
||||
int TXvt_recordset::connect(const char* db, const char* user, const char* pass, TT_driver tipoDb)
|
||||
{
|
||||
return xvt_create_connection(_con, db, user, pass, tipoDb);
|
||||
if (_con != NULL)
|
||||
{
|
||||
// Se è già connesso lo scollego
|
||||
if (_CON(_con)->isConnected())
|
||||
_CON(_con)->Disconnect();
|
||||
|
||||
SAString dbAddress = db;
|
||||
SAString usr = user;
|
||||
SAString psw = pass;
|
||||
SAClient_t dbDriver = (SAClient_t)tipoDb;
|
||||
if (dbAddress.IsEmpty() || usr.IsEmpty())
|
||||
{
|
||||
_codeError = NOT_INITIALIZED;
|
||||
_stringError = NOT_INITIALIZEDS;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Mi collego
|
||||
_CON(_con)->Connect(dbAddress, usr, psw, dbDriver);
|
||||
// Imposto che non si possono vedere i record non committati
|
||||
_CON(_con)->setIsolationLevel(SA_ReadCommitted);
|
||||
return NOERR;
|
||||
}
|
||||
catch (SAException &x)
|
||||
{
|
||||
_codeError = x.ErrNativeCode();
|
||||
_stringError = x.ErrMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_codeError = NOT_INITIALIZED;
|
||||
_stringError = NOT_INITIALIZEDS;
|
||||
}
|
||||
return _codeError;
|
||||
}
|
||||
|
||||
void TXvt_recordset::disconnect()
|
||||
@ -172,6 +145,7 @@ void TXvt_recordset::disconnect()
|
||||
|
||||
bool TXvt_recordset::commit(bool autoRoll)
|
||||
{
|
||||
CHECK_FREEZED
|
||||
try
|
||||
{
|
||||
_CON(_con)->Commit();
|
||||
@ -191,6 +165,7 @@ bool TXvt_recordset::commit(bool autoRoll)
|
||||
|
||||
bool TXvt_recordset::rollback()
|
||||
{
|
||||
CHECK_FREEZED
|
||||
try
|
||||
{
|
||||
_CON(_con)->Rollback();
|
||||
@ -232,11 +207,11 @@ void TXvt_recordset::setVisibility(isoLvl vis)
|
||||
_CON(_con)->setIsolationLevel((SAIsolationLevel_t)vis);
|
||||
}
|
||||
|
||||
bool TXvt_recordset::isConnect()
|
||||
const bool TXvt_recordset::isConnect() const
|
||||
{
|
||||
return _CON(_con)->isConnected();
|
||||
}
|
||||
bool TXvt_recordset::isAlive()
|
||||
const bool TXvt_recordset::isAlive() const
|
||||
{
|
||||
return _CON(_con)->isAlive();
|
||||
}
|
||||
@ -265,14 +240,53 @@ long TXvt_recordset::getServerVN()
|
||||
return _CON(_con)->ServerVersion();
|
||||
}
|
||||
|
||||
bool TXvt_recordset::isLoaded() const
|
||||
{
|
||||
return _loaded;
|
||||
}
|
||||
|
||||
long TXvt_recordset::items()
|
||||
{
|
||||
// Per non creare casini utilizzo una funzione apposita che mi ritorna il numero
|
||||
P_CONN_VOID conn = new SAConnection;
|
||||
char q[500];
|
||||
long items;
|
||||
|
||||
// Connetto la nuova istanza
|
||||
_CON(conn)->Connect(_db, _usr, _psw, (SAClient_t)_drv);
|
||||
|
||||
// Controllo sia tutto a posto
|
||||
|
||||
// Creo la query
|
||||
strcat_s(q, sizeof(q), "SELECT COUNT(*) ");
|
||||
strcat_s(q, sizeof(q), (strstr(_query, "FROM") != NULL ? strstr(_query, "FROM") : strstr(_query, "from"))); // Serve?
|
||||
|
||||
items = xvt_rcs_get_items(conn, q);
|
||||
if(conn != _con)
|
||||
delete conn;
|
||||
return items;
|
||||
}
|
||||
|
||||
long xvt_rcs_get_items(P_CONN_VOID con, const char* query)
|
||||
{
|
||||
P_COMM_VOID rcs = new SACommand(_CON(con));
|
||||
_RCS(rcs)->setCommandText(query);
|
||||
long r = 0;
|
||||
for(bool ok = _RCS(rcs)->FetchFirst(); ok; ok = _RCS(rcs)->FetchNext())
|
||||
r++;
|
||||
delete rcs;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
* Gestione Recordset *
|
||||
**************************************************************************************************/
|
||||
bool TXvt_recordset::set(const char* query)
|
||||
{
|
||||
CHECK_FREEZED
|
||||
try
|
||||
{
|
||||
_query = query;
|
||||
_RCS(_recset)->setCommandText(query);
|
||||
}
|
||||
catch (SAException &x)
|
||||
@ -286,6 +300,7 @@ bool TXvt_recordset::set(const char* query)
|
||||
|
||||
bool TXvt_recordset::exec(bool autoF)
|
||||
{
|
||||
CHECK_FREEZED
|
||||
try
|
||||
{
|
||||
_RCS(_recset)->Execute();
|
||||
@ -420,6 +435,11 @@ bool TXvt_recordset::go(int newPos)
|
||||
return result;
|
||||
}
|
||||
|
||||
const int TXvt_recordset::rowsAffected()
|
||||
{
|
||||
return _RCS(_recset)->RowsAffected();
|
||||
}
|
||||
|
||||
int TXvt_recordset::get_int(const char* field)
|
||||
{
|
||||
try
|
||||
@ -430,7 +450,6 @@ int TXvt_recordset::get_int(const char* field)
|
||||
{
|
||||
_codeError = x.ErrNativeCode();
|
||||
_stringError = x.ErrMessage();
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -498,7 +517,7 @@ real TXvt_recordset::GetReal(const char * field)
|
||||
return Get(field);
|
||||
}
|
||||
*/
|
||||
const char* TXvt_recordset::getDate(const char * field)
|
||||
const char* TXvt_recordset::get_date(const char * field)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -543,7 +562,7 @@ char TXvt_recordset::get_char(const char* field)
|
||||
}
|
||||
}
|
||||
|
||||
long TXvt_recordset::getCodeError(bool erase)
|
||||
long TXvt_recordset::get_code_error(bool erase)
|
||||
{
|
||||
long app = _codeError;
|
||||
if (erase)
|
||||
@ -551,10 +570,17 @@ long TXvt_recordset::getCodeError(bool erase)
|
||||
return app;
|
||||
}
|
||||
|
||||
const char* TXvt_recordset::getStringError(bool erase)
|
||||
const char* TXvt_recordset::get_string_error(bool erase)
|
||||
{
|
||||
const char* app = _stringError;
|
||||
if (erase)
|
||||
_stringError = "";
|
||||
return app;
|
||||
}
|
||||
}
|
||||
|
||||
const bool TXvt_recordset::setErrorFreezed()
|
||||
{
|
||||
_codeError = ERROR_FREEZED;
|
||||
_stringError = ERROR_FREEZEDS;
|
||||
return false;
|
||||
}
|
||||
|
@ -3,19 +3,19 @@
|
||||
#ifndef __XVTDB_H
|
||||
#define __XVTDB_H
|
||||
|
||||
#include <string>
|
||||
#include "xvtdb_errors.h"
|
||||
|
||||
#define DBDLL __declspec(dllexport)
|
||||
#if defined(DBDLL_EXPORT)
|
||||
# define DBDLL __declspec(dllexport)
|
||||
#else
|
||||
# define DBDLL __declspec(dllimport)
|
||||
#endif // DBDLL_EXPORT
|
||||
|
||||
#ifndef NOERR
|
||||
#define NOERR 0
|
||||
#endif
|
||||
|
||||
#define NOT_INITIALIZED -86552
|
||||
#define ERROR_FREEZED -883
|
||||
#define SQLAPIV "SQLAPI++ 4.1.5" // Da tenere aggiornato
|
||||
|
||||
DBDLL enum TT_driver
|
||||
#define CHECK_FREEZED if (is_freezed()) { return setErrorFreezed(); }
|
||||
|
||||
enum TT_driver
|
||||
{
|
||||
//! DBMS client is not specified
|
||||
TSDB_undefined,
|
||||
@ -45,17 +45,12 @@ DBDLL enum TT_driver
|
||||
TSDB_SQLAnywhere
|
||||
};
|
||||
|
||||
DBDLL enum isoLvl { unknown = -1, uncommitted, committed, rr, serializable };
|
||||
enum isoLvl { unknown = -1, uncommitted, committed, rr, serializable };
|
||||
|
||||
#define P_CONN_VOID void *
|
||||
#define P_COMM_VOID void *
|
||||
|
||||
/* Esempio parametri da passare con MSSQL:
|
||||
* db = SERVER@DATABASE (NBKDELLI7TOLLAR\MSSQLSERVER14@project_vahlalla)
|
||||
*/
|
||||
DBDLL int xvt_create_connection(P_CONN_VOID con, const char* db, const char* user, const char* pass, TT_driver tipoDb);
|
||||
|
||||
|
||||
long xvt_rcs_get_items(P_CONN_VOID con, const char* query);
|
||||
/******************************************************************************
|
||||
* TXvt_recordset : DataBase redcordset *
|
||||
* Wrapper base di SACommand e SAConnection, classe per l'esecuzione di query *
|
||||
@ -67,15 +62,23 @@ protected:
|
||||
/**< Recordset */
|
||||
P_COMM_VOID _recset;
|
||||
/**< Oggetto della connessione */
|
||||
P_COMM_VOID _con;
|
||||
P_CONN_VOID _con;
|
||||
/**< Database */
|
||||
const char* _db;
|
||||
/**< Utente */
|
||||
const char* _usr;
|
||||
/**< Password */
|
||||
const char* _psw;
|
||||
/**< Driver */
|
||||
TT_driver _drv;
|
||||
/**< Query */
|
||||
const char* _query;
|
||||
/**< Ultima stringa con codice di errore ricevuto */
|
||||
const char* _stringError;
|
||||
/**< Ultimo codice di errore ricevuto */
|
||||
long _codeError;
|
||||
/**< Numero record corrente */
|
||||
long _recno;
|
||||
/**< Indica se va disconnessa la classe durante la chiusura */
|
||||
bool _toDisconnect;
|
||||
/**< Indica se l'oggetto è bloccato, in tal caso non si possono fare set/exec */
|
||||
bool _freezed;
|
||||
/**< Indica se il cursore è caricato */
|
||||
@ -83,13 +86,15 @@ protected:
|
||||
|
||||
const bool checkPermission();
|
||||
|
||||
private:
|
||||
// Disabilito il copy constructor
|
||||
TXvt_recordset(const TXvt_recordset& nope);
|
||||
|
||||
public:
|
||||
/**< Costruttore, crea un oggetto vuoto, PERICOLOSO!! Ricordarsi di inizializzarlo opportunamente con il metodo connect() e set() */
|
||||
TXvt_recordset();
|
||||
/**< Costruttore, crea un oggetto dai parametri di connessione passati */
|
||||
TXvt_recordset(const char* db, const char* user, const char* pass, TT_driver tipoDb, const char * query = "", const bool ex = false, const bool freezed = false);
|
||||
/**< Costruttore, accetta in ingresso una connessione, volendo è anche possibile impostare una query ed eseguirla. Attenzione! Non risponde se la query ha avuto un esito positivo o negativo! */
|
||||
TXvt_recordset(P_CONN_VOID c, const char * query = "", bool ex = false);
|
||||
/**< Distruttore */
|
||||
~TXvt_recordset();
|
||||
|
||||
@ -99,7 +104,13 @@ public:
|
||||
|
||||
// Funzioni fondamentali
|
||||
|
||||
/**< Eseguo la connessione */
|
||||
/**< Eseguo la connessione
|
||||
* Esempio parametri da passare con MSSQL:
|
||||
* db = SERVER@DATABASE (NBKDELLI7TOLLAR\MSSQLSERVER14@project_vahlalla)
|
||||
* user = Piero
|
||||
* pass = Angela
|
||||
* driver = TSDB_MSSQL
|
||||
*/
|
||||
int connect(const char* db, const char* user, const char* pass, TT_driver tipoDb);
|
||||
/* Mi scollego */
|
||||
void disconnect();
|
||||
@ -122,9 +133,9 @@ public:
|
||||
|
||||
// Getters
|
||||
/** Ritorna se la conessione è connessa */
|
||||
bool isConnect();
|
||||
const bool isConnect() const;
|
||||
/**< Ritorna se la connessione è attiva */
|
||||
bool isAlive();
|
||||
const bool isAlive() const;
|
||||
/** Ritorna la visibilità impostata */
|
||||
int getVisibility();
|
||||
/**< Ritorna se è attivo l'autocommit, true -> attivo, false -> disattivo o sconosciuto */
|
||||
@ -137,7 +148,10 @@ public:
|
||||
const char* getServerV();
|
||||
/**< Ritorno la versione del Server che sto utilizzando in formato numerico */
|
||||
long getServerVN();
|
||||
|
||||
/**< Ritorno se il recordset è carico */
|
||||
bool isLoaded() const;
|
||||
/** Ritorno il numero di elementi nella query */
|
||||
long items();
|
||||
|
||||
/**************************************************************************************************
|
||||
* Gestione Recordset *
|
||||
@ -160,6 +174,8 @@ public:
|
||||
bool last();
|
||||
/**< Si sposta alla posizione n, in caso di esito negativo valorizza _stringError e _codeError */
|
||||
bool go(int newPos);
|
||||
/**< Ritorna il numero di righe affette dall'ultima query */
|
||||
const int rowsAffected();
|
||||
|
||||
// Getters
|
||||
/**< Ritorna il valore nel campo (field) in formato (int) */
|
||||
@ -173,7 +189,7 @@ public:
|
||||
/**< Ritorna il valore nel campo (field) in formato (bool) */
|
||||
bool get_bool(const char* field);
|
||||
/**< Ritorna il valore nel campo (field) in formato (const char *)->(DD-MM-YYYY) */
|
||||
const char* getDate(const char* field);
|
||||
const char* get_date(const char* field);
|
||||
/**< Ritorna il valore nel campo (field) passato in formato (const char *) */
|
||||
const char* get(const char* field);
|
||||
/**< Ritorna il valore nel campo (field) in formato (char) */
|
||||
@ -182,20 +198,29 @@ public:
|
||||
long pos() const { return _recno; }
|
||||
|
||||
// Error Handling
|
||||
/**< Ritorno l'ultimo codice errore segnalato in formato /int) */
|
||||
long getCodeError(bool erase = true);
|
||||
/**< Ritorno l'ultimo codice errore segnalato in formato numerico) */
|
||||
long get_code_error(bool erase = true);
|
||||
/**< Ritorno l'ultima stringa di errore segnalato in formato (const char *) */
|
||||
const char* getStringError(bool erase = true);
|
||||
const char* get_string_error(bool erase = true);
|
||||
//char * getCharPointer(const char * field) { return const_cast<char*>(static_cast<const char*>(recset.Field(field).asString())); }
|
||||
|
||||
// Utilities
|
||||
/**< Controlla se il cursore è bloccato */
|
||||
const bool isFreezed() const { return _freezed; }
|
||||
const bool is_freezed() const { return _freezed; }
|
||||
/**< Congela il cursore */
|
||||
void freeze() { _freezed = true; }
|
||||
/**< Scongela il cursore */
|
||||
void defrost() { _freezed = false; }
|
||||
|
||||
/* Funzioni tenute per compatibiltà: */
|
||||
/**< Scongela il cursore */
|
||||
void unfreeze() { defrost(); }
|
||||
/**< Ritornano se è congelato o meno, attenzione: i valori di ritorno non sono const!*/
|
||||
bool frozen() const { return is_freezed(); }
|
||||
bool not_frozen() const { return !is_freezed(); }
|
||||
/**< Imposta l'errore di record congelato */
|
||||
const bool setErrorFreezed();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
7
src/xvtdb/xvtdb_errors.h
Normal file
7
src/xvtdb/xvtdb_errors.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define NOERR 0
|
||||
#define NOT_INITIALIZED -86552
|
||||
#define NOT_INITIALIZEDS "ERROR: Recordset not initialized"
|
||||
#define ERROR_FREEZED -883
|
||||
#define ERROR_FREEZEDS "ERROR: Recordset on ice"
|
Loading…
x
Reference in New Issue
Block a user