2018-02-09 13:52:46 +00:00
/**********************************************************************************
* # # # # # # \ *
* # # __ # # \ *
* # # / \ __ | # # # # # # \ # # # # # # \ # # # # \ # # # # # # \ # # # # # # \ *
* # # | \ ____ # # \ # # _ # # _ # # \ # # __ # # \ # # __ # # \ *
* # # | # # # # # # # | # # / # # / # # | # # / # # | # # / # # | *
* # # | # # \ # # __ # # | # # | # # | # # | # # | # # | # # | # # | *
* \ # # # # # # | \ # # # # # # # | # # | # # | # # | # # # # # # # | \ # # # # # # | *
* \ ______ / \ _______ | \ __ | \ __ | \ __ | # # ____ / \ ______ / *
* # # | *
* # # | *
* \ __ | *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/********************************************************************************************************************************
* TSDB . H *
* Inizio sviluppo : 13.10 .2016 *
* Autore : Tolla *
* Descrizione : *
* La seguente libreria ha due scopi : *
* - Implementare una serie di funzioni che emulino interamente il funzionamento attuale di campo in Visual FoxPro su MSQL *
2019-03-12 17:38:18 +01:00
* - Creare delle nuove API per gestire il database in MSSQL con cui verranno riscritti i programmi *
2018-02-09 13:52:46 +00:00
* Librerie esterne utilizzate : *
* - SQLAPI + + ( Permette la gestione dei pi <EFBFBD> famosi DB attualmente esistenti ) *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef __TSDB_H
# define __TSDB_H
2019-03-12 17:38:18 +01:00
# ifndef __XVTDB_H
# include <xvtdb.h>
2018-02-09 13:52:46 +00:00
# endif
// Tolla tools
# ifndef __TTOOLS_H
# include <ttools.h>
# endif
# ifndef __STRINGS_H
# include <strings.h>
# endif // !__STRINGS_H
# ifndef __DATE_H
# include <date.h>
# endif // !__DATE_H
# ifndef __REAL_H
# include <real.h>
# endif // !__REAL_H
# define CHIAVE_ID_ "_ID_"
2019-03-12 17:38:18 +01:00
# include "recset.h"
2018-02-09 13:52:46 +00:00
/********************************************************************************
* SSimpleQuery ( Sirio Simple Query ) *
* " Wrapper " di TXvt_recordset , implementa OGNI funzione in modo tale da *
* poterlo sostituire brutalmente in qualsiasi momento cos <EFBFBD> da non aver *
* problemi come durante il passaggio da ISAM a SQL ( spero ) . *
* Se ti stai domandando perch <EFBFBD> non <EFBFBD> stata usata l ' ereditariet <EFBFBD> ( magari con *
* un bel " : private TXvt_recordset " cos <EFBFBD> da bloccare il tutto ) <EFBFBD> per bloccare *
* qualsiasi riferimento a questa classe in eventuali reimplementazioni future . *
* Preferisco scrivere un po ' di codice ridondante adesso che andare a fare *
* salti mortali dopo *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-06 16:30:37 +02:00
class SSimple_query
2018-02-09 13:52:46 +00:00
{
protected :
TXvt_recordset _rec ;
/**< Costruttore, accetta in ingresso una connessione, volendo <20> anche possibile impostare una query ed eseguirla. Attenzione! Non risponde se la query ha avuto un esito positivo o negativo! */
//SSimpleQuery(P_CONN_VOID &c, const char * query = "", bool ex = false);
public :
// Connection functions
/**< Eseguo la connessione */
2019-02-27 16:58:16 +01:00
int sq_connect ( const char * db , const char * user , const char * pass , const TT_driver tipo_db ) { return _rec . connect ( db , user , pass , tipo_db ) ; }
2018-02-09 13:52:46 +00:00
/* Mi scollego */
2018-07-06 16:30:37 +02:00
void sq_disconnect ( ) { _rec . disconnect ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Esegue la commit, di default in caso di errore viene chiamato il metodo rollback() */
2019-02-27 16:58:16 +01:00
const bool sq_commit ( const bool auto_roll = true ) { return _rec . commit ( auto_roll ) ; }
2018-02-09 13:52:46 +00:00
/**< Esegue il rollback all'ultimo commit */
2018-07-06 16:30:37 +02:00
const bool sq_rollback ( ) { return _rec . rollback ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Imposto il tipo di client che utilizzo */
2019-02-27 16:58:16 +01:00
void sq_set_client ( int client ) { _rec . set_client ( static_cast < TT_driver > ( client ) ) ; }
void sq_set_client ( const TT_driver client ) { _rec . set_client ( client ) ; }
2019-03-13 18:00:13 +01:00
// Imposto una opzione generica della connessione
2019-02-27 16:58:16 +01:00
void sq_set_con_option ( const char * opt ) { _rec . set_con_option ( opt ) ; }
2018-02-09 13:52:46 +00:00
/**< Abilito/Disabilito l'autocommit, (disabilitato di default) */
2019-02-27 16:58:16 +01:00
void sq_set_autocommit ( const bool ac ) { _rec . set_autocommit ( ac ) ; }
2018-02-09 13:52:46 +00:00
/** Imposta la visibilit<69> delle transazioni (vedi Funzione) */
2019-02-27 16:58:16 +01:00
void sq_set_visibility ( const iso_lvl vis = committed ) { _rec . set_visibility ( vis ) ; }
2018-02-09 13:52:46 +00:00
// Getters
/** Ritorna se la conessione <20> connessa */
2019-02-27 16:58:16 +01:00
const bool sq_is_connect ( ) const { return _rec . is_connect ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna se la connessione <20> attiva */
2019-02-27 16:58:16 +01:00
const bool sq_is_alive ( ) const { return _rec . is_alive ( ) ; }
2018-02-09 13:52:46 +00:00
/** Ritorna la visibilit<69> impostata */
2019-02-27 16:58:16 +01:00
const int sq_get_visibility ( ) { return _rec . get_visibility ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna se <20> attivo l'autocommit, true -> attivo, false -> disattivo o sconosciuto */
2019-02-27 16:58:16 +01:00
const bool sq_get_autocommit ( ) { return _rec . get_autocommit ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore dell'opzione specificata */
2019-02-27 16:58:16 +01:00
const char * sq_get_option ( const char * opt ) { return _rec . get_option ( opt ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorno la versione del Client che sto utilizzando */
2019-02-27 16:58:16 +01:00
const long sq_get_client_v ( ) { return _rec . get_client_v ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorno la versione del Server che sto utilizzando */
2019-03-19 16:45:34 +01:00
const char * sq_get_server_v ( ) { return _rec . get_server_v ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorno la versione del Server che sto utilizzando in formato numerico */
2019-02-27 16:58:16 +01:00
const long sq_get_server_vn ( ) { return _rec . get_server_vn ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorno se il recordset <20> carico */
2019-02-27 16:58:16 +01:00
const bool sq_is_loaded ( ) const { return _rec . is_loaded ( ) ; }
2018-02-09 13:52:46 +00:00
/** Ritorno il numero di elementi nella query */
2018-07-06 16:30:37 +02:00
const long sq_items ( ) { return _rec . items ( ) ; }
2018-02-09 13:52:46 +00:00
2019-03-13 18:00:13 +01:00
// Configuration
2018-02-09 13:52:46 +00:00
/**< Imposta la query ricevuta come (const char *) nel recordset */
2018-07-06 16:30:37 +02:00
const bool sq_set ( const char * query ) { return _rec . set ( query ) ; }
2018-02-09 13:52:46 +00:00
/**< Imposta la query ricevuta come (string) nel recordset */
2019-02-27 16:58:16 +01:00
const bool sq_set ( const string & query ) { return _rec . set ( query . c_str ( ) ) ; }
2018-02-09 13:52:46 +00:00
/**< Imposta la query ricevuta come (TString) nel recordset */
2018-07-06 16:30:37 +02:00
const bool sq_set ( TString & query ) { return _rec . set ( static_cast < const char * > ( query ) ) ; }
2018-02-09 13:52:46 +00:00
/**< Esegue la query impostata nel recordset, se viene passato autoF == true esegue anche un comando sqNext() */
2018-07-06 16:30:37 +02:00
const bool sq_exec ( bool autoF = true ) { return _rec . exec ( autoF ) ; }
2018-02-09 13:52:46 +00:00
/**< Unisce le funzioni sqSet e sqExec, riceve la query come (const char *) */
2019-02-27 16:58:16 +01:00
const bool sq_set_exec ( const char * query , const bool auto_f = true ) { _rec . set ( query ) ; return _rec . exec ( auto_f ) ; }
2018-02-09 13:52:46 +00:00
/**< Unisce le funzioni sqSet e sqExec, riceve la query come (string) */
2019-02-27 16:58:16 +01:00
const bool sq_set_exec ( const string & query , const bool auto_f = true ) { _rec . set ( query . c_str ( ) ) ; return _rec . exec ( auto_f ) ; }
2018-02-09 13:52:46 +00:00
/**< Unisce le funzioni sqSet e sqExec, riceve la query come (TString) */
2019-02-27 16:58:16 +01:00
const bool sq_set_exec ( TString & query , const bool auto_f = true ) { return sq_set_exec ( static_cast < const char * > ( query ) , auto_f ) ; }
2018-02-09 13:52:46 +00:00
/**< Si sposta avanti di un record, in caso di esito negativo valorizza _stringError e _codeError */
2018-07-06 16:30:37 +02:00
const bool sq_next ( ) { return _rec . next ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Si sposta indietro di un record, in caso di esito negativo valorizza _stringError e _codeError */
2018-07-06 16:30:37 +02:00
const bool sq_prev ( ) { return _rec . prev ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Si sposta al primo record, in caso di esito negativo valorizza _stringError e _codeError */
2019-03-13 18:00:13 +01:00
const bool sq_first ( ) { return _rec . first ( ) ; }
/**< Si sposta all'ultimo record, in caso di esito negativo valorizza _stringError e _codeError */
2018-07-06 16:30:37 +02:00
const bool sq_last ( ) { return _rec . last ( ) ; }
2018-02-09 13:52:46 +00:00
/**< Si sposta alla posizione n, in caso di esito negativo valorizza _stringError e _codeError */
2019-02-27 16:58:16 +01:00
const bool sq_go ( const int new_pos ) { return _rec . go ( new_pos ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il numero di righe affette dall'ultima query */
2019-02-27 16:58:16 +01:00
const int sq_rows_affected ( ) const { return _rec . rows_affected ( ) ; }
2018-02-09 13:52:46 +00:00
// Getters
/**< Ritorna il valore nel campo (field) in formato (int) */
2018-07-06 16:30:37 +02:00
const int sq_get_int ( const char * field ) { return _rec . get_int ( field ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (short) */
2018-07-06 16:30:37 +02:00
const short sq_get_short ( const char * field ) { return _rec . get_short ( field ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (long) */
2018-07-06 16:30:37 +02:00
const long sq_get_long ( const char * field ) { return _rec . get_long ( field ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (double) */
2018-07-06 16:30:37 +02:00
const double sq_get_double ( const char * field ) { return _rec . get_double ( field ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (bool) */
2018-07-06 16:30:37 +02:00
const bool sq_get_bool ( const char * field ) { return _rec . get_bool ( field ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (TDate) */
2018-07-06 16:30:37 +02:00
const TDate sq_get_date ( const char * field ) ;
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (real) */
2018-07-06 16:30:37 +02:00
const real sq_get_real ( const char * field ) ;
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (SADateTime), Campo non gestisce le ore */
//SADateTime sqGetDateTime(const char* field) { get_short(field); }
/**< Ritorna il valore nel campo (field) passato come (const char *) in formato (const char *) */
2019-02-11 15:01:27 +01:00
TString sq_get ( const char * field , bool rtrim = true ) ;
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) passato come (string) in formato (const char *) */
2019-02-27 16:58:16 +01:00
TString sq_get ( const string & field , bool rtrim = true ) ;
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) passato come (TString) in formato (const char *) */
2019-02-11 15:01:27 +01:00
TString sq_get ( TString & field , bool rtrim = true ) ;
2019-03-13 18:00:13 +01:00
/**< Ritorna il valore della colonna numero (column) passato come (unsigned int) */
TString sq_get ( unsigned int column , bool rtrim = true ) ;
2018-02-09 13:52:46 +00:00
/**< Ritorna il valore nel campo (field) in formato (char) */
2018-07-06 16:30:37 +02:00
const char sq_get_char ( const char * field ) { return _rec . get_char ( field ) ; }
2019-03-13 18:00:13 +01:00
/**< Ritorna il numero di campi dopo l'ultimo comando di esecuzione effettuato; se il risultato esiste */
unsigned int sq_get_num_fields ( ) const ;
2019-03-15 10:51:50 +01:00
/**< Ritorna il nome del campo numero (column) in formato (TString= */
TString sq_get_name_field ( unsigned column ) const ;
/**< Ritorna la grandezza del campo numero (column) */
int sq_get_width_field ( unsigned column ) const ;
/**< Ritorna il tipo del campo numero (column) in formato (TFieldtypes) */
TFieldtypes sq_get_type_field ( unsigned column ) const ;
2018-02-09 13:52:46 +00:00
/**< Ritorna la posizione attuale */
2018-07-06 16:30:37 +02:00
const long sq_pos ( ) const { return _rec . pos ( ) ; }
2018-03-14 14:45:46 +00:00
2018-02-09 13:52:46 +00:00
// Error Getters
/**< Ritorno l'ultimo codice errore segnalato in formato /int) */
2019-02-27 16:58:16 +01:00
const long sq_get_code_error ( const bool erase = true ) { return _rec . get_code_error ( erase ) ; }
2018-02-09 13:52:46 +00:00
/**< Ritorno l'ultima stringa di errore segnalato in formato (const char *) */
2019-02-27 16:58:16 +01:00
const char * sq_get_string_error ( const bool erase = true ) { return _rec . get_string_error ( erase ) ; }
2019-02-11 14:58:35 +01:00
/**< Ritorno l'ultima stringa di errore segnalato in formato (const char *) */
2019-02-27 16:58:16 +01:00
const char * sq_get_text_error ( const bool erase = true ) { return _rec . get_text_error ( erase ) ; }
2019-03-19 16:45:34 +01:00
const char * sq_get_token_text_error ( const int token , const bool erase = true ) ;
2019-03-12 17:38:18 +01:00
2019-03-13 18:00:13 +01:00
// Gestione freeze
/**< Controlla se il cursore <20> bloccato */
const bool is_freezed ( ) const { return _rec . is_freezed ( ) ; }
/**< Congela il cursore */
void freeze ( ) { _rec . freeze ( ) ; }
/**< Scongela il cursore */
2019-03-12 17:38:18 +01:00
void defrost ( ) { _rec . defrost ( ) ; }
2019-03-12 18:04:44 +01:00
/**< Costruttore, non inizializza nulla, da caricare successivamente */
SSimple_query ( ) = default ;
/**< Costruttore, Accetta in ingresso dei parametri per la connessione, volendo <20> anche possibile impostare una query ed eseguirla. Attenzione! Non risponde se la query ha avuto un esito positivo o negativo! */
SSimple_query ( const char * db , const char * user , const char * pass , const TT_driver tipo_db , const char * query = " " , const bool ex = false , const bool freezed = false ) : _rec ( db , user , pass , tipo_db , query , ex , freezed ) { }
//SSimpleQuery(const TString& db, const TString& user, const TString& pass, TT_driver tipoDb, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipoDb, query, ex, freezed) {}
/**< Distruttore */
virtual ~ SSimple_query ( ) = default ;
2019-03-12 17:38:18 +01:00
} ;
class TDB_recordset : public TRecordset
{
2019-03-12 18:04:44 +01:00
SSimple_query * _rec ;
2019-03-12 17:38:18 +01:00
TString _sql ;
TString _dsn , _usr , _pwd , _drv ;
2019-03-19 12:37:55 +01:00
bool _freezed ;
TRecnotype _current_row ;
TString_array _row , _column ;
bool _is_loaded ;
TRecnotype _items ;
unsigned _ncolumns ;
2019-03-12 17:38:18 +01:00
protected :
// Parsa la stringa di connessione contenuta nella query
2019-03-15 10:51:50 +01:00
bool set_connection ( const char * conn_str ) const ;
bool connect ( const char * db , const char * user , const char * pass , const TT_driver tipo_db ) const ;
bool connect ( const char * db , const char * user , const char * pass , const char * tipo_db ) const ;
2019-03-12 17:38:18 +01:00
static TT_driver str_to_driver ( const char * tipo_db ) ;
2019-03-19 12:37:55 +01:00
void set_loaded ( ) ;
void unset_loaded ( ) ;
2019-03-12 17:38:18 +01:00
public :
2019-03-19 12:37:55 +01:00
void freeze ( const bool on = true ) ; ;
void reset ( ) ;
bool set ( const char * sql ) ;
bool move_to ( TRecnotype pos ) override ; // Pure
bool move_next ( ) override ;
void requery ( ) override ; // da impl. Pure
bool is_connected ( ) const ;
unsigned columns ( ) const override ; // Pure
TRecnotype items ( ) const override ; // Pure
TRecnotype current_row ( ) const override { return _current_row ; } // Pure
2019-03-15 10:51:50 +01:00
// Con il valore di default viene restituita la riga alla pos. attuale
2019-03-19 12:37:55 +01:00
const TString_array get_row ( TRecnotype n = - 1 ) ;
const TString_array get_next_row ( ) ;
const TString & query_text ( ) const override { return _sql ; }
2019-03-13 18:00:13 +01:00
const TVariant & get ( unsigned int column ) const override ; // Pure
2019-03-19 12:37:55 +01:00
const TRecordset_column_info & column_info ( unsigned int column ) const override ; // Pure
2019-03-12 17:38:18 +01:00
2019-03-19 12:37:55 +01:00
// Ritorna la connessione attuale
2019-03-15 10:51:50 +01:00
const TVariant & active_connection ( ) const ;
2019-03-19 12:37:55 +01:00
bool exec ( const char * sql ) ;
bool commit ( ) const ;
2019-03-15 10:51:50 +01:00
2019-03-12 17:38:18 +01:00
TDB_recordset ( const char * sql , bool freezed = false ) ;
2019-03-15 10:51:50 +01:00
~ TDB_recordset ( ) ;
2018-02-09 13:52:46 +00:00
} ;
# endif