Patch level : 12.00 1262
Files correlati : Commento : nvio postino con ODBC
This commit is contained in:
parent
850dbf6978
commit
6664b94657
@ -73,7 +73,7 @@ bool TODBC_recordset::connect(const char* dsn, const char* usr, const char* pwd,
|
||||
if (name.starts_with("ACEODB"))
|
||||
_driver = ODBC_access;
|
||||
else
|
||||
if (name.starts_with("SQLSRV"))
|
||||
if (name.starts_with("SQLSRV") || name.starts_with("sqlncl"))
|
||||
_driver = ODBC_mssql;
|
||||
else
|
||||
if (name.starts_with("MYSQL??"))
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <golem.h>
|
||||
#include <netsock.h>
|
||||
#include <odbcrset.h>
|
||||
#include <progind.h>
|
||||
#include <recarray.h>
|
||||
#include <relation.h>
|
||||
#include <scanner.h>
|
||||
@ -295,15 +296,131 @@ static int write_xml(TConfig& cfg, void* jolly)
|
||||
|
||||
typedef enum { db_add, db_update, db_remove } db_op;
|
||||
|
||||
HIDDEN const TString & build_statement(const db_op op, int logicnum, const TString_array & keys, const TString_array & values)
|
||||
const TString & table_name(int logicnum)
|
||||
{
|
||||
TString & name = get_tmp_string();
|
||||
const int firm = prefix().get_codditta();
|
||||
TDir d(logicnum);
|
||||
|
||||
if (d.is_firm())
|
||||
name << format("%05lda", firm) << '.';
|
||||
else
|
||||
name << "COM.";
|
||||
name << logic2table(logicnum);
|
||||
return name;
|
||||
}
|
||||
|
||||
HIDDEN bool create_table(TODBC_recordset & recset, int logicnum, const char * table_name, TTrec & recdef)
|
||||
{
|
||||
TString sql = "CREATE TABLE [";
|
||||
int nfields = recdef.fields();
|
||||
|
||||
sql << table_name << "](\n";
|
||||
for (int i = 0; i < nfields; i++)
|
||||
{
|
||||
TToken_string def = recdef.fielddef(i);
|
||||
TString field(def.get(0));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
|
||||
if (i > 0)
|
||||
sql << ", ";
|
||||
sql << "[" << field << "] ";
|
||||
switch (t)
|
||||
{
|
||||
case _charfld:
|
||||
case _alfafld:
|
||||
sql << "VARCHAR(" << def.get_int(2) << ")";
|
||||
break;
|
||||
case _memofld:
|
||||
sql << "VARCHAR(MAX)"; break;
|
||||
case _datefld:
|
||||
sql << "DATE"; break;
|
||||
case _boolfld:
|
||||
sql << "BIT DEFAULT 0"; break;
|
||||
case _realfld:
|
||||
case _wordfld:
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
default: sql << "NUMERIC(" << def.get_int(2) << "," << def.get_int(3) << ")"; break;
|
||||
}
|
||||
|
||||
}
|
||||
sql << ");\n";
|
||||
int err = recset.exec(sql);
|
||||
|
||||
if (err < 0)
|
||||
return false;
|
||||
for (int k = 0; k < recdef.keys(); k++)
|
||||
{
|
||||
TToken_string key(recdef.keydef(k), '+');
|
||||
bool dupkeys = false;
|
||||
int pos = key.find("|");
|
||||
int el = 0;
|
||||
|
||||
if (pos > 0)
|
||||
{
|
||||
dupkeys = key.mid(pos + 1).full();
|
||||
key = key.left(pos);
|
||||
}
|
||||
sql = "CREATE ";
|
||||
sql << (dupkeys ? "INDEX KEY" : "UNIQUE INDEX KEY") << k + 1 << " ON [" << table_name << "] (";
|
||||
|
||||
FOR_EACH_STR_TOKEN(key, field)
|
||||
{
|
||||
if (el++ > 0)
|
||||
sql << ',';
|
||||
if (field.starts_with("UPPER"))
|
||||
{
|
||||
field = field.mid(6, field.len() - 7);
|
||||
sql << field << "_UPPER";
|
||||
TString alter = "ALTER TABLE [";
|
||||
|
||||
alter << table_name << "] ADD " << field << "_UPPER AS UPPER(" << field << ");";
|
||||
err = recset.exec(alter);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = field.find("[");
|
||||
|
||||
if (pos > 0)
|
||||
{
|
||||
TString fld = field.left(pos);
|
||||
|
||||
sql << fld << "_MID";
|
||||
|
||||
const int start = atoi(field.mid(pos + 1));
|
||||
|
||||
pos = field.find(",", pos + 1);
|
||||
const int end = pos > 0 ? atoi(field.mid(pos + 1)) : 0;
|
||||
|
||||
TString alter = "ALTER TABLE [";
|
||||
|
||||
alter << table_name << "] ADD " << fld << "_MID AS " << (recset.driver() == ODBC_mssql ? "SUBSTRING(" : "MID(") << fld << ',' << start;
|
||||
|
||||
if (end > 0)
|
||||
alter << ',' << end - start + 1;
|
||||
alter << ");";
|
||||
err = recset.exec(alter);
|
||||
}
|
||||
else
|
||||
sql << field;
|
||||
}
|
||||
}
|
||||
sql << ");\n";
|
||||
int err = recset.exec(sql);
|
||||
|
||||
if (err < 0)
|
||||
return false;
|
||||
}
|
||||
return err >= 0;
|
||||
}
|
||||
|
||||
HIDDEN const TString & build_statement(const db_op op, int logicnum, const char * table_name, const TString_array & keys, const TString_array & values)
|
||||
{
|
||||
TString & statement = get_tmp_string();
|
||||
TString table_name;
|
||||
const int firm = prefix().get_codditta();
|
||||
|
||||
if (firm > 0)
|
||||
table_name << format("%05lda", firm) << '_';
|
||||
table_name << logic2table(logicnum);
|
||||
if (op == db_add)
|
||||
{
|
||||
statement << "INSERT INTO [" << table_name << "] (";
|
||||
@ -355,6 +472,111 @@ HIDDEN const TString & build_statement(const db_op op, int logicnum, const TStri
|
||||
return statement;
|
||||
}
|
||||
|
||||
HIDDEN const char * make_val(const char * fld, TFieldtypes t, TString &src)
|
||||
{
|
||||
TString & val = get_tmp_string();
|
||||
int pos = src.find("'");
|
||||
|
||||
val << fld << '=';
|
||||
while (pos > 0)
|
||||
{
|
||||
src.insert("'", pos);
|
||||
pos = src.find("'", pos + 2);
|
||||
}
|
||||
switch (t)
|
||||
{
|
||||
case _alfafld:
|
||||
case _charfld:
|
||||
case _datefld:
|
||||
case _memofld:
|
||||
val << '\'' << src << '\'';
|
||||
break;
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
case _realfld:
|
||||
case _wordfld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
val << (src.blank() ? "0" : src);
|
||||
break;
|
||||
case _boolfld:
|
||||
val << (src.blank() ? "'FALSE'" : "'TRUE'");
|
||||
break;
|
||||
default:
|
||||
val << src;
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
HIDDEN bool popolate_table(TODBC_recordset & recset, int logicnum, const char * table_name, TTrec & recdef)
|
||||
{
|
||||
bool ok = false;
|
||||
int nfields = recdef.fields();
|
||||
TCursor c(new TRelation(logicnum));
|
||||
const long items = c.items();
|
||||
TProgress_monitor pi(items, format(TR("caricamento tabella %s"), table_name));
|
||||
|
||||
for (c.pos() = 0; pi.addstatus() && c.pos() < items; ++c)
|
||||
{
|
||||
TString_array values;
|
||||
TString_array keys;
|
||||
|
||||
for (int i = 0; i < nfields; i++)
|
||||
{
|
||||
TToken_string def = recdef.fielddef(i);
|
||||
TString field(def.get(0));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
TString str = c.curr().get(field);
|
||||
TToken_string row(make_val(field, t, str), '=');
|
||||
|
||||
values.add(row);
|
||||
}
|
||||
|
||||
TToken_string key(recdef.keydef(), '+');
|
||||
int pos = key.find("|");
|
||||
|
||||
if (pos > 0)
|
||||
key = key.left(pos);
|
||||
FOR_EACH_STR_TOKEN(key, field)
|
||||
{
|
||||
TString fld = field;
|
||||
int pos = fld.find("[");
|
||||
|
||||
if (pos > 0)
|
||||
fld = fld.left(pos);
|
||||
|
||||
TToken_string def = recdef.fielddef(recdef.field(fld));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
TString str = c.curr().get(fld);
|
||||
|
||||
if (pos > 0)
|
||||
{
|
||||
int start = atoi(field.mid(pos));
|
||||
|
||||
pos = field.find(',', pos);
|
||||
str = str.smid(start, pos > 0 ? pos : 0);
|
||||
}
|
||||
|
||||
TToken_string row(make_val(field, t, str), '=');
|
||||
|
||||
keys.add(row);
|
||||
}
|
||||
|
||||
const TString & statement = build_statement(db_add, logicnum, table_name, keys, values);
|
||||
int err = recset.exec(statement);
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
const TString & statement = build_statement( db_update, logicnum, table_name, keys, values);
|
||||
|
||||
err = recset.exec(statement);
|
||||
}
|
||||
if (err <= 0)
|
||||
error_box(FR("Errore n. %d invio file %d"), logicnum, err);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
HIDDEN void odbc_send(const TString & dsn, int num, TAuto_token_string & elab_files, const TFilename & name)
|
||||
{
|
||||
TODBC_recordset recset;
|
||||
@ -406,111 +628,96 @@ HIDDEN void odbc_send(const TString & dsn, int num, TAuto_token_string & elab_fi
|
||||
ini.set_paragraph(*row);
|
||||
TTrec wrk(curr_file_num);
|
||||
int nfields = wrk.fields();
|
||||
const TString name = table_name(curr_file_num);
|
||||
|
||||
for (int i = 0; i < nfields; i++)
|
||||
TString check_statement = "SELECT TOP 1 * FROM [";
|
||||
|
||||
check_statement << name << "];";
|
||||
if (recset.exec(check_statement) < 0)
|
||||
{
|
||||
TToken_string def = wrk.fielddef(i);
|
||||
TString field(def.get(0));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
TToken_string row(field, '=');
|
||||
|
||||
TString str = ini.get(field);
|
||||
TString val;
|
||||
|
||||
str.strip("\"");
|
||||
switch (t)
|
||||
{
|
||||
case _alfafld:
|
||||
case _charfld:
|
||||
case _datefld:
|
||||
case _memofld:
|
||||
val << '\'' << str << '\'';
|
||||
break;
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
case _realfld:
|
||||
case _wordfld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
val = str.blank() ? "0" : str;
|
||||
break;
|
||||
case _boolfld:
|
||||
val = str.blank() ? "'FALSE'" : "'TRUE'";
|
||||
break;
|
||||
default:
|
||||
val = str;
|
||||
break;
|
||||
}
|
||||
row.add(val);
|
||||
values.add(row);
|
||||
create_table(recset, num, name, wrk);
|
||||
popolate_table(recset, num, name, wrk);
|
||||
recset.exec("COMMIT;");
|
||||
}
|
||||
|
||||
TToken_string key(wrk.keydef(), '+');
|
||||
int pos = key.find("|");
|
||||
|
||||
if (pos > 0)
|
||||
key = key.left(pos);
|
||||
FOR_EACH_STR_TOKEN(key, field)
|
||||
else
|
||||
{
|
||||
TToken_string row(field, '=');
|
||||
int pos = field.find("[");
|
||||
for (int i = 0; i < nfields; i++)
|
||||
{
|
||||
TToken_string def = wrk.fielddef(i);
|
||||
TString field(def.get(0));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
TString str = ini.get(field);
|
||||
str = str.strip("\"");
|
||||
TToken_string row(make_val(field, t, str), '=');
|
||||
|
||||
values.add(row);
|
||||
}
|
||||
|
||||
TToken_string key(wrk.keydef(), '+');
|
||||
int pos = key.find("|");
|
||||
|
||||
if (pos > 0)
|
||||
field = field.left(pos);
|
||||
|
||||
TString str = ini.get(field);
|
||||
|
||||
if (str.blank())
|
||||
key = key.left(pos);
|
||||
pos = 0;
|
||||
FOR_EACH_STR_TOKEN(key, field)
|
||||
{
|
||||
ini.set_paragraph(main_file);
|
||||
str = ini.get(field);
|
||||
TString fld = field;
|
||||
|
||||
if (fld.starts_with("UPPER"))
|
||||
{
|
||||
fld = fld.smid(7);
|
||||
fld.rtrim(1);
|
||||
fld << "_UPPER";
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = fld.find("[");
|
||||
|
||||
if (pos > 0)
|
||||
fld = fld.left(pos);
|
||||
}
|
||||
|
||||
TString str = ini.get(field);
|
||||
|
||||
if (str.blank())
|
||||
str << rowkey.get();
|
||||
ini.set_paragraph(*row);
|
||||
{
|
||||
ini.set_paragraph(main_file);
|
||||
str = ini.get(fld);
|
||||
if (str.blank())
|
||||
str << rowkey.get();
|
||||
ini.set_paragraph(*row);
|
||||
}
|
||||
str = str.strip("\"");
|
||||
|
||||
TToken_string def = wrk.fielddef(wrk.field(fld));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
|
||||
if (pos > 0)
|
||||
{
|
||||
int start = atoi(field.mid(pos + 1));
|
||||
|
||||
pos = field.find(',', pos + 1);
|
||||
str = str.smid(start, pos > 0 ? atoi(field.mid(pos + 1)) : 0);
|
||||
fld << "_MID";
|
||||
}
|
||||
|
||||
TToken_string row(make_val(fld, t, str), '=');
|
||||
keys.add(row);
|
||||
}
|
||||
const TString & statement = build_statement(op, curr_file_num, name, keys, values);
|
||||
int err = recset.exec(statement);
|
||||
|
||||
TToken_string def = wrk.fielddef(wrk.field(field));
|
||||
TFieldtypes t = (TFieldtypes)def.get_int(1);
|
||||
TString val;
|
||||
|
||||
str.strip("\"");
|
||||
switch (t)
|
||||
if (op < db_remove && err <= 0)
|
||||
{
|
||||
case _alfafld:
|
||||
case _charfld:
|
||||
case _datefld:
|
||||
case _memofld:
|
||||
val << '\'' << str << '\'';
|
||||
break;
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
case _realfld:
|
||||
case _wordfld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
val = str.blank() ? "0" : str;
|
||||
break;
|
||||
case _boolfld:
|
||||
val = str.blank() ? "'FALSE'" : "'TRUE'";
|
||||
break;
|
||||
default:
|
||||
val = str;
|
||||
break;
|
||||
const TString & statement = build_statement(op == db_add ? db_update : db_add, curr_file_num, name, keys, values);
|
||||
|
||||
err = recset.exec(statement);
|
||||
}
|
||||
row.add(val);
|
||||
keys.add(row);
|
||||
if (err <= 0)
|
||||
error_box(FR("Errore n. %d invio file %d"), curr_file_num, err);
|
||||
else
|
||||
recset.exec("COMMIT;");
|
||||
}
|
||||
const TString & statement = build_statement(op, curr_file_num, keys, values);
|
||||
int err = recset.exec(statement);
|
||||
|
||||
if (op < db_remove && err <= 0)
|
||||
{
|
||||
const TString & statement = build_statement(op == db_add ? db_update : db_add, curr_file_num, keys, values);
|
||||
|
||||
err = recset.exec(statement);
|
||||
}
|
||||
if (err <= 0)
|
||||
error_box(FR("Errore file %d invio n. %d"), curr_file_num, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -680,8 +887,10 @@ bool TPostman::dispatch_transaction(const TRectype& rec,
|
||||
FOR_EACH_TOKEN(odbc_dest, r)
|
||||
{
|
||||
const TString & dsn = r;
|
||||
|
||||
TAuto_token_string files = odbc_files.get();
|
||||
|
||||
|
||||
::odbc_send(dsn, rec.num(), files, name);
|
||||
}
|
||||
remove_file(name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user