diff --git a/src/include/odbcrset.cpp b/src/include/odbcrset.cpp index a1073d141..0518bcf56 100755 --- a/src/include/odbcrset.cpp +++ b/src/include/odbcrset.cpp @@ -741,8 +741,8 @@ TRecordset* create_recordset(const TString& sql) rex = new TCSV_recordset(sql); else if (sql.starts_with("AS400", true)) rex = new TAS400_recordset(sql); - if (sql.starts_with("CONNECT", true)) - rex = new TDB_recordset(sql); + //if (sql.starts_with("CONNECT", true)) + //rex = new TDB_recordset(sql); else rex = new TSQL_recordset(sql); } diff --git a/src/include/tsdb.cpp b/src/include/tsdb.cpp index 3ac11e194..895c21a7b 100644 --- a/src/include/tsdb.cpp +++ b/src/include/tsdb.cpp @@ -38,14 +38,20 @@ TString SSimple_query::sq_get(TString& field, bool rtrim) return sq_get(static_cast(field), rtrim); } +TString SSimple_query::sq_get(unsigned int column, bool rtrim) +{ + return _rec.get(column); +} + +unsigned SSimple_query::sq_get_num_fields() const +{ + return _rec.get_num_fields(); +} + void TDB_recordset::reset() { - _first_row = 0; _items = 0; _current_row = -1; - _pagesize = 512; - _page.destroy(); - _column.destroy(); _columns_loaded = false; } @@ -63,7 +69,7 @@ void TDB_recordset::set(const char* sql) { TString query(sql); int pos_EOCon = query.find(')'); // End Of Conn - TString conn_str = query.sub(0, ++pos_EOCon); + const TString conn_str = query.sub(0, ++pos_EOCon); set_connection(conn_str); real_query << query.sub(pos_EOCon); @@ -79,7 +85,7 @@ void TDB_recordset::set(const char* sql) _rec->sq_set(_sql); } -void TDB_recordset::set_connection(const char* conn_str) +void TDB_recordset::set_connection(const char* conn_str) const { TString pn(conn_str); TString srv = "", usr = "", pwd = "", drv = ""; @@ -116,7 +122,7 @@ void TDB_recordset::set_connection(const char* conn_str) connect(srv.ltrim(), usr.ltrim(), pwd.ltrim(), str_to_driver(drv.ltrim())); } -int TDB_recordset::connect(const char * db, const char * user, const char * pass, const TT_driver tipo_db) +int TDB_recordset::connect(const char * db, const char * user, const char * pass, const TT_driver tipo_db) const { return _rec->sq_connect(db, user, pass, tipo_db); } @@ -173,18 +179,79 @@ TRecnotype TDB_recordset::items() const { if(!_rec->sq_is_loaded() && _items == 0) _rec->sq_exec(); - return _rec->sq_items(); + auto& i = const_cast(_items); + i = _rec->sq_items(); + return i; } bool TDB_recordset::move_to(TRecnotype pos) { + const TRecnotype tot = items(); + _current_row = pos; + + if (_freezed && _loaded) + { + if (pos < 0) + _current_row = 0; + if (pos > tot) + _current_row = tot; + return true; + } + return _rec->sq_go(pos); } +const TArray* TDB_recordset::row(TRecnotype n) +{ + static TRecnotype last_n = -1; + + if(n >= 0 && n < _rec->sq_items()) + { + if (n == last_n && !_row.empty()) // Richiedo sempre la stessa riga + return &_row; + if (move_to(n)) + { + const unsigned ncol = _rec->sq_get_num_fields(); + last_n = n; + + for (unsigned i = 0; i < ncol; i++) + _row.add(_rec->sq_get(i, false)); + return &_row; + } + } + + _row.destroy(); + return &_row; +} + +void TDB_recordset::requery() +{ + _items = 0; +} + +unsigned TDB_recordset::columns() const +{ + return _rec->sq_get_num_fields(); +} + +const TVariant& TDB_recordset::get(unsigned int column) const +{ + static TVariant field = NULL_VARIANT; + static unsigned int last_get = 0; + if(column != last_get || field == NULL_VARIANT) + { + last_get = column; + field = _rec->sq_get(column); + return field; + } + return field; +} + TDB_recordset::TDB_recordset(const char* sql, const bool freezed) : _freezed(freezed), _loaded(false) { set(sql); + _current_row = -1; _rec = new SSimple_query(); _items = 0; set(sql); diff --git a/src/include/tsdb.h b/src/include/tsdb.h index 4fa723407..ecbe4e667 100644 --- a/src/include/tsdb.h +++ b/src/include/tsdb.h @@ -85,7 +85,7 @@ public: /**< Imposto il tipo di client che utilizzo */ void sq_set_client(int client) { _rec.set_client(static_cast(client)); } void sq_set_client(const TT_driver client) { _rec.set_client(client); } - // Imposto una opzione generica dellla connessione + // Imposto una opzione generica della connessione void sq_set_con_option(const char* opt) { _rec.set_con_option(opt); } /**< Abilito/Disabilito l'autocommit, (disabilitato di default) */ void sq_set_autocommit(const bool ac) { _rec.set_autocommit(ac); } @@ -113,7 +113,7 @@ public: /** Ritorno il numero di elementi nella query */ const long sq_items() { return _rec.items(); } - // Conguration + // Configuration /**< Imposta la query ricevuta come (const char *) nel recordset */ const bool sq_set(const char* query) { return _rec.set(query); } /**< Imposta la query ricevuta come (string) nel recordset */ @@ -132,9 +132,9 @@ public: const bool sq_next() { return _rec.next(); } /**< Si sposta indietro di un record, in caso di esito negativo valorizza _stringError e _codeError */ const bool sq_prev() { return _rec.prev(); } - /**< Si sposta avanti di un record, in caso di esito negativo valorizza _stringError e _codeError */ - const bool sq_first() { return _rec.first(); } /**< Si sposta al primo record, in caso di esito negativo valorizza _stringError e _codeError */ + const bool sq_first() { return _rec.first(); } + /**< Si sposta all'ultimo record, in caso di esito negativo valorizza _stringError e _codeError */ const bool sq_last() { return _rec.last(); } /**< Si sposta alla posizione n, in caso di esito negativo valorizza _stringError e _codeError */ const bool sq_go(const int new_pos) { return _rec.go(new_pos); } @@ -165,8 +165,12 @@ public: TString sq_get(const string& field, bool rtrim = true); /**< Ritorna il valore nel campo (field) passato come (TString) in formato (const char *) */ TString sq_get(TString& field, bool rtrim = true); + /**< Ritorna il valore della colonna numero (column) passato come (unsigned int) */ + TString sq_get(unsigned int column, bool rtrim = true); /**< Ritorna il valore nel campo (field) in formato (char) */ const char sq_get_char(const char* field) { return _rec.get_char(field); } + /**< Ritorna il numero di campi dopo l'ultimo comando di esecuzione effettuato; se il risultato esiste */ + unsigned int sq_get_num_fields() const; /**< Ritorna la posizione attuale */ const long sq_pos() const { return _rec.pos(); } @@ -178,12 +182,12 @@ public: /**< Ritorno l'ultima stringa di errore segnalato in formato (const char *) */ const char* sq_get_text_error(const bool erase = true) { return _rec.get_text_error(erase); } - // Gestione freeze - /**< Controlla se il cursore è bloccato */ - const bool is_freezed() const { return _rec.is_freezed(); } - /**< Congela il cursore */ - void freeze() { _rec.freeze(); } - /**< Scongela il cursore */ + // Gestione freeze + /**< Controlla se il cursore è bloccato */ + const bool is_freezed() const { return _rec.is_freezed(); } + /**< Congela il cursore */ + void freeze() { _rec.freeze(); } + /**< Scongela il cursore */ void defrost() { _rec.defrost(); } /**< Costruttore, non inizializza nulla, da caricare successivamente */ @@ -201,29 +205,30 @@ class TDB_recordset : public TRecordset TString _sql; TString _dsn, _usr, _pwd, _drv; - bool _freezed, _loaded, _columns_loaded{}; - TRecnotype _first_row{}, _pagesize{}, _items, _current_row{}; - TArray _page, _column; + bool _freezed, _loaded, _columns_loaded{}; + TRecnotype _items, _current_row; + TArray _row, _column; protected: void reset(); void set(const char* sql); // Parsa la stringa di connessione contenuta nella query - void set_connection(const char * conn_str); - int connect(const char * db, const char * user, const char * pass, const TT_driver tipo_db); + void set_connection(const char * conn_str) const; + int connect(const char * db, const char * user, const char * pass, const TT_driver tipo_db) const; int connect(const char * db, const char * user, const char * pass, const char * tipo_db) const; static TT_driver str_to_driver(const char* tipo_db); public: - TRecnotype items() const override; // Pure - bool move_to(TRecnotype pos) override; // Pure - virtual TRecnotype current_row() const; // Pure - virtual void requery(); // Pure - virtual const TString& query_text() const { return _sql; }; + TRecnotype items() const override; // Pure + bool move_to(TRecnotype pos) override; // Pure + TRecnotype current_row() const override { return _current_row; } // Pure + const TArray* row(TRecnotype n); + void requery() override; // da impl. Pure + const TString& query_text() const override { return _sql; }; - virtual unsigned int columns() const; // Pure - virtual const TRecordset_column_info& column_info(unsigned int column) const; // Pure - virtual const TVariant& get(unsigned int column) const; // Pure + unsigned int columns() const override; // Pure + //virtual const TRecordset_column_info& column_info(unsigned int column) const; // Pure + const TVariant& get(unsigned int column) const override; // Pure TDB_recordset(const char * sql, bool freezed = false); }; diff --git a/src/xvtdb/xvtdb.cpp b/src/xvtdb/xvtdb.cpp index a32971871..eaf8ee46d 100644 --- a/src/xvtdb/xvtdb.cpp +++ b/src/xvtdb/xvtdb.cpp @@ -649,6 +649,21 @@ const char* TXvt_recordset::get(const char* field) } } +const char* TXvt_recordset::get(unsigned int field) +{ + try + { + return _RCS(_recset)->Field(field).asString(); + } + catch(SAException &x) + { + _code_error = x.ErrNativeCode(); + _GET_ERROR(x.ErrMessage(), _string_error); + _GET_ERROR(x.ErrText(), _string_error_full_text); + return '\0'; + } +} + char TXvt_recordset::get_char(const char* field) { try @@ -664,6 +679,11 @@ char TXvt_recordset::get_char(const char* field) } } +int TXvt_recordset::get_num_fields() const +{ + return _RCS(_recset)->FieldCount(); +} + long TXvt_recordset::get_code_error(bool erase) { long app = _code_error; diff --git a/src/xvtdb/xvtdb.h b/src/xvtdb/xvtdb.h index 26664d76b..a93187255 100644 --- a/src/xvtdb/xvtdb.h +++ b/src/xvtdb/xvtdb.h @@ -195,8 +195,12 @@ public: 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 del campo numero (field) passato, in formato (const char *) */ + const char* get(unsigned int field); /**< Ritorna il valore nel campo (field) in formato (char) */ char get_char(const char* field); + /**< Ritorna il numero di campi dopo l'ultimo comando di esecuzione effettuato; se il risultato esiste */ + int get_num_fields() const; /**< Ritorna la posizione attuale */ long pos() const { return _recno; }