campo-sirio/ce/sesa.cpp
angelo a35855912d Corretto messaggio
git-svn-id: svn://10.65.10.50/trunk@5190 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-09-11 14:44:53 +00:00

668 lines
16 KiB
C++
Executable File

#include "stdafx.h"
#include <fstream.h>
#include <io.h>
#include "columnst.h"
#include "sesa.h"
static CDatabase _db;
static CString _strWorkDir;
#ifndef WIN32
#define S4DLL
#include <d4all.h>
static CODE4 _codebase;
static DATA4 *_dbdata;
#endif
///////////////////////////////////////////////////////////
// SESA field info
///////////////////////////////////////////////////////////
class SESA_Field : public CObject
{
CString m_strName;
int m_nType;
CString m_strValue;
CTime m_tValue;
double m_dValue;
float m_fValue;
BOOL m_bValue;
public:
const CString& Name() const { return m_strName; }
int Type() const { return m_nType; }
CString& StrValue() { return m_strValue; }
CTime& TimeValue() { return m_tValue; }
double& DoubleValue() { return m_dValue; }
float& FloatValue() { return m_fValue; }
BOOL& BoolValue() { return m_bValue; }
SESA_Field(LPCSTR strName, int nType);
virtual ~SESA_Field() { }
};
SESA_Field::SESA_Field(LPCSTR strName, int nType)
: m_strName(strName), m_nType(nType), m_bValue(FALSE), m_dValue(0.0)
{ }
class SESA_FieldList : public CObject
{
CObList m_List;
public:
void Add(const CString& strField, int nType);
POSITION GetHeadPosition() const;
SESA_Field& GetNext(POSITION& rPosition);
SESA_Field& Find(const CString& strField);
void RemoveAll();
int GetCount() const { return m_List.GetCount(); }
virtual ~SESA_FieldList();
};
void SESA_FieldList::Add(const CString& strName, int nType)
{
SESA_Field* pField = new SESA_Field(strName, nType);
m_List.AddTail(pField);
}
POSITION SESA_FieldList::GetHeadPosition() const
{
return m_List.GetHeadPosition();
}
SESA_Field& SESA_FieldList::GetNext(POSITION& rPosition)
{
SESA_Field* pField = (SESA_Field*)m_List.GetNext(rPosition);
ASSERT(pField);
return *pField;
}
SESA_Field& SESA_FieldList::Find(const CString& strName)
{
for (POSITION pos = GetHeadPosition(); pos;)
{
SESA_Field& fld = GetNext(pos);
if (fld.Name() == strName)
return fld;
}
return SESA_Field("", 0);
}
void SESA_FieldList::RemoveAll()
{
while (!m_List.IsEmpty())
{
CObject* pField = m_List.RemoveHead();
delete pField;
}
}
SESA_FieldList::~SESA_FieldList()
{
RemoveAll();
}
///////////////////////////////////////////////////////////
// Sesa recordset
///////////////////////////////////////////////////////////
class SESA_Recordset : public CRecordset
{
// DECLARE_DYNAMIC(SESA_Recordset)
SESA_FieldList m_FieldList;
CStringList m_DumpList;
protected:
virtual CString GetDefaultConnect();
virtual CString GetDefaultSQL();
virtual void DoFieldExchange(CFieldExchange* pFX);
public:
BOOL Open(LPCSTR strTable);
void DumpHeader(ostream& out);
void ReadDumpList(const CString& strFile);
void DumpFields(ostream& out);
SESA_Recordset(CDatabase* pDatabase);
virtual ~SESA_Recordset() { }
};
//IMPLEMENT_DYNAMIC(SESA_Recordset, CRecordset)
CString SESA_Recordset::GetDefaultConnect()
{
return "ODBC;"; // Copied from CATALOG sample application
}
CString SESA_Recordset::GetDefaultSQL()
{
ASSERT(FALSE); // Copied from CATALOG sample application
return "!";
}
BOOL SESA_Recordset::Open(LPCSTR strTable)
{
CColumns Cols(&_db);
Cols.m_strTableNameParam = strTable;
BOOL ok = Cols.Open(CRecordset::forwardOnly, NULL, CRecordset::readOnly);
if (ok)
{
while (!Cols.IsEOF())
{
m_FieldList.Add(Cols.m_strColumnName, Cols.m_nDataType);
Cols.MoveNext();
}
RETCODE nRetCode;
AFX_SQL_SYNC(::SQLFreeStmt(Cols.m_hstmt, SQL_CLOSE));
m_nFields = m_FieldList.GetCount();
}
if (ok)
{
ok = CRecordset::Open(CRecordset::forwardOnly, strTable, CRecordset::readOnly);
if (!ok)
{
CString msg;
msg = "Impossibile aprire la tabella ";
msg += strTable;
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
}
}
return ok;
}
void SESA_Recordset::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
BOOL bLoad= pFX->m_nOperation == CFieldExchange::Fixup;
int nField = 1;
for (POSITION pos = m_FieldList.GetHeadPosition(); pos; nField++)
{
SESA_Field& fld = m_FieldList.GetNext(pos);
CString& val = fld.StrValue();
switch(fld.Type())
{
case SQL_BIT:
{
BOOL& b = fld.BoolValue();
RFX_Bool(pFX, fld.Name(), b);
if (bLoad)
{
if (b == FALSE ||
#ifdef WIN32
IsFieldNull(&b))
#else
IsFieldFlagNull(nField, CFieldExchange::outputColumn))
#endif
val.Empty();
else
val = "X";
}
}
break;
case SQL_CHAR:
case SQL_NUMERIC:
RFX_Text(pFX, fld.Name(), val);
break;
case SQL_DATE:
{
CTime& t = fld.TimeValue();
RFX_Date(pFX, fld.Name(), t);
if (bLoad)
{
TIMESTAMP_STRUCT* pts = (TIMESTAMP_STRUCT*)m_pvFieldProxy[nField];
if (pts->year == 0)
val.Empty();
else
{
char* buf = val.GetBuffer(16);
sprintf(buf, "%02d-%02d-%04d", pts->day, pts->month, pts->year);
val.ReleaseBuffer();
}
}
}
break;
case SQL_REAL:
{
float& d = fld.FloatValue();
RFX_Single(pFX, fld.Name(), d);
if (bLoad)
{
if (d == 0.0 ||
#ifdef WIN32
IsFieldNull(&d))
#else
IsFieldFlagNull(nField, CFieldExchange::outputColumn))
#endif
{
val.Empty();
}
else
{
char* buf = val.GetBuffer(32);
sprintf(buf, "%.12g", d);
val.ReleaseBuffer();
}
}
}
break;
case SQL_FLOAT:
case SQL_DOUBLE:
{
double& d = fld.DoubleValue();
RFX_Double(pFX, fld.Name(), d);
if (bLoad)
{
if (d == 0.0 ||
#ifdef WIN32
IsFieldNull(&d))
#else
IsFieldFlagNull(nField, CFieldExchange::outputColumn))
#endif
{
val.Empty();
}
else
{
char* buf = val.GetBuffer(32);
sprintf(buf, "%.12lg", d);
val.ReleaseBuffer();
}
}
}
break;
default:
ASSERT(0);
break;
}
}
}
void SESA_Recordset::DumpHeader(ostream& out)
{
out << "[MAIN]" << endl
<< "TYPEFIELD=-1" << endl
<< "DECSEP=." << endl
<< "FIELDSEP=|" << endl
<< endl;
out << "[RECORD]" << endl;
int num = 0;
for (POSITION pos = m_FieldList.GetHeadPosition(); pos; num++)
{
const SESA_Field& fld = m_FieldList.GetNext(pos);
out << "NAME(" << num << ") = " << fld.Name() << endl
<< endl;
}
}
void SESA_Recordset::ReadDumpList(const CString& strFile)
{
char szField[16];
char szName[16];
char szFile[32];
// Mette .\ davanti al nome per cercare nella directory corrente,
// altrimenti lo cerca nella directory di Windows
sprintf(szFile, ".\\%s", strFile);
for (int num = 0; ; num++)
{
sprintf(szField, "NAME(%d)", num);
GetPrivateProfileString("RECORD", szField, "", szName, sizeof(szName), szFile);
if (*szName)
m_DumpList.AddTail(szName);
else
break;
}
}
void SESA_Recordset::DumpFields(ostream& out)
{
if (m_DumpList.IsEmpty())
{
int num = 0;
for (POSITION pos = m_FieldList.GetHeadPosition(); pos; num++)
{
SESA_Field& fld = m_FieldList.GetNext(pos);
if (num) out << '|';
out << fld.StrValue();
}
}
else
{
int num = 0;
for (POSITION npos = m_DumpList.GetHeadPosition(); npos; num++)
{
CString& strName = m_DumpList.GetNext(npos);
SESA_Field& fld = m_FieldList.Find(strName);
if (num) out << '|';
out << fld.StrValue();
}
}
out << endl;
}
SESA_Recordset::SESA_Recordset(CDatabase* pDatabase)
: CRecordset(pDatabase)
{ }
///////////////////////////////////////////////////////////
// SESA functions
///////////////////////////////////////////////////////////
inline BOOL is_space(char c) { return c >= '\t' && c <= ' '; }
static BOOL UpdateODBCIni(LPCSTR szEntry, LPCSTR szDefault, BOOL bForce = FALSE)
{
BOOL bWrite = bForce;
if (!bForce)
{
char szBuffer[80];
::GetPrivateProfileString("SIGLAPP", szEntry, "", szBuffer, sizeof(szBuffer), "odbc.ini");
bWrite = *szBuffer == '\0';
}
if (bWrite)
::WritePrivateProfileString("SIGLAPP", szEntry, szDefault, "odbc.ini");
return bWrite;
}
BOOL SESA_OpenDatabase(const char* lpszDSN, const char* lpszConnect)
{
if (lpszDSN == NULL || *lpszDSN == '\0')
lpszDSN = "SIGLAPP";
if (lpszConnect == NULL || *lpszConnect == '\0')
lpszConnect = "ODBC;"; //UID=sa;PWD=";
BOOL ok;
TRY
{
// DataSrc Excl ReadOnly ConnectString
ok = _db.Open(lpszDSN, FALSE, TRUE, lpszConnect);
if (ok)
_db.m_bStripTrailingSpaces = TRUE;
}
CATCH_ALL(e)
{
ok = FALSE;
}
END_CATCH_ALL
if (!ok)
{
CString msg;
msg = "Impossibile connettersi al database ";
msg += lpszDSN;
msg += " usando ";
msg += lpszConnect;
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
}
return ok;
}
BOOL SESA_CloseDatabase()
{
if (_db.IsOpen())
_db.Close();
return TRUE;
}
BOOL SESA_DumpTableODBC(const char* lpszTableName)
{
const BOOL bWasOpen = _db.IsOpen();
if (!bWasOpen)
{
BOOL bOk = SESA_OpenDatabase();
if (!bOk)
return FALSE;
}
SESA_Recordset rs(&_db);
BOOL ok = rs.Open(lpszTableName);
if (ok)
{
CString strName = _strWorkDir;
strName += lpszTableName;
strName += ".ini";
if (access(strName, 0x00) == 0)
{
rs.ReadDumpList(strName);
}
else
{
ofstream out(strName);
rs.DumpHeader(out);
}
strName = _strWorkDir;
strName += lpszTableName;
strName += ".txt";
ofstream out(strName);
while (!rs.IsEOF())
{
rs.DumpFields(out);
rs.MoveNext();
}
RETCODE nRetCode;
AFX_SQL_SYNC(::SQLFreeStmt(rs.m_hstmt, SQL_CLOSE));
}
else
{
CString msg;
msg = "Impossibile aprire la tabella ";
msg += lpszTableName;
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
}
if (!bWasOpen)
SESA_CloseDatabase();
return ok;
}
BOOL SESA_DumpTableCODEBASE(const char* SIGLAPP, const char* lpszTableName)
{
BOOL ok = TRUE;
#ifndef WIN32
CString filename;
CString msg;
d4init(&_codebase);
_dbdata = NULL;
_codebase.read_lock=0;
_codebase.default_unique_error=e4unique;
_codebase.safety=0;
_codebase.lock_attempts=1;
u4ncpy(_codebase.date_format,"CCYYMMDD",sizeof(_codebase.date_format));
filename = SIGLAPP;
if (filename.Right(1) != "\\" && filename.Right(1) != "/")
filename += "\\";
filename += lpszTableName;
_codebase.error_code=0;
_dbdata=d4open(&_codebase,(char*)(const char*)filename);
if (_dbdata != NULL)
{
CString strName = _strWorkDir;
CString fld_name,fld_val;
CStringArray field_list;
strName += lpszTableName;
strName += ".ini";
if (access(strName, 0x00) == 0)
{
// Legge la lista dei campi dal .ini se esiste gia'
char szField[16];
char szName[16];
char szFile[32];
// Mette .\ davanti al nome per cercare nella directory corrente,
// altrimenti lo cerca nella directory di Windows
sprintf(szFile, ".\\%s", strName);
for (int num = 0; ; num++)
{
sprintf(szField, "NAME(%d)", num);
GetPrivateProfileString("RECORD", szField, "", szName, sizeof(szName), szFile);
if (*szName)
field_list.Add(szName);
else
break;
}
}
else
{
// Scarica il tracciato dei campi
ofstream out(strName);
out << "[MAIN]" << endl
<< "TYPEFIELD=-1" << endl
<< "DECSEP=." << endl
<< "FIELDSEP=|" << endl
<< endl;
out << "[RECORD]" << endl;
FIELD4INFO *field_info = d4field_info(_dbdata);
if (field_info != NULL)
{
const int num_fields = d4num_fields(_dbdata);
for (int num=0; num < num_fields; num++)
{
out << "NAME(" << num << ") = " << field_info[num].name << endl
<< endl;
field_list.Add(field_info[num].name);
}
u4free(field_info);
}
else
{
msg = "Impossibile reperire informazioni sulla testata del file";
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
ok = FALSE;
}
}
if (ok)
{
strName = _strWorkDir;
strName += lpszTableName;
strName += ".txt";
ofstream out(strName);
d4top(_dbdata); // No tag is required
while (!d4eof(_dbdata) && ok)
{
if (!d4deleted(_dbdata)) // Dump only undeleted records
{
const int items = field_list.GetSize();
for (int num = 0; num < items && ok; num++)
{
fld_name = field_list.GetAt(num);
if (num)
out << '|';
FIELD4* fldfld = d4field(_dbdata,(char*)(const char*)fld_name);
if (fldfld != NULL)
{
fld_val = f4str(fldfld);
char * v = fld_val.GetBuffer(80);
// Trims leading & trailing spaces
{
char* last = v;
// Salta spazi iniziali
for (const char* s = v; *s && is_space(*s); s++);
// Copia stringa
for(char* c = v; *s; s++)
{
*c++ = *s;
if (!is_space(*s)) last = c;
}
// Elimina spazi finali
*last = '\0';
}
out << v;
fld_val.ReleaseBuffer();
}
else
{
msg = "Impossibile reperire il campo ";
msg += fld_val;
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
ok = FALSE;
}
}
out << endl;
}
d4skip(_dbdata,1L); // Skip next
}
}
d4close(_dbdata);
}
else
{
msg = "Impossibile aprire il file ";
msg += filename;
AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
ok = FALSE;
}
d4init_undo(&_codebase);
#endif
return ok;
}
BOOL SESA_DumpTable(const char* lpszTableName)
{
char szBuffer[80];
::GetPrivateProfileString("SIGLAPP",
#ifndef WIN32
"Driver",
#else
"Driver32",
#endif
"", szBuffer, sizeof(szBuffer), "odbc.ini");
if (*szBuffer == '\0' || !SESA_DumpTableODBC(lpszTableName))
{
const char *SIGLAPP = getenv("SPPROOT");
if (SIGLAPP)
return SESA_DumpTableCODEBASE(SIGLAPP, lpszTableName);
else
{
AfxMessageBox("Impossibile trovare la variabile d'ambiente SPPROOT", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
}
return TRUE;
}
BOOL SESA_WorkDir(const char* strDir)
{
_strWorkDir = strDir;
_strWorkDir = _strWorkDir.SpanExcluding(" ");
const char& last = _strWorkDir[_strWorkDir.GetLength()-1];
if (last != '\\' && last != '/')
_strWorkDir += "\\";
return !_strWorkDir.IsEmpty();
}