#include #include /****************************************************************************** * SSimpleQuery * * Classe per esecuzioni di query temporanee (wrapper semplice per SACommand) * ******************************************************************************/ const TDate SSimple_query::sq_get_date(const char * field) { const TDate app(_rec.get_date(field)); return app; } const real SSimple_query::sq_get_real(const char * field) { const real app(_rec.get(field)); return app; } TString SSimple_query::sq_get(const char* field, bool rtrim) { TString fld = _rec.get(field); if (rtrim) fld.rtrim(); return fld; } TString SSimple_query::sq_get(const string& field, const bool rtrim) { return sq_get(field.c_str(), rtrim); } 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(); } TString SSimple_query::sq_get_name_field(const unsigned column) const { return _rec.get_name_field(column); } int SSimple_query::sq_get_width_field(const unsigned column) const { return _rec.get_width_field(column); } TFieldtypes SSimple_query::sq_get_type_field(const unsigned column) const { const TString type = _rec.get_type_field(column); if (type == "dtUnknown") return _nullfld; if (type == "dtBool") return _boolfld; if (type == "dtShort") return _intfld; if (type == "dtULong") return _longfld; if (type == "dtDouble") return _realfld; if (type == "dtNumeric") return _realfld; if (type == "dtDateTime") return _datefld; if (type == "dtString") return _alfafld; if (type == "dtBytes") return _intfld; if (type == "dtLongBinary") return _alfafld; if (type == "dtLongChar") return _alfafld; if (type == "dtBLob") return _alfafld; if (type == "dtCLob") return _alfafld; if (type == "dtCursor") return _nullfld; if (type == "dtSpecificToDBMS") return _nullfld; return _nullfld; } const char* SSimple_query::sq_get_token_text_error(const int token, const bool erase) { TToken_string errors(sq_get_text_error(erase), '\n'); return errors.get(token); } void TDB_recordset::reset() { _current_row = -1; _is_loaded = false; _items = 0; _row.destroy(); _column.destroy(); } /* La query può iniziare con la stringa di connessione così fatta: * CONNECT(server, user, psw, driver = "MSSQL") il driver può essere omesso. * Se c'è la estraggo, setto la connessione e prendo la vera query. * Se no setto direttamente la query. * Ritorno false se non mi sono mai connesso a niente e non passo * la stringa di connessione. */ bool TDB_recordset::set(const char* sql) { bool ok; TString real_query = ""; // Posso modificare oppure non posso ma _sql è vuota if(!_freezed || _sql.empty()) { if (_sql.empty() || !_freezed && !_sql.empty()) { // Guardo se la query inizia con la stringa di connessione if (TString(sql).starts_with("CONNECT(", true)) { TString query(sql); int pos_EOCon = query.find(')'); // End Of Conn const TString& conn_str = query.sub(0, ++pos_EOCon); ok = set_connection(conn_str); if (!ok) return false; real_query << query.sub(pos_EOCon); } else if (!is_connected()) return false; else real_query << sql; // Non sto facendo una select if(real_query.find("SELECT") == -1 && real_query.find("select") == -1) { _sql.cut(0); reset(); return false; } // Serve? if (!_freezed || _sql != sql) reset(); _sql.cut(0) << real_query; if (_sql.find("SELECT") >= 0 || _sql.find("select") >= 0) find_and_reset_vars(); bool is_set; if ((is_set = _rec->sq_set(_sql))) { unset_loaded(); } return is_set; } } return false; } /* Parso la stringa di connessione ed estraggo i dati. * Se il numero di dati è sufficiente eseguo la connessione. * Ritorno false se non riesco a connettermi o il numero di dati è sbagliato */ bool TDB_recordset::set_connection(const char* conn_str) const { TString pn(conn_str); TString srv = "", usr = "", pwd = "", drv = ""; int first_pos = pn.find("(", 0); int last_pos = pn.find(",", first_pos); int i; for (i = 0; last_pos != -1; i++) { switch (i) { case 0: srv = pn.sub(first_pos + 1, last_pos); break; case 1: usr = pn.sub(first_pos + 1, last_pos); break; case 2: pwd = pn.sub(first_pos + 1, last_pos); break; case 3: drv = pn.sub(first_pos + 1, last_pos); break; default: last_pos = -1; break; } first_pos = last_pos; last_pos = pn.find(",", first_pos + 1); if( last_pos == -1 ) last_pos = pn.find(")", first_pos + 1); } // Guardo se ho valorizzato almeno i primi 3 elementi della connect // Se non valorizzo l'ultimo come default: MSSQL Server if (i == 3) return connect(srv.ltrim(), usr.ltrim(), pwd.ltrim(), TSDB_MSSQL); if(i == 4) return connect(srv.ltrim(), usr.ltrim(), pwd.ltrim(), str_to_driver(drv.ltrim())); return false; } // Ritorna true se si connette bool 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) == NOERR; } TT_driver TDB_recordset::str_to_driver(const char* tipo_db) { if (_stricmp(tipo_db, "") == 0) return TSDB_undefined; //! ODBC if (_stricmp(tipo_db, "ODBC") == 0) return TSDB_ODBC; //! Oracle if (_stricmp(tipo_db, "Oracle") == 0) return TSDB_Oracle; //! Microsoft SQL Server if (_stricmp(tipo_db, "MSSQL") == 0) return TSDB_MSSQL; //! InterBase or Firebird if (_stricmp(tipo_db, "InterBase") == 0) return TSDB_InterBase; //! SQLBase if (_stricmp(tipo_db, "SQLBase") == 0) return TSDB_SQLBase; //! IBM DB2 if (_stricmp(tipo_db, "DB2") == 0) return TSDB_DB2; //! Informix if (_stricmp(tipo_db, "Informix") == 0) return TSDB_Informix; //! Sybase ASE if (_stricmp(tipo_db, "Sybase") == 0) return TSDB_Sybase; //! MySQL if (_stricmp(tipo_db, "MySQL") == 0) return TSDB_MySQL; //! PostgreSQL if (_stricmp(tipo_db, "PostgreSQL") == 0) return TSDB_PostgreSQL; //! SQLite if (_stricmp(tipo_db, "SQLite") == 0) return TSDB_SQLite; //! SQL Anywere if (_stricmp(tipo_db, "SQLAnywhere") == 0) return TSDB_SQLAnywhere; return TSDB_undefined; } void TDB_recordset::set_loaded() { _is_loaded = true; _items = _rec->sq_items(); _ncolumns = _rec->sq_get_num_fields(); } void TDB_recordset::unset_loaded() { _is_loaded = false; _items = 0; _ncolumns = 0; _current_row = 0; } void TDB_recordset::freeze(const bool on) { if (on) _rec->freeze(); else _rec->defrost(); _freezed = on; } bool TDB_recordset::connect(const char* db, const char* user, const char* pass, const char* tipo_db) const { return _rec->sq_connect(db, user, pass, str_to_driver(tipo_db)) == NOERR; } TRecnotype TDB_recordset::items() const { if (_is_loaded) return _items; return _rec->sq_items(); } bool TDB_recordset::move_to(TRecnotype pos) { const TRecnotype tot = items(); TRecnotype row = pos; bool ok = true; if (pos < 0) row = 0; if (pos > tot) row = tot; if (!_is_loaded) { if (!_sql.empty() && ((ok = _rec->sq_exec()))) set_loaded(); } if( ok && ((ok = _rec->sq_go(row))) ) _current_row = pos; return ok; } bool TDB_recordset::move_next() { bool ok = true; if (!_is_loaded) { if (!_sql.empty() && ((ok = _rec->sq_exec()))) set_loaded(); } if (ok && _rec->sq_next()) { _current_row = _rec->sq_pos(); return true; } return false; } const TString_array TDB_recordset::get_next_row() { if (move_next()) return get_row(); return TArray().destroy(); } const TString_array TDB_recordset::get_row(TRecnotype n) { bool ok = true; // Get della riga attuale if (n == -1) n = current_row(); else if (_current_row != n) ok = move_to(n); // Solo se non sono già su quella riga if (ok) { const unsigned ncol = _rec->sq_get_num_fields(); _row.destroy(); for (unsigned i = 0; i < ncol; i++) _row.add(TString(_rec->sq_get(i, false))); return _row; } // else _row.destroy(); return _row; } void TDB_recordset::requery() { } unsigned TDB_recordset::columns() const { if(!_is_loaded) return _rec->sq_get_num_fields(); return _ncolumns; } const TRecordset_column_info& TDB_recordset::column_info(const unsigned column) const { static TRecordset_column_info info; if (_is_loaded) { info._name = _rec->sq_get_name_field(column); // TString info._width = _rec->sq_get_width_field(column); // int info._type = _rec->sq_get_type_field(column); // TFieldtypes return info; } info._name.cut(0); // TString info._width = 0; // int info._type = _alfafld; // TFieldtypes info._pos = 0; return info; } const TVariant& TDB_recordset::get(unsigned int column) const { static TVariant field = NULL_VARIANT; static unsigned int last_get = 0; if(!_freezed || column != last_get || field == NULL_VARIANT) { last_get = column; field = _rec->sq_get(column); return field; } return field; } bool TDB_recordset::is_connected() const { return _rec->sq_is_connect(); } const TVariant& TDB_recordset::active_connection() const { static TVariant conn = NULL_VARIANT; conn.add(_dsn); conn.add(_usr); conn.add(_drv); return conn; } bool TDB_recordset::exec(const char* sql) { bool exec = false; if ((exec = _rec->sq_set_exec(sql))) { _is_loaded = true; _items = _rec->sq_items(); } return exec; } bool TDB_recordset::commit() const { return _rec->sq_commit(); } TDB_recordset::TDB_recordset(const char* sql, const bool freezed) : _freezed(freezed) { _current_row = -1; _rec = new SSimple_query(); //_rec->sq_set_autocommit(true); _sql.cut(0); _is_loaded = false; _items = 0; _ncolumns = 0; freeze(freezed); set(sql); } TDB_recordset::~TDB_recordset() { delete _rec; }