Patch level : 2.0 nopatch

Files correlati     : servers
Ricompilazione Demo : [ ]
Commento            :

Gestione database tramite ODBC


git-svn-id: svn://10.65.10.50/trunk@11402 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2003-09-11 07:16:13 +00:00
parent 12533dff5b
commit b64e39b06b
6 changed files with 632 additions and 90 deletions

View File

@ -582,7 +582,12 @@ bool TBaseServerApp::OnInit()
ok = Initialization(); ok = Initialization();
#ifdef WIN32 #ifdef WIN32
if (ok) m_Tray.Init(); m_Tray = NULL;
if (ok)
{
m_Tray = new TTaskBarIcon;
m_Tray->Init();
}
#endif #endif
return ok; return ok;
@ -604,6 +609,14 @@ int TBaseServerApp::OnExit()
delete m_log; delete m_log;
} }
#ifdef WIN32
if (m_Tray != NULL)
{
delete m_Tray;
m_Tray = NULL;
}
#endif
return wxApp::OnExit(); return wxApp::OnExit();
} }

View File

@ -84,7 +84,7 @@ private:
int m_nTmpCounter; int m_nTmpCounter;
#ifdef WIN32 #ifdef WIN32
TTaskBarIcon m_Tray; TTaskBarIcon* m_Tray;
#endif #endif
protected: protected:

View File

@ -1,17 +1,409 @@
#include <wx/wxprec.h> #include <wx/wx.h>
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif //WX_PRECOMP
#include "BaseServ.h" #include "BaseServ.h"
#include <wx/dbtable.h> #include <wx/dbtable.h>
//#include <wx/db.h> #include <wx/dynarray.h>
#include <wx/mstream.h> #include <wx/mstream.h>
wxString GetSoapParam(const TXmlItem &xmlMethod, const char* strParam)
{
wxString val;
const TXmlItem* xml = xmlMethod.FindFirst(strParam);
if (xml != NULL)
val = xml->GetEnclosedText();
return val;
}
///////////////////////////////////////////////////////////
// TRecord
// Tabella di database con 1 o piu' viste in base alla chiave
///////////////////////////////////////////////////////////
class TRecord : public wxObject
{
private:
wxArrayString m_Fields;
wxString m_strLocker; // User locking the record
bool m_bDeleted;
public:
bool Locked() const { return !m_strLocker.IsEmpty(); }
const wxString& LockedBy() const { return m_strLocker; }
bool Deleted() const { return m_bDeleted; }
void MarkAsDeleted() { m_bDeleted = true; }
void MarkAsUndeleted() { m_bDeleted = false; }
void Add(const wxString& strValue) { m_Fields.Add(strValue); }
const wxString& operator[] (size_t i) const { return m_Fields[i]; }
wxString& operator[] (size_t i) { return m_Fields[i]; }
};
///////////////////////////////////////////////////////////
// TArrayObject
///////////////////////////////////////////////////////////
WX_DEFINE_ARRAY(wxObject*, TArrayObject);
///////////////////////////////////////////////////////////
// TIndexEntry
///////////////////////////////////////////////////////////
struct TIndexEntry : public wxObject
{
wxString m_strkey;
long m_nRecno;
};
///////////////////////////////////////////////////////////
// TIndex
///////////////////////////////////////////////////////////
class TIndex : public wxObject
{
enum { MAX_KEY_ENTRIES = 8 };
int m_nField[MAX_KEY_ENTRIES];
int m_nSize[MAX_KEY_ENTRIES];
bool m_bUpper[MAX_KEY_ENTRIES];
int m_nKeyFields;
TArrayObject m_ndx;
protected:
void AddRecord(const TRecord& rec, long recno);
long FindPosition(long recno) const;
public:
void AddKeyField(int nPos, int nSize, bool upper);
long FindPosition(const wxString& key) const;
long SkipTo(long recno, long offset) const;
void Update(const TArrayObject& records);
bool Ok() const { return m_nKeyFields > 0; }
long GetCount() const { return m_ndx.GetCount(); }
TIndex();
};
void TIndex::AddKeyField(int nPos, int nSize, bool upper)
{
if (m_nKeyFields < MAX_KEY_ENTRIES)
{
m_nField[m_nKeyFields] = nPos;
m_nSize[m_nKeyFields] = nPos;
m_bUpper[m_nKeyFields] = upper;
m_nKeyFields++;
}
}
long TIndex::FindPosition(const wxString& key) const
{
int nFirst = 0;
int nLast = m_ndx.GetCount()-1;
while (nFirst <= nLast)
{
const int nCurr = (nFirst + nLast) / 2;
const int nCmp = ((TIndexEntry*)m_ndx[nCurr])->m_strkey.Cmp(key);
if (nCmp == 0)
return nCurr;
if (nCmp > 0)
nLast = nCurr-1;
if (nCmp < 0)
nFirst = nCurr+1;
}
return nFirst;
}
long TIndex::FindPosition(long recno) const
{
long i;
for (i = m_ndx.GetCount()-1; i >= 0; i--)
if (((TIndexEntry*)m_ndx[i])->m_nRecno == recno)
break;
return i;
}
long TIndex::SkipTo(long recno, long offset) const
{
const long tot = m_ndx.GetCount();
long i = 0;
if (tot > 0)
{
if (recno == 0) // Goto first
i = ((TIndexEntry*)m_ndx[0])->m_nRecno; else
if (recno < 0) // Goto last
i = ((TIndexEntry*)m_ndx[tot-1])->m_nRecno; else
{
const long p = FindPosition(recno) + offset;
if (p >= 0 && p < tot)
i = ((TIndexEntry*)m_ndx[p])->m_nRecno;
}
}
return i;
}
void TIndex::AddRecord(const TRecord& rec, long recno)
{
TIndexEntry* e = new TIndexEntry;
e->m_nRecno = recno;
for (int i = 0; i < m_nKeyFields; i++)
{
const char* val = rec[m_nField[i]];
if (m_bUpper[i])
{
e->m_strkey.Printf("%*s", -m_nSize[i], val);
e->m_strkey.Upper();
}
else
e->m_strkey.Printf("%*s", m_nSize[i], val);
}
const int nPos = FindPosition(e->m_strkey);
m_ndx.Insert(e, nPos);
}
void TIndex::Update(const TArrayObject& records)
{
WX_CLEAR_ARRAY(m_ndx);
for (size_t i = 0; i < records.GetCount(); i++)
AddRecord(*((TRecord*)records[i]), i+1);
}
TIndex::TIndex() : m_nKeyFields(0)
{ }
///////////////////////////////////////////////////////////
// TTable
// Tabella di database con 1 o piu' viste in base alla chiave
///////////////////////////////////////////////////////////
class TTable : public wxObject
{
wxDbColInf* m_ci;
wxDbTable* m_table;
UWORD m_nColumns;
char* m_field[128];
TArrayObject m_Records, m_Indexes;
long m_nCurrent;
protected:
void KillRecordSet();
bool FillRecordSet();
bool GoTo(long& recno);
int FindColumn(const char* name) const;
public:
long Rows(int index) const;
void GetRecord(long recno, wxOutputStream& out);
void GetRecordLength(wxOutputStream& out);
bool CreateIndex(int index, const TXmlItem& fields);
TIndex& Index(int n);
bool ok() const { return m_nColumns > 0; }
TTable(wxDb* db, const wxString& strName);
virtual ~TTable();
};
long TTable::Rows(int index) const
{
const TIndex& idx = ((TTable*)this)->Index(index);
return idx.Ok() ? idx.GetCount() : m_Records.GetCount();
}
bool TTable::GoTo(long& rec)
{
const long tot = m_Records.GetCount();
bool ok = false;
if (rec < 0) // -1 = last record
rec = tot + rec + 1;
if (rec > 0 && rec <= tot)
{
m_nCurrent = rec;
ok = true;
}
return ok;
}
void TTable::GetRecord(long recno, wxOutputStream& out)
{
if (GoTo(recno))
{
const TRecord& record = *((TRecord*)m_Records[m_nCurrent-1]);
TXmlItem rec; rec.SetTag("Record");
rec.SetAttr("RecNo", recno);
for (UWORD c = 0; c < m_nColumns; c++)
{
const wxString& str = record[c];
if (!str.IsEmpty() && str != "1899-12-30")
rec.AddSoapString("Field", str).SetAttr("Name", m_ci[c].colName);
}
rec.Write(out, 2);
}
}
void TTable::GetRecordLength(wxOutputStream& out)
{
int len = 0;
for (UWORD i = 0; i < m_nColumns; i++)
{
const wxDbColInf& ci = m_ci[i];
switch (ci.sqlDataType)
{
case SQL_C_DATE:
len += 8;
break;
default:
if (ci.bufferLength > 128) // It's a MEMO!
len += 10;
else
len += ci.bufferLength;
break;
}
}
out << wxString::Format("%d", len);
}
int TTable::FindColumn(const char* name) const
{
int i = m_nColumns-1;
for ( ; i >= 0; i--)
{
if (wxStricmp(m_ci[i].colName, name) == 0)
break;
}
return i;
}
TIndex& TTable::Index(int index)
{
if (index < 0 || index > 8)
index = 0;
for (int i = m_Indexes.GetCount(); i <= index; i++)
m_Indexes.Add(new TIndex);
return *((TIndex*)m_Indexes[index]);
}
bool TTable::CreateIndex(int index, const TXmlItem& fields)
{
TIndex& ndx = Index(index);
if (!ndx.Ok())
{
for (int c = 0; c < fields.GetChildren(); c++)
{
const TXmlItem& field = *fields.GetChild(c);
if (field.GetTag() == "Field")
{
const int i = FindColumn(field.GetAttr("Name"));
if (i >= 0)
{
const bool upper = !field.GetAttr("Upper").IsEmpty();
ndx.AddKeyField(i, m_ci[i].bufferLength, upper);
}
}
}
ndx.Update(m_Records);
}
return ndx.Ok();
}
void TTable::KillRecordSet()
{
WX_CLEAR_ARRAY(m_Records);
m_Records.Clear();
}
bool TTable::FillRecordSet()
{
KillRecordSet();
const bool ok = m_table->Query();
if (ok)
{
while (m_table->GetNext())
{
TRecord* rec = new TRecord;
for (UWORD i = 0; i < m_nColumns; i++)
{
char* spc = NULL;
for (char* c = m_field[i]; *c; c++)
{
if (*c == ' ')
{
if (spc == NULL)
spc = c;
}
else
spc = NULL;
}
if (spc != NULL)
*spc = '\0';
rec->Add(m_field[i]);
}
m_Records.Add(rec);
}
}
for (size_t i = 1; i < m_Indexes.GetCount(); i++)
{
TIndex& ndx = Index(i);
if (ndx.Ok())
ndx.Update(m_Records);
}
return ok;
}
TTable::TTable(wxDb* db, const wxString& strName)
{
m_ci = db->GetColumns(strName, &m_nColumns);
m_table = new wxDbTable(db, strName, m_nColumns, strName, false);
// Bind columns
for (UWORD i = 0; i < m_nColumns; i++)
{
const wxDbColInf& ci = m_ci[i];
const int length = ci.bufferLength+1;
m_field[i] = new char[length];
memset(m_field[i], 0, length);
int nSqlType = ci.sqlDataType;
if (nSqlType <= 0 || nSqlType == 2)
nSqlType = SQL_C_CHAR;
m_table->SetColDefs(i, ci.colName, DB_DATA_TYPE_VARCHAR,
m_field[i], nSqlType, length);
}
if (m_table->Open(false, false))
{
if (!FillRecordSet())
GetServerApp().WriteLog(wxString::Format("Can't query table %s", strName));
}
else
GetServerApp().WriteLog(wxString::Format("Can't open table %s", strName));
m_nCurrent = 0; // Before the first
}
TTable::~TTable()
{
KillRecordSet();
delete m_table;
for (UWORD i = 0; m_field[i] != NULL; i++)
delete m_field[i];
delete m_ci;
}
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// TDataBase // TDataBase
// Database di dati comuni (COM) o di DITTA (00001A, ecc...)
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
class TDataBase : public wxHashTable class TDataBase : public wxHashTable
@ -20,25 +412,24 @@ class TDataBase : public wxHashTable
wxDb* m_db; wxDb* m_db;
public: public:
bool Open(const wxString& dsn, const wxString& user, bool Open(const wxString& dsn, const wxString& user, const wxString& password);
const wxString& password, const wxString& path);
bool IsOpen() const; bool IsOpen() const;
void Close(); void Close();
wxDb& DataBase() { return *m_db; } wxDb& DataBase() { return *m_db; }
TTable* Table(const wxString& strName);
TDataBase(); TDataBase();
virtual ~TDataBase(); virtual ~TDataBase();
}; };
bool TDataBase::Open(const wxString& dsn, const wxString& user, bool TDataBase::Open(const wxString& dsn, const wxString& user, const wxString& password)
const wxString& password, const wxString& path)
{ {
Close(); Close();
m_ci.SetDsn(dsn); m_ci.SetDsn(dsn);
m_ci.SetUserID(user); m_ci.SetUserID(user);
m_ci.SetPassword(password); m_ci.SetPassword(password);
m_ci.SetDefaultDir(path);
if (m_ci.AllocHenv()) if (m_ci.AllocHenv())
{ {
@ -72,6 +463,18 @@ bool TDataBase::IsOpen() const
return m_db != NULL; return m_db != NULL;
} }
TTable* TDataBase::Table(const wxString& strName)
{
TTable* s = (TTable*)Get(strName);
if (s == NULL)
{
s = new TTable(m_db, strName);
if (s->ok())
Put(strName, s);
}
return s;
}
TDataBase::TDataBase() : wxHashTable(wxKEY_STRING), m_db(NULL) TDataBase::TDataBase() : wxHashTable(wxKEY_STRING), m_db(NULL)
{ {
m_ci.Henv = 0; m_ci.Henv = 0;
@ -85,15 +488,17 @@ TDataBase::~TDataBase()
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// TStudy // TStudy
// Elenco di Databases: COM, 00001A, 00002A, ecc...
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
class TStudy : public wxHashTable class TStudy : public wxHashTable
{ {
wxString m_strName, m_strUser, m_strPass, m_strPath; wxString m_strUser, m_strPass;
wxString m_strName;
public: public:
TDataBase& DB(long firm); // 0 = COM TDataBase& DB(long firm); // 0 = COM
TStudy(const char* strName, const char* strUser, const char* strPass, const char* strPath); TStudy(const char* strName, const char* strUser, const char* strPass);
}; };
TDataBase& TStudy::DB(long firm) TDataBase& TStudy::DB(long firm)
@ -104,27 +509,76 @@ TDataBase& TStudy::DB(long firm)
wxString strDsn, strPath; wxString strDsn, strPath;
if (firm > 0) if (firm > 0)
{ strDsn.sprintf("%s_%05lda", m_strName, firm);
strDsn.sprintf("%s%ld", m_strName, firm);
strPath.sprintf("%s/%05lda", m_strPath, firm);
}
else else
{ strDsn.sprintf("%s_COM", m_strName);
strDsn = m_strName;
strPath.sprintf("%s/com", m_strPath);
}
db = new TDataBase; db = new TDataBase;
db->Open(strDsn, m_strUser, m_strPass, strPath);
db->Open(strDsn, m_strUser, m_strPass);
Put(firm, db); Put(firm, db);
} }
return *db; return *db;
} }
TStudy::TStudy(const char* strName, const char* strUser, const char* strPass, const char* strBasePath) TStudy::TStudy(const char* strName, const char* strUser, const char* strPass)
: wxHashTable(wxKEY_INTEGER), m_strName(strName), m_strUser(strUser), m_strPass(strPass) : wxHashTable(wxKEY_INTEGER), m_strName(strName), m_strUser(strUser), m_strPass(strPass)
{ {
m_strPath.sprintf("%s/%s", strBasePath, strName); DeleteContents(true);
}
///////////////////////////////////////////////////////////
// TCommercialist
///////////////////////////////////////////////////////////
class TCommercialist : public wxHashTable
{
wxString m_strUser, m_strPass; // User impersonated by the TCommenrcialist
public:
const wxString& User() const { return m_strUser; }
const wxString& Password() const { return m_strPass; }
TStudy& Study(const wxString& strStudy);
TTable* Table(const TXmlItem& item);
TCommercialist();
};
TStudy& TCommercialist::Study(const wxString& strStudy)
{
TStudy* s = (TStudy*)Get(strStudy);
if (s == NULL)
{
if (m_strUser.IsEmpty())
{
TBaseServerApp& a = GetServerApp();
m_strUser = a.GetConfigString("User", "ADMIN");
m_strPass = a.GetConfigString("Password", "AD.MIN");
}
s = new TStudy(strStudy, m_strUser, m_strPass);
Put(strStudy, s);
}
return *s;
}
TTable* TCommercialist::Table(const TXmlItem& xmlMethod)
{
TTable* tab = NULL;
const wxString strStudy = GetSoapParam(xmlMethod, "Study");
const long nFirm = atol(GetSoapParam(xmlMethod, "Firm"));
TStudy& study = Study(strStudy);
TDataBase& firm = study.DB(nFirm);
if (firm.IsOpen())
{
const wxString strTable = GetSoapParam(xmlMethod, "Table");
tab = firm.Table(strTable);
}
return tab;
}
TCommercialist::TCommercialist()
{
DeleteContents(true); DeleteContents(true);
} }
@ -134,6 +588,8 @@ TStudy::TStudy(const char* strName, const char* strUser, const char* strPass, co
class TDataBaseServer : public TBaseServerApp class TDataBaseServer : public TBaseServerApp
{ {
TCommercialist m_caminetti;
protected: protected:
virtual const wxChar* GetAppName() const; virtual const wxChar* GetAppName() const;
virtual void ProcessCommand(wxString cmd, wxSocketBase& outs); virtual void ProcessCommand(wxString cmd, wxSocketBase& outs);
@ -144,13 +600,18 @@ protected:
void AddAsterisk(const wxString& strField, const wxString& strQuery, void AddAsterisk(const wxString& strField, const wxString& strQuery,
TDataBase& db, wxArrayString& arr); TDataBase& db, wxArrayString& arr);
wxString ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr); wxString ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr);
void WriteTable(const wxString& strDsn, const wxString& strUser, void WriteTable(wxString strDsn, wxString strUser,
const wxString& strPass, const wxString& strOriginalQuery, wxString strPass, wxString strOriginalQuery,
wxFileOutputStream& out); wxOutputStream& out);
wxString GetSoapParam(const TXmlItem& xmlMethod, const char* strParam); void SoapProcessMethod(const TXmlItem& xmlMethod, wxOutputStream& out);
void SoapProcessQuery(const TXmlItem &xmlMethod, wxFileOutputStream& out); void SoapProcessQuery(const TXmlItem &xmlMethod, wxOutputStream& out);
void SoapProcessMethod(const TXmlItem& xmlMethod, wxFileOutputStream& out);
void SoapProcessTableRows(const TXmlItem &xmlMethod, wxOutputStream& out);
void SoapProcessGetRecord(const TXmlItem &xmlMethod, wxOutputStream& out);
void SoapProcessGetRecordLength(const TXmlItem &xmlMethod, wxOutputStream& out);
void SoapProcessCreateIndex(const TXmlItem &xmlMethod, wxOutputStream& out);
void SoapProcessSkipRecord(const TXmlItem &xmlMethod, wxOutputStream& out);
public: public:
bool IsMagicName(wxString& strFilename) const; bool IsMagicName(wxString& strFilename) const;
@ -252,10 +713,10 @@ void TDataBaseServer::GenerateSql(wxString& strFilename)
form.AddChild("br"); form.AddChild("br");
form.AddChild("h3") << "SQL query:"; form.AddChild("h3") << "SQL query:";
TXmlItem& q = form.AddChild("textarea"); TXmlItem& q = form.AddChild("textarea");
q.SetAttr("name", "Query"); q.SetAttr("name", "Sql");
q.SetAttr("cols", "80"); q.SetAttr("rows", "10"); q.SetAttr("cols", "80"); q.SetAttr("rows", "10");
wxString query = GetConfigString("Query"); wxString query = GetConfigString("Sql");
q << query; q << query;
form.AddChild("br"); form.AddChild("br");
@ -327,6 +788,8 @@ void TDataBaseServer::AddAsterisk(const wxString& strField, const wxString& strQ
} }
arr.Add(strFieldName); arr.Add(strFieldName);
} }
delete dci;
} }
wxString TDataBaseServer::ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr) wxString TDataBaseServer::ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr)
@ -369,9 +832,9 @@ wxString TDataBaseServer::ParseQuery(const wxString& strOriginalQuery, TDataBase
return strQuery; return strQuery;
} }
void TDataBaseServer::WriteTable(const wxString& strDsn, const wxString& strUser, void TDataBaseServer::WriteTable(wxString strDsn, wxString strUser,
const wxString& strPass, const wxString& strOriginalQuery, wxString strPass, wxString strOriginalQuery,
wxFileOutputStream& out) wxOutputStream& out)
{ {
const clock_t tTotalStart = clock(); const clock_t tTotalStart = clock();
@ -382,8 +845,16 @@ void TDataBaseServer::WriteTable(const wxString& strDsn, const wxString& strUser
out << "<table border=1>\n"; out << "<table border=1>\n";
const wxString strBasePath = GetConfigString("DataPath"); if (strDsn.IsEmpty())
TStudy s(strDsn, strUser, strPass, strBasePath); strDsn = GetConfigString("DataPath");
if (strUser.IsEmpty())
strUser = GetConfigString("User");
if (strPass.IsEmpty())
strPass = GetConfigString("Password");
TStudy s(strDsn, strUser, strPass);
TDataBase& d = s.DB(0); // Ditta/COM TDataBase& d = s.DB(0); // Ditta/COM
if (d.IsOpen()) if (d.IsOpen())
{ {
@ -439,17 +910,17 @@ void TDataBaseServer::WriteTable(const wxString& strDsn, const wxString& strUser
void TDataBaseServer::ProcessFormQuery(const wxString& strFileName, THashTable& hashArgs) void TDataBaseServer::ProcessFormQuery(const wxString& strFileName, THashTable& hashArgs)
{ {
const wxString strDsn = hashArgs.Get("Dsn"); const wxString strDsn = hashArgs.Get("DSN");
const wxString strUser = hashArgs.Get("User"); const wxString strUser = hashArgs.Get("User");
const wxString strPass = hashArgs.Get("Password"); const wxString strPass = hashArgs.Get("Password");
const wxString strOriginalQuery = hashArgs.Get("Query"); const wxString strOriginalQuery = hashArgs.Get("SQL");
SetConfigString("Dsn", strDsn); SetConfigString("DSN", strDsn);
SetConfigString("User", strUser); SetConfigString("User", strUser);
wxString strQuery = strOriginalQuery; wxString strQuery = strOriginalQuery;
strQuery.Replace("\r\n", " "); strQuery.Replace("\r\n", " ");
SetConfigString("Query", strQuery); SetConfigString("SQL", strQuery);
wxFileOutputStream out(strFileName); wxFileOutputStream out(strFileName);
@ -485,31 +956,85 @@ void TDataBaseServer::ProcessFormCommand(wxString cmd, wxSocketBase& outs)
SendFile(strFileName, outs); SendFile(strFileName, outs);
} }
wxString TDataBaseServer::GetSoapParam(const TXmlItem &xmlMethod, const char* strParam) void TDataBaseServer::SoapProcessQuery(const TXmlItem &xmlMethod, wxOutputStream& out)
{ {
wxString val; const wxString dsn = GetSoapParam(xmlMethod, "DSN");
const TXmlItem* xml = xmlMethod.FindFirst(strParam); const wxString usr = GetSoapParam(xmlMethod, "User");
if (xml != NULL) const wxString pwd = GetSoapParam(xmlMethod, "Password");
val = xml->GetEnclosedText(); const wxString sql = GetSoapParam(xmlMethod, "SQL");
return val;
}
void TDataBaseServer::SoapProcessQuery(const TXmlItem &xmlMethod, wxFileOutputStream& out)
{
const wxString dsn = GetSoapParam(xmlMethod, "dsn");
const wxString usr = GetSoapParam(xmlMethod, "user");
const wxString pwd = GetSoapParam(xmlMethod, "password");
const wxString sql = GetSoapParam(xmlMethod, "sql");
WriteTable(dsn, usr, pwd, sql, out); WriteTable(dsn, usr, pwd, sql, out);
} }
void TDataBaseServer::SoapProcessMethod(const TXmlItem &xmlMethod, wxFileOutputStream& out) void TDataBaseServer::SoapProcessTableRows(const TXmlItem &xmlMethod, wxOutputStream& out)
{ {
wxString str = xmlMethod.GetTag(); TTable* tab = m_caminetti.Table(xmlMethod);
if (tab != NULL)
{
const int index = atoi(GetSoapParam(xmlMethod, "Index"));
out << wxString::Format("%ld", tab->Rows(index));
}
}
void TDataBaseServer::SoapProcessGetRecord(const TXmlItem &xmlMethod, wxOutputStream& out)
{
TTable* tab = m_caminetti.Table(xmlMethod);
if (tab != NULL)
{
const long recno = atol(GetSoapParam(xmlMethod, "RecNo"));
tab->GetRecord(recno, out);
}
}
void TDataBaseServer::SoapProcessSkipRecord(const TXmlItem &xmlMethod, wxOutputStream& out)
{
TTable* tab = m_caminetti.Table(xmlMethod);
if (tab != NULL)
{
const int index = atoi(GetSoapParam(xmlMethod, "Index"));
const long recno = atol(GetSoapParam(xmlMethod, "RecNo"));
const long offset = atol(GetSoapParam(xmlMethod, "Offset"));
const long newrecno = tab->Index(index).SkipTo(recno, offset);
tab->GetRecord(newrecno, out);
}
}
void TDataBaseServer::SoapProcessGetRecordLength(const TXmlItem &xmlMethod, wxOutputStream& out)
{
TTable* tab = m_caminetti.Table(xmlMethod);
if (tab != NULL)
tab->GetRecordLength(out);
}
void TDataBaseServer::SoapProcessCreateIndex(const TXmlItem &xmlMethod, wxOutputStream& out)
{
TTable* tab = m_caminetti.Table(xmlMethod);
if (tab != NULL)
{
const int index = atoi(GetSoapParam(xmlMethod, "Index"));
const bool ok = index > 0 && tab->CreateIndex(index, xmlMethod);
out << (ok ? "1" : "0");
}
}
void TDataBaseServer::SoapProcessMethod(const TXmlItem &xmlMethod, wxOutputStream& out)
{
const wxString strTag = xmlMethod.GetTag();
wxString str = strTag;
str << "Result"; str << "Result";
out << "<" << str << ">\n"; out << "<" << str << ">\n";
if (xmlMethod.GetTag() == "m:query") if (strTag == "m:GetRecord")
SoapProcessGetRecord(xmlMethod, out); else
if (strTag == "m:SkipRecord")
SoapProcessSkipRecord(xmlMethod, out); else
if (strTag == "m:GetRecordLength")
SoapProcessGetRecordLength(xmlMethod, out); else
if (strTag == "m:TableRows")
SoapProcessTableRows(xmlMethod, out); else
if (strTag == "m:CreateIndex")
SoapProcessCreateIndex(xmlMethod, out); else
if (strTag == "m:Query")
SoapProcessQuery(xmlMethod, out); SoapProcessQuery(xmlMethod, out);
out << "</" << str << ">\n"; out << "</" << str << ">\n";
@ -517,51 +1042,48 @@ void TDataBaseServer::SoapProcessMethod(const TXmlItem &xmlMethod, wxFileOutputS
void TDataBaseServer::ProcessSoapCommand(wxString cmd, wxSocketBase& sock) void TDataBaseServer::ProcessSoapCommand(wxString cmd, wxSocketBase& sock)
{ {
const wxString strFilename = GetTempFilename(); wxMemoryOutputStream outf;
outf << "<SOAP-ENV:Envelope>\n<SOAP-ENV:Body>\n";
if (!strFilename.IsEmpty())
const int soapstart = cmd.Find("<SOAP-ENV:");
if (soapstart > 0)
{ {
wxFileOutputStream outf(strFilename); const size_t soaplen = cmd.length() - soapstart;
outf << "<SOAP-ENV:Envelope>\n<SOAP-ENV:Body>\n"; const char* buff = (const char*)cmd;
buff += soapstart;
const int soapstart = cmd.Find("<SOAP-ENV:"); wxMemoryInputStream input(buff, soaplen);
if (soapstart > 0) TXmlItem query;
if (query.Read(input))
{ {
const size_t soaplen = cmd.length() - soapstart; const TXmlItem* pxmlBody = query.FindFirst("SOAP-ENV:Body");
const char* buff = (const char*)cmd; if (pxmlBody != NULL) for (int m = 0; ; m++)
buff += soapstart;
wxMemoryInputStream input(buff, soaplen);
TXmlItem query;
if (query.Read(input))
{ {
const TXmlItem* pxmlBody = query.FindFirst("SOAP-ENV:Body"); const TXmlItem* pxmlMethod = pxmlBody->GetChild(m);
if (pxmlBody != NULL) for (int m = 0; ; m++) if (pxmlMethod == NULL)
break;
if (pxmlMethod->GetTag().StartsWith("m:"))
{ {
const TXmlItem* pxmlMethod = pxmlBody->GetChild(m); SoapProcessMethod(*pxmlMethod, outf);
if (pxmlMethod == NULL)
break;
if (pxmlMethod->GetTag().StartsWith("m:"))
{
SoapProcessMethod(*pxmlMethod, outf);
}
} }
} }
} }
outf << "</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n";
} }
outf << "</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n";
wxFileInputStream inf(strFilename); const size_t nSize = outf.GetSize();
char* mem = new char[nSize];
outf.CopyTo(mem, nSize);
sock << "HTTP/1.1 200 OK\n"; sock << "HTTP/1.1 200 OK\n";
sock << "Server: " << GetAppName() << "\n"; sock << "Server: " << GetAppName() << "\n";
sock << "Host: " << wxGetFullHostName() << "\n"; sock << "Host: " << wxGetFullHostName() << "\n";
sock << "Connection: keep-alive\n"; sock << "Connection: keep-alive\n";
sock << "Content-Type: text/xml; charset=utf-8\n"; sock << "Content-Type: text/xml; charset=utf-8\n";
sock << "Content-Length: " << inf.GetSize() << "\n"; sock << "Content-Length: " << nSize << "\n";
sock << "Date: " << wxDateTime::Now().Format("%#c") << "\n"; sock << "Date: " << wxDateTime::Now().Format("%#c") << "\n";
sock << "\n"; sock << "\n" << mem;
SendContent(inf, sock); delete mem;
} }
void TDataBaseServer::ProcessCommand(wxString cmd, wxSocketBase& outs) void TDataBaseServer::ProcessCommand(wxString cmd, wxSocketBase& outs)

View File

@ -115,7 +115,7 @@ void TLerchServer::GenerateFile(wxString& strFilename)
TXmlItem& a = td0.AddChild("a"); TXmlItem& a = td0.AddChild("a");
a.SetAttr("href", wxString::Format("http://%s:%d/index.htm", strHost, nPort)); a.SetAttr("href", wxString::Format("http://%s:%d/index.htm", strHost, nPort));
TXmlItem& img = a.AddChild("img"); TXmlItem& img = a.AddChild("img");
img.SetAttr("src", strIcon); img.SetAttr("border", 0); img.SetAttr("alt", arr[i]); img.SetAttr("src", strIcon); img.SetAttr("border", 0L); img.SetAttr("alt", arr[i]);
AddMiniForm(tr, bRunning ? "kill.cgi" : "start.cgi", arr[i], bRunning ? "Stop" : "Start"); AddMiniForm(tr, bRunning ? "kill.cgi" : "start.cgi", arr[i], bRunning ? "Stop" : "Start");
AddMiniForm(tr, "config.cgi", arr[i], "Configure"); AddMiniForm(tr, "config.cgi", arr[i], "Configure");

View File

@ -171,7 +171,8 @@ TXmlItem& TXmlItem::SetAttr(const wxChar* strAttr, const wxChar* strVal)
m_Attributes = new wxHashTable(wxKEY_STRING, 17); m_Attributes = new wxHashTable(wxKEY_STRING, 17);
m_Attributes->DeleteContents(true); m_Attributes->DeleteContents(true);
} }
m_Attributes->Delete(strAttr); else
m_Attributes->Delete(strAttr);
m_Attributes->Put(strAttr, new TXmlAttr(strVal)); m_Attributes->Put(strAttr, new TXmlAttr(strVal));
return *this; return *this;
} }
@ -188,6 +189,11 @@ wxString TXmlItem::GetAttr(const wxChar* strAttr) const
return strResult; return strResult;
} }
TXmlItem& TXmlItem::SetAttr(const wxChar* strAttr, long nVal)
{
return SetAttr(strAttr, wxString::Format("%ld", nVal));
}
int TXmlItem::GetChildren() const int TXmlItem::GetChildren() const
{ {
int n = 0; int n = 0;

View File

@ -31,6 +31,7 @@ public:
TXmlItem& SetAttr(const wxChar* strAttr, const wxChar* strVal); TXmlItem& SetAttr(const wxChar* strAttr, const wxChar* strVal);
wxString GetAttr(const wxChar* strAttr) const; wxString GetAttr(const wxChar* strAttr) const;
TXmlItem& SetAttr(const wxChar* strAttr, long nVal);
TXmlItem& AddChild(const wxChar* strTag); TXmlItem& AddChild(const wxChar* strTag);
TXmlItem& AddSoapString(const wxChar* name, const wxChar* value, bool typized = false); TXmlItem& AddSoapString(const wxChar* name, const wxChar* value, bool typized = false);