campo-sirio/include/odbc.cpp
guy feb69c6dff Patch level : 2.0 nopatch
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

Aggiunti files per supporto ODBC via XML


git-svn-id: svn://10.65.10.50/trunk@11403 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-09-11 07:26:47 +00:00

653 lines
13 KiB
C++
Executable File

#ifndef CB6
#include <xvt.h>
#include <codeb.h>
#include <config.h>
#include <diction.h>
#include <extcdecl.h>
#include <lffiles.h>
#include <netsock.h>
#include <prefix.h>
#include <xml.h>
#include <strstrea.h>
class TDB_table : public TObject
{
TString _study, _firm, _name;
int _logicnum;
int _mode, _index;
int _rec_len;
long _rec_count;
TString _query;
TString _query_name;
long _recno; // 0 = bof; 1 = first record; 2 second record
TXmlItem _record;
TString _record_buf, _key_buf;
protected:
void build_soap_method(const char* strMethod, TXmlItem& method) const;
int fill_record(const TXmlItem* res);
public:
virtual bool ok() const { return rec_len() > 0; }
int select_tag(int t);
int tag() const { return _index; }
int rec_len() const;
long rec_count() const;
bool bof() const { return _recno <= 0; }
bool eof() const { return _recno > rec_count(); }
char* get_record();
char* get_key();
long recno() const { return _recno; }
int go_to(long recno);
int skip_to(long recno, long offset);
int seek(const char* key);
TDB_table(const char* file, int mode, int index);
};
class TDB_manager : public TSocketClient
{
TString _server;
TArray _table;
int _error;
protected:
public:
TCodeb_handle open(const char* name, int mode, int index);
int close(TCodeb_handle h);
TDB_table& table(TCodeb_handle h) const;
int set_error(int e) { return _error = e; }
int get_error() const { return _error; }
TXmlItem* call_soap(const TXmlItem& method, TXmlItem& answer);
TDB_manager();
~TDB_manager();
};
static TDB_manager* _db = NULL;
///////////////////////////////////////////////////////////
// TDB_table
///////////////////////////////////////////////////////////
void TDB_table::build_soap_method(const char* strMethod, TXmlItem& method) const
{
CHECKS(strMethod[0] == 'm' && strMethod[1] == ':', "Missing m: in SOAP method", strMethod);
method.Destroy();
method.SetTag(strMethod);
method.AddSoapString("Study", _study);
method.AddSoapString("Firm", _firm);
method.AddSoapString("Table", _name);
method.AddSoapInt("Index", _index);
}
long TDB_table::rec_count() const
{
if (_rec_count <= 0)
{
TXmlItem method, answer;
build_soap_method("m:TableRows", method);
const TXmlItem* res = _db->call_soap(method, answer);
if (res != NULL)
{
TString16 str;
res->GetEnclosedText(str);
(long&)_rec_count = atol(str);
}
}
return _rec_count;
}
int TDB_table::fill_record(const TXmlItem* res)
{
if (res != NULL)
{
const TXmlItem* rec = res->FindFirst("Record");
_recno = atol(rec->GetAttr("RecNo"));
if (_recno > _rec_count)
_rec_count = _recno;
const RecDes& rd = prefix().get_recdes(_logicnum);
TString16 name;
TString value;
for (int i = 0; i < rec->GetChildren(); i++)
{
const TXmlItem& fld = *rec->GetChild(i);
name = fld.GetAttr("Name"); name.upper();
const int index = findfld(&rd, name);
if (index != FIELDERR)
{
fld.GetEnclosedText(value);
switch (rd.Fd[index].TypeF)
{
case _boolfld:
value = value[0] == '1' ? "Y" : "N"; break;
case _intfld:
case _longfld:
case _intzerofld:
case _longzerofld:
value.right_just(rd.Fd[index].Len); break;
case _memofld:
value.cut(0); break;
default:
break;
}
_record_buf.overwrite(value, rd.Fd[index].RecOff);
}
}
return NOERR;
}
_recno = _rec_count*4+1; // EOF
return _db->set_error(5);
}
int TDB_table::go_to(long recno)
{
if (recno == _recno)
return NOERR;
TXmlItem method;
build_soap_method("m:GetRecord", method);
method.AddSoapInt("RecNo", recno);
const TXmlItem* res = _db->call_soap(method, _record);
return fill_record(res);
}
int TDB_table::skip_to(long recno, long offset)
{
TXmlItem method;
build_soap_method("m:SkipRecord", method);
method.AddSoapInt("RecNo", recno);
method.AddSoapInt("Offset", offset);
const TXmlItem* res = _db->call_soap(method, _record);
return fill_record(res);
}
char* TDB_table::get_record()
{
return _record_buf.get_buffer();
}
char* TDB_table::get_key()
{
_key_buf.cut(0);
if (_logicnum > 0 && _index > 0 && _recno > 0 && _recno <= rec_count())
{
const TXmlItem* rec = _record.FindFirst("Record");
if (rec != NULL)
{
const RecDes& rd = prefix().get_recdes(_logicnum);
const KeyDes& kd = rd.Ky[_index-1]; // Elenco dei campi della chiave
TString str;
for (int i = 0; i < kd.NkFields; i++)
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = rd.Fd[nf];
for (int i = 0; i < rec->GetChildren(); i++)
{
const TXmlItem& fld = *rec->GetChild(i);
if (fld.GetAttr("Name").compare(rf.Name, -1, true) == 0)
{
fld.GetEnclosedText(str);
switch (rf.TypeF)
{
case _intfld:
case _longfld:
case _intzerofld:
case _longzerofld:
str.right_just(rf.Len); break;
default:
str.rpad(rf.Len); break;
}
_key_buf << str;
break;
}
}
}
}
}
return _key_buf.get_buffer();
}
int TDB_table::seek(const char* key)
{
/*
TXmlItem method;
build_soap_method("m:SeekRecord", method);
method.AddSoapString("Key", key);
const TXmlItem* res = _db->call_soap(method, _record);
return fill_record(res);
*/
return skip_to(0, 0);
}
int TDB_table::rec_len() const
{
if (_rec_len <= 0)
{
TXmlItem method, answer;
build_soap_method("m:GetRecordLength", method);
const TXmlItem* res = _db->call_soap(method, answer);
if (res != NULL)
{
TString16 str;
if (res->GetEnclosedText(str))
(int&)_rec_len = atoi(str)+1; // Add deleted flag (1 byte)
}
}
return _rec_len;
}
int TDB_table::select_tag(int t)
{
int err = NOERR;
if (t != _index)
{
_index = t;
if (ok())
{
TXmlItem method, answer;
build_soap_method("m:CreateIndex", method);
const RecDes& rd = prefix().get_recdes(_logicnum);
const KeyDes& kd = rd.Ky[_index-1]; // Elenco dei campi della chiave
for (int i = 0; i < kd.NkFields; i++)
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = rd.Fd[nf];
TXmlItem& fld = method.AddChild("Field");
fld.SetAttr("Name", rf.Name);
if (kd.FieldSeq[i] >= MaxFields)
fld.SetAttr("Upper", "1");
}
TString16 str;
const TXmlItem* res = _db->call_soap(method, answer);
if (res != NULL)
res->GetEnclosedText(str);
if (str != "1")
err = _db->set_error(883); // ???
}
}
return err;
}
TDB_table::TDB_table(const char* file, int mode, int index)
: _mode(mode), _index(index), _recno(-1), _rec_count(-1), _rec_len(-1), _logicnum(0)
{
TToken_string tok(file, '/' );
const int dot = tok.rfind('.');
if (dot > 0) tok.cut(dot);
tok.replace('\\', '/');
tok.upper();
const int items = tok.items();
tok.get(items-1, _name);
tok.get(items-2, _firm);
tok.get(items-3, _study);
FileDes filedes;
memset(&filedes, 0, sizeof(filedes));
for (int i = LF_USER; i < 100; i++)
{
CGetFile(i, &filedes, _nolock, _nordir);
if (_name.compare(filedes.SysName+1, -1, true) == 0)
{
_logicnum = i;
break;
}
}
}
///////////////////////////////////////////////////////////
// TDB_manager
///////////////////////////////////////////////////////////
TCodeb_handle TDB_manager::open(const char* name, int mode, int index)
{
TCodeb_handle h = -1; // Inizializzo handle non valido
// Crea tabella
TDB_table* t = new TDB_table(name, mode, index);
if (t->ok())
{
// Cerca primo handle disponibile
for (h = 0; _table.objptr(h) != NULL; h++);
_table.add(t, h);
}
else
delete t;
return h;
}
int TDB_manager::close(TCodeb_handle h)
{
const int err = _table.destroy(h) ? 0 : 2;
return err;
}
TDB_table& TDB_manager::table(TCodeb_handle h) const
{
TDB_table* t = (TDB_table*)_table.objptr(h);
CHECKD(t != NULL, "Invalid TABLE handle ", h);
return *t;
}
TXmlItem* TDB_manager::call_soap(const TXmlItem& method, TXmlItem& answer)
{
TXmlItem* result = NULL;
CONNID conn = 0;
for (int i = 0; conn == 0 && i < 5; i++)
conn = QueryConnection("", _server);
if (conn != 0)
{
TString str(8192);
method.AsString(str);
if (HttpSoap(conn, str))
{
size_t size;
char* buf = (char*)GetBuffer(size);
istrstream inf(buf, size);
if (answer.Read(inf))
{
str = method.GetTag();
str << "Result";
result = answer.FindFirst(str);
}
}
else
error_box(FR("Impossible eseguire '%s' sul soap server '%s'"),
(const char*)method.GetTag(), (const char*)_server);
RemoveConnection(conn);
}
else
error_box(FR("Impossible connettersi al soap server '%s'"), (const char*)_server);
return result;
}
TDB_manager::TDB_manager()
{
TConfig ini(CONFIG_INSTALL, "Server");
_server = ini.get("DataBase", NULL, -1, "127.0.0.1:3885");
}
TDB_manager::~TDB_manager()
{ }
///////////////////////////////////////////////////////////
// codeb.h implementation
///////////////////////////////////////////////////////////
void DB_init(void)
{
DB_exit();
_db = new TDB_manager();
}
void DB_exit(void)
{
if (_db != NULL)
{
delete _db;
_db = NULL;
}
}
TCodeb_handle DB_open(const char *filename, int mode, int index)
{
return _db->open(filename, mode, index);
}
int DB_close(TCodeb_handle handle)
{
return _db->close(handle);
}
char* DB_getrecord(int handle)
{
return _db->table(handle).get_record();
}
int DB_reclen(int handle)
{
return _db->table(handle).rec_len();
}
int DB_keylen(int handle)
{
return 0;
}
long DB_recno(int handle)
{
return _db->table(handle).recno();
}
long int DB_reccount(int handle)
{
return _db->table(handle).rec_count();
}
int DB_tagselect(int handle,int index_no)
{
return _db->table(handle).select_tag(index_no);
}
int DB_tagget(int handle)
{
return _db->table(handle).tag();
}
int DB_first(int handle)
{
return _db->table(handle).skip_to(0, 0);
}
int DB_last(int handle)
{
return _db->table(handle).skip_to(-1, 0);
}
int DB_next(int handle)
{
return DB_skip(handle, +1);
}
int DB_prev(int handle)
{
return DB_skip(handle, -1);
}
int DB_skip(int handle,long offset)
{
TDB_table& tab = _db->table(handle);
return tab.skip_to(tab.recno(), offset);
}
int DB_lock(int handle)
{
return 0;
}
int DB_unlock(int handle)
{
return 0;
}
int DB_seek(int handle,char *key)
{
return _db->table(handle).seek(key);
}
int DB_eof(int handle)
{
return _db->table(handle).eof();
}
int DB_bof(int handle)
{
return _db->table(handle).bof();
}
int DB_go(int handle,long recno)
{
return _db->table(handle).go_to(recno);
}
int DB_delete(int handle)
{
return 0;
}
int DB_recall(int handle)
{
return 0;
}
int DB_delkey(int handle, char* key, long recno)
{
return 0;
}
int DB_flush(int handle)
{
return 0;
}
int DB_rewrite(int handle)
{
return 0;
}
bool DB_has_memo(int handle)
{
return false;
}
int DB_add(int handle)
{
return 0;
}
int DB_lockfile(int handle)
{
return 0;
}
int DB_packfile(short vis, const char * filename, long eod)
{
return 0;
}
int DB_packmemo(short vis, const char * filename)
{
return 0;
}
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod, bool ask )
{
return 0;
}
int DB_build(const char * filename, RecDes *r)
{
return 0;
}
int DB_recinfo(const char * filename, FileDes *d, RecDes *r, char* keys)
{
return 0;
}
int DB_get_error(void)
{
return _db->get_error();
}
void DB_zero_error(void)
{
_db->set_error(0);
}
int DB_index_seek(int handle, char* from)
{
return DB_seek(handle, from);
}
long DB_index_recno(int handle)
{
return DB_recno(handle);
}
long DB_index_next(int handle)
{
return DB_next(handle);
}
char* DB_index_getkey(int handle)
{
return _db->table(handle).get_key();
}
int DB_index_go(int handle, const char * key, long recno)
{
return DB_go(handle, recno);
}
char* DB_memoptr(const int handle, const char * fieldname )
{
return 0;
}
int DB_memowrite(const int handle, const char * fieldname, const char * data )
{
return 0;
}
int DB_index_eof(int handle)
{
return DB_eof(handle);
}
int DB_lock_rec(int handle,long nrec)
{
return 0;
}
int DB_file_locked(int handle)
{
return 0;
}
int DB_rec_locked(int handle,long nrec)
{
return 0;
}
long DB_getconf()
{
return 0;
}
long DB_changed(int handle)
{
return 0;
}
#endif