mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-16 08:15:53 +01:00
204 lines
4.4 KiB
C++
204 lines
4.4 KiB
C++
|
/*
|
||
|
* PROGRAM: Object oriented API samples.
|
||
|
* MODULE: 08.events.cpp
|
||
|
* DESCRIPTION: A sample of working with events.
|
||
|
*
|
||
|
* Example for the following interfaces:
|
||
|
* IEvents - returned by queEvents(), used to cancel events monitoring
|
||
|
* IEventCallback - it's callback is invoked when event happens
|
||
|
*
|
||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||
|
* the License. You may obtain a copy of the License at
|
||
|
* http://www.mozilla.org/MPL/
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||
|
* for the specific language governing rights and limitations under the
|
||
|
* License.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is Adriano dos Santos Fernandes.
|
||
|
* Portions created by the Initial Developer are Copyright (C) 2011 the Initial Developer.
|
||
|
* All Rights Reserved.
|
||
|
*
|
||
|
* Contributor(s):
|
||
|
* Alexander Peshkov
|
||
|
*/
|
||
|
|
||
|
#include "ifaceExamples.h"
|
||
|
|
||
|
#ifndef WIN32
|
||
|
#include <unistd.h>
|
||
|
#else
|
||
|
#include <windows.h>
|
||
|
#endif
|
||
|
|
||
|
static IMaster* master = fb_get_master_interface();
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
// This class encapsulates single event handling
|
||
|
class Event : public IEventCallbackImpl<Event, ThrowStatusWrapper>
|
||
|
{
|
||
|
public:
|
||
|
Event(IAttachment* aAttachment, const char* name)
|
||
|
: refCounter(0),
|
||
|
attachment(aAttachment),
|
||
|
counter(0),
|
||
|
status(master->getStatus()),
|
||
|
events(NULL),
|
||
|
first(true)
|
||
|
{
|
||
|
eveLen = isc_event_block(&eveBuffer, &eveResult, 1, name);
|
||
|
events = attachment->queEvents(&status, this, eveLen, eveBuffer);
|
||
|
}
|
||
|
|
||
|
void process(int pass)
|
||
|
{
|
||
|
if (!events)
|
||
|
return;
|
||
|
|
||
|
ISC_ULONG tot = 0;
|
||
|
if (counter)
|
||
|
{
|
||
|
isc_event_counts(&tot, eveLen, eveBuffer, eveResult);
|
||
|
|
||
|
events->release();
|
||
|
events = NULL;
|
||
|
counter = 0;
|
||
|
events = attachment->queEvents(&status, this, eveLen, eveBuffer);
|
||
|
}
|
||
|
|
||
|
if (tot && !first)
|
||
|
printf("Event count on pass %d is %d\n", pass, tot);
|
||
|
else
|
||
|
printf("Pass %d - no events\n", pass);
|
||
|
|
||
|
first = false;
|
||
|
}
|
||
|
|
||
|
// IEventCallback implementation
|
||
|
void eventCallbackFunction(unsigned int length, const ISC_UCHAR* data)
|
||
|
{
|
||
|
memcpy(eveResult, data, length);
|
||
|
++counter;
|
||
|
if (!first)
|
||
|
printf("AST called\n");
|
||
|
}
|
||
|
|
||
|
// refCounted implementation
|
||
|
virtual void addRef()
|
||
|
{
|
||
|
++refCounter;
|
||
|
}
|
||
|
|
||
|
virtual int release()
|
||
|
{
|
||
|
if (--refCounter == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
~Event()
|
||
|
{
|
||
|
if (events)
|
||
|
events->release();
|
||
|
if (eveBuffer)
|
||
|
isc_free((char*)eveBuffer);
|
||
|
if (eveResult)
|
||
|
isc_free((char*)eveResult);
|
||
|
status.dispose();
|
||
|
}
|
||
|
|
||
|
FbSampleAtomic refCounter;
|
||
|
IAttachment* attachment;
|
||
|
volatile int counter;
|
||
|
ThrowStatusWrapper status;
|
||
|
IEvents* events;
|
||
|
unsigned char* eveBuffer;
|
||
|
unsigned char* eveResult;
|
||
|
unsigned eveLen;
|
||
|
bool first;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
int rc = 0;
|
||
|
|
||
|
// set default password if none specified in environment
|
||
|
setenv("ISC_USER", "sysdba", 0);
|
||
|
setenv("ISC_PASSWORD", "masterkey", 0);
|
||
|
|
||
|
// With ThrowStatusWrapper passed as status interface FbException will be thrown on error
|
||
|
ThrowStatusWrapper status(master->getStatus());
|
||
|
|
||
|
// Declare pointers to required interfaces
|
||
|
IProvider* prov = master->getDispatcher();
|
||
|
IAttachment* att = NULL;
|
||
|
ITransaction* tra = NULL;
|
||
|
Event* event = NULL;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// attach database
|
||
|
att = prov->attachDatabase(&status, "employee", 0, NULL);
|
||
|
|
||
|
// register an event
|
||
|
event = new Event(att, "EVENT1");
|
||
|
event->addRef();
|
||
|
|
||
|
const char cmdBlock[] = "execute block as begin post_event 'EVENT1'; end";
|
||
|
|
||
|
for (int i = 0; i < 3; ++i)
|
||
|
{
|
||
|
#ifndef WIN32
|
||
|
sleep(1); // sec
|
||
|
#else
|
||
|
Sleep(1000); // msec
|
||
|
#endif
|
||
|
event->process(i);
|
||
|
|
||
|
tra = att->startTransaction(&status, 0, NULL);
|
||
|
att->execute(&status, tra, 0, cmdBlock, SAMPLES_DIALECT,
|
||
|
NULL, NULL, NULL, NULL);
|
||
|
tra->commit(&status);
|
||
|
tra = NULL;
|
||
|
}
|
||
|
|
||
|
// cleanup
|
||
|
event->release();
|
||
|
event = NULL;
|
||
|
att->detach(&status);
|
||
|
att = NULL;
|
||
|
}
|
||
|
catch (const FbException& error)
|
||
|
{
|
||
|
// handle error
|
||
|
rc = 1;
|
||
|
|
||
|
char buf[256];
|
||
|
master->getUtilInterface()->formatStatus(buf, sizeof(buf), error.getStatus());
|
||
|
fprintf(stderr, "%s\n", buf);
|
||
|
}
|
||
|
|
||
|
// release interfaces after error caught
|
||
|
if (event)
|
||
|
event->release();
|
||
|
if (tra)
|
||
|
tra->release();
|
||
|
if (att)
|
||
|
att->release();
|
||
|
|
||
|
// generic cleanup
|
||
|
prov->release();
|
||
|
status.dispose();
|
||
|
|
||
|
return rc;
|
||
|
}
|