Files correlati : Ricompilazione Demo : [ ] Commento :sistemati errori legati al nuovo wxWidgets git-svn-id: svn://10.65.10.50/trunk@13937 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1144 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1144 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <wx/wx.h>
 | 
						|
 | 
						|
#include "baseserv.h"
 | 
						|
 | 
						|
#include <wx/dbtable.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.bufferSize > 128) // It's a MEMO!
 | 
						|
        len += 10;
 | 
						|
      else
 | 
						|
        len += ci.bufferSize; 
 | 
						|
      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].bufferSize, 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.bufferSize+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.c_str()));
 | 
						|
  }
 | 
						|
  else
 | 
						|
    GetServerApp().WriteLog(wxString::Format("Can't open table %s", strName.c_str()));
 | 
						|
 | 
						|
  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
 | 
						|
{
 | 
						|
  wxDbConnectInf m_ci;
 | 
						|
  wxDb* m_db;
 | 
						|
 | 
						|
public:
 | 
						|
	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)
 | 
						|
{
 | 
						|
  Close();
 | 
						|
 | 
						|
  m_ci.SetDsn(dsn);
 | 
						|
  m_ci.SetUserID(user);
 | 
						|
  m_ci.SetPassword(password);
 | 
						|
	
 | 
						|
  if (m_ci.AllocHenv())
 | 
						|
	{
 | 
						|
		m_db = ::wxDbGetConnection(&m_ci, false); // Forward only?
 | 
						|
		if (m_db == NULL)
 | 
						|
      m_ci.FreeHenv();
 | 
						|
		else
 | 
						|
		{
 | 
						|
			const wxString strLog = GetServerApp().GetLogFileName();
 | 
						|
			if (!strLog.IsEmpty())
 | 
						|
			  m_db->SetSqlLogging(sqlLogON, strLog, TRUE);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return IsOpen();
 | 
						|
}
 | 
						|
 | 
						|
void TDataBase::Close()
 | 
						|
{
 | 
						|
  if (m_db)
 | 
						|
	{
 | 
						|
		m_db->SetSqlLogging(sqlLogOFF);
 | 
						|
		::wxDbFreeConnection(m_db);
 | 
						|
		m_db = NULL;
 | 
						|
		m_ci.FreeHenv();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
	DeleteContents(true);
 | 
						|
}
 | 
						|
 | 
						|
TDataBase::~TDataBase()
 | 
						|
{
 | 
						|
	Close();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TStudy
 | 
						|
// Elenco di Databases: COM, 00001A, 00002A, ecc...
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TStudy : public wxHashTable
 | 
						|
{
 | 
						|
  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);
 | 
						|
};
 | 
						|
 | 
						|
TDataBase& TStudy::DB(long firm)
 | 
						|
{
 | 
						|
	TDataBase* db = (TDataBase*)Get(firm);
 | 
						|
	if (db == NULL)
 | 
						|
	{
 | 
						|
  	wxString strDsn, strPath;
 | 
						|
 | 
						|
		if (firm > 0)
 | 
						|
			strDsn.sprintf("%s_%05lda", m_strName.c_str(), firm);
 | 
						|
		else
 | 
						|
			strDsn.sprintf("%s_COM", m_strName.c_str());
 | 
						|
 | 
						|
		db = new TDataBase;
 | 
						|
 | 
						|
		db->Open(strDsn, m_strUser, m_strPass);
 | 
						|
		Put(firm, db);
 | 
						|
	}
 | 
						|
	return *db;
 | 
						|
}
 | 
						|
 | 
						|
TStudy::TStudy(const char* strName, const char* strUser, const char* strPass) 
 | 
						|
      : wxHashTable(wxKEY_INTEGER), m_strUser(strUser), m_strPass(strPass), m_strName(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);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TDataBaseServer
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TDataBaseServer : public TBaseServerApp
 | 
						|
{
 | 
						|
  TCommercialist m_caminetti;
 | 
						|
 | 
						|
protected:  
 | 
						|
	virtual const wxChar* GetAppName() const;
 | 
						|
  virtual void ProcessCommand(wxString cmd, wxSocketBase& outs);
 | 
						|
  virtual bool Initialization();
 | 
						|
  virtual bool Deinitialization();
 | 
						|
 | 
						|
protected:  
 | 
						|
  void AddAsterisk(const wxString& strField, const wxString& strQuery, 
 | 
						|
									 TDataBase& db, wxArrayString& arr);
 | 
						|
  wxString ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr);
 | 
						|
  void WriteTable(wxString strDsn, wxString strUser,
 | 
						|
									wxString strPass, wxString strOriginalQuery,
 | 
						|
									wxOutputStream& 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;
 | 
						|
 | 
						|
  void ProcessFormQuery(const wxString& strFileName, THashTable& hashArgs);
 | 
						|
  void ProcessFormCommand(wxString cmd, wxSocketBase& outs);
 | 
						|
  void ProcessSoapCommand(wxString cmd, wxSocketBase& outs);
 | 
						|
 | 
						|
  void GenerateIndex(wxString& strFilename);
 | 
						|
  void GenerateSql(wxString& strFilename);
 | 
						|
  void GenerateFile(wxString& strFilename);
 | 
						|
};
 | 
						|
 | 
						|
// Implementare almeno queste due funzioni pure virtuali
 | 
						|
 | 
						|
const wxChar* TDataBaseServer::GetAppName() const
 | 
						|
{
 | 
						|
	return "DataBase";
 | 
						|
}
 | 
						|
 | 
						|
bool TDataBaseServer::IsMagicName(wxString& strFilename) const
 | 
						|
{
 | 
						|
  wxString strName;
 | 
						|
	wxSplitPath(strFilename, NULL, &strName, NULL);
 | 
						|
  strName.MakeLower();
 | 
						|
  const int q = strName.Find('?');
 | 
						|
	if (q > 0)
 | 
						|
	  strName.Truncate(q);
 | 
						|
 | 
						|
	if (strName == "index" || strName == "sql")
 | 
						|
	{
 | 
						|
		strFilename = strName;
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	if (strName == "log")
 | 
						|
	{
 | 
						|
		strFilename = GetLogFileName();
 | 
						|
	}
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::GenerateIndex(wxString& strFilename)
 | 
						|
{
 | 
						|
	TXmlItem html; 
 | 
						|
	TXmlItem& body = CreatePageBody(html).AddChild("center");
 | 
						|
 | 
						|
	TXmlItem& table = body.AddChild("table");
 | 
						|
  table.SetAttr("border", "1");
 | 
						|
	table.SetAttr("width", "70%");
 | 
						|
 | 
						|
	TXmlItem& tr0 = body.AddChild("tr");
 | 
						|
  TXmlItem& aq = tr0.AddChild("td").AddChild("a");
 | 
						|
	aq.SetAttr("href", "sql.htm"); aq << "SQL query";
 | 
						|
	tr0.AddChild("td") << "Perform any SQL query on the selected Data Source";
 | 
						|
 | 
						|
	TXmlItem& tr1 = body.AddChild("tr");
 | 
						|
  TXmlItem& al = tr1.AddChild("td").AddChild("a");
 | 
						|
	al.SetAttr("href", "Log"); al << "Log File";
 | 
						|
	tr1.AddChild("td") << "Display current server log";
 | 
						|
 | 
						|
	TXmlItem& tr2 = body.AddChild("tr");
 | 
						|
  TXmlItem& as = tr2.AddChild("td").AddChild("a");
 | 
						|
	as.SetAttr("href", "stop.cgi"); as << "Stop";
 | 
						|
	tr2.AddChild("td") << "Stop this database server";
 | 
						|
	
 | 
						|
	strFilename = GetTempFilename();
 | 
						|
	html.Save(strFilename);
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::GenerateSql(wxString& strFilename)
 | 
						|
{
 | 
						|
	TXmlItem html; 
 | 
						|
	TXmlItem& body = CreatePageBody(html).AddChild("center");
 | 
						|
 | 
						|
	TXmlItem& form = body.AddChild("form");
 | 
						|
	form.SetAttr("method", "post");
 | 
						|
	form.SetAttr("action", "Query.cgi");
 | 
						|
 | 
						|
  TXmlItem& table = form.AddChild("table").SetAttr("width", "70%");
 | 
						|
  
 | 
						|
	TXmlItem& tr0 = table.AddChild("tr");
 | 
						|
	tr0.AddChild("td") << "Data Source Name";
 | 
						|
	TXmlItem& dsn = tr0.AddChild("td").AddChild("input");
 | 
						|
	dsn.SetAttr("type", "string"); dsn.SetAttr("name", "Dsn");
 | 
						|
	dsn.SetAttr("value", GetConfigString("Dsn"));
 | 
						|
 | 
						|
	TXmlItem& tr1 = table.AddChild("tr");
 | 
						|
	tr1.AddChild("td") << "User";
 | 
						|
	TXmlItem& user = tr1.AddChild("td").AddChild("input");
 | 
						|
	user.SetAttr("type", "string"); user.SetAttr("name", "User");
 | 
						|
	user.SetAttr("value", GetConfigString("User"));
 | 
						|
 | 
						|
	TXmlItem& tr2 = table.AddChild("tr");
 | 
						|
	tr2.AddChild("td") << "Password";
 | 
						|
	TXmlItem& pass = tr2.AddChild("td").AddChild("input");
 | 
						|
	pass.SetAttr("type", "password"); pass.SetAttr("name", "User");
 | 
						|
 | 
						|
	form.AddChild("br");
 | 
						|
	form.AddChild("h3") << "SQL query:";
 | 
						|
	TXmlItem& q = form.AddChild("textarea");
 | 
						|
	q.SetAttr("name", "Sql");
 | 
						|
	q.SetAttr("cols", "80"); q.SetAttr("rows", "10");
 | 
						|
 | 
						|
	wxString query = GetConfigString("Sql");
 | 
						|
	q << query;
 | 
						|
      
 | 
						|
	form.AddChild("br");
 | 
						|
	form.AddChild("br");
 | 
						|
 | 
						|
	TXmlItem& sub = form.AddChild("input");
 | 
						|
	sub.SetAttr("type", "submit"); 
 | 
						|
	sub.SetAttr("value", "Execute");
 | 
						|
 | 
						|
	AddLinkButton(body, "Return to main page", "/");
 | 
						|
 | 
						|
	strFilename = GetTempFilename();
 | 
						|
	html.Save(strFilename);
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::GenerateFile(wxString& strFilename)
 | 
						|
{
 | 
						|
  wxString strName, strArgs;
 | 
						|
	wxSplitPath(strFilename, NULL, &strName, NULL);
 | 
						|
  strName.MakeLower();
 | 
						|
  const int q = strFilename.Find('?');
 | 
						|
	if (q > 0)
 | 
						|
		strArgs = strFilename.Mid(q+1);
 | 
						|
 | 
						|
	if (strName == "index")
 | 
						|
    GenerateIndex(strFilename); else
 | 
						|
	if (strName == "sql")
 | 
						|
    GenerateSql(strFilename); else
 | 
						|
	if (strName == "log")
 | 
						|
		strFilename = GetLogFileName();
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::AddAsterisk(const wxString& strField, const wxString& strQuery, 
 | 
						|
																 TDataBase& db, wxArrayString& arr)
 | 
						|
{
 | 
						|
	wxString strTable;
 | 
						|
	const int nDot = strField.Find(".*");
 | 
						|
	if (nDot < 0)
 | 
						|
	{
 | 
						|
		const int nFrom = strQuery.Find("FROM ");
 | 
						|
		if (nFrom > 0)
 | 
						|
			strTable = strQuery.Mid(nFrom+5);
 | 
						|
		const int nComma = strTable.Find(',');
 | 
						|
		const int nSpace = strTable.Find(' ');
 | 
						|
		int nTrunc = strTable.Length();
 | 
						|
		if (nComma > 0)
 | 
						|
			nTrunc = nComma;
 | 
						|
		if (nSpace > 0 && nSpace < nTrunc)
 | 
						|
			nTrunc = nSpace;
 | 
						|
		strTable.Truncate(nTrunc);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		strTable = strField.Left(nDot);
 | 
						|
	strTable.Trim(false); strTable.Trim(true);
 | 
						|
 | 
						|
	UWORD numCols;
 | 
						|
	wxDbColInf* dci = db.DataBase().GetColumns(strTable, &numCols);
 | 
						|
 | 
						|
	wxString strFieldName;
 | 
						|
	for (UWORD i = 0; i < numCols; i++)
 | 
						|
	{
 | 
						|
		if (strField == "*")
 | 
						|
			strFieldName = dci[i].colName;
 | 
						|
		else
 | 
						|
		{
 | 
						|
		  strFieldName = strTable;
 | 
						|
		  strFieldName += ".";
 | 
						|
		  strFieldName += dci[i].colName;
 | 
						|
		}
 | 
						|
    arr.Add(strFieldName);
 | 
						|
	}
 | 
						|
 | 
						|
  delete dci;
 | 
						|
}
 | 
						|
 | 
						|
wxString TDataBaseServer::ParseQuery(const wxString& strOriginalQuery, TDataBase& db, wxArrayString& arr)
 | 
						|
{
 | 
						|
	wxString strQuery;
 | 
						|
 | 
						|
  const int nSelect = strOriginalQuery.Find("SELECT ");
 | 
						|
	const int nFrom = strOriginalQuery.Find("FROM ");
 | 
						|
 | 
						|
	if (nSelect >= 0 && nFrom > nSelect)
 | 
						|
	{
 | 
						|
		wxString strFields = strOriginalQuery.Mid(nSelect+7, nFrom-nSelect-7);
 | 
						|
		strFields.Trim(false); strFields.Trim(true);
 | 
						|
		while(!strFields.IsEmpty())
 | 
						|
		{
 | 
						|
			const int nComma = strFields.Find(',');
 | 
						|
			wxString strField = nComma < 0 ? strFields : strFields.Mid(0, nComma);
 | 
						|
			strField.Trim(); strField.Trim(false);
 | 
						|
			if (strField.Find("*") >= 0)
 | 
						|
        AddAsterisk(strField, strOriginalQuery, db, arr);
 | 
						|
			else
 | 
						|
				arr.Add(strField);
 | 
						|
			if (nComma > 0)
 | 
						|
				strFields = strFields.Mid(nComma+1);
 | 
						|
			else
 | 
						|
				break;
 | 
						|
		}
 | 
						|
		strQuery = "SELECT ";
 | 
						|
		for (size_t i = 0; i < arr.GetCount(); i++)
 | 
						|
		{
 | 
						|
			if (i > 0)
 | 
						|
				strQuery << ",";
 | 
						|
			strQuery << arr[i];
 | 
						|
		}
 | 
						|
		strQuery << strOriginalQuery.Mid(nFrom-1);
 | 
						|
	}
 | 
						|
	else
 | 
						|
    strQuery = strOriginalQuery; 
 | 
						|
 | 
						|
	return strQuery;
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::WriteTable(wxString strDsn, wxString strUser,
 | 
						|
																 wxString strPass, wxString strOriginalQuery,
 | 
						|
																 wxOutputStream& out)
 | 
						|
{
 | 
						|
	const clock_t tTotalStart = clock();
 | 
						|
 | 
						|
	clock_t tQueryTime = 0;
 | 
						|
	clock_t tRetrieveTime = 0;
 | 
						|
  clock_t tTotalTime = 0;
 | 
						|
	size_t nRecords = 0;
 | 
						|
	
 | 
						|
	out << "<table border=1>\n";
 | 
						|
 | 
						|
  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())
 | 
						|
	{
 | 
						|
		wxArrayString arr;
 | 
						|
		const wxString strQuery = ParseQuery(strOriginalQuery, d, arr);
 | 
						|
 | 
						|
		wxDb& db = d.DataBase();
 | 
						|
 | 
						|
		const clock_t tQueryStart = clock();
 | 
						|
		db.ExecSql(strQuery);
 | 
						|
		tQueryTime    = clock() - tQueryStart;
 | 
						|
		
 | 
						|
		const int nColumns = arr.GetCount();
 | 
						|
		if (nColumns > 0)
 | 
						|
		{
 | 
						|
			out << " <thead>\n";
 | 
						|
			for (int i = 0; i < nColumns; i++)
 | 
						|
				out << "  <th>" << arr[i] << "</th>\n";
 | 
						|
			out << " </thead>\n";
 | 
						|
	
 | 
						|
			const int bufsize = 33000;
 | 
						|
			wxChar* buffer = new wxChar[bufsize];
 | 
						|
 | 
						|
			const clock_t tRetrieveStart = clock();
 | 
						|
			for (nRecords = 0; db.GetNext(); nRecords++)
 | 
						|
			{
 | 
						|
				out << " <tr>\n";
 | 
						|
				for (int c = 1; c <= nColumns; c++)
 | 
						|
				{
 | 
						|
					SDWORD cb;
 | 
						|
					if (db.GetData(c, SQL_C_CHAR, buffer, bufsize, &cb))
 | 
						|
					{
 | 
						|
						if (strcmp(buffer, "1899-12-30") == 0)
 | 
						|
							*buffer = '\0';
 | 
						|
						out << "  <td>" << buffer << "</td>\n";
 | 
						|
					}
 | 
						|
					else
 | 
						|
						break;
 | 
						|
				}
 | 
						|
				out << " </tr>\n";
 | 
						|
			}
 | 
						|
			delete buffer;
 | 
						|
			tRetrieveTime = clock() - tRetrieveStart;
 | 
						|
		}
 | 
						|
	}
 | 
						|
  out << "</table>\n";
 | 
						|
 | 
						|
	tTotalTime = clock() - tTotalStart;
 | 
						|
 | 
						|
	WriteLog(wxString::Format("--- %u Records. Query:%u Retrieve:%u Total:%u", 
 | 
						|
		                        nRecords, (unsigned int) tQueryTime, (unsigned int) tRetrieveTime, (unsigned int) tTotalTime));
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::ProcessFormQuery(const wxString& strFileName, THashTable& hashArgs)
 | 
						|
{
 | 
						|
	const wxString strDsn = hashArgs.Get("DSN");
 | 
						|
	const wxString strUser = hashArgs.Get("User");
 | 
						|
	const wxString strPass = hashArgs.Get("Password");
 | 
						|
	const wxString strOriginalQuery = hashArgs.Get("SQL");
 | 
						|
 | 
						|
	SetConfigString("DSN", strDsn);
 | 
						|
	SetConfigString("User", strUser);
 | 
						|
 | 
						|
  wxString strQuery = strOriginalQuery;
 | 
						|
  strQuery.Replace("\r\n", " ");
 | 
						|
	SetConfigString("SQL", strQuery);
 | 
						|
 | 
						|
	wxFileOutputStream out(strFileName);
 | 
						|
 | 
						|
	out << "<html>\n";
 | 
						|
	out << "<body bgcolor='#EFCEAD' background='back.gif'>\n";
 | 
						|
 | 
						|
	WriteTable(strDsn, strUser, strPass, strOriginalQuery, out);
 | 
						|
 | 
						|
	out << "</body>\n";
 | 
						|
	out << "</html>\n";
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::ProcessFormCommand(wxString cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
  const int stop = cmd.Find(" HTTP");
 | 
						|
	wxString strFileName = cmd.Mid(5, stop-5).Trim();
 | 
						|
 | 
						|
	wxString strName, args;
 | 
						|
	wxSplitPath(strFileName, NULL, &strName, NULL);
 | 
						|
 | 
						|
	const int pos = cmd.Find("\r\n\r\n");
 | 
						|
	if (pos > 0)
 | 
						|
	  args = cmd.Mid(pos+4);
 | 
						|
 | 
						|
	THashTable hashArgs(13);
 | 
						|
  ParseArguments(args, hashArgs);
 | 
						|
 | 
						|
  strFileName = GetTempFilename();
 | 
						|
 | 
						|
	if (strName == "Query")
 | 
						|
		ProcessFormQuery(strFileName, hashArgs);
 | 
						|
 | 
						|
	SendFile(strFileName, outs);
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::SoapProcessQuery(const TXmlItem &xmlMethod, wxOutputStream& 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);
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::SoapProcessTableRows(const TXmlItem &xmlMethod, wxOutputStream& out)
 | 
						|
{
 | 
						|
  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 (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";
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::ProcessSoapCommand(wxString cmd, wxSocketBase& sock)
 | 
						|
{
 | 
						|
	wxMemoryOutputStream outf;
 | 
						|
	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 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:"))
 | 
						|
				{
 | 
						|
					SoapProcessMethod(*pxmlMethod, outf);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	outf << "</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n";
 | 
						|
 | 
						|
  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: " << nSize << "\n";
 | 
						|
	sock << "Date: " << wxDateTime::Now().Format("%#c") << "\n";
 | 
						|
  sock << "\n" << mem;
 | 
						|
 | 
						|
	delete mem;
 | 
						|
}
 | 
						|
 | 
						|
void TDataBaseServer::ProcessCommand(wxString cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
	if (cmd.StartsWith("GET "))
 | 
						|
	{
 | 
						|
		const int stop = cmd.Find(" HTTP");
 | 
						|
		wxString str = cmd.Mid(4, stop-4).Trim();
 | 
						|
		if (str == "/")
 | 
						|
			str += "index.htm";
 | 
						|
		wxString strFilename = GetDocumentRoot() + str;
 | 
						|
 | 
						|
		if (IsMagicName(strFilename))
 | 
						|
			GenerateFile(strFilename);
 | 
						|
    else
 | 
						|
		{
 | 
						|
			const int ims = cmd.Find("If-Modified-Since: ");
 | 
						|
			if (ims > 0)
 | 
						|
			{
 | 
						|
				const wxString strDate = cmd.Mid(ims+19, 24);
 | 
						|
				wxDateTime tIms; 
 | 
						|
				if (tIms.ParseDateTime(strDate))
 | 
						|
				{
 | 
						|
					const wxDateTime tFile = ::wxFileModificationTime(strFilename);
 | 
						|
					if (tFile <= tIms)
 | 
						|
          {
 | 
						|
						SendNotModifiedFile(outs);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	  SendFile(strFilename, outs);
 | 
						|
	} else
 | 
						|
  if (cmd.StartsWith("POST "))
 | 
						|
	{
 | 
						|
    if (cmd.Find("SOAPAction") > 0)
 | 
						|
			ProcessSoapCommand(cmd, outs);
 | 
						|
		else
 | 
						|
      ProcessFormCommand(cmd, outs);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
bool TDataBaseServer::Initialization()
 | 
						|
{
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
bool TDataBaseServer::Deinitialization()
 | 
						|
{
 | 
						|
	wxDbCloseConnections();
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
// Istanziare l'applicazione principale
 | 
						|
 | 
						|
IMPLEMENT_APP(TDataBaseServer)
 |