kenpem
asked on
PUSHed data: HOW TO write a service/application to accept
I use an online payment processor that can send ("push") status notifications to me by POSTing XML data to a URL aimed at a script/service on my server.
I'm not looking for an all-out lead-me-by-the-hand answer in this question, but if somebody could (a) give me a very brief idea of what is involved; and (b) point me at a good Delphi-relevant online resource that explains the nitty gritty mechanics, I'd appreciate it. Of course if somebody clarifies everything and steers me down a smooth road I'll probably up the points accordingly.
I use Delphi 7 (Enterprise Architect) and have no plans or desire to upgrade. On purely stubborn grounds, I refuse to use a Microsoft language to implement this solution!
I'm not looking for an all-out lead-me-by-the-hand answer in this question, but if somebody could (a) give me a very brief idea of what is involved; and (b) point me at a good Delphi-relevant online resource that explains the nitty gritty mechanics, I'd appreciate it. Of course if somebody clarifies everything and steers me down a smooth road I'll probably up the points accordingly.
I use Delphi 7 (Enterprise Architect) and have no plans or desire to upgrade. On purely stubborn grounds, I refuse to use a Microsoft language to implement this solution!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
When I wrote that app, I used Blaine Southham's BRSHTTPServer to build a web server for testing.
http://www.torry.net/vcl/internet/serverside/brshttp.zip
It includes source code so you can modify it to suit your needs.
I modified it to intercept the XML and parse it into an Oracle DB.
http://www.torry.net/vcl/internet/serverside/brshttp.zip
It includes source code so you can modify it to suit your needs.
I modified it to intercept the XML and parse it into an Oracle DB.
Here it is. This is a very old application (from 1999) that used Paradox
to store the data and a TrayIcon and TTImer to check the BD for new/changed
records. Then it would create an XML file of the changed/new records and
send them using ICS THTTPCli to a java servlet that took the data and inserted
it into and Oracle DB. The XML was formatted to match what Oracle was
expecting. The servlet returned results that needed to be parsed as well. Like
I said above, I used BRSHTTPServer to test/debug this and it worked great.
Hope this helps you figure out your solution.
unit uXMLSenderApp;
(*
Modifications: 10/7/1999 - ES
Catch null datetimes other than grdate
10/18/99 - ES
Fix minimizing problem when called from EConvert
See FormCreate.
10/19/1999 - ES
Catch grdate that has spaces
10/22/1999 - ES
Log Error messages to ErrorData.txt
and fix error msg lines.
*)
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
MSXML_TLB, ExtCtrls, Db, DBTables, ComObj, HttpProt, Registry, ActiveX,
Menus, TrayIcon, Grids, DBGrids, StdCtrls, Buttons, ComCtrls, ExtPage,
FileCtrl, CheckLst;
const ServiceKey: PChar = '\SOFTWARE\ASI\EConnect';
type
TfrmDataPump = class(TForm)
Timer1: TTimer;
HttpCli1: THttpCli;
mnuMain: TMainMenu;
pmnuMain: TPopupMenu;
pmniCloseEConnect: TMenuItem;
pmniShowEConnect: TMenuItem;
pmniStartEConnect: TMenuItem;
pmniStopEConnect: TMenuItem;
pmniLogging: TMenuItem;
pmniLoggingOn: TMenuItem;
pmniLoggingOff: TMenuItem;
mniStartEConnect: TMenuItem;
mniStopEConnect: TMenuItem;
mniMinimizeEConnect: TMenuItem;
mniFile: TMenuItem;
mniCloseEConnect: TMenuItem;
TrayIcon1: TTrayIcon;
ExtPageControl1: TExtPageControl;
tsErrors: TTabSheet;
tsData: TTabSheet;
dbgLVL1DATA: TDBGrid;
StatusBar1: TStatusBar;
dbgLVL1ERROR: TDBGrid;
Panel1: TPanel;
bitbtnViewErrorList: TBitBtn;
tsLogs: TTabSheet;
memDebugLog: TMemo;
mniLogging: TMenuItem;
mniLoggingOn: TMenuItem;
mniLoggingOff: TMenuItem;
PopupMenu1: TPopupMenu;
SortAscending1: TMenuItem;
SortDescending1: TMenuItem;
SortNatural1: TMenuItem;
tmrSearch: TTimer;
N1: TMenuItem;
mniUpdateGridOn: TMenuItem;
mniUpdateGridOff: TMenuItem;
mniSetProxyAddress: TMenuItem;
N3: TMenuItem;
Panel2: TPanel;
bitbtnViewLVL1Data: TBitBtn;
edtLocate: TEdit;
rbLocateByName: TRadioButton;
rbLocateByID: TRadioButton;
DB1: TDatabase;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
procedure pmniCloseEConnectClick(Sen der: TObject);
procedure pmniShowEConnectClick(Send er: TObject);
procedure pmniStartEConnectClick(Sen der: TObject);
procedure pmniStopEConnectClick(Send er: TObject);
procedure bitbtnViewLVL1DataClick(Se nder: TObject);
procedure HttpCli1RequestDone(Sender : TObject; RqType: THttpRequest;
Error: Word);
procedure mniMinimizeEConnectClick(S ender: TObject);
procedure mniLoggingOnClick(Sender: TObject);
procedure mniLoggingOffClick(Sender: TObject);
procedure bitbtnViewErrorListClick(S ender: TObject);
procedure tsErrorsEnter(Sender: TObject);
procedure tsLogsEnter(Sender: TObject);
procedure StatusBar1DrawPanel(Status Bar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
procedure FormShow(Sender: TObject);
procedure SortAscending1Click(Sender : TObject);
procedure SortDescending1Click(Sende r: TObject);
procedure SortNatural1Click(Sender: TObject);
procedure edtLocateKeyPress(Sender: TObject; var Key: Char);
procedure tmrSearchTimer(Sender: TObject);
procedure mniUpdateGridOnClick(Sende r: TObject);
procedure mniUpdateGridOffClick(Send er: TObject);
procedure mniSetProxyAddressClick(Se nder: TObject);
procedure tsErrorsExit(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
ReturnedList, ErrorList: TStringList;
DataOut: TMemoryStream;
DataIn: TMemoryStream;
paramDBType: Integer;
SentList: TStringList;
bStarted, bNeedDTD, bYesData, bErrors, bUseCDATA: Boolean;
sURL, sDTDPath, sEConDir: string;
sConfigURL, sProxyAddr, sProxyPort, sProxyUser, sProxyPwd: string;
iTimerInterval, iRetryCount, iNumRetries: Integer;
iNumRecsToSend: Integer;
oXMLDoc: OleVariant;
DebugFile: TextFile;
RETFile: TextFile;
ERRFile: TextFile;
sDebugFile: string;
Dir: string;
public
{ Public declarations }
procedure PostData(dOut: TMemoryStream);
procedure StoreReturnedData(Returned List: TStringList);
procedure LogErrorMsgs(ErrorList: TStringList);
procedure IntializeConfig;
function GetConfigInfo: Boolean;
function CountInErrorLog(iLocalNum: Integer): Integer;
function GetPath(Alias: string): string;
end;
var
frmDataPump: TfrmDataPump;
implementation
uses udmMain, uSort, uProxySettings;
{$R *.DFM}
procedure TfrmDataPump.FormCreate(Se nder: TObject);
var
MyInfo: TStartUpInfo;
begin
GetStartUpInfo(MyInfo);
ShowWindow(Handle, MyInfo.wShowWindow);
end;
procedure TfrmDataPump.IntializeConf ig;
var
reg: TRegistry;
sDBType, sParadoxAlias: string;
begin
// Determine the current registry value
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKey(ServiceKey, True)) then
begin
sDBType := reg.ReadString('Database Type');
paramDBType := 0; // Paradox using BDE
iTimerInterval := reg.ReadInteger('Timer Interval');
sParadoxAlias := reg.ReadString('ParadoxAli as');
iNumRecsToSend := reg.ReadInteger('NoRecords ToSend');
sURL := reg.ReadString('URL');
sDTDPath := reg.ReadString('DTDPath');
sConfigURL := reg.ReadString('ConfigURL' );
bNeedDTD := reg.ReadBool('NeedDTD');
bUseCDATA := reg.ReadBool('UseCDATA');
iRetryCount := reg.ReadInteger('RetryCoun t');
sEconDir := GetPath('Web1st') + '\EConnect\';
if reg.ReadBool('UseProxy') then
begin
sProxyAddr := reg.ReadString('ProxyAddr' );
sProxyPort := reg.ReadString('ProxyPort' );
sProxyUser := reg.ReadString('ProxyUser' );
sProxyPwd := reg.ReadString('ProxyPassw ord');
end
else
begin
sProxyAddr := '';
sProxyPort := '80';
sProxyUser := '';
sProxyPwd := '';
end;
HttpCli1.Proxy := sProxyAddr;
HttpCli1.ProxyPassword := sProxyPwd;
HttpCli1.ProxyPort := sProxyPort;
HttpCli1.ProxyUsername := sProxyuser;
reg.CloseKey;
end
else // Key doesn't exist...Set Defaults and write key
begin
Timer1.Interval := 300000; // 5 minute intervals
paramDBType := 0; // Paradox using BDE
reg.WriteString('Database Type', 'P');
reg.WriteString('DTDPath', GetPath('Web1st') + '\EConnect\Lvl1data.dtd');
reg.WriteString('ConfigURL ', 'http://datapump.thepavement.com/servlet/GetConfig');
reg.WriteString('URL', 'http://datapump.thepavement.com/servlet/GetPost');
reg.WriteString('ParadoxAl ias', 'WebForms');
reg.WriteBool('NeedDTD', False);
reg.WriteBool('UseProxy', False);
reg.WriteString('ProxyAddr ', '');
reg.WriteString('ProxyPort ', '');
reg.WriteString('ProxyUser ', '');
reg.WriteString('ProxyPass word', '');
reg.WriteInteger('Timer Interval', 300000);
reg.WriteInteger('RetryCou nt', 1);
reg.WriteInteger('NoRecord sToSend', 50); // initially send only 50 records
reg.WriteBool('UseCDATA', False);
sEconDir := GetPath('Web1st') + '\EConnect\';
end;
DB1.AliasName := sParadoxAlias;
{
dmMain.BDEQuery.DatabaseNa me := sParadoxAlias;
dmMain.tblLVL1DATA.Databas eName := sParadoxAlias;
dmMain.tblLVL1ERROR.Databa seName := sParadoxAlias;
dmMain.BDEQuery2.DatabaseN ame := sParadoxAlias;
dmMain.qryLVL1DATA.Databas eName := sParadoxAlias;
dmMain.qryLVL1ERROR.Databa seName := sParadoxAlias;
}
finally
reg.Destroy;
end;
end;
procedure TfrmDataPump.FormClose(Sen der: TObject; var Action: TCloseAction);
begin
if bStarted then
pmniStopEConnectClick(Self );
Timer1.Enabled := False;
end;
procedure TfrmDataPump.Timer1Timer(S ender: TObject);
var
oRoot, oNode, oAttr, oChild, oPI, oXMLCDATASection: OleVariant;
iType, i, j, x, iCardNum, iLocalNum, size: Integer;
s, s2, sUploaded: string;
flag, bData: Boolean;
DTDSL: TStringList;
begin
// Flash if there are errors in the error list
if bErrors then
StatusBar1.Panels[1].Text := 'Errors in LVL1ERROR.DB';
StatusBar1.Panels[0].Text := 'Beginning Timer';
Application.ProcessMessage s;
if mniLoggingOn.Checked then
begin
Append(DebugFile);
Writeln(DebugFile, '*****');
WriteLn(DebugFile, 'Starting Timer:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
LockWindowUpdate(memDebugL og.Handle) ;
memDebugLog.Lines.Clear;
memDebugLog.Lines.LoadFrom File(sDebu gFile);
LockWindowUpdate(0);
end;
j := 0;
// temporarily set the shortdate format for Y2K.
if ShortDateFormat = 'M/d/yy' then
ShortDateFormat := 'm/d/yyyy';
Timer1.Interval := iTimerInterval;
Timer1.Enabled := False; // Turn the timer off so it doesn't
// come on when this code is running
// we've got records to roll back...we didn't get anything
// back from the server...
if (not bYesData) and (SentList.Count > 0) and (iNumRetries <= iRetryCount) then
begin
for i := 0 to Pred(SentList.Count) do
begin
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'Update LVL1DATA ' +
' Set PENDING = 1, ' +
' UPLOADED = NULL ' +
'Where LOCAL_NUM = ' + SentList.Strings[i];
dmMain.BDEQuery.ExecSQL;
end;
bYesData := True;
Inc(iNumRetries);
flag := False
end
else
flag := True;
// flag := GetConfigInfo; // when we get this built...Set a flag here
// for connectivity problems.
SentList.Clear;
if flag then
begin
bData := False;
// Check to see if Data is available
case paramDBType of
0: // BDE
begin
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'SELECT Count(*) FROM LVL1DATA ' +
' WHERE PENDING = 1 ' +
' and UPLOADED IS NULL';
dmMain.BDEQuery.Open;
i := dmMain.BDEQuery.Fields[0]. AsInteger;
j := i;
if i > 0 then
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Records To Send:' + IntToStr(i));
CloseFile(DebugFile);
end;
bData := True;
end
else
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'No Records To Send');
CloseFile(DebugFile);
end;
end;
dmMain.BDEQuery.Close;
end;
end; // case
if bData then
begin
try
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Beginning XML Build:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
// Build the XML document
oXMLDoc := VarNull;
oXMLDoc := CreateOleObject('Microsoft .XMLDOM');
oRoot := oXMLDoc.CreateElement('ROW SET');
oXMLDoc.AppendChild(oRoot) ;
case paramDBType of
0: // Paradox
begin
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'SELECT CARDNUM, LOCAL_NUM FROM LVL1DATA ' +
' WHERE PENDING = 1 ' +
' and UPLOADED IS NULL ';
dmMain.BDEQuery.Open;
dmMain.BDEQuery.First;
x := 1;
{
iNumrecsToSend is read from the registry.
if it is 0 then it sends all records. j is
assigned in the routine that checks to see how many
records pending to send.
}
if iNumRecsToSend = 0 then
iNumRecsToSend := j;
while (x <= iNumRecsToSend) and (not dmMain.BDEQuery.EOF) do
begin
iCardNum := dmMain.BDEQuery.Fields[0]. AsInteger;
oNode := oXMLDoc.CreateElement('ROW ');
oXMLDoc.DocumentElement.Ap pendChild( oNode);
dmMain.BDEQuery2.SQL.Clear ;
// Update the uploaded and modified timestamps
sUploaded := FormatDateTime('MM/DD/YYYY hh:nn:ss', Now);
dmMain.BDEQuery2.SQL.Text := 'UPDATE LVL1DATA ' +
' SET UPLOADED = ''' + sUploaded + ''', ' +
' MODIFIED = ''' + sUploaded + ''' ' +
' WHERE CARDNUM = ' + IntToStr(iCardNum);
dmMain.BDEQuery2.ExecSQL;
dmMain.BDEQuery2.Close;
dmMain.BDEQuery2.SQL.Clear ;
// now select the record to parse the data into XML...
dmMain.BDEQuery2.SQL.Text := 'SELECT * FROM LVL1DATA ' +
' WHERE CARDNUM = :CARDNUM';
dmMain.BDEQuery2.ParamByNa me('CARDNU M').AsInte ger := iCardNum;
dmMain.BDEQuery2.Open;
iLocalNum := dmMain.BDEQuery2.FieldByNa me('LOCAL_ NUM').AsIn teger;
// Keeping track of records sent for error tracking later
if (SentList.IndexOf(IntToStr (iLocalNum )) = -1) then
SentList.Add(IntToStr(iLoc alNum));
// iterate through the fields list to build XML
for i := 0 to Pred(dmMain.BDEQuery2.Fiel ds.Count) do
begin
oChild := oXMLDoc.CreateNode('elemen t', dmMain.BDEQuery2.Fields[i] .FieldName , '');
iType := Ord(dmMain.BDEQuery2.Field s[i].DataT ype);
case TFieldType(iType) of
ftString:
oChild.Text := dmMain.BDEQuery2.Fields[i] .AsString;
ftInteger, ftWord, ftSmallint:
begin
if dmMain.BDEQuery2.Fields[i] .AsInteger > 0 then
oChild.Text := IntToStr(dmMain.BDEQuery2. Fields[i]. AsInteger)
else
oChild.Text := '';
end;
ftFloat, ftCurrency, ftBCD:
begin
if dmMain.BDEQuery2.Fields[i] .AsFloat > 0 then
oChild.Text := FloatToStr(dmMain.BDEQuery 2.Fields[i ].AsFloat)
else
oChild.Text := '';
end;
ftBoolean: if dmMain.BDEQuery2.Fields[i] .Value then
oChild.Text := 'True'
else
oChild.Text := 'False';
ftDate, ftDateTime:
begin
if dmMain.BDEQuery2.Fields[i] .FieldName = 'DB001_GRDATE' then
begin
if (not dmMain.BDEQuery2.Fields[i] .IsNull) or
(Length(Trim(dmMain.BDEQue ry2.Fields [i].AsStri ng)) > 0) then
oChild.Text := FormatDateTime('MM/DD/YYYY ',
dmMain.BDEQuery2.Fields[i] .AsDateTim e)
else
oChild.Text := '';
end
else
// Catch Null datetimes other than GRDATE
// Forgot this...
if not dmMain.BDEQuery2.Fields[i] .IsNull then
oChild.Text := FormatDateTime('MM/DD/YYYY hh:nn:ss',
dmMain.BDEQuery2.Fields[i] .AsDateTim e)
else
oChild.Text := '';
end;
ftTime:
if not dmMain.BDEQuery2.Fields[i] .IsNull then
oChild.Text := FormatDateTime('hh:nn:ss',
dmMain.BDEQuery2.Fields[i] .AsDateTim e)
else
oChild.Text := '';
ftMemo:
begin
if bUseCDATA then
begin
oChild := oXMLDoc.createElement(dmMa in.BDEQuer y2.Fields[ i].FieldNa me);
oChild.appendChild(
oXMLDoc.createCDATASection (dmMain.BD EQuery2.Fi elds[i].As String));
end
else
oChild.Text := dmMain.BDEQuery2.Fields[i] .FieldName ;
end;
end; // case
oNode.AppendChild(oChild);
end; // for
Inc(x);
dmMain.BDEQuery.Next;
dmMain.BDEQuery2.Close;
end; // while not dmMain.BDEQuery.EOF
dmMain.BDEQuery.Close;
end; // 0
end; // case paramDBType
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Done Building XML:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
DataOut.Clear;
DataIn.Clear;
// usually, we will need a DTD
if not bNeedDTD then
begin
oPI := oXMLDoc.CreateProcessingIn struction( 'xml', 'version="1.0"');
// <?xml version="1.0" encoding="iso-8859-1"?>
oXMLDoc.InsertBefore(oPI, oXMLDoc.ChildNodes.Item[0] );
// Build String from oXMLDoc.XML
s := oXMLDoc.XML;
// for some reason, we need to delete the last two bytes.
Delete(s, Length(s) - 1, 2);
DataOut.Write(s[1], Length(s));
end
else
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Adding DTD to XML:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
DTDSL := TStringList.Create;
DTDSL.LoadFromFile(sDTDPat h);
DataOut.Seek(0, soFromBeginning);
DTDSL.SaveToStream(DataOut );
s := oXMLDoc.XML;
DataOut.Write(s[1], Length(s));
DataOut.Seek(0, soFromBeginning);
if mniLoggingOn.Checked then
begin
DTDSL.LoadFromStream(DataO ut);
DTDSL.SaveToFile(sEconDir + 'Econnect.xml');
end;
DTDSL.Free;
end;
if Length(s) > 0 then // Check if some data to post
begin
DataOut.Seek(0, soFromBeginning);
PostData(DataOut);
end;
finally
oXMLDoc := VarNull;
oRoot := VarNull;
oNode := VarNull;
oChild := VarNull;
oPI := VarNull;
oAttr := VarNull;
ShortDateFormat := 'm/d/yy';
end; // Try
end; // if bData
end; // if flag
StatusBar1.Panels[0].Text := 'Timer1 Ended';
Application.ProcessMessage s;
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Ending Timer:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
Timer1.Enabled := True;
end;
procedure TfrmDataPump.PostData(dOut : TMemoryStream);
var
s: string;
begin
ErrorList.Clear;
ReturnedList.Clear;
dOut.Seek(0, soFromBeginning);
HttpCli1.SendStream := dOut;
HttpCli1.Agent := 'ASI XML Sender';
HttpCli1.ContentTypePost := 'text/xml';
HttpCli1.RcvdStream := DataIn;
HttpCli1.URL := sURL;
try
StatusBar1.Panels[0].Text := 'Posting Data';
Application.ProcessMessage s;
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Posting Http:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
bYesData := False;
HttpCli1.PostAsync;
except
// Log any error messages and headers
s := '0;' + HttpCli1.ReasonPhrase + ';' + DateTimeToStr(Now) + ';' +
IntToStr(HttpCli1.StatusCo de);
ErrorList.Add(s);
LogErrorMsgs(ErrorList);
Exit;
end;
StatusBar1.Panels[0].Text := 'Exiting Out of PostData';
end;
procedure TfrmDataPump.StoreReturned Data(Retur nedList: TStringList);
var
i, j, x, z: Integer;
s, s1: string;
sErrMsg, sModified, sDB001_PIN, sEUserID: string;
begin
{ReturnedList Format:
Index 0 = LOCALNUM
Index 1 = DB001_CARDNUM
Index 2 = ERRORMSG
Index 3 = EUSERID
Index 4 = DB001_PIN
}
StatusBar1.Panels[0].Text := 'Storing Data';
Application.ProcessMessage s;
x := 0;
if mniLoggingOn.Checked then
begin
Append(RETFile);
for i := 0 to Pred(ReturnedList.count) do
Write(RETFile, ReturnedList.Strings[i] + #13);
CloseFile(RETFile);
end;
case paramDBType of
0: // Paradox
begin
for i := 0 to (ReturnedList.Count div 5) - 1 do
begin
x := i * 5;
j := SentList.IndexOf(ReturnedL ist.String s[x]);
if j > -1 then
begin
SentList.Delete(j);
if (Length(Trim(ReturnedList. Strings[x + 2])) > 0) then
//and
// (Pos('Student already exists', Trim(ReturnedList.Strings[ x + 2])) = 0) then
begin
// There was an error message posted with this record
// so place the info in ErrorList.
// Post it to the error log and
s := ReturnedList.Strings[x] + ';' + ReturnedList.Strings[x + 2] + ';' + DateTimeToStr(Now) + ';' + '300';
ErrorList.Add(s);
end
else
begin
{
They are passing a '*' in the db001_cardnum field
when it is an updated record, otherwise it is a new
post.
}
if ReturnedList.Strings[x + 1] <> '*' then
begin
if Length(Trim(ReturnedList.S trings[x + 2])) = 0 then
sErrMsg := 'lvl1Data.ERRORMSG = '''', '
else
sErrMsg := 'lvl1Data.ERRORMSG = ''' + ReturnedList.Strings[x + 2] + ''', ';
sModified := 'lvl1Data.MODIFIED = ''' + FormatDateTime('MM/DD/YYYY hh:nn:ss', Now) + ''', ';
sDB001_PIN := 'lvl1Data.DB001_PIN = ''' + ReturnedList.Strings[x + 4] + ''', ';
sEUserID := 'lvl1Data.EUSERID = ''' + ReturnedList.Strings[x + 3] + '''';
dmMain.BDEQuery.SQL.Text := 'UPDATE LVL1DATA ' +
' SET lvl1Data.DB001_CARDNUM = ' + ReturnedList.Strings[x + 1] + ', ' +
sErrMsg +
sModified +
'lvl1Data.PENDING = 0, ' +
sDB001_PIN +
sEUserID +
' WHERE lvl1Data.LOCAL_NUM = ' + ReturnedList.Strings[x] +
' and lvl1Data.UPLOADED is not NULL ';
dmMain.BDEQuery.ExecSQL;
dmMain.BDEQuery.SQL.Text := 'UPDATE LVL1DATA ' +
' SET lvl1Data.DB001_CARDNUM = ' + ReturnedList.Strings[x + 1] + ', ' +
sErrMsg +
sModified +
sDB001_PIN +
sEUserID +
' WHERE lvl1Data.LOCAL_NUM = ' + ReturnedList.Strings[x] +
' AND UPLOADED is NULL';
end
else
begin
{
This is an update record. DB001_CARDNUM is passed
as * when it is an updated record and I just update
the errormsg field, if there is one, the modified field
and the pending field...
}
if Length(Trim(ReturnedList.S trings[x + 2])) = 0 then
sErrMsg := 'lvl1Data.ERRORMSG = '''', '
else
sErrMsg := 'lvl1Data.ERRORMSG = ''' + ReturnedList.Strings[x + 2] + ''', ';
dmMain.BDEQuery.SQL.Text := 'UPDATE LVL1DATA ' +
' SET lvl1Data.MODIFIED = ''' + FormatDateTime('MM/DD/YYYY hh:nn:ss', Now) + ''', ' +
sErrMsg +
'lvl1Data.PENDING = 0 ' +
' WHERE lvl1Data.LOCAL_NUM = ' + ReturnedList.Strings[x] +
' and lvl1Data.UPLOADED is not NULL ';
end;
dmMain.BDEQuery.ExecSQL;
end;
end // if
else
begin
// Not found in the SentList stringlist.
// Post it to the error log and
if (Pos('HTTP', ReturnedList.Strings[x]) > 0) or
(Pos('Content', ReturnedList.Strings[x]) > 0) then
ReturnedList.Delete(x)
else
begin
if ReturnedList.Count > 2 then
begin
if Length(ReturnedList.String s[x + 2]) > 0 then
s := ReturnedList.Strings[x] + ';' + ReturnedList.Strings[x + 2] + ';' + DateTimeToStr(Now) + ';' + '301'
else
s := ReturnedList.Strings[x] + ';' + 'Not Found in Sent List' + ';' + DateTimeToStr(Now) + ';' + '301';
ErrorList.Add(s);
end; // if ReturnedList.Count > 2
end; // if (Pos('HTTP', ReturnedList.Strings[x]) > 0 )...
end; // if ReturnedList.Strings.Index Of...
end; // for i := 0 to (ReturnedList.Count...
if SentList.Count > 0 then
begin
// More sent than returned
// Post it to the error log
for i := 0 to Pred(SentList.Count) do
begin
if (ReturnedList.Count > 2) and (ReturnedList.Count < SentList.Count) then
begin
if Length(ReturnedList.String s[x + 2]) > 0 then
s := ReturnedList.Strings[x] + ';' + ReturnedList.Strings[x + 2] + ';' + DateTimeToStr(Now) + ';' + '302'
else
s := ReturnedList.Strings[x] + ';' + 'Sent more than Returned' + ';' + DateTimeToStr(Now) + ';' + '302';
ErrorList.Add(s);
end; // if ReturnedList.Count > 2
// Clear the Uploaded for this record
// So it can be sent again
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'Update LVL1DATA ' +
' Set PENDING = 1, ' +
' UPLOADED = NULL ' +
'Where LOCAL_NUM = ' + SentList.Strings[i];
dmMain.BDEQuery.ExecSQL;
end; // for
end; // if SentList.Count > 0
end; // 0
end; // case
if mniUpdateGridOn.Checked then
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Disab leControls ;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Disa bleControl s;
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1DATA.Open;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Enabl eControls;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Enab leControls ;
Screen.Cursor := crDefault;
end;
bYesData := True;
StatusBar1.Panels[0].Text := 'Done Storing Data';
if ErrorList.Count > 0 then
LogErrorMsgs(ErrorList);
end;
procedure TfrmDataPump.LogErrorMsgs( ErrorList: TStringList);
function ReplaceStr(const S: string; C: Char; const Replace: string): string;
var
i: Integer;
begin
Result := '';
for i := Length(S) downto 1 do
if S[i] = C then
Result := Replace + Result
else
Result := S[i] + Result;
end;
var
i, iLocalNum, iSeverity: Integer;
s, sErrorMsg: string;
dErrorDate: TDateTime;
begin
if mniLoggingOn.Checked then
begin
Append(ERRFile);
for i := 0 to Pred(ErrorList.Count) do
Write(ERRFile, ErrorList.Strings[i] + #13);
CloseFile(ERRFile);
end;
StatusBar1.Panels[0].Text := 'Logging Error Records';
bErrors := True;
StatusBar1.Panels[1].Text := 'Errors in LVL1ERROR.DB';
for i := 0 to Pred(ErrorList.Count) do
begin
s := ErrorList.Strings[i];
iLocalNum := StrToInt(Trim(Copy(s, 1, Pos(';', s) - 1)));
s := Copy(s, Pos(';', s) + 1, Length(s));
sErrorMsg := Trim(Copy(s, 1, Pos(';', s) - 1));
s := Copy(s, Pos(';', s) + 1, Length(s));
dErrorDate := StrToDateTime(Trim(Copy(s, 1, Pos(';', s) - 1)));
s := Copy(s, Pos(';', s) + 1, Length(s));
iSeverity := StrToInt(s);
case paramDBType of
0: // BDE
begin
if CountInErrorLog(iLocalNum) = 0 then
// We are modifying the uploaded to null so it will be picked up again
// ONLY if the record is not already in the error database
// So we first add the record to the error database and then on the
// next error occurrance, it won't get inserted/updated.
begin
// Insert into lvl1error table
dmMain.BDEQuery2.SQL.Clear ;
dmMain.BDEQuery2.SQL.Text := 'INSERT INTO LVL1ERROR ' +
' (LVL1DATA, ERRORMSG, ERRORDATE, SEVERITY) ' +
'values ' +
' (:LVL1DATA, :ERRORMSG, :ERRORDATE, :SEVERITY) ';
dmMain.BDEQuery2.ParamByNa me('LVL1DA TA').AsFlo at := iLocalNum;
dmMain.BDEQuery2.ParamByNa me('ERRORM SG').AsStr ing := sErrorMsg;
dmMain.BDEQuery2.ParamByNa me('ERRORD ATE').AsDa teTime := dErrorDate;
dmMain.BDEQuery2.ParamByNa me('SEVERI TY').AsFlo at := iSeverity;
dmMain.BDEQuery2.Prepare;
dmMain.BDEQuery2.ExecSQL;
dmMain.BDEQuery2.Close;
// Now clear the uploaded so it will be sent again
dmMain.BDEQuery3.SQL.Clear ;
dmMain.BDEQuery3.SQL.Text := 'UPDATE LVL1DATA ' +
' SET UPLOADED = NULL, ' +
' PENDING = 1, ' +
' ERRORMSG = :ERRORMSG ' +
' WHERE LOCAL_NUM = :LOCAL_NUM';
dmMain.BDEQuery3.ParamByNa me('LOCAL_ NUM').AsIn teger := iLocalNum;
dmMain.BDEQuery3.ParamByNa me('ERRORM SG').AsStr ing := sErrorMsg;
dmMain.BDEQuery3.Prepare;
dmMain.BDEQuery3.ExecSQL;
dmMain.BDEQuery3.Close;
end; // if not IsInErrorLog(...
end; // 0
end; // case
end; // for
dmMain.BDEQuery3.UnPrepare ;
dmMain.BDEQuery2.UnPrepare ;
StatusBar1.Panels[0].Text := 'Done Logging Error Records';
if mniUpdateGridOn.Checked then
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Disab leControls ;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Disa bleControl s;
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1DATA.Open;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Enabl eControls;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Enab leControls ;
Screen.Cursor := crDefault;
end;
end;
(*
Function to check to see if the particlar lvl1data.cardnum is in the
lvl1error table...
*)
function TfrmDataPump.CountInErrorL og(iLocalN um: Integer): Integer;
var
sSql: string;
i: Integer;
begin
Result := 0;
sSQL := 'SELECT Count(*) FROM LVL1ERROR ' +
' WHERE LVL1DATA = :CARDNUM';
case paramDBType of
0: // BDE
begin
dmMain.BDEQuery2.SQL.Clear ;
dmMain.BDEQuery2.SQL.Text := sSQL;
dmMain.BDEQuery2.ParamByNa me('CARDNU M').AsInte ger := iLocalNum;
dmMain.BDEQuery2.Open;
Result := dmMain.BDEQuery2.Fields[0] .AsInteger ;
dmMain.BDEQuery2.Close;
end;
end; // case
end;
(*
Function called each time to see if config parameters have changed...
*)
function TfrmDataPump.GetConfigInfo : Boolean;
var
s, s2: string;
DataIn, DataOut: TMemoryStream;
begin
StatusBar1.Panels[0].Text := 'Retrieving Config Info';
s := '*';
DataOut := TMemoryStream.Create;
DataIn := TMemoryStream.Create;
if Length(s) > 0 then // Check if some data to post
DataOut.Write(s[1], Length(s));
DataOut.Seek(0, soFromBeginning);
HttpCli1.SendStream := DataOut;
HttpCli1.Proxy := '';
HttpCli1.ProxyPort := '';
HttpCli1.Agent := 'ASI XML Sender';
HttpCli1.ContentTypePost := 'text/xml';
DataIn := TMemoryStream.Create;
HttpCli1.RcvdStream := DataIn;
// We can get the configuration parameters using this CGI
HttpCli1.URL := 'http://pippen.econnect.com/servlet/GetConfig';
try
HttpCli1.Post;
except
// Server problem
Result := False;
end;
// HTML error page returned from www server
if Pos('<head>', HttpCli1.RcvdHeader.String s[0]) > 0 then
Result := False
else
Result := True;
// need a way to parse this info into the registry...
// gotta figure out the format first...
StatusBar1.Panels[0].Text := '';
end;
procedure TfrmDataPump.pmniCloseECon nectClick( Sender: TObject);
begin
if bStarted then
begin
if (ReturnedList <> nil) and (ReturnedList.Count > 0) then
ReturnedList.Free;
if (ErrorList <> nil) and (ErrorList.Count > 0) then
ErrorList.Free;
if (SentList <> nil) and (SentList.Count > 0) then
SentList.Free;
if DataOut <> nil then
DataOut.Free;
if DataIn <> nil then
DataIn.Free;
end;
dmMain.qryLVL1DATA.Active := False;
dmMain.qryLVL1ERROR.Active := False;
Close;
end;
procedure TfrmDataPump.pmniShowEConn ectClick(S ender: TObject);
begin
Application.Restore;
end;
procedure TfrmDataPump.pmniStartECon nectClick( Sender: TObject);
begin
if (ReturnedList <> nil) and (ReturnedList.Count > 0) then
ReturnedList.Free;
if (ErrorList <> nil) and (ErrorList.Count > 0) then
ErrorList.Free;
if (SentList <> nil) and (SentList.Count > 0) then
SentList.Free;
if DataOut <> nil then
DataOut.Free;
if DataIn <> nil then
DataIn.Free;
if mniUpdateGridOn.Checked then
begin
dmMain.qryLVL1DATA.Active := True;
dmMain.qryLVL1ERROR.Active := True;
end;
iNumRetries := 0;
bErrors := False;
bNeedDTD := False;
IntializeConfig;
Timer1.Interval := 5000; // initially set to 5 seconds to start...
ReturnedList := TStringList.Create;
ErrorList := TStringList.Create;
SentList := TStringList.Create;
DataOut := TMemoryStream.Create;
DataIn := TMemoryStream.Create;
bStarted := True;
bYesData := True;
Timer1.Enabled := True;
Application.Title := 'EConnectWR - Running';
frmDataPump.Caption := 'EConnectWR - Running';
end;
procedure TfrmDataPump.pmniStopEConn ectClick(S ender: TObject);
begin
bStarted := False;
Application.Title := 'EConnectWR - Stopped';
frmDataPump.Caption := 'EConnectWR - Stopped';
Timer1.Enabled := False;
end;
procedure TfrmDataPump.bitbtnViewLVL 1DataClick (Sender: TObject);
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Disab leControls ;
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1DATA.Open;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Enabl eControls;
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.HttpCli1Reque stDone(Sen der: TObject; RqType: THttpRequest;
Error: Word);
var
s: string;
i: Integer;
begin
StatusBar1.Panels[0].Text := 'Receiving Data';
Application.ProcessMessage s;
case RqType of
httpPOST:
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Receiving Http:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
DataIn.Seek(0, soFromBeginning);
ReturnedList.LoadFromStrea m(DataIn);
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Lines Returned from stream:' + IntToStr(ReturnedList.Coun t));
CloseFile(DebugFile);
end;
// HTML error page returned from www server
if ((ReturnedList.Count > 0) and
((Pos('<head>', ReturnedList.Strings[0]) > 0) or
(Pos('java', ReturnedList.Strings[0]) > 0))) then
begin
if mniLoggingOn.Checked then
begin
Append(RETFile);
for i := 0 to Pred(ReturnedList.count) do
Write(RETFile, ReturnedList.Strings[i] + #13);
CloseFile(RETFile);
end;
ErrorList.Clear;
// We've got to abort this because servlet failed!!!!
if (Pos('java', ReturnedList.Strings[0]) > 0) then
begin
for i := 0 to Pred(ReturnedList.Count) do
begin
s := '0;' + ReturnedList.Strings[i] + ';' + DateTimeToStr(Now) + ';' + '999';
ErrorList.Add(s);
end;
end
else
begin
s := '0;' + ReturnedList.Strings[5] + ';' + DateTimeToStr(Now) + ';' + Copy(ReturnedList.Strings[ 1], 5, 3);
ErrorList.Add(s);
end;
LogErrorMsgs(ErrorList);
Exit;
end
else
begin
// Now Store the data that was returned and parsed into the StringList...
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Storing Data:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
end;
if ReturnedList.Count > 0 then
begin
StoreReturnedData(Returned List);
ReturnedList.Clear;
end;
if mniUpdateGridOn.Checked then
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Disab leControls ;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Disa bleControl s;
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1DATA.Open;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage = tsData then
dbgLVL1DATA.DataSource.Dat aSet.Enabl eControls;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Enab leControls ;
Screen.Cursor := crDefault;
end;
end;
end;
end;
end;
procedure TfrmDataPump.mniMinimizeEC onnectClic k(Sender: TObject);
begin
Application.Minimize;
end;
procedure TfrmDataPump.mniLoggingOnC lick(Sende r: TObject);
begin
if bStarted then
begin
ShowMessage('You can not change Logging Options while the EConnectWR is running');
end
else
begin
tsLogs.TabVisible := True;
tsLogs.PageIndex := 2;
ExtPageControl1.ActivePage := tsData;
ExtPageControl1.ReAlignTab Sheets(Tru e);
AssignFile(RETFile, sEconDir + 'ReturnedData.txt');
ReWrite(RETFile);
CloseFile(RETFile);
AssignFile(ERRFile, sEconDir + 'ErrorData.txt');
ReWrite(ERRFile);
CloseFile(ERRFile);
sDebugFile := sEConDir + 'debugfile.txt';
AssignFile(DebugFile, sDebugFile);
if not mniLoggingOn.Checked then
begin
ReWrite(DebugFile);
WriteLn(DebugFile, 'Starting Logging:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
mniLoggingOn.Checked := True;
mniLoggingOff.Checked := False;
end;
end;
end;
procedure TfrmDataPump.mniLoggingOff Click(Send er: TObject);
begin
if bStarted then
begin
ShowMessage('You can not change Logging Options while the EConnectWR is running');
end
else
begin
tsLogs.TabVisible := False;
if not mniLoggingOff.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Stopping Logging:' + FormatDateTime('hh:nn:ss', Now));
CloseFile(DebugFile);
mniLoggingOn.Checked := False;
mniLoggingOff.Checked := True;
end;
end;
end;
procedure TfrmDataPump.bitbtnViewErr orListClic k(Sender: TObject);
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Disa bleControl s;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage = tsErrors then
dbgLVL1ERROR.DataSource.Da taSet.Enab leControls ;
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.tsErrorsEnter (Sender: TObject);
begin
dmMain.qryLVL1ERROR.Active := True;
bErrors := False;
StatusBar1.Panels[1].Text := '';
end;
function TfrmDataPump.GetPath(Alias : string): string;
function GetAliasPath(AliasStr: string): string;
var
AliasList,
ParamList: TStringList;
I: Integer;
function PathOfAlias(AList: TStringList): string;
var
I: Integer;
Found: Boolean;
begin
I := -1;
Found := False;
repeat
Inc(I);
Found := (Copy(AList[I], 1, 4) = 'PATH');
until (I = Pred(AList.count)) or Found;
if Found then
Result := Copy(AList[I], 6, Length(AList[I]) - 5);
end;
begin
AliasList := TStringList.Create;
ParamList := TStringList.Create;
try
Session.GetAliasNames(Alia sList);
I := 0;
while (I < AliasList.Count) and
(UpperCase(AliasList[I]) <> UpperCase(AliasStr)) do
Inc(I);
if (I < AliasList.Count) then begin
Session.GetAliasParams(Ali asList[I], ParamList);
Result := PathOfAlias(ParamList);
end else
Result := '';
finally
AliasList.Free;
ParamList.Free;
end;
end;
var
s: string;
i: Integer;
begin
s := GetAliasPath(Alias);
for i := Length(s) downto 0 do
begin
if S[i] = '\' then
Break;
end;
Result := Copy(s, 1, i - 1);
end;
procedure TfrmDataPump.tsLogsEnter(S ender: TObject);
begin
LockWindowUpdate(memDebugL og.Handle) ;
memDebugLog.Lines.Clear;
memDebugLog.Lines.LoadFrom File(sDebu gFile);
LockWindowUpdate(0);
end;
procedure TfrmDataPump.StatusBar1Dra wPanel(Sta tusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
procedure DrawStatusPanel(Rect: TRect; Color: TColor; Text: string;
Alignment: Word);
var
PanelRect: TRect;
begin
PanelRect := Rect;
InflateRect(PanelRect, -2, 0);
StatusBar1.Canvas.Font.Col or := Color;
DrawText(StatusBar1.Canvas .Handle, PChar(Text), -1, PanelRect,
DT_NOPREFIX or DT_SINGLELINE or DT_VCENTER or Alignment);
end;
begin
if Panel.Index = 1 then
begin
DrawStatusPanel(Rect, clRed, Panel.Text, DT_LEFT)
end;
end;
procedure TfrmDataPump.FormShow(Send er: TObject);
var
Dir: string;
begin
Dir := ExtractFilePath(ParamStr(0 )) + 'PRIV';
if not DirectoryExists(Dir) then
CreateDir(Dir);
Session.PrivateDir := Dir;
if (ParamStr(1) = '/auto') and (not bStarted) then
begin
pmniStartEConnectClick(Sel f);
end;
if not bStarted then
begin
Application.Title := 'EConnectWR - Stopped';
frmDataPump.Caption := 'EConnectWR - Stopped';
end;
end;
procedure TfrmDataPump.SortAscending 1Click(Sen der: TObject);
var
i: Integer;
Grid: TDBGrid;
begin
Screen.Cursor := crSQLWait;
Grid := TDBGrid(PopupMenu1.PopupCo mponent);
Grid.DataSource.DataSet.Di sableContr ols;
i := Grid.SelectedIndex;
with TGridSort.Create do
begin
GridSort(Grid, i, 'A');
Free;
end;
Grid.DataSource.DataSet.En ableContro ls;
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.SortDescendin g1Click(Se nder: TObject);
var
i: Integer;
Grid: TDBGrid;
begin
Screen.Cursor := crSQLWait;
Grid := TDBGrid(PopupMenu1.PopupCo mponent);
Grid.DataSource.DataSet.Di sableContr ols;
i := Grid.SelectedIndex;
with TGridSort.Create do
begin
GridSort(Grid, i, 'D');
Free;
end;
Grid.DataSource.DataSet.En ableContro ls;
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.SortNatural1C lick(Sende r: TObject);
var
i: Integer;
Grid: TDBGrid;
begin
Screen.Cursor := crSQLWait;
Grid := TDBGrid(PopupMenu1.PopupCo mponent);
Grid.DataSource.DataSet.Di sableContr ols;
i := Grid.SelectedIndex;
with TGridSort.Create do
begin
GridSort(Grid, i, 'N');
Free;
end;
Grid.DataSource.DataSet.En ableContro ls;
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.edtLocateKeyP ress(Sende r: TObject; var Key: Char);
begin
tmrSearch.Enabled := FALSE;
tmrSearch.Enabled := TRUE;
end;
procedure TfrmDataPump.tmrSearchTime r(Sender: TObject);
var
sl: TStringList;
ds: TDataSet;
i: Integer;
begin
tmrSearch.Enabled := FALSE;
Screen.Cursor := crSQLWait;
ds := dbgLVL1DATA.DataSource.Dat aSet;
ds.DisableControls;
dmMain.qryLVL1DATA.Close;
sl := TStringList.Create;
sl.Assign(dmMain.qryLVL1DA TA.SQL);
for i := 0 to pred(sl.Count) do
begin
if Pos('ORDER BY', UpperCase(sl.Strings[i])) > 0 then
sl.Delete(i);
if Pos('WHERE', UpperCase(sl.Strings[i])) > 0 then
sl.Delete(i);
end;
if rbLocateByName.Checked then
begin
sl.Add('WHERE UPPER(DB001_LNAME) LIKE :DB001_LNAME');
dmMain.qryLVL1DATA.SQL.Ass ign(sl);
dmMain.qryLVL1DATA.ParamBy Name('DB00 1_LNAME'). AsString := UpperCase(edtLocate.Text) + '%';
end;
if rbLocateByID.Checked then
begin
sl.Add('WHERE DB001_ID LIKE :DB001_ID');
dmMain.qryLVL1DATA.SQL.Ass ign(sl);
dmMain.qryLVL1DATA.ParamBy Name('DB00 1_ID').AsS tring := edtLocate.Text + '%';
end;
dmMain.qryLVL1DATA.Prepare ;
dmMain.qryLVL1DATA.Open;
ds.EnableControls;
Screen.Cursor := crDefault;
sl.Free;
end;
procedure TfrmDataPump.mniUpdateGrid OnClick(Se nder: TObject);
begin
if not mniUpdateGridOn.Checked then
begin
mniUpdateGridOn.Checked := True;
mniUpdateGridOff.Checked := False;
end;
end;
procedure TfrmDataPump.mniUpdateGrid OffClick(S ender: TObject);
begin
if not mniUpdateGridOff.Checked then
begin
mniUpdateGridOn.Checked := False;
mniUpdateGridOff.Checked := True;
end;
end;
procedure TfrmDataPump.mniSetProxyAd dressClick (Sender: TObject);
var
frmProxy: TfrmProxySettings;
reg: TRegistry;
begin
// set proxy address...
frmProxy := TfrmProxySettings.Create(A pplication );
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKey(ServiceKey, True)) then
begin
//frmProxy.edtIpAddress.ip Address := reg.ReadString('ProxyAddr' );
frmProxy.edtProxyPort.Text := reg.ReadString('ProxyPort' );
frmProxy.edtProxyUserName. Text := reg.ReadString('ProxyUser' );
frmProxy.edtProxyPassword. Text := reg.ReadString('ProxyPassw ord');
frmProxy.ShowModal;
end;
finally
reg.Destroy;
end;
if frmProxy.ModalResult = mrOK then
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKey(ServiceKey, True)) then
begin
reg.WriteBool('UseProxy', True);
//reg.WriteString('ProxyAd dr', frmProxy.edtIpAddress.ipAd dress);
reg.WriteString('ProxyPort ', frmProxy.edtProxyPort.Text );
reg.WriteString('ProxyUser ', frmProxy.edtProxyUserName. Text);
reg.WriteString('ProxyPass word', frmProxy.edtProxyPassword. Text);
//sProxyAddr := reg.ReadString('ProxyAddr' );
sProxyPort := reg.ReadString('ProxyPort' );
sProxyUser := reg.ReadString('ProxyUser' );
sProxyPwd := reg.ReadString('ProxyPassw ord');
HttpCli1.Proxy := sProxyAddr;
HttpCli1.ProxyPassword := sProxyPwd;
HttpCli1.ProxyPort := sProxyPort;
HttpCli1.ProxyUsername := sProxyuser;
end;
finally
reg.Destroy;
end;
end;
frmProxy.Free;
frmProxy := nil;
end;
procedure TfrmDataPump.tsErrorsExit( Sender: TObject);
begin
dmMain.qryLVL1ERROR.Active := False;
end;
end.
to store the data and a TrayIcon and TTImer to check the BD for new/changed
records. Then it would create an XML file of the changed/new records and
send them using ICS THTTPCli to a java servlet that took the data and inserted
it into and Oracle DB. The XML was formatted to match what Oracle was
expecting. The servlet returned results that needed to be parsed as well. Like
I said above, I used BRSHTTPServer to test/debug this and it worked great.
Hope this helps you figure out your solution.
unit uXMLSenderApp;
(*
Modifications: 10/7/1999 - ES
Catch null datetimes other than grdate
10/18/99 - ES
Fix minimizing problem when called from EConvert
See FormCreate.
10/19/1999 - ES
Catch grdate that has spaces
10/22/1999 - ES
Log Error messages to ErrorData.txt
and fix error msg lines.
*)
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
MSXML_TLB, ExtCtrls, Db, DBTables, ComObj, HttpProt, Registry, ActiveX,
Menus, TrayIcon, Grids, DBGrids, StdCtrls, Buttons, ComCtrls, ExtPage,
FileCtrl, CheckLst;
const ServiceKey: PChar = '\SOFTWARE\ASI\EConnect';
type
TfrmDataPump = class(TForm)
Timer1: TTimer;
HttpCli1: THttpCli;
mnuMain: TMainMenu;
pmnuMain: TPopupMenu;
pmniCloseEConnect: TMenuItem;
pmniShowEConnect: TMenuItem;
pmniStartEConnect: TMenuItem;
pmniStopEConnect: TMenuItem;
pmniLogging: TMenuItem;
pmniLoggingOn: TMenuItem;
pmniLoggingOff: TMenuItem;
mniStartEConnect: TMenuItem;
mniStopEConnect: TMenuItem;
mniMinimizeEConnect: TMenuItem;
mniFile: TMenuItem;
mniCloseEConnect: TMenuItem;
TrayIcon1: TTrayIcon;
ExtPageControl1: TExtPageControl;
tsErrors: TTabSheet;
tsData: TTabSheet;
dbgLVL1DATA: TDBGrid;
StatusBar1: TStatusBar;
dbgLVL1ERROR: TDBGrid;
Panel1: TPanel;
bitbtnViewErrorList: TBitBtn;
tsLogs: TTabSheet;
memDebugLog: TMemo;
mniLogging: TMenuItem;
mniLoggingOn: TMenuItem;
mniLoggingOff: TMenuItem;
PopupMenu1: TPopupMenu;
SortAscending1: TMenuItem;
SortDescending1: TMenuItem;
SortNatural1: TMenuItem;
tmrSearch: TTimer;
N1: TMenuItem;
mniUpdateGridOn: TMenuItem;
mniUpdateGridOff: TMenuItem;
mniSetProxyAddress: TMenuItem;
N3: TMenuItem;
Panel2: TPanel;
bitbtnViewLVL1Data: TBitBtn;
edtLocate: TEdit;
rbLocateByName: TRadioButton;
rbLocateByID: TRadioButton;
DB1: TDatabase;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
procedure pmniCloseEConnectClick(Sen
procedure pmniShowEConnectClick(Send
procedure pmniStartEConnectClick(Sen
procedure pmniStopEConnectClick(Send
procedure bitbtnViewLVL1DataClick(Se
procedure HttpCli1RequestDone(Sender
Error: Word);
procedure mniMinimizeEConnectClick(S
procedure mniLoggingOnClick(Sender: TObject);
procedure mniLoggingOffClick(Sender:
procedure bitbtnViewErrorListClick(S
procedure tsErrorsEnter(Sender: TObject);
procedure tsLogsEnter(Sender: TObject);
procedure StatusBar1DrawPanel(Status
Panel: TStatusPanel; const Rect: TRect);
procedure FormShow(Sender: TObject);
procedure SortAscending1Click(Sender
procedure SortDescending1Click(Sende
procedure SortNatural1Click(Sender: TObject);
procedure edtLocateKeyPress(Sender: TObject; var Key: Char);
procedure tmrSearchTimer(Sender: TObject);
procedure mniUpdateGridOnClick(Sende
procedure mniUpdateGridOffClick(Send
procedure mniSetProxyAddressClick(Se
procedure tsErrorsExit(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
ReturnedList, ErrorList: TStringList;
DataOut: TMemoryStream;
DataIn: TMemoryStream;
paramDBType: Integer;
SentList: TStringList;
bStarted, bNeedDTD, bYesData, bErrors, bUseCDATA: Boolean;
sURL, sDTDPath, sEConDir: string;
sConfigURL, sProxyAddr, sProxyPort, sProxyUser, sProxyPwd: string;
iTimerInterval, iRetryCount, iNumRetries: Integer;
iNumRecsToSend: Integer;
oXMLDoc: OleVariant;
DebugFile: TextFile;
RETFile: TextFile;
ERRFile: TextFile;
sDebugFile: string;
Dir: string;
public
{ Public declarations }
procedure PostData(dOut: TMemoryStream);
procedure StoreReturnedData(Returned
procedure LogErrorMsgs(ErrorList: TStringList);
procedure IntializeConfig;
function GetConfigInfo: Boolean;
function CountInErrorLog(iLocalNum:
function GetPath(Alias: string): string;
end;
var
frmDataPump: TfrmDataPump;
implementation
uses udmMain, uSort, uProxySettings;
{$R *.DFM}
procedure TfrmDataPump.FormCreate(Se
var
MyInfo: TStartUpInfo;
begin
GetStartUpInfo(MyInfo);
ShowWindow(Handle, MyInfo.wShowWindow);
end;
procedure TfrmDataPump.IntializeConf
var
reg: TRegistry;
sDBType, sParadoxAlias: string;
begin
// Determine the current registry value
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKey(ServiceKey, True)) then
begin
sDBType := reg.ReadString('Database Type');
paramDBType := 0; // Paradox using BDE
iTimerInterval := reg.ReadInteger('Timer Interval');
sParadoxAlias := reg.ReadString('ParadoxAli
iNumRecsToSend := reg.ReadInteger('NoRecords
sURL := reg.ReadString('URL');
sDTDPath := reg.ReadString('DTDPath');
sConfigURL := reg.ReadString('ConfigURL'
bNeedDTD := reg.ReadBool('NeedDTD');
bUseCDATA := reg.ReadBool('UseCDATA');
iRetryCount := reg.ReadInteger('RetryCoun
sEconDir := GetPath('Web1st') + '\EConnect\';
if reg.ReadBool('UseProxy') then
begin
sProxyAddr := reg.ReadString('ProxyAddr'
sProxyPort := reg.ReadString('ProxyPort'
sProxyUser := reg.ReadString('ProxyUser'
sProxyPwd := reg.ReadString('ProxyPassw
end
else
begin
sProxyAddr := '';
sProxyPort := '80';
sProxyUser := '';
sProxyPwd := '';
end;
HttpCli1.Proxy := sProxyAddr;
HttpCli1.ProxyPassword := sProxyPwd;
HttpCli1.ProxyPort := sProxyPort;
HttpCli1.ProxyUsername := sProxyuser;
reg.CloseKey;
end
else // Key doesn't exist...Set Defaults and write key
begin
Timer1.Interval := 300000; // 5 minute intervals
paramDBType := 0; // Paradox using BDE
reg.WriteString('Database Type', 'P');
reg.WriteString('DTDPath',
reg.WriteString('ConfigURL
reg.WriteString('URL', 'http://datapump.thepavement.com/servlet/GetPost');
reg.WriteString('ParadoxAl
reg.WriteBool('NeedDTD', False);
reg.WriteBool('UseProxy', False);
reg.WriteString('ProxyAddr
reg.WriteString('ProxyPort
reg.WriteString('ProxyUser
reg.WriteString('ProxyPass
reg.WriteInteger('Timer Interval', 300000);
reg.WriteInteger('RetryCou
reg.WriteInteger('NoRecord
reg.WriteBool('UseCDATA', False);
sEconDir := GetPath('Web1st') + '\EConnect\';
end;
DB1.AliasName := sParadoxAlias;
{
dmMain.BDEQuery.DatabaseNa
dmMain.tblLVL1DATA.Databas
dmMain.tblLVL1ERROR.Databa
dmMain.BDEQuery2.DatabaseN
dmMain.qryLVL1DATA.Databas
dmMain.qryLVL1ERROR.Databa
}
finally
reg.Destroy;
end;
end;
procedure TfrmDataPump.FormClose(Sen
begin
if bStarted then
pmniStopEConnectClick(Self
Timer1.Enabled := False;
end;
procedure TfrmDataPump.Timer1Timer(S
var
oRoot, oNode, oAttr, oChild, oPI, oXMLCDATASection: OleVariant;
iType, i, j, x, iCardNum, iLocalNum, size: Integer;
s, s2, sUploaded: string;
flag, bData: Boolean;
DTDSL: TStringList;
begin
// Flash if there are errors in the error list
if bErrors then
StatusBar1.Panels[1].Text := 'Errors in LVL1ERROR.DB';
StatusBar1.Panels[0].Text := 'Beginning Timer';
Application.ProcessMessage
if mniLoggingOn.Checked then
begin
Append(DebugFile);
Writeln(DebugFile, '*****');
WriteLn(DebugFile, 'Starting Timer:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
LockWindowUpdate(memDebugL
memDebugLog.Lines.Clear;
memDebugLog.Lines.LoadFrom
LockWindowUpdate(0);
end;
j := 0;
// temporarily set the shortdate format for Y2K.
if ShortDateFormat = 'M/d/yy' then
ShortDateFormat := 'm/d/yyyy';
Timer1.Interval := iTimerInterval;
Timer1.Enabled := False; // Turn the timer off so it doesn't
// come on when this code is running
// we've got records to roll back...we didn't get anything
// back from the server...
if (not bYesData) and (SentList.Count > 0) and (iNumRetries <= iRetryCount) then
begin
for i := 0 to Pred(SentList.Count) do
begin
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'Update LVL1DATA ' +
' Set PENDING = 1, ' +
' UPLOADED = NULL ' +
'Where LOCAL_NUM = ' + SentList.Strings[i];
dmMain.BDEQuery.ExecSQL;
end;
bYesData := True;
Inc(iNumRetries);
flag := False
end
else
flag := True;
// flag := GetConfigInfo; // when we get this built...Set a flag here
// for connectivity problems.
SentList.Clear;
if flag then
begin
bData := False;
// Check to see if Data is available
case paramDBType of
0: // BDE
begin
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'SELECT Count(*) FROM LVL1DATA ' +
' WHERE PENDING = 1 ' +
' and UPLOADED IS NULL';
dmMain.BDEQuery.Open;
i := dmMain.BDEQuery.Fields[0].
j := i;
if i > 0 then
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Records To Send:' + IntToStr(i));
CloseFile(DebugFile);
end;
bData := True;
end
else
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'No Records To Send');
CloseFile(DebugFile);
end;
end;
dmMain.BDEQuery.Close;
end;
end; // case
if bData then
begin
try
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Beginning XML Build:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
// Build the XML document
oXMLDoc := VarNull;
oXMLDoc := CreateOleObject('Microsoft
oRoot := oXMLDoc.CreateElement('ROW
oXMLDoc.AppendChild(oRoot)
case paramDBType of
0: // Paradox
begin
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'SELECT CARDNUM, LOCAL_NUM FROM LVL1DATA ' +
' WHERE PENDING = 1 ' +
' and UPLOADED IS NULL ';
dmMain.BDEQuery.Open;
dmMain.BDEQuery.First;
x := 1;
{
iNumrecsToSend is read from the registry.
if it is 0 then it sends all records. j is
assigned in the routine that checks to see how many
records pending to send.
}
if iNumRecsToSend = 0 then
iNumRecsToSend := j;
while (x <= iNumRecsToSend) and (not dmMain.BDEQuery.EOF) do
begin
iCardNum := dmMain.BDEQuery.Fields[0].
oNode := oXMLDoc.CreateElement('ROW
oXMLDoc.DocumentElement.Ap
dmMain.BDEQuery2.SQL.Clear
// Update the uploaded and modified timestamps
sUploaded := FormatDateTime('MM/DD/YYYY
dmMain.BDEQuery2.SQL.Text := 'UPDATE LVL1DATA ' +
' SET UPLOADED = ''' + sUploaded + ''', ' +
' MODIFIED = ''' + sUploaded + ''' ' +
' WHERE CARDNUM = ' + IntToStr(iCardNum);
dmMain.BDEQuery2.ExecSQL;
dmMain.BDEQuery2.Close;
dmMain.BDEQuery2.SQL.Clear
// now select the record to parse the data into XML...
dmMain.BDEQuery2.SQL.Text := 'SELECT * FROM LVL1DATA ' +
' WHERE CARDNUM = :CARDNUM';
dmMain.BDEQuery2.ParamByNa
dmMain.BDEQuery2.Open;
iLocalNum := dmMain.BDEQuery2.FieldByNa
// Keeping track of records sent for error tracking later
if (SentList.IndexOf(IntToStr
SentList.Add(IntToStr(iLoc
// iterate through the fields list to build XML
for i := 0 to Pred(dmMain.BDEQuery2.Fiel
begin
oChild := oXMLDoc.CreateNode('elemen
iType := Ord(dmMain.BDEQuery2.Field
case TFieldType(iType) of
ftString:
oChild.Text := dmMain.BDEQuery2.Fields[i]
ftInteger, ftWord, ftSmallint:
begin
if dmMain.BDEQuery2.Fields[i]
oChild.Text := IntToStr(dmMain.BDEQuery2.
else
oChild.Text := '';
end;
ftFloat, ftCurrency, ftBCD:
begin
if dmMain.BDEQuery2.Fields[i]
oChild.Text := FloatToStr(dmMain.BDEQuery
else
oChild.Text := '';
end;
ftBoolean: if dmMain.BDEQuery2.Fields[i]
oChild.Text := 'True'
else
oChild.Text := 'False';
ftDate, ftDateTime:
begin
if dmMain.BDEQuery2.Fields[i]
begin
if (not dmMain.BDEQuery2.Fields[i]
(Length(Trim(dmMain.BDEQue
oChild.Text := FormatDateTime('MM/DD/YYYY
dmMain.BDEQuery2.Fields[i]
else
oChild.Text := '';
end
else
// Catch Null datetimes other than GRDATE
// Forgot this...
if not dmMain.BDEQuery2.Fields[i]
oChild.Text := FormatDateTime('MM/DD/YYYY
dmMain.BDEQuery2.Fields[i]
else
oChild.Text := '';
end;
ftTime:
if not dmMain.BDEQuery2.Fields[i]
oChild.Text := FormatDateTime('hh:nn:ss',
dmMain.BDEQuery2.Fields[i]
else
oChild.Text := '';
ftMemo:
begin
if bUseCDATA then
begin
oChild := oXMLDoc.createElement(dmMa
oChild.appendChild(
oXMLDoc.createCDATASection
end
else
oChild.Text := dmMain.BDEQuery2.Fields[i]
end;
end; // case
oNode.AppendChild(oChild);
end; // for
Inc(x);
dmMain.BDEQuery.Next;
dmMain.BDEQuery2.Close;
end; // while not dmMain.BDEQuery.EOF
dmMain.BDEQuery.Close;
end; // 0
end; // case paramDBType
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Done Building XML:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
DataOut.Clear;
DataIn.Clear;
// usually, we will need a DTD
if not bNeedDTD then
begin
oPI := oXMLDoc.CreateProcessingIn
// <?xml version="1.0" encoding="iso-8859-1"?>
oXMLDoc.InsertBefore(oPI, oXMLDoc.ChildNodes.Item[0]
// Build String from oXMLDoc.XML
s := oXMLDoc.XML;
// for some reason, we need to delete the last two bytes.
Delete(s, Length(s) - 1, 2);
DataOut.Write(s[1], Length(s));
end
else
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Adding DTD to XML:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
DTDSL := TStringList.Create;
DTDSL.LoadFromFile(sDTDPat
DataOut.Seek(0, soFromBeginning);
DTDSL.SaveToStream(DataOut
s := oXMLDoc.XML;
DataOut.Write(s[1], Length(s));
DataOut.Seek(0, soFromBeginning);
if mniLoggingOn.Checked then
begin
DTDSL.LoadFromStream(DataO
DTDSL.SaveToFile(sEconDir + 'Econnect.xml');
end;
DTDSL.Free;
end;
if Length(s) > 0 then // Check if some data to post
begin
DataOut.Seek(0, soFromBeginning);
PostData(DataOut);
end;
finally
oXMLDoc := VarNull;
oRoot := VarNull;
oNode := VarNull;
oChild := VarNull;
oPI := VarNull;
oAttr := VarNull;
ShortDateFormat := 'm/d/yy';
end; // Try
end; // if bData
end; // if flag
StatusBar1.Panels[0].Text := 'Timer1 Ended';
Application.ProcessMessage
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Ending Timer:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
Timer1.Enabled := True;
end;
procedure TfrmDataPump.PostData(dOut
var
s: string;
begin
ErrorList.Clear;
ReturnedList.Clear;
dOut.Seek(0, soFromBeginning);
HttpCli1.SendStream := dOut;
HttpCli1.Agent := 'ASI XML Sender';
HttpCli1.ContentTypePost := 'text/xml';
HttpCli1.RcvdStream := DataIn;
HttpCli1.URL := sURL;
try
StatusBar1.Panels[0].Text := 'Posting Data';
Application.ProcessMessage
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Posting Http:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
bYesData := False;
HttpCli1.PostAsync;
except
// Log any error messages and headers
s := '0;' + HttpCli1.ReasonPhrase + ';' + DateTimeToStr(Now) + ';' +
IntToStr(HttpCli1.StatusCo
ErrorList.Add(s);
LogErrorMsgs(ErrorList);
Exit;
end;
StatusBar1.Panels[0].Text := 'Exiting Out of PostData';
end;
procedure TfrmDataPump.StoreReturned
var
i, j, x, z: Integer;
s, s1: string;
sErrMsg, sModified, sDB001_PIN, sEUserID: string;
begin
{ReturnedList Format:
Index 0 = LOCALNUM
Index 1 = DB001_CARDNUM
Index 2 = ERRORMSG
Index 3 = EUSERID
Index 4 = DB001_PIN
}
StatusBar1.Panels[0].Text := 'Storing Data';
Application.ProcessMessage
x := 0;
if mniLoggingOn.Checked then
begin
Append(RETFile);
for i := 0 to Pred(ReturnedList.count) do
Write(RETFile, ReturnedList.Strings[i] + #13);
CloseFile(RETFile);
end;
case paramDBType of
0: // Paradox
begin
for i := 0 to (ReturnedList.Count div 5) - 1 do
begin
x := i * 5;
j := SentList.IndexOf(ReturnedL
if j > -1 then
begin
SentList.Delete(j);
if (Length(Trim(ReturnedList.
//and
// (Pos('Student already exists', Trim(ReturnedList.Strings[
begin
// There was an error message posted with this record
// so place the info in ErrorList.
// Post it to the error log and
s := ReturnedList.Strings[x] + ';' + ReturnedList.Strings[x + 2] + ';' + DateTimeToStr(Now) + ';' + '300';
ErrorList.Add(s);
end
else
begin
{
They are passing a '*' in the db001_cardnum field
when it is an updated record, otherwise it is a new
post.
}
if ReturnedList.Strings[x + 1] <> '*' then
begin
if Length(Trim(ReturnedList.S
sErrMsg := 'lvl1Data.ERRORMSG = '''', '
else
sErrMsg := 'lvl1Data.ERRORMSG = ''' + ReturnedList.Strings[x + 2] + ''', ';
sModified := 'lvl1Data.MODIFIED = ''' + FormatDateTime('MM/DD/YYYY
sDB001_PIN := 'lvl1Data.DB001_PIN = ''' + ReturnedList.Strings[x + 4] + ''', ';
sEUserID := 'lvl1Data.EUSERID = ''' + ReturnedList.Strings[x + 3] + '''';
dmMain.BDEQuery.SQL.Text := 'UPDATE LVL1DATA ' +
' SET lvl1Data.DB001_CARDNUM = ' + ReturnedList.Strings[x + 1] + ', ' +
sErrMsg +
sModified +
'lvl1Data.PENDING = 0, ' +
sDB001_PIN +
sEUserID +
' WHERE lvl1Data.LOCAL_NUM = ' + ReturnedList.Strings[x] +
' and lvl1Data.UPLOADED is not NULL ';
dmMain.BDEQuery.ExecSQL;
dmMain.BDEQuery.SQL.Text := 'UPDATE LVL1DATA ' +
' SET lvl1Data.DB001_CARDNUM = ' + ReturnedList.Strings[x + 1] + ', ' +
sErrMsg +
sModified +
sDB001_PIN +
sEUserID +
' WHERE lvl1Data.LOCAL_NUM = ' + ReturnedList.Strings[x] +
' AND UPLOADED is NULL';
end
else
begin
{
This is an update record. DB001_CARDNUM is passed
as * when it is an updated record and I just update
the errormsg field, if there is one, the modified field
and the pending field...
}
if Length(Trim(ReturnedList.S
sErrMsg := 'lvl1Data.ERRORMSG = '''', '
else
sErrMsg := 'lvl1Data.ERRORMSG = ''' + ReturnedList.Strings[x + 2] + ''', ';
dmMain.BDEQuery.SQL.Text := 'UPDATE LVL1DATA ' +
' SET lvl1Data.MODIFIED = ''' + FormatDateTime('MM/DD/YYYY
sErrMsg +
'lvl1Data.PENDING = 0 ' +
' WHERE lvl1Data.LOCAL_NUM = ' + ReturnedList.Strings[x] +
' and lvl1Data.UPLOADED is not NULL ';
end;
dmMain.BDEQuery.ExecSQL;
end;
end // if
else
begin
// Not found in the SentList stringlist.
// Post it to the error log and
if (Pos('HTTP', ReturnedList.Strings[x]) > 0) or
(Pos('Content', ReturnedList.Strings[x]) > 0) then
ReturnedList.Delete(x)
else
begin
if ReturnedList.Count > 2 then
begin
if Length(ReturnedList.String
s := ReturnedList.Strings[x] + ';' + ReturnedList.Strings[x + 2] + ';' + DateTimeToStr(Now) + ';' + '301'
else
s := ReturnedList.Strings[x] + ';' + 'Not Found in Sent List' + ';' + DateTimeToStr(Now) + ';' + '301';
ErrorList.Add(s);
end; // if ReturnedList.Count > 2
end; // if (Pos('HTTP', ReturnedList.Strings[x]) > 0 )...
end; // if ReturnedList.Strings.Index
end; // for i := 0 to (ReturnedList.Count...
if SentList.Count > 0 then
begin
// More sent than returned
// Post it to the error log
for i := 0 to Pred(SentList.Count) do
begin
if (ReturnedList.Count > 2) and (ReturnedList.Count < SentList.Count) then
begin
if Length(ReturnedList.String
s := ReturnedList.Strings[x] + ';' + ReturnedList.Strings[x + 2] + ';' + DateTimeToStr(Now) + ';' + '302'
else
s := ReturnedList.Strings[x] + ';' + 'Sent more than Returned' + ';' + DateTimeToStr(Now) + ';' + '302';
ErrorList.Add(s);
end; // if ReturnedList.Count > 2
// Clear the Uploaded for this record
// So it can be sent again
dmMain.BDEQuery.SQL.Clear;
dmMain.BDEQuery.SQL.Text := 'Update LVL1DATA ' +
' Set PENDING = 1, ' +
' UPLOADED = NULL ' +
'Where LOCAL_NUM = ' + SentList.Strings[i];
dmMain.BDEQuery.ExecSQL;
end; // for
end; // if SentList.Count > 0
end; // 0
end; // case
if mniUpdateGridOn.Checked then
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1DATA.Open;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
Screen.Cursor := crDefault;
end;
bYesData := True;
StatusBar1.Panels[0].Text := 'Done Storing Data';
if ErrorList.Count > 0 then
LogErrorMsgs(ErrorList);
end;
procedure TfrmDataPump.LogErrorMsgs(
function ReplaceStr(const S: string; C: Char; const Replace: string): string;
var
i: Integer;
begin
Result := '';
for i := Length(S) downto 1 do
if S[i] = C then
Result := Replace + Result
else
Result := S[i] + Result;
end;
var
i, iLocalNum, iSeverity: Integer;
s, sErrorMsg: string;
dErrorDate: TDateTime;
begin
if mniLoggingOn.Checked then
begin
Append(ERRFile);
for i := 0 to Pred(ErrorList.Count) do
Write(ERRFile, ErrorList.Strings[i] + #13);
CloseFile(ERRFile);
end;
StatusBar1.Panels[0].Text := 'Logging Error Records';
bErrors := True;
StatusBar1.Panels[1].Text := 'Errors in LVL1ERROR.DB';
for i := 0 to Pred(ErrorList.Count) do
begin
s := ErrorList.Strings[i];
iLocalNum := StrToInt(Trim(Copy(s, 1, Pos(';', s) - 1)));
s := Copy(s, Pos(';', s) + 1, Length(s));
sErrorMsg := Trim(Copy(s, 1, Pos(';', s) - 1));
s := Copy(s, Pos(';', s) + 1, Length(s));
dErrorDate := StrToDateTime(Trim(Copy(s,
s := Copy(s, Pos(';', s) + 1, Length(s));
iSeverity := StrToInt(s);
case paramDBType of
0: // BDE
begin
if CountInErrorLog(iLocalNum)
// We are modifying the uploaded to null so it will be picked up again
// ONLY if the record is not already in the error database
// So we first add the record to the error database and then on the
// next error occurrance, it won't get inserted/updated.
begin
// Insert into lvl1error table
dmMain.BDEQuery2.SQL.Clear
dmMain.BDEQuery2.SQL.Text := 'INSERT INTO LVL1ERROR ' +
' (LVL1DATA, ERRORMSG, ERRORDATE, SEVERITY) ' +
'values ' +
' (:LVL1DATA, :ERRORMSG, :ERRORDATE, :SEVERITY) ';
dmMain.BDEQuery2.ParamByNa
dmMain.BDEQuery2.ParamByNa
dmMain.BDEQuery2.ParamByNa
dmMain.BDEQuery2.ParamByNa
dmMain.BDEQuery2.Prepare;
dmMain.BDEQuery2.ExecSQL;
dmMain.BDEQuery2.Close;
// Now clear the uploaded so it will be sent again
dmMain.BDEQuery3.SQL.Clear
dmMain.BDEQuery3.SQL.Text := 'UPDATE LVL1DATA ' +
' SET UPLOADED = NULL, ' +
' PENDING = 1, ' +
' ERRORMSG = :ERRORMSG ' +
' WHERE LOCAL_NUM = :LOCAL_NUM';
dmMain.BDEQuery3.ParamByNa
dmMain.BDEQuery3.ParamByNa
dmMain.BDEQuery3.Prepare;
dmMain.BDEQuery3.ExecSQL;
dmMain.BDEQuery3.Close;
end; // if not IsInErrorLog(...
end; // 0
end; // case
end; // for
dmMain.BDEQuery3.UnPrepare
dmMain.BDEQuery2.UnPrepare
StatusBar1.Panels[0].Text := 'Done Logging Error Records';
if mniUpdateGridOn.Checked then
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1DATA.Open;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
Screen.Cursor := crDefault;
end;
end;
(*
Function to check to see if the particlar lvl1data.cardnum is in the
lvl1error table...
*)
function TfrmDataPump.CountInErrorL
var
sSql: string;
i: Integer;
begin
Result := 0;
sSQL := 'SELECT Count(*) FROM LVL1ERROR ' +
' WHERE LVL1DATA = :CARDNUM';
case paramDBType of
0: // BDE
begin
dmMain.BDEQuery2.SQL.Clear
dmMain.BDEQuery2.SQL.Text := sSQL;
dmMain.BDEQuery2.ParamByNa
dmMain.BDEQuery2.Open;
Result := dmMain.BDEQuery2.Fields[0]
dmMain.BDEQuery2.Close;
end;
end; // case
end;
(*
Function called each time to see if config parameters have changed...
*)
function TfrmDataPump.GetConfigInfo
var
s, s2: string;
DataIn, DataOut: TMemoryStream;
begin
StatusBar1.Panels[0].Text := 'Retrieving Config Info';
s := '*';
DataOut := TMemoryStream.Create;
DataIn := TMemoryStream.Create;
if Length(s) > 0 then // Check if some data to post
DataOut.Write(s[1], Length(s));
DataOut.Seek(0, soFromBeginning);
HttpCli1.SendStream := DataOut;
HttpCli1.Proxy := '';
HttpCli1.ProxyPort := '';
HttpCli1.Agent := 'ASI XML Sender';
HttpCli1.ContentTypePost := 'text/xml';
DataIn := TMemoryStream.Create;
HttpCli1.RcvdStream := DataIn;
// We can get the configuration parameters using this CGI
HttpCli1.URL := 'http://pippen.econnect.com/servlet/GetConfig';
try
HttpCli1.Post;
except
// Server problem
Result := False;
end;
// HTML error page returned from www server
if Pos('<head>', HttpCli1.RcvdHeader.String
Result := False
else
Result := True;
// need a way to parse this info into the registry...
// gotta figure out the format first...
StatusBar1.Panels[0].Text := '';
end;
procedure TfrmDataPump.pmniCloseECon
begin
if bStarted then
begin
if (ReturnedList <> nil) and (ReturnedList.Count > 0) then
ReturnedList.Free;
if (ErrorList <> nil) and (ErrorList.Count > 0) then
ErrorList.Free;
if (SentList <> nil) and (SentList.Count > 0) then
SentList.Free;
if DataOut <> nil then
DataOut.Free;
if DataIn <> nil then
DataIn.Free;
end;
dmMain.qryLVL1DATA.Active := False;
dmMain.qryLVL1ERROR.Active
Close;
end;
procedure TfrmDataPump.pmniShowEConn
begin
Application.Restore;
end;
procedure TfrmDataPump.pmniStartECon
begin
if (ReturnedList <> nil) and (ReturnedList.Count > 0) then
ReturnedList.Free;
if (ErrorList <> nil) and (ErrorList.Count > 0) then
ErrorList.Free;
if (SentList <> nil) and (SentList.Count > 0) then
SentList.Free;
if DataOut <> nil then
DataOut.Free;
if DataIn <> nil then
DataIn.Free;
if mniUpdateGridOn.Checked then
begin
dmMain.qryLVL1DATA.Active := True;
dmMain.qryLVL1ERROR.Active
end;
iNumRetries := 0;
bErrors := False;
bNeedDTD := False;
IntializeConfig;
Timer1.Interval := 5000; // initially set to 5 seconds to start...
ReturnedList := TStringList.Create;
ErrorList := TStringList.Create;
SentList := TStringList.Create;
DataOut := TMemoryStream.Create;
DataIn := TMemoryStream.Create;
bStarted := True;
bYesData := True;
Timer1.Enabled := True;
Application.Title := 'EConnectWR - Running';
frmDataPump.Caption := 'EConnectWR - Running';
end;
procedure TfrmDataPump.pmniStopEConn
begin
bStarted := False;
Application.Title := 'EConnectWR - Stopped';
frmDataPump.Caption := 'EConnectWR - Stopped';
Timer1.Enabled := False;
end;
procedure TfrmDataPump.bitbtnViewLVL
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1DATA.Open;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.HttpCli1Reque
Error: Word);
var
s: string;
i: Integer;
begin
StatusBar1.Panels[0].Text := 'Receiving Data';
Application.ProcessMessage
case RqType of
httpPOST:
begin
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Receiving Http:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
DataIn.Seek(0, soFromBeginning);
ReturnedList.LoadFromStrea
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Lines Returned from stream:' + IntToStr(ReturnedList.Coun
CloseFile(DebugFile);
end;
// HTML error page returned from www server
if ((ReturnedList.Count > 0) and
((Pos('<head>', ReturnedList.Strings[0]) > 0) or
(Pos('java', ReturnedList.Strings[0]) > 0))) then
begin
if mniLoggingOn.Checked then
begin
Append(RETFile);
for i := 0 to Pred(ReturnedList.count) do
Write(RETFile, ReturnedList.Strings[i] + #13);
CloseFile(RETFile);
end;
ErrorList.Clear;
// We've got to abort this because servlet failed!!!!
if (Pos('java', ReturnedList.Strings[0]) > 0) then
begin
for i := 0 to Pred(ReturnedList.Count) do
begin
s := '0;' + ReturnedList.Strings[i] + ';' + DateTimeToStr(Now) + ';' + '999';
ErrorList.Add(s);
end;
end
else
begin
s := '0;' + ReturnedList.Strings[5] + ';' + DateTimeToStr(Now) + ';' + Copy(ReturnedList.Strings[
ErrorList.Add(s);
end;
LogErrorMsgs(ErrorList);
Exit;
end
else
begin
// Now Store the data that was returned and parsed into the StringList...
if mniLoggingOn.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Storing Data:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
end;
if ReturnedList.Count > 0 then
begin
StoreReturnedData(Returned
ReturnedList.Clear;
end;
if mniUpdateGridOn.Checked then
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
dmMain.qryLVL1DATA.Close;
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1DATA.Open;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage
dbgLVL1DATA.DataSource.Dat
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
Screen.Cursor := crDefault;
end;
end;
end;
end;
end;
procedure TfrmDataPump.mniMinimizeEC
begin
Application.Minimize;
end;
procedure TfrmDataPump.mniLoggingOnC
begin
if bStarted then
begin
ShowMessage('You can not change Logging Options while the EConnectWR is running');
end
else
begin
tsLogs.TabVisible := True;
tsLogs.PageIndex := 2;
ExtPageControl1.ActivePage
ExtPageControl1.ReAlignTab
AssignFile(RETFile, sEconDir + 'ReturnedData.txt');
ReWrite(RETFile);
CloseFile(RETFile);
AssignFile(ERRFile, sEconDir + 'ErrorData.txt');
ReWrite(ERRFile);
CloseFile(ERRFile);
sDebugFile := sEConDir + 'debugfile.txt';
AssignFile(DebugFile, sDebugFile);
if not mniLoggingOn.Checked then
begin
ReWrite(DebugFile);
WriteLn(DebugFile, 'Starting Logging:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
mniLoggingOn.Checked := True;
mniLoggingOff.Checked := False;
end;
end;
end;
procedure TfrmDataPump.mniLoggingOff
begin
if bStarted then
begin
ShowMessage('You can not change Logging Options while the EConnectWR is running');
end
else
begin
tsLogs.TabVisible := False;
if not mniLoggingOff.Checked then
begin
Append(DebugFile);
WriteLn(DebugFile, 'Stopping Logging:' + FormatDateTime('hh:nn:ss',
CloseFile(DebugFile);
mniLoggingOn.Checked := False;
mniLoggingOff.Checked := True;
end;
end;
end;
procedure TfrmDataPump.bitbtnViewErr
begin
Screen.Cursor := crSQLWait;
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
dmMain.qryLVL1ERROR.Close;
dmMain.qryLVL1ERROR.Open;
if ExtPageControl1.ActivePage
dbgLVL1ERROR.DataSource.Da
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.tsErrorsEnter
begin
dmMain.qryLVL1ERROR.Active
bErrors := False;
StatusBar1.Panels[1].Text := '';
end;
function TfrmDataPump.GetPath(Alias
function GetAliasPath(AliasStr: string): string;
var
AliasList,
ParamList: TStringList;
I: Integer;
function PathOfAlias(AList: TStringList): string;
var
I: Integer;
Found: Boolean;
begin
I := -1;
Found := False;
repeat
Inc(I);
Found := (Copy(AList[I], 1, 4) = 'PATH');
until (I = Pred(AList.count)) or Found;
if Found then
Result := Copy(AList[I], 6, Length(AList[I]) - 5);
end;
begin
AliasList := TStringList.Create;
ParamList := TStringList.Create;
try
Session.GetAliasNames(Alia
I := 0;
while (I < AliasList.Count) and
(UpperCase(AliasList[I]) <> UpperCase(AliasStr)) do
Inc(I);
if (I < AliasList.Count) then begin
Session.GetAliasParams(Ali
Result := PathOfAlias(ParamList);
end else
Result := '';
finally
AliasList.Free;
ParamList.Free;
end;
end;
var
s: string;
i: Integer;
begin
s := GetAliasPath(Alias);
for i := Length(s) downto 0 do
begin
if S[i] = '\' then
Break;
end;
Result := Copy(s, 1, i - 1);
end;
procedure TfrmDataPump.tsLogsEnter(S
begin
LockWindowUpdate(memDebugL
memDebugLog.Lines.Clear;
memDebugLog.Lines.LoadFrom
LockWindowUpdate(0);
end;
procedure TfrmDataPump.StatusBar1Dra
Panel: TStatusPanel; const Rect: TRect);
procedure DrawStatusPanel(Rect: TRect; Color: TColor; Text: string;
Alignment: Word);
var
PanelRect: TRect;
begin
PanelRect := Rect;
InflateRect(PanelRect, -2, 0);
StatusBar1.Canvas.Font.Col
DrawText(StatusBar1.Canvas
DT_NOPREFIX or DT_SINGLELINE or DT_VCENTER or Alignment);
end;
begin
if Panel.Index = 1 then
begin
DrawStatusPanel(Rect, clRed, Panel.Text, DT_LEFT)
end;
end;
procedure TfrmDataPump.FormShow(Send
var
Dir: string;
begin
Dir := ExtractFilePath(ParamStr(0
if not DirectoryExists(Dir) then
CreateDir(Dir);
Session.PrivateDir := Dir;
if (ParamStr(1) = '/auto') and (not bStarted) then
begin
pmniStartEConnectClick(Sel
end;
if not bStarted then
begin
Application.Title := 'EConnectWR - Stopped';
frmDataPump.Caption := 'EConnectWR - Stopped';
end;
end;
procedure TfrmDataPump.SortAscending
var
i: Integer;
Grid: TDBGrid;
begin
Screen.Cursor := crSQLWait;
Grid := TDBGrid(PopupMenu1.PopupCo
Grid.DataSource.DataSet.Di
i := Grid.SelectedIndex;
with TGridSort.Create do
begin
GridSort(Grid, i, 'A');
Free;
end;
Grid.DataSource.DataSet.En
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.SortDescendin
var
i: Integer;
Grid: TDBGrid;
begin
Screen.Cursor := crSQLWait;
Grid := TDBGrid(PopupMenu1.PopupCo
Grid.DataSource.DataSet.Di
i := Grid.SelectedIndex;
with TGridSort.Create do
begin
GridSort(Grid, i, 'D');
Free;
end;
Grid.DataSource.DataSet.En
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.SortNatural1C
var
i: Integer;
Grid: TDBGrid;
begin
Screen.Cursor := crSQLWait;
Grid := TDBGrid(PopupMenu1.PopupCo
Grid.DataSource.DataSet.Di
i := Grid.SelectedIndex;
with TGridSort.Create do
begin
GridSort(Grid, i, 'N');
Free;
end;
Grid.DataSource.DataSet.En
Screen.Cursor := crDefault;
end;
procedure TfrmDataPump.edtLocateKeyP
begin
tmrSearch.Enabled := FALSE;
tmrSearch.Enabled := TRUE;
end;
procedure TfrmDataPump.tmrSearchTime
var
sl: TStringList;
ds: TDataSet;
i: Integer;
begin
tmrSearch.Enabled := FALSE;
Screen.Cursor := crSQLWait;
ds := dbgLVL1DATA.DataSource.Dat
ds.DisableControls;
dmMain.qryLVL1DATA.Close;
sl := TStringList.Create;
sl.Assign(dmMain.qryLVL1DA
for i := 0 to pred(sl.Count) do
begin
if Pos('ORDER BY', UpperCase(sl.Strings[i])) > 0 then
sl.Delete(i);
if Pos('WHERE', UpperCase(sl.Strings[i])) > 0 then
sl.Delete(i);
end;
if rbLocateByName.Checked then
begin
sl.Add('WHERE UPPER(DB001_LNAME) LIKE :DB001_LNAME');
dmMain.qryLVL1DATA.SQL.Ass
dmMain.qryLVL1DATA.ParamBy
end;
if rbLocateByID.Checked then
begin
sl.Add('WHERE DB001_ID LIKE :DB001_ID');
dmMain.qryLVL1DATA.SQL.Ass
dmMain.qryLVL1DATA.ParamBy
end;
dmMain.qryLVL1DATA.Prepare
dmMain.qryLVL1DATA.Open;
ds.EnableControls;
Screen.Cursor := crDefault;
sl.Free;
end;
procedure TfrmDataPump.mniUpdateGrid
begin
if not mniUpdateGridOn.Checked then
begin
mniUpdateGridOn.Checked := True;
mniUpdateGridOff.Checked := False;
end;
end;
procedure TfrmDataPump.mniUpdateGrid
begin
if not mniUpdateGridOff.Checked then
begin
mniUpdateGridOn.Checked := False;
mniUpdateGridOff.Checked := True;
end;
end;
procedure TfrmDataPump.mniSetProxyAd
var
frmProxy: TfrmProxySettings;
reg: TRegistry;
begin
// set proxy address...
frmProxy := TfrmProxySettings.Create(A
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKey(ServiceKey, True)) then
begin
//frmProxy.edtIpAddress.ip
frmProxy.edtProxyPort.Text
frmProxy.edtProxyUserName.
frmProxy.edtProxyPassword.
frmProxy.ShowModal;
end;
finally
reg.Destroy;
end;
if frmProxy.ModalResult = mrOK then
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKey(ServiceKey, True)) then
begin
reg.WriteBool('UseProxy', True);
//reg.WriteString('ProxyAd
reg.WriteString('ProxyPort
reg.WriteString('ProxyUser
reg.WriteString('ProxyPass
//sProxyAddr := reg.ReadString('ProxyAddr'
sProxyPort := reg.ReadString('ProxyPort'
sProxyUser := reg.ReadString('ProxyUser'
sProxyPwd := reg.ReadString('ProxyPassw
HttpCli1.Proxy := sProxyAddr;
HttpCli1.ProxyPassword := sProxyPwd;
HttpCli1.ProxyPort := sProxyPort;
HttpCli1.ProxyUsername := sProxyuser;
end;
finally
reg.Destroy;
end;
end;
frmProxy.Free;
frmProxy := nil;
end;
procedure TfrmDataPump.tsErrorsExit(
begin
dmMain.qryLVL1ERROR.Active
end;
end.
ASKER
OK thanks guys, I was hoping for just a couple of pointers a gotcha-warnings.
ASKER
Thanks so far.
The XML transmission is already happening, I just don't have anything in place yet to catch it. I've written CGI and ISAPI applications before - is there anything in particular I need to look out for? I'm happy at the moment simply to grab the XML and dump it into text files or a database for later process, I don't need to parse them on the spot.