Patch level : 2.2
Files correlati : Ricompilazione Demo : [ ] Commento : Migliorata ricerca reports in custom git-svn-id: svn://10.65.10.50/trunk@13330 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
ed3c70e150
commit
61a02849f2
@ -716,19 +716,19 @@ bool list_custom_files(const char* ext, const char* classe, TString_array& files
|
||||
|
||||
bool select_custom_file(TFilename& path, const char* ext, const char* library)
|
||||
{
|
||||
TArray_sheet sheet(-1, -1, 82, 20, TR("Selezione"), HR("Nome@8|Classe@8|Descrizione@50|Custom"));
|
||||
TArray_sheet sheet(-1, -1, 80, 20, TR("Selezione"), HR("Nome@8|Classe|Descrizione@50|Custom"));
|
||||
TString_array& files = sheet.rows_array();
|
||||
|
||||
bool ok = list_custom_files(ext, library, files);
|
||||
if (ok)
|
||||
{
|
||||
TFilename path;
|
||||
TFilename name;
|
||||
FOR_EACH_ARRAY_ROW(files, i, row)
|
||||
{
|
||||
path = row->get(0);
|
||||
path.ext(ext);
|
||||
path.custom_path();
|
||||
if (path.find("custom") > 0)
|
||||
name = row->get(0);
|
||||
name.ext(ext);
|
||||
name.custom_path();
|
||||
if (name.find("custom") > 0)
|
||||
row->add("X");
|
||||
}
|
||||
|
||||
@ -749,12 +749,19 @@ bool select_custom_file(TFilename& path, const char* ext, const char* library)
|
||||
// Private interface
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SQLITE3
|
||||
#include "../sqlite3/sqlite3.h"
|
||||
#else
|
||||
#include "../sqlite/sqlite.h"
|
||||
|
||||
#endif
|
||||
|
||||
class TSQLite : public TObject
|
||||
{
|
||||
#ifdef SQLITE3
|
||||
sqlite3* _handle;
|
||||
#else
|
||||
sqlite* _handle;
|
||||
#endif
|
||||
TFilename _currdb;
|
||||
|
||||
protected:
|
||||
@ -763,15 +770,24 @@ protected:
|
||||
void build_curr_path(TFilename& name) const;
|
||||
void test_path();
|
||||
|
||||
#ifdef SQLITE3
|
||||
bool bind_record(const TRectype& rec, const RecDes& rd, sqlite3_stmt* pStatement) const;
|
||||
#else
|
||||
bool esporta(const TRectype& rec, ostream& sql) const;
|
||||
#endif
|
||||
bool create_dbf_times();
|
||||
long get_dbf_time(const TString& table);
|
||||
bool set_dbf_time(const TString& table, long last);
|
||||
bool import(int logicnum);
|
||||
|
||||
public:
|
||||
#ifdef SQLITE3
|
||||
sqlite3* open(const char* fname = NULL);
|
||||
bool exec(const char* sql, sqlite3_callback callback = NULL, void* jolly = NULL, bool show_error = true);
|
||||
#else
|
||||
sqlite* open(const char* fname = NULL);
|
||||
bool exec(const char* sql, sqlite_callback callback = NULL, void* jolly = NULL, bool show_error = true);
|
||||
#endif
|
||||
void close();
|
||||
|
||||
bool exists(const char* table);
|
||||
@ -796,6 +812,36 @@ void TSQLite::build_curr_path(TFilename& name) const
|
||||
name.add(firm);
|
||||
}
|
||||
|
||||
#ifdef SQLITE3
|
||||
|
||||
sqlite3* TSQLite::open(const char* fname)
|
||||
{
|
||||
close();
|
||||
_currdb = fname;
|
||||
int err = sqlite3_open(_currdb, &_handle);
|
||||
|
||||
if (err = SQLITE_CORRUPT)
|
||||
{
|
||||
close();
|
||||
xvt_fsys_removefile(_currdb);
|
||||
err = sqlite3_open(_currdb, &_handle);
|
||||
}
|
||||
|
||||
if (err == SQLITE_OK)
|
||||
{
|
||||
create_dbf_times();
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* errmsg = sqlite3_errmsg(_handle); // Stringa di sitema: inutile sqlite3_free(errmsg)
|
||||
error_box(errmsg);
|
||||
}
|
||||
|
||||
return _handle;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
sqlite* TSQLite::open(const char* fname)
|
||||
{
|
||||
close();
|
||||
@ -812,6 +858,7 @@ sqlite* TSQLite::open(const char* fname)
|
||||
|
||||
return _handle;
|
||||
}
|
||||
#endif
|
||||
|
||||
void TSQLite::test_path()
|
||||
{
|
||||
@ -821,14 +868,22 @@ void TSQLite::test_path()
|
||||
open(n);
|
||||
}
|
||||
|
||||
#ifdef SQLITE3
|
||||
bool TSQLite::exec(const char* sql, sqlite3_callback callback, void* jolly, bool show_error)
|
||||
#else
|
||||
bool TSQLite::exec(const char* sql, sqlite_callback callback, void* jolly, bool show_error)
|
||||
#endif
|
||||
{
|
||||
if (_handle == NULL)
|
||||
test_path();
|
||||
|
||||
TWait_cursor hourglass;
|
||||
char* errmsg = NULL;
|
||||
#ifdef SQLITE3
|
||||
const int rc = sqlite3_exec(_handle, sql, callback, jolly, &errmsg);
|
||||
#else
|
||||
const int rc = sqlite_exec(_handle, sql, callback, jolly, &errmsg);
|
||||
#endif
|
||||
if (errmsg != NULL)
|
||||
{
|
||||
if (show_error)
|
||||
@ -839,7 +894,11 @@ bool TSQLite::exec(const char* sql, sqlite_callback callback, void* jolly, bool
|
||||
msg << '\n' << errmsg;
|
||||
error_box(msg);
|
||||
}
|
||||
#ifdef SQLITE3
|
||||
sqlite3_free(errmsg);
|
||||
#else
|
||||
sqlite_freemem(errmsg);
|
||||
#endif
|
||||
}
|
||||
return rc == SQLITE_OK;
|
||||
}
|
||||
@ -848,7 +907,11 @@ void TSQLite::close()
|
||||
{
|
||||
if (_handle != NULL)
|
||||
{
|
||||
#ifdef SQLITE3
|
||||
sqlite3_close(_handle);
|
||||
#else
|
||||
sqlite_close(_handle);
|
||||
#endif
|
||||
_handle = NULL;
|
||||
}
|
||||
}
|
||||
@ -937,6 +1000,125 @@ bool TSQLite::exists(const char* table)
|
||||
return yes;
|
||||
}
|
||||
|
||||
#ifdef SQLITE3
|
||||
bool TSQLite::bind_record(const TRectype& rec, const RecDes& rd, sqlite3_stmt* pStatement) const
|
||||
{
|
||||
int rc = SQLITE_OK;
|
||||
TVariant tmp;
|
||||
for (int i = 0; i < rd.NFields && rc==SQLITE_OK ; i++)
|
||||
{
|
||||
get_sql_value(rec, rd.Fd[i], tmp);
|
||||
const TString& val = tmp.as_string();
|
||||
rc = sqlite3_bind_text(pStatement, i+1, val, val.len(), SQLITE_TRANSIENT);
|
||||
}
|
||||
return rc == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool TSQLite::import(int logicnum)
|
||||
{
|
||||
const TString& table = logic2table(logicnum);
|
||||
|
||||
long last = get_dbf_time(table);
|
||||
if (logicnum >= LF_USER) // Dummy test
|
||||
{
|
||||
TLocalisamfile file(logicnum);
|
||||
if (!file.is_changed_since(last))
|
||||
return true;
|
||||
}
|
||||
|
||||
const RecDes& rd = prefix().get_recdes(logicnum);
|
||||
|
||||
TString sql;
|
||||
if (exists(table))
|
||||
{
|
||||
// Drop old table
|
||||
sql.cut(0) << "DROP TABLE "<< table << ';';
|
||||
exec(sql);
|
||||
}
|
||||
|
||||
// Create new table
|
||||
sql.cut(0) << "CREATE TABLE "<< table << "\n(";
|
||||
int i;
|
||||
for (i = 0; i < rd.NFields; i++)
|
||||
{
|
||||
if (i > 0) sql << ',';
|
||||
sql << rd.Fd[i].Name << ' ';
|
||||
switch (rd.Fd[i].TypeF)
|
||||
{
|
||||
case _alfafld: sql << "TEXT"; break;
|
||||
case _memofld: sql << "BLOB"; break;
|
||||
case _datefld: sql << "DATE"; break;
|
||||
default : sql << "NUMERIC"; break;
|
||||
}
|
||||
}
|
||||
sql << ");";
|
||||
if (!exec(sql))
|
||||
return false;
|
||||
|
||||
TRelation rel(logicnum);
|
||||
TCursor cur(&rel);
|
||||
const TRecnotype items = cur.items();
|
||||
if (items > 0)
|
||||
{
|
||||
cur.freeze();
|
||||
|
||||
TString msg;
|
||||
msg << TR("Importazione tabella") << ' ' << table;
|
||||
msg << ": " << items << ' ' << TR("righe");
|
||||
TProgind pi(items, msg, true, true);
|
||||
|
||||
exec("BEGIN"); // Inizio transazione
|
||||
|
||||
// Creo il comando INSERT INTO table VALUES(?,?,?,?,?,?);
|
||||
sql.cut(0) << "INSERT INTO " << table << " VALUES(";
|
||||
for (i = 0; i < rd.NFields; i++)
|
||||
{
|
||||
if (i != 0) sql << ',';
|
||||
sql << '?';
|
||||
}
|
||||
sql << ");";
|
||||
|
||||
sqlite3_stmt* pStatement = NULL;
|
||||
int rc = sqlite3_prepare(_handle, sql, sql.len(), &pStatement, NULL);
|
||||
|
||||
const TRectype& curr = rel.curr();
|
||||
for (cur = 0; cur.pos() < items; ++cur)
|
||||
{
|
||||
pi.addstatus(1);
|
||||
if (pi.iscancelled())
|
||||
break;
|
||||
bind_record(curr, rd, pStatement); // Sostituisce i ? coi veri valori
|
||||
rc = sqlite3_step(pStatement); // Ritorna sempre 101 (SQLITE_DONE)
|
||||
rc = sqlite3_reset(pStatement); // Azzero lo statement per ricominciare
|
||||
}
|
||||
rc = sqlite3_finalize(pStatement);
|
||||
exec("COMMIT"); // Fine transazione
|
||||
}
|
||||
|
||||
// Creo gli indici DOPO l'importazione per maggiore velocita'
|
||||
TProgind pi(rd.NKeys, TR("Creazione indici"), false, true);
|
||||
for (int index = 0; index < rd.NKeys; index++)
|
||||
{
|
||||
pi.addstatus(1);
|
||||
sql.cut(0) << "CREATE INDEX " << table << '_' << (index+1) << " ON "<< table << "\n(";
|
||||
const KeyDes& kd = rd.Ky[index];
|
||||
for (int k = 0; k < kd.NkFields; k++)
|
||||
{
|
||||
if (k > 0) sql << ',';
|
||||
const int ndx = kd.FieldSeq[k] % MaxFields;
|
||||
sql << rd.Fd[ndx].Name;
|
||||
}
|
||||
sql << ");";
|
||||
exec(sql);
|
||||
}
|
||||
|
||||
set_dbf_time(table, last); // Aggiorna ora di ultima modifica
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool TSQLite::esporta(const TRectype& rec, ostream& sql) const
|
||||
{
|
||||
const RecDes& rd = *rec.rec_des();
|
||||
@ -975,7 +1157,8 @@ bool TSQLite::import(int logicnum)
|
||||
|
||||
// Create new table
|
||||
sql.cut(0) << "CREATE TABLE "<< table << "\n(";
|
||||
for (int i = 0; i < rd.NFields; i++)
|
||||
int i;
|
||||
for (i = 0; i < rd.NFields; i++)
|
||||
{
|
||||
if (i > 0) sql << ',';
|
||||
sql << rd.Fd[i].Name << ' ';
|
||||
@ -1048,6 +1231,7 @@ bool TSQLite::import(int logicnum)
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TSQLite::parse_select_from(const char* szSql)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user