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:
parent
12533dff5b
commit
b64e39b06b
@ -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();
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ private:
|
||||
int m_nTmpCounter;
|
||||
|
||||
#ifdef WIN32
|
||||
TTaskBarIcon m_Tray;
|
||||
TTaskBarIcon* m_Tray;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
@ -1,17 +1,409 @@
|
||||
#include <wx/wxprec.h>
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif //WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "BaseServ.h"
|
||||
|
||||
#include <wx/dbtable.h>
|
||||
//#include <wx/db.h>
|
||||
#include <wx/dynarray.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
|
||||
// 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 << "<table border=1>\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 << "</" << str << ">\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 << "<SOAP-ENV:Envelope>\n<SOAP-ENV:Body>\n";
|
||||
|
||||
const int soapstart = cmd.Find("<SOAP-ENV:");
|
||||
if (soapstart > 0)
|
||||
{
|
||||
wxFileOutputStream outf(strFilename);
|
||||
outf << "<SOAP-ENV:Envelope>\n<SOAP-ENV:Body>\n";
|
||||
|
||||
const int soapstart = cmd.Find("<SOAP-ENV:");
|
||||
if (soapstart > 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 << "</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 << "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)
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user