mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +01:00
Fixed docs - thanks to Martin
This commit is contained in:
parent
8d423b6225
commit
3c4062c092
@ -7,12 +7,12 @@
|
||||
<META NAME="AUTHOR" CONTENT="alex ">
|
||||
<META NAME="CREATED" CONTENT="20130531;10003100">
|
||||
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
|
||||
<META NAME="CHANGED" CONTENT="20160407;18553100">
|
||||
<META NAME="CHANGED" CONTENT="20160905;13142600">
|
||||
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
|
||||
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
|
||||
<STYLE TYPE="text/css">
|
||||
<!--
|
||||
@page { size: 8.5in 11in; margin: 0.79in }
|
||||
TD P { margin-bottom: 0.08in; color: #000000 }
|
||||
H1 { color: #000000 }
|
||||
P { margin-bottom: 0.08in; color: #000000 }
|
||||
-->
|
||||
@ -519,7 +519,7 @@ cycle:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while
|
||||
(curs->fetchNext(&status, buffer) == IStatus::RESULT_OK)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// row processing</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// row processing</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
@ -587,43 +587,43 @@ namespace Firebird), timestamp – with class FbTimestamp, containing
|
||||
two public data members date and time of appropriate class, char -
|
||||
with struct <A HREF="#FbChar">FbChar</A> and varchar – with struct
|
||||
<A HREF="#FbVarChar">FbVarChar</A>. For each field preprocessor
|
||||
creates two data members in the message – <I>name</I> for
|
||||
field/parameter value and <I>nameNull</I> for NULL indicator. Message
|
||||
constructor has 2 parameters – pointer to status wrapper and master
|
||||
interface:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>FB_MESSAGE(Output,
|
||||
creates two data members in the message – </FONT><FONT SIZE=4><I>name</I></FONT><FONT SIZE=4>
|
||||
for field/parameter value and </FONT><FONT SIZE=4><I>nameNull</I></FONT><FONT SIZE=4>
|
||||
for NULL indicator. Message constructor has 2 parameters – pointer
|
||||
to status wrapper and master interface:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FB_MESSAGE(Output,
|
||||
ThrowStatusWrapper,</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_SMALLINT,
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_SMALLINT,
|
||||
relationId)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_CHAR(31),
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_CHAR(31),
|
||||
relationName)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_VARCHAR(100),
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_VARCHAR(100),
|
||||
description)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>)
|
||||
output(&status, master);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>) output(&status,
|
||||
master);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>For static messages use of
|
||||
FB_MESSAGE is sooner of all the best choice – they can be at the
|
||||
same time easily passed to execute, openCursor and fetch methods:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>rs =
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>rs =
|
||||
att->openCursor(&status, tra, 0, sqlText,</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>SQL_DIALECT_V6,
|
||||
NULL, NULL, output.getMetadata(), NULL, 0);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>SQL_DIALECT_V6, NULL,
|
||||
NULL, output.getMetadata(), NULL, 0);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>and used to work with
|
||||
values of individual fields:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>while
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while
|
||||
(rs->fetchNext(&status, output.getData()) ==
|
||||
IStatus::RESULT_OK)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>printf("%4d
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>printf("%4d
|
||||
%31.31s %*.*s\n", output->relationId,
|
||||
output->relationName.str,</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>output->descriptionNull
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>output->descriptionNull
|
||||
? 0 : output->description.length,</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>output->descriptionNull
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>output->descriptionNull
|
||||
? 0 : output->description.length, output->description.str);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>An example of using macro
|
||||
@ -663,9 +663,8 @@ blobFieldNumber)];</I></FONT></P>
|
||||
and FB_MESSAGE macro blob field is declared as having FB_BLOB type:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FB_MESSAGE(Msg,
|
||||
ThrowStatusWrapper,</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_BLOB,
|
||||
b)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>) message(&status,
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_BLOB, b)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>) message(&status,
|
||||
master);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>ISC_QUAD* blobPtr =
|
||||
&message->b;</I></FONT></P>
|
||||
@ -687,7 +686,7 @@ engine:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>unsigned segmentLength;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while
|
||||
(userFunctionProvidingBlobData(&segmentData, &segmentLength))</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>blob->putSegment(&status,
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>blob->putSegment(&status,
|
||||
segmentLength, segmentData);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>After sending some data to
|
||||
blob do not forget to close blob interface:</FONT></P>
|
||||
@ -707,32 +706,30 @@ may be done using fetch() or execute() methods. After it use
|
||||
openBlob() attachment's method:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I><A HREF="#Blob">IBlob</A>*
|
||||
blob = att->openBlob(status, tra, blobPtr, 0, NULL);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Blob interface is ready
|
||||
to provide blob data. Use getSegment() method to receive data from
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Blob interface is ready to
|
||||
provide blob data. Use getSegment() method to receive data from
|
||||
engine:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>char buffer[BUFSIZE];</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>unsigned actualLength;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>for(;;)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>switch
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>switch
|
||||
(blob->getSegment(&status, sizeof(buffer), buffer,
|
||||
&actualLength))</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>case
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>case
|
||||
IStatus::RESULT_OK:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in">
|
||||
<FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer, actualLength,
|
||||
true);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>continue;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>case
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer,
|
||||
actualLength, true);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>continue;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>case
|
||||
IStatus::RESULT_SEGMENT:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in">
|
||||
<FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer, actualLength,
|
||||
false);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>continue;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>default:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>break;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer,
|
||||
actualLength, false);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>continue;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>default:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>break;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Last parameter in
|
||||
userFunctionAcceptingBlobData() is a flag that end of segment is
|
||||
@ -751,23 +748,25 @@ completed in FB3, we expect to have something more interesting in
|
||||
next version. The minimum existing support is as follows: <A HREF="#Attachment">IAttachment</A>
|
||||
contains call queEvents() which performs almost same functions as
|
||||
isc_que_events() call. Instead the pair of parameters
|
||||
<I>FPTR_EVENT_CALLBACK ast</I> and <I>void* arg</I>, required to
|
||||
invoke user code when event happens in firebird engine, callback
|
||||
interface IEventCallback is used. This is traditional approach which
|
||||
helps to avoid non-safe casts from void* in user function. Another
|
||||
important difference is that instead event identifier (a kind of
|
||||
handler) this function returns reference counted interface <A HREF="#Events">IEvents</A>
|
||||
having method cancel() used when waiting for event should be stopped.
|
||||
Unlike identifier which is automatically destroyed when event arrives
|
||||
</FONT><FONT SIZE=4><I>FPTR_EVENT_CALLBACK ast</I></FONT><FONT SIZE=4>
|
||||
and </FONT><FONT SIZE=4><I>void* arg</I></FONT><FONT SIZE=4>,
|
||||
required to invoke user code when event happens in firebird engine,
|
||||
callback interface IEventCallback is used. This is traditional
|
||||
approach which helps to avoid non-safe casts from void* in user
|
||||
function. Another important difference is that instead event
|
||||
identifier (a kind of handler) this function returns reference
|
||||
counted interface <A HREF="#Events">IEvents</A> having method
|
||||
cancel() used when waiting for event should be stopped. Unlike
|
||||
identifier which is automatically destroyed when event arrives
|
||||
interface can not be automatically destroyed – in case when event
|
||||
is received right before canceling interface call to cancel() would
|
||||
cause segfault when interface is already destroyed. Therefore
|
||||
interface <A HREF="#Events">IEvents</A> must be explicitly released
|
||||
after receiving an event. This may be done for example right before
|
||||
queuing for an event next time:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>events->release();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>events = NULL;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>events =
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>events->release();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>events = NULL;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>events =
|
||||
attachment->queEvents(&status, this, eveLen, eveBuffer);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Setting interface pointer
|
||||
to NULL is useful in case of exception during queEvents. In other
|
||||
@ -780,7 +779,7 @@ use for additional details our sample 08.events.cpp. </FONT>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>To begin to use services
|
||||
one should first of all connect to service manager. This is done
|
||||
using attachServiceManager() method of <A HREF="#Provider">IProvider</A>.
|
||||
This method returns <A HREF="#Service">IService</A> interface which
|
||||
This method returns <A HREF="#Service">IService</A> interface which
|
||||
is used later to talk to service. To prepare SPB to attach to service
|
||||
manager one can use IXpbBuilder:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IXpbBuilder* spb1 =
|
||||
@ -830,7 +829,7 @@ spb2->getBufferLength(&status), spb2->getBuffer(&status));</FONT><
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Many started services
|
||||
(including mentioned here gstat) return text information during
|
||||
execution. To display it one should query started service anout that
|
||||
information line by line. This is done by calling query() method of
|
||||
information line by line. This is done by calling query() method of
|
||||
<A HREF="#Service">IService</A> interface with appropriate send and
|
||||
receive blocks of parameters. Send block may contain various helper
|
||||
information (like timeout when querying service) or information to be
|
||||
@ -848,7 +847,7 @@ steps we are ready to query service in a loop (each line returned in
|
||||
a single call to query()):</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>do</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>svc->query(&status,
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>svc->query(&status,
|
||||
0, NULL, sizeof(receiveItems1), receiveItems1, sizeof(results),
|
||||
results);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>} while
|
||||
@ -890,13 +889,13 @@ services tasks do not forget to close an interface:</FONT></P>
|
||||
<FONT FACE="Albany, sans-serif"><FONT SIZE=5>Writing plugins.</FONT></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>To write a plugin means to
|
||||
implement some interfaces and place your implementation into dynamic
|
||||
library (.dll in windows or .so in linux) later referenced as <I>plugin
|
||||
module</I> or just <I>module</I>. In most cases single plugin is
|
||||
place in dynamic library but in common case. One of that interfaces –
|
||||
<A HREF="#PluginModule">IPluginModule</A> – is module-wide (as more
|
||||
or less clear from it's name), others are per plugin. Also each
|
||||
plugin module should contain special exported entrypoint
|
||||
firebird_plugin() which name is defined in include file
|
||||
library (.dll in windows or .so in linux) later referenced as </FONT><FONT SIZE=4><I>plugin
|
||||
module</I></FONT><FONT SIZE=4> or just </FONT><FONT SIZE=4><I>module</I></FONT><FONT SIZE=4>.
|
||||
In most cases single plugin is place in dynamic library but in common
|
||||
case. One of that interfaces – <A HREF="#PluginModule">IPluginModule</A>
|
||||
– is module-wide (as more or less clear from it's name), others are
|
||||
per plugin. Also each plugin module should contain special exported
|
||||
entrypoint firebird_plugin() which name is defined in include file
|
||||
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>In previous part of this
|
||||
text we were mostly describing how to use existing interfaces, here
|
||||
@ -915,12 +914,13 @@ sample yourself and learn it when reading later.</FONT></P>
|
||||
</P>
|
||||
<H1><FONT SIZE=4>Implementation of plugin module.</FONT></H1>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Plugins actively interact
|
||||
with special firebird component called <I>plugin manager</I>. In
|
||||
particular plugin manager should be aware what plugin modules were
|
||||
loaded and must be notified if operating system tries to unload one
|
||||
of that modules without explicit plugin manager command (this may
|
||||
happen first of all when using embedded access – when exit() is
|
||||
called in a program or main firebird library <I><SPAN STYLE="font-weight: normal">fbclient</SPAN></I>
|
||||
with special firebird component called </FONT><FONT SIZE=4><I>plugin
|
||||
manager</I></FONT><FONT SIZE=4>. In particular plugin manager should
|
||||
be aware what plugin modules were loaded and must be notified if
|
||||
operating system tries to unload one of that modules without explicit
|
||||
plugin manager command (this may happen first of all when using
|
||||
embedded access – when exit() is called in a program or main
|
||||
firebird library </FONT><FONT SIZE=4><I><SPAN STYLE="font-weight: normal">fbclient</SPAN></I></FONT><FONT SIZE=4>
|
||||
is unloaded). Primary task of IPluginModule interface is that
|
||||
notification. First of all one must decide - how to detect that
|
||||
module is going to be unloaded? When dynamic library is unloaded for
|
||||
@ -943,44 +943,38 @@ looks as follows:</FONT></P>
|
||||
public IPluginModuleImpl<PluginModule, CheckStatusWrapper></I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>private:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IPluginManager*
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IPluginManager*
|
||||
pluginManager;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>PluginModule()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>:
|
||||
pluginManager(NULL)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{ }</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>PluginModule()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>: pluginManager(NULL)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{ }</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>~PluginModule()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>if
|
||||
(pluginManager)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in">
|
||||
<FONT SIZE=4><I>pluginManager->unregisterModule(this);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>doClean();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>~PluginModule()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>if (pluginManager)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager->unregisterModule(this);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>doClean();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void
|
||||
registerMe(IPluginManager* m)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>pluginManager =
|
||||
m;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in">
|
||||
<FONT SIZE=4><I>pluginManager->registerModule(this);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager = m;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager->registerModule(this);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void doClean()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>pluginManager
|
||||
= NULL;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void doClean()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager = NULL;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
@ -989,15 +983,15 @@ plugin manager interface <A HREF="#PluginManager">IPluginManager</A>.
|
||||
It's passed to registerModule() function and saved in private
|
||||
variable, at the same time module is registered in plugin manager by
|
||||
the call to registerModule() method with own address as a single
|
||||
parameter. Variable <I>pluginManager </I>not only stores pointer to
|
||||
interface, at the same time it serves as a flag that module is
|
||||
registered. When destructor of registered module is invoked it
|
||||
notifies plugin manager (yes, this is what for this class exists!)
|
||||
about unexpected unload by the call to unregisterModule() passing
|
||||
pointer to itself. When plugin manager is going to unload module in
|
||||
regular way in first of all calls doClean() method changing module
|
||||
state to unregistered and this avoiding call to unregisterModule()
|
||||
when OS performs actual unload.</FONT></P>
|
||||
parameter. Variable </FONT><FONT SIZE=4><I>pluginManager </I></FONT><FONT SIZE=4>not
|
||||
only stores pointer to interface, at the same time it serves as a
|
||||
flag that module is registered. When destructor of registered module
|
||||
is invoked it notifies plugin manager (yes, this is what for this
|
||||
class exists!) about unexpected unload by the call to
|
||||
unregisterModule() passing pointer to itself. When plugin manager is
|
||||
going to unload module in regular way in first of all calls doClean()
|
||||
method changing module state to unregistered and this avoiding call
|
||||
to unregisterModule() when OS performs actual unload.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Implementing plugin's
|
||||
@ -1031,13 +1025,13 @@ non-existent type SomePlugin):</FONT></P>
|
||||
ISomePluginImpl<MyPlugin, CheckStatusWrapper></I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>explicit
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>explicit
|
||||
MyPlugin(<A HREF="#PluginConfig">IPluginConfig</A>* cnf) throw()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>:
|
||||
config(cnf), refCounter(0), owner(NULL)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>config->addRef();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>: config(cnf),
|
||||
refCounter(0), owner(NULL)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>config->addRef();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Constructor
|
||||
gets as parameter plugin configuration interface. If you are going to
|
||||
have you plugin configured in some way it's good idea to save this
|
||||
@ -1047,74 +1041,67 @@ familiar configuration and minimize code written. Certainly when
|
||||
saving any reference counted interface it's better not forget to add
|
||||
reference to it. Also set reference counter to 0 and plugin owner to
|
||||
NULL.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>~MyPlugin()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>config->release();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>~MyPlugin()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>config->release();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Destructor
|
||||
releases config interface. Pay attention – we do not change
|
||||
reference counter of our owner cause it owns us, not we own it.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// IRefCounted
|
||||
implementation</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>int release()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>if
|
||||
(--refCounter == 0)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>delete
|
||||
this;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return
|
||||
0;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return
|
||||
1;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void addRef()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>++refCounter;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// IRefCounted
|
||||
implementation</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>int release()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>if (--refCounter == 0)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>delete this;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return 0;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return 1;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void addRef()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>++refCounter;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Absolutely
|
||||
typical implementation of reference counted object.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// IPluginBase
|
||||
implementation</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void
|
||||
setOwner(IReferenceCounted* o)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>owner =
|
||||
o;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IReferenceCounted*
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// IPluginBase
|
||||
implementation</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void
|
||||
setOwner(IReferenceCounted* o)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>owner = o;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IReferenceCounted*
|
||||
getOwner()</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return
|
||||
owner;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return owner;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>As it
|
||||
was promised implementation of IPluginBase is trivial.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// ISomePlugin
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// ISomePlugin
|
||||
implementation</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// … here go
|
||||
various methods required for particular plugin type</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// … here go various
|
||||
methods required for particular plugin type</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>private:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IPluginConfig*
|
||||
config;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>FbSampleAtomic
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IPluginConfig* config;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FbSampleAtomic
|
||||
refCounter;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IReferenceCounted*
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IReferenceCounted*
|
||||
owner;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
@ -1134,17 +1121,17 @@ manager. Factory typically looks this way:</FONT></P>
|
||||
IPluginFactoryImpl<Factory, CheckStatusWrapper></I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IPluginBase*
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IPluginBase*
|
||||
createPlugin(CheckStatusWrapper* status, IPluginConfig*
|
||||
factoryParameter)</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>MyPlugin* p =
|
||||
new MyPlugin(factoryParameter);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>p->addRef();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return p;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>MyPlugin* p = new
|
||||
MyPlugin(factoryParameter);</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>p->addRef();</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return p;</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Here
|
||||
attention should be payed to the fact that even in a case when code
|
||||
@ -1182,13 +1169,12 @@ plugin manager:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>extern "C" void
|
||||
FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>IPluginManager*
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>IPluginManager*
|
||||
pluginManager = master->getPluginManager();</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>module.registerMe(pluginManager);</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in">
|
||||
<FONT SIZE=4>pluginManager->registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>module.registerMe(pluginManager);</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>pluginManager->registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
|
||||
"DbCrypt_example", &factory);</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>}</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>First of all we call
|
||||
@ -1396,39 +1382,38 @@ objects:</FONT></P>
|
||||
</OL>
|
||||
<P STYLE="margin-bottom: 0in"><A NAME="Directory codes"></A><FONT SIZE=4>Directory
|
||||
codes:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_BIN – bin
|
||||
(utilities like isql, gbak, gstat)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SBIN – sbin
|
||||
(fbguard and firebird server)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_CONF –
|
||||
configuration files (firebird.conf, databases.conf, plugins.conf)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_LIB – lib
|
||||
(fbclient, ib_util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_INC – include
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_BIN – bin (utilities
|
||||
like isql, gbak, gstat)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SBIN – sbin (fbguard
|
||||
and firebird server)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_CONF – configuration
|
||||
files (firebird.conf, databases.conf, plugins.conf)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_LIB – lib (fbclient,
|
||||
ib_util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_INC – include
|
||||
(ibase.h, firebird/Interfaces.h)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_DOC -
|
||||
documentation</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_UDF – UDF
|
||||
(ib_udf, fbudf)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SAMPLE - samples</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SAMPLEDB –
|
||||
samples database (employee.fdb)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_HELP – qli help
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_DOC - documentation</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_UDF – UDF (ib_udf,
|
||||
fbudf)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SAMPLE - samples</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SAMPLEDB – samples
|
||||
database (employee.fdb)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_HELP – qli help
|
||||
(help.fdb)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_INTL –
|
||||
international libraries (fbintl)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_MISC –
|
||||
miscellaneous files (like uninstall manifest and something else)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SECDB – where
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_INTL – international
|
||||
libraries (fbintl)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_MISC – miscellaneous
|
||||
files (like uninstall manifest and something else)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SECDB – where
|
||||
security database is stored (securityN.fdb)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_MSG – where
|
||||
messages file is stored (firebird.msg)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_LOG – where log
|
||||
file is stored (firebird.log)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_GUARD – where
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_MSG – where messages
|
||||
file is stored (firebird.msg)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_LOG – where log file
|
||||
is stored (firebird.log)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_GUARD – where
|
||||
guardian lock is stored (fb_guard)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_PLUGINS –
|
||||
plugins directory ([lib]Engine13.{dll|so})</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_PLUGINS – plugins
|
||||
directory ([lib]Engine13.{dll|so})</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
@ -1757,15 +1742,15 @@ interface – API of plugin manager.</FONT></P>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Constants defined by
|
||||
PluginManager interface (plugin types):</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_PROVIDER</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_AUTH_SERVER</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_AUTH_CLIENT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_AUTH_USER_MANAGEMENT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_EXTERNAL_ENGINE</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_TRACE</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_WIRE_CRYPT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_DB_CRYPT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_KEY_HOLDER</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_PROVIDER</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_AUTH_SERVER</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_AUTH_CLIENT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_AUTH_USER_MANAGEMENT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_EXTERNAL_ENGINE</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_TRACE</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_WIRE_CRYPT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_DB_CRYPT</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_KEY_HOLDER</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
@ -1966,7 +1951,7 @@ Statement interface:</FONT></P>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>IAttachment::prepare()
|
||||
flags:</FONT></P>
|
||||
<P STYLE="margin-left: 0.38in; text-indent: -0.01in; margin-bottom: 0in; page-break-before: auto">
|
||||
<P STYLE="margin-left: 0.38in; text-indent: -0.01in; margin-bottom: 0in; page-break-before: auto; page-break-after: auto">
|
||||
<FONT SIZE=4>PREPARE_PREFETCH_NONE – constant to pass no flags, 0
|
||||
value.</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>The following flags may be
|
||||
@ -2088,8 +2073,8 @@ moment when given timer should alarm.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
|
||||
start(StatusType* status, ITimer* timer, ISC_UINT64 microSeconds) –
|
||||
start <A HREF="#Timer">ITimer</A> to alarm after given delay (in
|
||||
microseconds, 10<SUP>-6</SUP> seconds). Timer will be waked up only
|
||||
once after this call.</FONT></P>
|
||||
microseconds, 10</FONT><SUP><FONT SIZE=4>-6</FONT></SUP><FONT SIZE=4>
|
||||
seconds). Timer will be waked up only once after this call.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void stop(StatusType*
|
||||
status, ITimer* timer) – stop <A HREF="#Timer">ITimer</A>. It's
|
||||
not an error to stop not started timer thus avoiding problems with
|
||||
@ -2190,7 +2175,8 @@ interface – various helper methods required here or there.</FONT></P>
|
||||
unsigned fractions) – replaces isc_encode_sql_time().</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned
|
||||
formatStatus(char* buffer, unsigned bufferSize, IStatus* status) –
|
||||
replaces fb_interpret().</FONT></P>
|
||||
replaces fb_interpret(). Size of buffer, passed into this method,
|
||||
should not be less than 50 bytes.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned
|
||||
getClientVersion() – returns integer, containing major version in
|
||||
byte 0 and minor version in byte 1.</FONT></P>
|
||||
@ -2311,13 +2297,13 @@ be selected by firebird and passed to that interface.</FONT></P>
|
||||
<OL>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
|
||||
setSymmetric(StatusType* status, const char* type, unsigned
|
||||
keyLength, const void* key) – make it store symmetric key of
|
||||
given type.</FONT></P>
|
||||
keyLength, const void* key) – make it store symmetric key of given
|
||||
type.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
|
||||
setAsymmetric(StatusType* status, const char* type, unsigned
|
||||
encryptKeyLength, const void* encryptKey, unsigned decryptKeyLength,
|
||||
const void* decryptKey) – make it store pair of asymmetric keys of
|
||||
given type.</FONT></P>
|
||||
given type.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>const void*
|
||||
getEncryptKey(unsigned* length) – get a key for encryption.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>const void*
|
||||
@ -2502,7 +2488,7 @@ interface:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><A NAME="IntUserField"></A><FONT SIZE=4>IntUserField
|
||||
interface:</FONT></P>
|
||||
<OL>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>int get() - get
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>int get() - get
|
||||
field's value.</FONT></P>
|
||||
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void set(StatusType*
|
||||
status, int newValue) – assigns value to the field. Sets entered
|
||||
@ -2663,7 +2649,7 @@ plugin or key holder plugin.</FONT></P>
|
||||
bufferLength, void* buffer) – when performing callback information
|
||||
is passed in both directions. The source of a key receives
|
||||
dataLength bytes of data and may send up to bufferLength bytes into
|
||||
buffer returning actual number of bytes placed into buffer.</FONT></P>
|
||||
buffer returning actual number of bytes placed into buffer.</FONT></P>
|
||||
</OL>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
@ -2737,40 +2723,40 @@ static messages.</FONT></P>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><A NAME="FbDate"></A><FONT SIZE=4>class
|
||||
FbDate methods:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void decode(IUtil*
|
||||
util, unsigned* year, unsigned* month, unsigned* day)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned
|
||||
getYear(IUtil* util) </FONT>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>void decode(IUtil* util,
|
||||
unsigned* year, unsigned* month, unsigned* day)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getYear(IUtil*
|
||||
util) </FONT>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned
|
||||
getMonth(IUtil* util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned getDay(IUtil*
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getMonth(IUtil*
|
||||
util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void encode(IUtil*
|
||||
util, unsigned year, unsigned month, unsigned day)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getDay(IUtil*
|
||||
util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>void encode(IUtil* util,
|
||||
unsigned year, unsigned month, unsigned day)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><A NAME="FbTime"></A><FONT SIZE=4>class
|
||||
FbTime methods:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void decode(IUtil*
|
||||
util, unsigned* hours, unsigned* minutes, unsigned* seconds,
|
||||
unsigned* fractions)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned
|
||||
getHours(IUtil* util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned
|
||||
getMinutes(IUtil* util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned
|
||||
getSeconds(IUtil* util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>void decode(IUtil* util,
|
||||
unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned*
|
||||
fractions)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getHours(IUtil*
|
||||
util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getMinutes(IUtil*
|
||||
util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getSeconds(IUtil*
|
||||
util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned
|
||||
getFractions(IUtil* util)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void encode(IUtil*
|
||||
util, unsigned hours, unsigned minutes, unsigned seconds, unsigned
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>void encode(IUtil* util,
|
||||
unsigned hours, unsigned minutes, unsigned seconds, unsigned
|
||||
fractions)</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>class FbTimestamp members:</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>FbDate date;</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>FbTime time;</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>FbDate date;</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>FbTime time;</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
@ -2785,7 +2771,7 @@ fields. </FONT>
|
||||
<P STYLE="margin-bottom: 0in"><A NAME="FbChar"></A><FONT SIZE=4>struct
|
||||
FbChar</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>char str[N];</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>char str[N];</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>};</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
@ -2793,10 +2779,9 @@ FbChar</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><A NAME="FbVarChar"></A><FONT SIZE=4>struct
|
||||
FbVarChar</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>ISC_USHORT length;</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>char str[N];</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void set(const char*
|
||||
s);</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>ISC_USHORT length;</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>char str[N];</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>void set(const char* s);</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>};</FONT></P>
|
||||
<P STYLE="margin-bottom: 0in"><BR>
|
||||
</P>
|
||||
|
Loading…
Reference in New Issue
Block a user