From b64e39b06bf5298f51ec831391ba6537e0c42d59 Mon Sep 17 00:00:00 2001 From: guy Date: Thu, 11 Sep 2003 07:16:13 +0000 Subject: [PATCH] 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 --- server/baseserv.cpp | 15 +- server/baseserv.h | 2 +- server/dbserver.cpp | 694 ++++++++++++++++++++++++++++++++++++++------ server/lerch.cpp | 2 +- server/xml.cpp | 8 +- server/xml.h | 1 + 6 files changed, 632 insertions(+), 90 deletions(-) diff --git a/server/baseserv.cpp b/server/baseserv.cpp index 615d103df..a83500ca6 100755 --- a/server/baseserv.cpp +++ b/server/baseserv.cpp @@ -582,7 +582,12 @@ bool TBaseServerApp::OnInit() ok = Initialization(); #ifdef WIN32 - if (ok) m_Tray.Init(); + m_Tray = NULL; + if (ok) + { + m_Tray = new TTaskBarIcon; + m_Tray->Init(); + } #endif return ok; @@ -604,6 +609,14 @@ int TBaseServerApp::OnExit() delete m_log; } +#ifdef WIN32 + if (m_Tray != NULL) + { + delete m_Tray; + m_Tray = NULL; + } +#endif + return wxApp::OnExit(); } diff --git a/server/baseserv.h b/server/baseserv.h index f8b88b417..0a888b564 100755 --- a/server/baseserv.h +++ b/server/baseserv.h @@ -84,7 +84,7 @@ private: int m_nTmpCounter; #ifdef WIN32 - TTaskBarIcon m_Tray; + TTaskBarIcon* m_Tray; #endif protected: diff --git a/server/dbserver.cpp b/server/dbserver.cpp index 511b05006..601393f3b 100755 --- a/server/dbserver.cpp +++ b/server/dbserver.cpp @@ -1,17 +1,409 @@ -#include - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif //WX_PRECOMP +#include #include "BaseServ.h" #include -//#include +#include #include +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 +// Database di dati comuni (COM) o di DITTA (00001A, ecc...) /////////////////////////////////////////////////////////// class TDataBase : public wxHashTable @@ -20,25 +412,24 @@ class TDataBase : public wxHashTable wxDb* m_db; public: - bool Open(const wxString& dsn, const wxString& user, - const wxString& password, const wxString& path); + bool Open(const wxString& dsn, const wxString& user, const wxString& password); bool IsOpen() const; void Close(); wxDb& DataBase() { return *m_db; } + TTable* Table(const wxString& strName); + TDataBase(); virtual ~TDataBase(); }; -bool TDataBase::Open(const wxString& dsn, const wxString& user, - const wxString& password, const wxString& path) +bool TDataBase::Open(const wxString& dsn, const wxString& user, const wxString& password) { Close(); m_ci.SetDsn(dsn); m_ci.SetUserID(user); m_ci.SetPassword(password); - m_ci.SetDefaultDir(path); if (m_ci.AllocHenv()) { @@ -72,6 +463,18 @@ bool TDataBase::IsOpen() const 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) { m_ci.Henv = 0; @@ -85,15 +488,17 @@ TDataBase::~TDataBase() /////////////////////////////////////////////////////////// // TStudy +// Elenco di Databases: COM, 00001A, 00002A, ecc... /////////////////////////////////////////////////////////// class TStudy : public wxHashTable { - wxString m_strName, m_strUser, m_strPass, m_strPath; + wxString m_strUser, m_strPass; + wxString m_strName; public: 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) @@ -104,27 +509,76 @@ TDataBase& TStudy::DB(long firm) wxString strDsn, strPath; if (firm > 0) - { - strDsn.sprintf("%s%ld", m_strName, firm); - strPath.sprintf("%s/%05lda", m_strPath, firm); - } + strDsn.sprintf("%s_%05lda", m_strName, firm); else - { - strDsn = m_strName; - strPath.sprintf("%s/com", m_strPath); - } + strDsn.sprintf("%s_COM", m_strName); db = new TDataBase; - db->Open(strDsn, m_strUser, m_strPass, strPath); + + db->Open(strDsn, m_strUser, m_strPass); Put(firm, 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) { - 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); } @@ -134,6 +588,8 @@ TStudy::TStudy(const char* strName, const char* strUser, const char* strPass, co class TDataBaseServer : public TBaseServerApp { + TCommercialist m_caminetti; + protected: virtual const wxChar* GetAppName() const; virtual void ProcessCommand(wxString cmd, wxSocketBase& outs); @@ -144,13 +600,18 @@ protected: void AddAsterisk(const wxString& strField, const wxString& strQuery, TDataBase& db, wxArrayString& arr); wxString ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr); - void WriteTable(const wxString& strDsn, const wxString& strUser, - const wxString& strPass, const wxString& strOriginalQuery, - wxFileOutputStream& out); + void WriteTable(wxString strDsn, wxString strUser, + wxString strPass, wxString strOriginalQuery, + wxOutputStream& out); - wxString GetSoapParam(const TXmlItem& xmlMethod, const char* strParam); - void SoapProcessQuery(const TXmlItem &xmlMethod, wxFileOutputStream& out); - void SoapProcessMethod(const TXmlItem& xmlMethod, wxFileOutputStream& out); + void SoapProcessMethod(const TXmlItem& xmlMethod, wxOutputStream& out); + void SoapProcessQuery(const TXmlItem &xmlMethod, wxOutputStream& 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: bool IsMagicName(wxString& strFilename) const; @@ -252,10 +713,10 @@ void TDataBaseServer::GenerateSql(wxString& strFilename) form.AddChild("br"); form.AddChild("h3") << "SQL query:"; TXmlItem& q = form.AddChild("textarea"); - q.SetAttr("name", "Query"); + q.SetAttr("name", "Sql"); q.SetAttr("cols", "80"); q.SetAttr("rows", "10"); - wxString query = GetConfigString("Query"); + wxString query = GetConfigString("Sql"); q << query; form.AddChild("br"); @@ -327,6 +788,8 @@ void TDataBaseServer::AddAsterisk(const wxString& strField, const wxString& strQ } arr.Add(strFieldName); } + + delete dci; } wxString TDataBaseServer::ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr) @@ -369,9 +832,9 @@ wxString TDataBaseServer::ParseQuery(const wxString& strOriginalQuery, TDataBase return strQuery; } -void TDataBaseServer::WriteTable(const wxString& strDsn, const wxString& strUser, - const wxString& strPass, const wxString& strOriginalQuery, - wxFileOutputStream& out) +void TDataBaseServer::WriteTable(wxString strDsn, wxString strUser, + wxString strPass, wxString strOriginalQuery, + wxOutputStream& out) { const clock_t tTotalStart = clock(); @@ -382,8 +845,16 @@ void TDataBaseServer::WriteTable(const wxString& strDsn, const wxString& strUser out << "\n"; - const wxString strBasePath = GetConfigString("DataPath"); - TStudy s(strDsn, strUser, strPass, strBasePath); + if (strDsn.IsEmpty()) + 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 if (d.IsOpen()) { @@ -439,17 +910,17 @@ void TDataBaseServer::WriteTable(const wxString& strDsn, const wxString& strUser 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 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); wxString strQuery = strOriginalQuery; strQuery.Replace("\r\n", " "); - SetConfigString("Query", strQuery); + SetConfigString("SQL", strQuery); wxFileOutputStream out(strFileName); @@ -485,31 +956,85 @@ void TDataBaseServer::ProcessFormCommand(wxString cmd, wxSocketBase& outs) SendFile(strFileName, outs); } -wxString TDataBaseServer::GetSoapParam(const TXmlItem &xmlMethod, const char* strParam) +void TDataBaseServer::SoapProcessQuery(const TXmlItem &xmlMethod, wxOutputStream& out) { - wxString val; - const TXmlItem* xml = xmlMethod.FindFirst(strParam); - if (xml != NULL) - val = xml->GetEnclosedText(); - 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"); + 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); } -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"; 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); out << "\n"; @@ -517,51 +1042,48 @@ void TDataBaseServer::SoapProcessMethod(const TXmlItem &xmlMethod, wxFileOutputS void TDataBaseServer::ProcessSoapCommand(wxString cmd, wxSocketBase& sock) { - const wxString strFilename = GetTempFilename(); - - if (!strFilename.IsEmpty()) + wxMemoryOutputStream outf; + outf << "\n\n"; + + const int soapstart = cmd.Find(" 0) { - wxFileOutputStream outf(strFilename); - outf << "\n\n"; - - const int soapstart = cmd.Find(" 0) + const size_t soaplen = cmd.length() - soapstart; + const char* buff = (const char*)cmd; + buff += soapstart; + wxMemoryInputStream input(buff, soaplen); + TXmlItem query; + if (query.Read(input)) { - const size_t soaplen = cmd.length() - soapstart; - const char* buff = (const char*)cmd; - buff += soapstart; - wxMemoryInputStream input(buff, soaplen); - TXmlItem query; - if (query.Read(input)) + const TXmlItem* pxmlBody = query.FindFirst("SOAP-ENV:Body"); + if (pxmlBody != NULL) for (int m = 0; ; m++) { - const TXmlItem* pxmlBody = query.FindFirst("SOAP-ENV:Body"); - if (pxmlBody != NULL) for (int m = 0; ; m++) + const TXmlItem* pxmlMethod = pxmlBody->GetChild(m); + if (pxmlMethod == NULL) + break; + if (pxmlMethod->GetTag().StartsWith("m:")) { - const TXmlItem* pxmlMethod = pxmlBody->GetChild(m); - if (pxmlMethod == NULL) - break; - if (pxmlMethod->GetTag().StartsWith("m:")) - { - SoapProcessMethod(*pxmlMethod, outf); - } + SoapProcessMethod(*pxmlMethod, outf); } } } - outf << "\n\n"; } + outf << "\n\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 << "Server: " << GetAppName() << "\n"; sock << "Host: " << wxGetFullHostName() << "\n"; sock << "Connection: keep-alive\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 << "\n"; + sock << "\n" << mem; - SendContent(inf, sock); + delete mem; } void TDataBaseServer::ProcessCommand(wxString cmd, wxSocketBase& outs) diff --git a/server/lerch.cpp b/server/lerch.cpp index 6ed0a0d6c..b3fb1ed59 100755 --- a/server/lerch.cpp +++ b/server/lerch.cpp @@ -115,7 +115,7 @@ void TLerchServer::GenerateFile(wxString& strFilename) TXmlItem& a = td0.AddChild("a"); a.SetAttr("href", wxString::Format("http://%s:%d/index.htm", strHost, nPort)); 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, "config.cgi", arr[i], "Configure"); diff --git a/server/xml.cpp b/server/xml.cpp index ed706d399..5368f6571 100755 --- a/server/xml.cpp +++ b/server/xml.cpp @@ -171,7 +171,8 @@ TXmlItem& TXmlItem::SetAttr(const wxChar* strAttr, const wxChar* strVal) m_Attributes = new wxHashTable(wxKEY_STRING, 17); m_Attributes->DeleteContents(true); } - m_Attributes->Delete(strAttr); + else + m_Attributes->Delete(strAttr); m_Attributes->Put(strAttr, new TXmlAttr(strVal)); return *this; } @@ -188,6 +189,11 @@ wxString TXmlItem::GetAttr(const wxChar* strAttr) const return strResult; } +TXmlItem& TXmlItem::SetAttr(const wxChar* strAttr, long nVal) +{ + return SetAttr(strAttr, wxString::Format("%ld", nVal)); +} + int TXmlItem::GetChildren() const { int n = 0; diff --git a/server/xml.h b/server/xml.h index b7e85268f..97e1788d9 100755 --- a/server/xml.h +++ b/server/xml.h @@ -31,6 +31,7 @@ public: TXmlItem& SetAttr(const wxChar* strAttr, const wxChar* strVal); wxString GetAttr(const wxChar* strAttr) const; + TXmlItem& SetAttr(const wxChar* strAttr, long nVal); TXmlItem& AddChild(const wxChar* strTag); TXmlItem& AddSoapString(const wxChar* name, const wxChar* value, bool typized = false);