diff --git a/src/include/about.cpp b/src/include/about.cpp index 82b2756b8..5ec21b5cb 100755 --- a/src/include/about.cpp +++ b/src/include/about.cpp @@ -555,6 +555,7 @@ TInfo_mask::TInfo_mask() : TProperty_sheet(TR("Informazioni")) add_prop(TR("Libreria GUI"), strwx); add_prop(TR("Libreria PDF"), printer); add_prop(TR("Libreria SQL"), strsql); + add_prop(TR("Libreria Matematica"), "GreenLeaf Library"); #ifdef _MSC_VER const int cver = _MSC_VER / 100 - 6; diff --git a/src/include/sqlfilerset.cpp b/src/include/sqlfilerset.cpp new file mode 100644 index 000000000..f72a21f9b --- /dev/null +++ b/src/include/sqlfilerset.cpp @@ -0,0 +1,232 @@ +#include +#include + +///////////////////////////////////////////////////////////////////////////////////// +// TSQLite_autoset +///////////////////////////////////////////////////////////////////////////////////// + +// Imposta il valore di un campo variant +void TSQLite_autoset::set(const char* fld, const TVariant& var) +{ + CHECK(fld && *fld, "Null field name"); + + if (var.is_null()) + { + _fields.remove(fld); + } + else + { + TVariant* obj = (TVariant*)_fields.objptr(fld); + if (obj != NULL) + *obj = var; + else + _fields.add(fld, new TVariant(var)); + } +} + +// Imposta il valore di un campo intero +void TSQLite_autoset::set(const char* fld, long val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo stringa +void TSQLite_autoset::set(const char* fld, const char* val) +{ + if (val == NULL) + set(fld, NULL_VARIANT); + else + { + const TVariant var(val); + set(fld, var); + } +} + +// Imposta il valore di un campo stringa +void TSQLite_autoset::set(const char* fld, const TString& val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo numerico +void TSQLite_autoset::set(const char* fld, const real& val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo data in formato ISO +void TSQLite_autoset::set(const char* fld, const TDate& val) +{ + if (val.ok()) + { + const TVariant var(val); + set(fld, var); + } + else + set(fld, ""); +} + +// Imposta il valore di un campo booleano +void TSQLite_autoset::set(const char* fld, bool var) +{ + set(fld, var ? "SI" : "NO"); +} + +// Legge il valore di un campo variant +const TVariant& TSQLite_autoset::get(const char* fld) const +{ + const TVariant* var = (const TVariant*)_fields.objptr(fld); + return var ? *var : NULL_VARIANT; +} + +// Converte un variant in una stringa valida per SQLite +const TString& TSQLite_autoset::var2str(const TString& fldname, const TVariant& var) const +{ + const TFieldtypes vt = var.type(); + if (vt == _realfld) + { + const TCurrency v(var.as_real(), "", ZERO, fldname.find("IMPONIBILE")>0 || fldname.find("IMPOSTA")>0); + TString& tmp = get_tmp_string(); + tmp << '\'' << v.string() << '\''; + tmp.replace(',','.'); + return tmp; + } + if (vt == _datefld) + { + TString& tmp = get_tmp_string(); + tmp << '\'' << var.as_date().string(full, '-', full, full, amg_date) << '\''; + return tmp; + } + + const TString& str = var.as_string(); + + bool apici = vt == _alfafld; + if (apici && str[0] != '0' && real::is_natural(str)) + apici = false; + + if (!apici) + return str; + + TString& tmp = get_tmp_string(); + tmp = str; + for (int a = str.rfind('\''); a >= 0; a--) + { + if (tmp[a] == '\'') + tmp.insert("'", a); + } + tmp.insert("'", 0); + tmp << '\''; + return tmp; +} + +// Elimina il record in base ai campi chiave +bool TSQLite_autoset::remove() +{ + TString256 query; + query << "DELETE FROM " << _table << " WHERE "; + int nkf = 0; + FOR_EACH_TOKEN(_key, fld) + { + const TVariant& var = get(fld); + if (!var.is_null()) + { + if (nkf++ > 0) + query << " AND "; + query << fld << '=' << var2str(fld, var) ; + } + } + CHECKS(nkf >= 2, "Can't remove partial key on table ", (const char*)_table); + query << ';'; + return xvt_sql_execute(_db, query, NULL, 0L) > 0; +} + +// Callback per la sottostante funzione search() +static int TSQLite_autoset_search_record(void* jolly, int cols, char** values, char** names) +{ + TSQLite_autoset& rec = *(TSQLite_autoset*)jolly; + for (int i = 0; i < cols; i++) + rec.set(names[i], values[i]); + return 0; +} + +// Carica un record in base ai campi chiave +bool TSQLite_autoset::search() +{ + CHECKS(_fields.items() >= _key.items(), "Can't search partial key on table ", _table); + TString256 query; + query << "SELECT * FROM " << _table << " WHERE "; + FOR_EACH_TOKEN(_key, fld) + { + const TVariant& var = get(fld); + if (!var.is_null()) + query << fld << '=' << var2str(fld, var) << " AND "; + } + query.rtrim(5); + query << ';'; + return xvt_sql_execute(_db, query, TSQLite_autoset_search_record, this) == 1; +} + +// Carica un record con le chiavi che passo +bool TSQLite_autoset::search(const char* key, ...) +{ + _fields.destroy(); + + va_list marker; + va_start(marker, key); + int i = 0; + while (key != NULL) + { + set(_key.get(i), key); + i++; + key = va_arg(marker, const char *); + } + va_end(marker); + + return search(); +} + +// Aggiunge un record al db +bool TSQLite_autoset::insert() +{ + CHECKS(_fields.items() > _key.items(), "Can't insert empty record on table ", _table); + + TString query, values; + query << "INSERT INTO " << _table << "\n("; + FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm) + { + const TVariant& var = get(fld); + if (!var.is_null()) + { + query << fld << ','; + values << var2str(fld, var) << ','; + } + } + query.rtrim(1); values.rtrim(1); + query << ")\nVALUES (" << values << ");"; + return xvt_sql_execute(_db, query, NULL, 0L) == 1; +} + +// Imposta una tabella su cui fare le operazioni +bool TSQLite_autoset::setTable(const char* table, const TFilename& db, const TFilename& inipath) +{ + if(db.ok()) + _db = xvt_sql_open(_dbname, user(), "", _dbname.path()); + if(inipath.ok()) + _inipath = inipath; + + _key = ini_get_string(_inipath, table, "INDEX_1"); + CHECKS(!_key.empty_items(), "Invalid primary key for table ", table); + return !_key.empty_items(); +} + +// Crea un record della tabella data ed imposta i nomi dei campi chiave +TSQLite_autoset::TSQLite_autoset(const TFilename& db, const TFilename& inipath, const char* table) + : _dbname(db), _inipath(inipath), _table(table), _key(15, ',') +{ + _db = xvt_sql_open(_dbname, user(), "", _dbname.path()); + if(table != NULL) + setTable(table); +} \ No newline at end of file diff --git a/src/include/strings.cpp b/src/include/strings.cpp index 9a2226538..05d155842 100755 --- a/src/include/strings.cpp +++ b/src/include/strings.cpp @@ -517,6 +517,20 @@ const TString& TString::before(const char* str) const return *this; } +const TString& TString::get_word(int from) const +{ + TString& ret = get_tmp_string(); + char c = _str[from]; + int l = len(); + while(from < l && c != ' ' && c != '\t' && c != '\n' && c != '\f' && c != '\v') // spazio, tab, newline, newpage, vertical tab + { + ret << c; + from ++; + c = _str[from]; + } + return ret; +} + // Certified 100% TString& TString::cut(int n) { diff --git a/src/include/strings.h b/src/include/strings.h index bd5f79629..0823624e6 100755 --- a/src/include/strings.h +++ b/src/include/strings.h @@ -128,6 +128,8 @@ public: // @cmember Ritorna l'oggetto TString prima della string passata const TString& before(char c) const; const TString& before(const char* str) const; + // @cmember Ritorna la parola successiva alla posizione passata + const TString& get_word(int from = 0) const; // @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri da sinistra TString sleft(int count) const diff --git a/src/include/utility.cpp b/src/include/utility.cpp index e635713ba..710d73ca6 100755 --- a/src/include/utility.cpp +++ b/src/include/utility.cpp @@ -707,8 +707,3 @@ void quoted_string(TString& query, const char* val) } query << '\''; } - -TString get_iva_sirio() -{ - return "04879210963"; -} diff --git a/src/include/utility.h b/src/include/utility.h index 8e64b6319..fcb3f581e 100755 --- a/src/include/utility.h +++ b/src/include/utility.h @@ -9,6 +9,10 @@ #include #endif +#ifndef __VARIANT_H +#include +#endif + #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define SAFE_DELETE(p) { delete p; p = NULL; } @@ -66,6 +70,7 @@ long daytime(); bool expand_sys_vars(TString& str); void quoted_string(TString& query, const char* val); -TString get_iva_sirio(); // Ritorna la partita IVA della Sirio +inline const char* get_iva_sirio() // Ritorna la partita IVA della Sirio +{ return "04879210963"; } #endif /* __UTILITY_H */ diff --git a/src/include/validate.cpp b/src/include/validate.cpp index 6d6b07381..5198e1c16 100755 --- a/src/include/validate.cpp +++ b/src/include/validate.cpp @@ -286,12 +286,12 @@ HIDDEN bool _cf_val(TMask_field& f, KEY key) return true; const TString& cf = f.get(); + const TString& stato = get_fld_val_param(f, 0); bool ok = true; if (cf.empty()) return true; if (isdigit(cf[0]) && cf.len() >= 11) - { - const TString& stato = get_fld_val_param(f, 0); + { if (stato.full() && stato != "IT") return true; if (cf[0]>='8' && cf.len() == 11) // codice fiscale ONLUS @@ -306,7 +306,7 @@ HIDDEN bool _cf_val(TMask_field& f, KEY key) ok = __cf_check(cf); if (!ok) { - if(f.dirty()) + if(f.dirty() && (stato.empty() || stato == "IT")) { ok = f.yesno_box(TR("Codice fiscale errato: si desidera accettarlo ugualmente?")); if (ok) f.set_dirty(false); @@ -376,7 +376,7 @@ HIDDEN bool _xt_cf_val(TMask_field& f, KEY key) if (f.mask().query_mode()) return true; - TString16 cf = f.get(); + TString cf = f.get(); if (cf.blank()) return true; @@ -391,9 +391,9 @@ HIDDEN bool _xt_cf_val(TMask_field& f, KEY key) TMask& m = f.mask(); - TMask_field& fld_sex = m.field(get_int_val_param(1)); - TMask_field& fld_dat = m.field(get_int_val_param(2)); - TMask_field& fld_com = m.field(get_int_val_param(3)); + TMask_field& fld_sex = m.field(get_int_val_param(1)); + TMask_field& fld_dat = m.field(get_int_val_param(2)); + TMask_field& fld_com = m.field(get_int_val_param(3)); const char sesso = fld_sex.get()[0]; TString16 data = fld_dat.get();