2016-02-24 16:32:57 +01:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2017-01-31 15:38:53 +01:00
< html >
< head >
< meta http-equiv = "content-type" content = "text/html; charset=utf-8" / >
< title > < / title >
2018-05-10 17:18:24 +02:00
< meta name = "generator" content = "LibreOffice 5.4.5.1 (Linux)" / >
2017-01-31 15:38:53 +01:00
< meta name = "author" content = "alex " / >
2018-05-10 17:18:24 +02:00
< meta name = "created" content = "2013-05-31T00:00:00.010003100" / >
< meta name = "changed" content = "2018-05-10T18:16:59.126724786" / >
< meta name = "created" content = "00:00:00" >
2017-10-23 16:10:49 +02:00
< meta name = "created" content = "00:00:00" >
< meta name = "created" content = "00:00:00" >
< meta name = "created" content = "00:00:00" >
< meta name = "created" content = "00:00:00" >
2017-10-17 12:16:29 +02:00
< meta name = "created" content = "00:00:00" >
2017-01-31 15:38:53 +01:00
< style type = "text/css" >
2017-10-17 12:16:29 +02:00
@page { size: 21.59cm 27.94cm; margin: 2.01cm }
2017-01-31 15:38:53 +01:00
h1 { color: #000000 }
2017-10-17 12:16:29 +02:00
p { margin-bottom: 0.2cm; color: #000000 }
2017-01-31 15:38:53 +01:00
< / style >
< / head >
< body lang = "en-US" text = "#000000" dir = "ltr" >
2017-10-17 12:16:29 +02:00
< p style = "margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid" >
2017-01-31 15:38:53 +01:00
< font face = "Albany, sans-serif" > < font size = "5" style = "font-size: 18pt" > Firebird
interfaces.< / font > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Firebird's
2017-01-31 15:38:53 +01:00
OO API is based on use of interfaces. That interfaces, though looking
in some aspects like OLE2 interfaces (some of them have addRef() and
release() methods) are non standard and have features, missing in
other widely used types of interfaces. First of all Firebird
interfaces are < / font > < font size = "4" style = "font-size: 14pt" > < b > language
independent< / b > < / font > – < font size = "4" style = "font-size: 14pt" > that
2016-02-26 17:10:48 +01:00
means that to define/use them one need not use language specific
2017-01-31 15:38:53 +01:00
constructions like < / font > < font size = "4" style = "font-size: 14pt" > < i > class< / i > < / font >
< font size = "4" style = "font-size: 14pt" > in C++, interface may be
2018-05-10 17:18:24 +02:00
defined using any language able to call functions using C calling
conventions and having concepts of array and pointer to
procedure/function. Next interfaces are < / font > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > < b > versioned< / b > < / span > < / font > < / span >
2017-01-31 15:38:53 +01:00
– < font size = "4" style = "font-size: 14pt" > i.e. we support different
versions of same interface. Binary layout of interfaces is designed
to support that features very efficient (there is no need in
additional virtual calls like in OLE2/COM with it's < / font > < strong > < font size = "4" style = "font-size: 14pt" > < span style = "font-weight: normal" > QueryInterface< / span > < / font > < / strong > < strong > < font size = "4" style = "font-size: 14pt" > )< / font > < / strong > < strong >
< / strong > < strong > < font size = "4" style = "font-size: 14pt" > < span style = "font-weight: normal" > but
2016-02-26 17:10:48 +01:00
it's not convenient for direct use from most languages. Therefore
2016-02-24 16:32:57 +01:00
language-specific wrappers should better be designed for different
languages making use of API easier. Currently we have wrappers for
C++ and Pascal, Java is coming soon. From end-user POV calls from C++
and Pascal have absolutely no difference, though some additional
2016-04-07 18:45:09 +02:00
language-specific features present in C++ (like ability to turn off
2017-01-31 15:38:53 +01:00
automatic status check after API calls) are missing in Pascal.< / span > < / font > < / strong > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-weight: normal" > < font size = "4" style = "font-size: 14pt" > Typically
2016-02-24 16:32:57 +01:00
database API is used to access data stored in database. Firebird OO
API certainly performs this task but in addition it supports writing
2017-01-31 15:38:53 +01:00
your own < / font > < font size = "4" style = "font-size: 14pt" > < b > plugins< / b > < / font >
– < font size = "4" style = "font-size: 14pt" > modules, making it
possible to enhance Firebird capabilities according to your needs.
Therefore this document contains 2 big parts – accessing databases
and writing plugins. Certainly some interfaces (like status vector)
are used in both parts of API, they will be discussed in data access
part and freely referenced later when discussing plugins. Therefore
even if you plan to write some plugin you should better start with
the first part of this document. Moreover a lot of plugins need to
access databases themselves and data access API is typically needed
for it.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "result_box" > < / a > < font size = "4" style = "font-size: 14pt" > < span style = "font-weight: normal" > Firebird
2016-02-24 16:32:57 +01:00
installation package contains a number of live samples of use of OO
API – they are in examples/interfaces (database access) and
2017-01-31 15:38:53 +01:00
examples/dbcrypt (plugin performing < / span > < / font > < font size = "4" style = "font-size: 14pt" > < span lang = "en-US" > fictitious
database encryption< / span > < / font > < font size = "4" style = "font-size: 14pt" > < span style = "font-weight: normal" > )
2016-02-25 02:07:40 +01:00
directories. It's supposed that the reader is familiar with ISC API
2017-01-31 15:38:53 +01:00
used in Firebird since interbase times.< / span > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < span style = "font-weight: normal" > This
2016-04-07 18:45:09 +02:00
document does not pretend to be a full Firebird 3 documentation –
it just describes new object oriented API, and a reader should be
familiar with main Firebird concepts, knowledge about ISC API is also
much welcome. For example – when describing how to work with
services there is no explanation what is service and why is it
2017-01-31 15:38:53 +01:00
needed, only description of how to obtain < a href = "#Service" > IService< / a >
2016-04-07 18:45:09 +02:00
interface and how to use it. Also pay attention that samples of code
do not use a lot of powerful features of C++. Not used reference
2016-05-10 16:55:13 +02:00
counted pointers, not used other RAII holders, not used templates
2016-04-07 18:45:09 +02:00
(except one present in firebird public headers), etc. Primary goal is
to make this text usable not only to C++ people because our API is
oriented to support not only C++ but other, more simple languages
2017-01-31 15:38:53 +01:00
too.< / span > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid" >
2017-01-31 15:38:53 +01:00
< font face = "Albany, sans-serif" > < font size = "5" style = "font-size: 18pt" > Accessing
databases.< / font > < / font > < / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Creating database and
attaching to existing database.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > First
2017-01-31 15:38:53 +01:00
of all we need to get access to < b > IMaster< / b > interface. IMaster is
primary Firebird interface, required to access all the rest of
interfaces. Therefore there is a special way of accessing it – the
only one needed to use OO API plain function called
fb_get_master_interface(). This function has no parameters and always
succeeds. There is one and only one instance of IMaster per Firebird
client library, therefore one need not care about releasing memory,
used by master interface. A simplest way to access it from your
program is to have appropriate global or static variable:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > static
2017-01-31 15:38:53 +01:00
< a href = "#Master" > IMaster< / a > * master = fb_get_master_interface();< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > For
2017-01-31 15:38:53 +01:00
a lot of methods, used in Firebird API, first parameter is < b > IStatus< / b >
interface. It's a logical replacement of ISC_STATUS_ARRAY, but works
separately with errors and warnings (not mixing them in same array),
can contain unlimited number of errors inside and (this will be
important if you plan to implement IStatus yourself) always keeps
strings, referenced by it, inside interface. Typically you need at
least one instance of IStatus to call other methods. You obtain it
from IMaster:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#Status" > IStatus< / a > *
2017-01-31 15:38:53 +01:00
st = master-> getStatus();< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > If
2017-01-31 15:38:53 +01:00
method getStatus() fails for some reason (OOM for example) it returns
NULL – obviously we can't use generic error reporting method which
is based on use of IStatus here.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Now
2017-01-31 15:38:53 +01:00
we are going to deal with first interface, directly related to
database calls. This is < a href = "#Provider" > IProvider< / a > –
interface called this way cause it's exactly that interface that must
be implemented by any provider in Firebird. Firebird client library
also has it's own implementation of IProvider, which must be used to
start any database activity. To obtain it we call IMaster's method:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IProvider*
2017-01-31 15:38:53 +01:00
prov = master-> getDispatcher();< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > When
2017-01-31 15:38:53 +01:00
attaching to existing database or moreover creating new one it's
often necessary to pass a lot of additional parameters
(logon/password, page size for new database, etc.) to API call.
Having separate language-level parameters is close to unreal – we
will have to modify a call too often to add new parameters, and
number of them will be very big no matter of the fact that typically
one needs to pass not too much of them. Therefore to pass additional
parameters special in-memory data structure, called < / font > < font size = "4" style = "font-size: 14pt" > < i > database
parameters block< / i > < / font > < font size = "4" style = "font-size: 14pt" > (DPB)
is used. Format of it is well defined, and it's possible to build DPB
byte after byte. But it's much easier to use special interface
< / font > < a href = "#XpbBuilder" > < font size = "4" style = "font-size: 14pt" > < b > IXpbBuilder< / b > < / font > < / a > < font size = "4" style = "font-size: 14pt" > ,
2016-02-26 17:10:48 +01:00
which simplifies creation of various parameters blocks. To obtain an
instance of IXpbBuilder you must know one more generic-use interface
2017-01-31 15:38:53 +01:00
of firebird API – < / font > < a href = "#Util" > < font size = "4" style = "font-size: 14pt" > < b > IUtil< / b > < / font > < / a > < font size = "4" style = "font-size: 14pt" > .
2016-02-26 17:10:48 +01:00
It's a kind of placeholder for the calls that do not fit well in
2017-01-31 15:38:53 +01:00
other places. So we do< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IUtil*
2017-01-31 15:38:53 +01:00
utl = master-> getUtilInterface();< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IXpbBuilder*
2017-01-31 15:38:53 +01:00
dpb = utl-> getXpbBuilder(& status, IXpbBuilder::DPB, NULL, 0);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > This
2017-01-31 15:38:53 +01:00
creates empty parameters' block builder of DPB type. Now adding
required parameter to it is trivial:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > dpb-> insertInt(& status,
2017-01-31 15:38:53 +01:00
isc_dpb_page_size, 4 * 1024);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > will
2017-01-31 15:38:53 +01:00
make firebird to create new database with pagesize equal to 4Kb and
meaning of< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > dpb-> insertString(& status,
2017-01-31 15:38:53 +01:00
isc_dpb_user_name, “sysdba”);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > dpb-> insertString(& status,
2017-01-31 15:38:53 +01:00
isc_dpb_password, “masterkey”);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > is
2017-01-31 15:38:53 +01:00
(I hope) obvious.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Status Wrapper" > < / a > < font size = "4" style = "font-size: 14pt" > < u > The
2017-01-31 15:38:53 +01:00
following is C++ specific: < / u > We are almost ready to call
2016-04-07 18:45:09 +02:00
createDatabase() method of IProvider, but before it a few words about
2017-01-31 15:38:53 +01:00
concept of < b > Status Wrapper< / b > should be said. Status wrapper is
2016-04-07 18:45:09 +02:00
not an interface, it's very thin envelope for IStatus interface. It
helps to customize behavior of C++ API (change a way how errors,
returned in IStatus interface, are processed). For the first time we
2017-01-31 15:38:53 +01:00
recommend use of < b > ThrowStatusWrapper< / b > , which raises C++
exception each time an error is returned in IStatus.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ThrowStatusWrapper
2017-01-31 15:38:53 +01:00
status(st);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Now
2017-01-31 15:38:53 +01:00
we may create new empty database:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#Attachment" > IAttachment< / a > *
2016-03-03 16:03:27 +01:00
att = prov-> createDatabase(& status, " fbtests.fdb" ,
2017-01-31 15:38:53 +01:00
dpb-> getBufferLength(& status), dpb-> getBuffer(& status));< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > printf(" Database
2017-01-31 15:38:53 +01:00
fbtests.fdb created\n" );< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Pay
2017-01-31 15:38:53 +01:00
attention that we do not check status after the call to
createDatabase(), because in case of error C++ or Pascal exception
will be raised (therefore it's very good idea to have
try/catch/except syntax in your program). We also use two new
functions from IXpbBuilder – getBufferLength() and getBuffer(),
which extract data from interface in native parameters block format.
As you can see there is no need to check explicitly for status of
functions, returning intermediate results.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Detaching
2017-01-31 15:38:53 +01:00
from just created database is trivial:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > att-> detach(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Now
2017-01-31 15:38:53 +01:00
it remains to enclose all operators into < i > try< / i > block and write a
handler in catch block. When using ThrowStatusWrapper you should
always catch defined in C++ API exception class FbException, in
Pascal you must also work with class FbException. Exception handler
block in simplest case may look this way:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > catch
2017-01-31 15:38:53 +01:00
(const FbException& error)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > char
2017-01-31 15:38:53 +01:00
buf[256];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > utl-> formatStatus(buf,
2017-01-31 15:38:53 +01:00
sizeof(buf), error.getStatus());< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > fprintf(stderr,
2017-01-31 15:38:53 +01:00
" %s\n" , buf);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Pay
2017-01-31 15:38:53 +01:00
attention that here we use one more function from < a href = "#Util" > IUtil< / a >
– formatStatus(). It returns in buffer text, describing an error
(warning), stored in IStatus parameter.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
attach to existing database just use attachDatabase() method of
IProvider instead createDatabase(). All parameters are the same for
both methods.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > att
2017-01-31 15:38:53 +01:00
= prov-> attachDatabase(& status, " fbtests.fdb" , 0,
NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > This
2017-01-31 15:38:53 +01:00
sample is using no additional DPB parameters. Take into account that
without logon/password any remote connection will fail if no trusted
2016-02-26 17:10:48 +01:00
authorization plugin is configured. Certainly login info may be also
provided in environment (in ISC_USER and ISC_PASSWORD variables) like
2017-01-31 15:38:53 +01:00
it was before.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Our
2017-01-31 15:38:53 +01:00
examples contain complete samples, dedicated except others to
creating databases – 01.create.cpp and 01.create.pas. When samples
are present it will be very useful to build and try to run
appropriate samples when reading this document.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Working with transactions.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Only
2017-01-31 15:38:53 +01:00
creating empty databases is definitely not enough to work with RDBMS.
We want to be able to create various objects (like tables and so on)
in database and insert data in that tables. Any operation within
database is performed by firebird under transaction control.
Therefore first of all we must learn to start transaction. Here we do
not discuss distributed transactions (supported by < a href = "#Dtc" > IDtc< / a >
2016-03-03 16:03:27 +01:00
interface) to avoid unneeded to most users overcomplication. Starting
of non-distributed transaction is very simple and done via attachment
2017-01-31 15:38:53 +01:00
interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#Transaction" > ITransaction< / a > *
2017-01-31 15:38:53 +01:00
tra = att-> startTransaction(& status, 0, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
this sample default transaction parameters are used – no TPB is
passed to startTransaction() method. If you need non-default
parameters you may create appropriate < a href = "#XpbBuilder" > IXpbBuilder< / a > ,
add required items to it:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#XpbBuilder" > IXpbBuilder< / a > *
2017-01-31 15:38:53 +01:00
tpb = utl-> getXpbBuilder(& status, IXpbBuilder::TPB, NULL, 0);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > tpb-> insertTag(& status,
2017-01-31 15:38:53 +01:00
isc_tpb_read_committed);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > and
2017-01-31 15:38:53 +01:00
pass resulting TPB to startTransaction():< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ITransaction*
2017-01-31 15:38:53 +01:00
tra = att-> startTransaction(& status,
tpb-> getBufferLength(& status), tpb-> getBuffer(& status));< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Transaction
2017-01-31 15:38:53 +01:00
interface is used as a parameter in a lot of other API calls but
itself it does not perform any actions except commit/rollback
transaction, may be retaining:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > tra-> commit(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > You
2017-01-31 15:38:53 +01:00
may take a look at how to start and commit transaction in examples
01.create.cpp and 01.create.pas.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Executing SQL operator
without input parameters and returned rows.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > With
2017-01-31 15:38:53 +01:00
started transaction we are ready to execute our first SQL operators.
Used for it execute() method in < a href = "#Attachment" > IAttachment< / a >
is rather universal and may be also used to execute SQL operators
with input and output parameters (which is typical for EXECUTE
PROCEDURE statement), but right now we will use the simple most form
of it. Both DDL and DML operators can be executed:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-weight: normal" > < font size = "4" style = "font-size: 14pt" > < i > att-> execute(& status,
2016-03-03 16:03:27 +01:00
tra, 0, " create table dates_table (d1 date)" ,
2017-01-31 15:38:53 +01:00
SQL_DIALECT_V6, NULL, NULL, NULL, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-weight: normal" > < font size = "4" style = "font-size: 14pt" > < i > tra-> commitRetaining(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-weight: normal" > < font size = "4" style = "font-size: 14pt" > < i > att-> execute(& status,
2016-03-03 16:03:27 +01:00
tra, 0, " insert into dates_table values (CURRENT_DATE)" ,
2017-01-31 15:38:53 +01:00
SQL_DIALECT_V6, NULL, NULL, NULL, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > As
2017-01-31 15:38:53 +01:00
you can see transaction interface is a required parameter for
execute() method (must be NULL only if you execute START TRANSACTION
statement). Next follows length of SQL operator (may be zero causing
use of C rules to determine string length), text of operator and SQL
dialect that should be used for it. The following for NULLs stand for
metadata descriptions and buffers of input parameters and output
data. Complete description of this method is provided in < a href = "#Attachment" > IAttachment< / a >
interface.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > You
2017-01-31 15:38:53 +01:00
may take a look at how to start and commit transaction in examples
01.create.cpp and 01.create.pas.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Executing SQL operator
with input parameters.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > There
2017-01-31 15:38:53 +01:00
are 2 ways to execute statement with input parameters. Choice of
correct method depends upon do you need to execute it more than once
and do you know in advance format of parameters. When that format is
known and statement is needed to be run only once single call to
2016-03-03 16:03:27 +01:00
IAttachment::execute() may be used. In other cases SQL statement
should be prepared first and after it executed, may be many times
2017-01-31 15:38:53 +01:00
with different parameters.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
prepare SQL statement for execution use prepare() method of
< a href = "#Attachment" > IAttachment< / a > interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#Statement" > IStatement< / a > *
2016-03-03 16:03:27 +01:00
stmt = att-> prepare(& status, tra, 0, “UPDATE department SET
2017-01-31 15:38:53 +01:00
budget = ? * budget + budget WHERE dept_no = ?”,< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > SQL_DIALECT_V6,
2017-01-31 15:38:53 +01:00
IStatement::PREPARE_PREFETCH_METADATA);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > If
2017-01-31 15:38:53 +01:00
you are not going to use parameters description from firebird (i.e.
you can provide that information yourself) please use
IStatement::PREPARE_PREFETCH_NONE instead PREPARE_PREFETCH_METADATA –
this will save client/server traffic and server resources a bit.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
ISC API XSQLDA is used to describe format of statement parameters.
New API does not use XSQLDA – instead interface IMessageMetadata is
used. A set of input parameters (and also a row fetched from cursor)
is described in firebird API in same way and later called message.
< a href = "#MessageMetadata" > IMessageMetadata< / a > is passed as a
parameter to the methods performing message exchange between your
program and database engine. There are many ways to have an instance
of IMessageMetadata – one can:< / font > < / p >
< ul >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > get
2017-01-31 15:38:53 +01:00
it from < a href = "#Statement" > IStatement< / a > ,< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > build
2017-01-31 15:38:53 +01:00
using < a href = "#MetadataBuilder" > IMetadataBuilder< / a > interface,< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > have
2017-01-31 15:38:53 +01:00
your own implementation of this interface.< / font > < / p >
< / ul >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Getting
2017-01-31 15:38:53 +01:00
metadata from prepared statement is very simple – method
getInputMetadata() return interface describing input message (i.e.
statement parameters), interface returned by getOutputMetadata()
describes output message (i.e. row in selected data or values
returned by procedure). In our case we can:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#MessageMetadata" > IMessageMetadata< / a > *
2017-01-31 15:38:53 +01:00
meta = stmt-> getInputMetadata(& status);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Or
2017-01-31 15:38:53 +01:00
we can build message metadata ourself. First of all we need builder
interface for it:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#MetadataBuilder" > IMetadataBuilder< / a > *
2017-01-31 15:38:53 +01:00
builder = master-> getMetadataBuilder(& status, 2);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Second
2017-01-31 15:38:53 +01:00
parameter is expected number of fields in the message, it can be
changed later, i.e. that's just an optimization.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Now
2017-01-31 15:38:53 +01:00
it's necessary to set individual fields characteristics in the
builder. An absolute minimum is field types and length for string
fields:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > builder-> setType(& status,
2017-01-31 15:38:53 +01:00
0, SQL_DOUBLE + 1);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > builder-> setType(& status,
2017-01-31 15:38:53 +01:00
1, SQL_TEXT + 1);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > builder-> setLength(& status,
2017-01-31 15:38:53 +01:00
1, 3);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > New API is using old constants
for SQL types, smallest bit as earlier stands for nullability. In
some case it may also make sense to set sub-type (for blobs),
character set (for text fields) or scale (for numeric fields). And
finally it's time to get an instance of IMessageMetadata:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#MessageMetadata" > IMessageMetadata< / a > *
2017-01-31 15:38:53 +01:00
meta = builder-> getMetadata(& status);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > Here we do not discuss in
details own implementation of IMessageMetadata. If one cares there is
a sample 05.user_metadata.cpp.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > So
2017-01-31 15:38:53 +01:00
finally we have obtained (one or another way) an instance of metadata
description of input parameters. But to work with a message we also
need buffer for it. Buffer size is one of main message metadata
characteristics and it's returned by method in IMessageMetadata:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > char*
2017-01-31 15:38:53 +01:00
buffer = new char[meta-> getMessageLength(& status)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
deal with individual values inside buffer offset to them should be
taken into an account. IMessageMetadata is aware of offsets for all
values in a message, using it we can create pointers to them:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > double*
2017-01-31 15:38:53 +01:00
percent_inc = (double*) & buffer[meta-> getOffset(& status,
0)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > char*
2017-01-31 15:38:53 +01:00
dept_no = & buffer[meta-> getOffset(& status, 1)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Also
2017-01-31 15:38:53 +01:00
let's do not forget to set to NOT NULL null flags:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > short*
2017-01-31 15:38:53 +01:00
flag = (short*)& buffer[meta-> getNullOffset(& status, 0)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > *flag
2017-01-31 15:38:53 +01:00
= 0;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > flag
2017-01-31 15:38:53 +01:00
= (short*) & buffer[meta-> getNullOffset(& status, 1)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > *flag
2017-01-31 15:38:53 +01:00
= 0;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > After
2017-01-31 15:38:53 +01:00
finishing with offsets we are ready to execute statement with some
parameters values:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > getInputValues(dept_no,
2017-01-31 15:38:53 +01:00
percent_inc);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > and
2017-01-31 15:38:53 +01:00
may execute prepared statement:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > stmt-> execute(& status,
2017-01-31 15:38:53 +01:00
tra, meta, buffer, NULL, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Two
2017-01-31 15:38:53 +01:00
more NULLs in the end of parameters stand for output message and is
used typically for EXECUTE PROCEDURE statement.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > If
2017-01-31 15:38:53 +01:00
you do not need to get metadata from statement and plan to execute it
only once you may choose a simpler way – use method execute() in
< a href = "#Attachment" > IAttachment< / a > interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > att-> execute(& status,
2016-04-07 18:45:09 +02:00
tra, 0, " UPDATE department SET budget = ? * budget + budget
2017-01-31 15:38:53 +01:00
WHERE dept_no = ?" , SQL_DIALECT_V6, meta, buffer, NULL, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
that case you do not need to use < a href = "#Statement" > IStatement< / a >
at all.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > An
2017-01-31 15:38:53 +01:00
example how to execute UPDATE with parameters is present in
02.update.cpp, you will also see how raised in trigger/procedure
exception may be caught by C++ program.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Opening cursor and
fetching data from it.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > The
2017-01-31 15:38:53 +01:00
only way to get rows of data, returned by SELECT operator, in OO API
is to use < a href = "#ResultSet" > IResultSet< / a > interface. This
interface is returned by openCursor() method in both IAttachment and
IStatement. openCursor() is in most aspects alike execute() and a
choice how to open cursor (using prepared statement or directly from
attachment interface) is the same. In the samples 03.select.cpp and
04.print_table.cpp both methods are used. Let's pay attention at one
specific openCursor() feature compared with execute() - one does not
pass buffer for output message into openCursor(), it will be passed
later when data is fetched from cursor. This makes it possible to
open cursor with unknown format of output message (NULL is passed
instead output metadata). Firebird is using in this case default
message format which may be requested from IResultSet interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > const
2017-01-31 15:38:53 +01:00
char* sql = " select * from ..." ; // some select statement< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#ResultSet" > IResultSet< / a > *
2016-04-07 18:45:09 +02:00
curs = att-> openCursor(& status, tra, 0, sql, SQL_DIALECT_V6,
2017-01-31 15:38:53 +01:00
NULL, NULL, NULL, NULL, 0);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#MessageMetadata" > IMessageMetadata< / a > *
2017-01-31 15:38:53 +01:00
meta = curs-> getMetadata(& status);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Later
2017-01-31 15:38:53 +01:00
this metadata may be used to allocate buffer for data and parse
fetched rows.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > As
2017-01-31 15:38:53 +01:00
an alternative one can first prepare statement, get metadata from
prepared statement and after it open cursor. This is preferred way if
cursor is likely to be opened > 1 times.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < a href = "#Statement" > IStatement< / a > *
2016-04-07 18:45:09 +02:00
stmt = att-> prepare(& status, tra, 0, sql, SQL_DIALECT_V6,
2017-01-31 15:38:53 +01:00
Istatement::PREPARE_PREFETCH_METADATA);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < a href = "#MessageMetadata" > IMessageMetadata< / a > *
2017-01-31 15:38:53 +01:00
meta = stmt-> getOutputMetadata(& status);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < a href = "#ResultSet" > IResultSet< / a > *
2017-01-31 15:38:53 +01:00
curs = stmt-> openCursor(& status, tra, NULL, NULL, NULL, 0);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > We
2017-01-31 15:38:53 +01:00
have obtained (one or another way) an instance of metadata
description of output fields (a row in a set). To work with a message
we also need buffer for it:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
2017-01-31 15:38:53 +01:00
char* buffer = new unsigned char[meta-> getMessageLength(& status)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IResultSet
2017-01-31 15:38:53 +01:00
has a lot of various fetch methods but when cursor is not opened with
SCROLL option only fetchNext() works, i.e. one can navigate only
forward record by record. In addition to errors and warnings in
status fetchNext() returns completion code, which may have values
RESULT_OK (when buffer is filled with values for next row) or
RESULT_NO_DATA (when no more rows left in cursor). RESULT_NO_DATA is
not error state, it's normal state after completion of the method,
but we know that data in cursor is over. If status wrapper, not
throwing exception in case of error return is used, one more value –
2016-04-07 18:45:09 +02:00
RESULT_ERROR – may be returned, that means no data in buffer and
error vector in status. Method fetchNext() is usually called in a
2017-01-31 15:38:53 +01:00
cycle:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > while
2017-01-31 15:38:53 +01:00
(curs-> fetchNext(& status, buffer) == IStatus::RESULT_OK)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > //
2017-01-31 15:38:53 +01:00
row processing< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > What
2017-01-31 15:38:53 +01:00
is done during row processing depends upon your needs. To access
particular field field's offset should be used:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
2017-01-31 15:38:53 +01:00
char* field_N_ptr = buffer + meta-> getOffset(& status, n);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > where n is the number of a
field in a message. That pointer should be casted to appropriate
type, depending upon field type. For example, for a VARCHAR field
cast to struct vary should be used:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > vary*
2017-01-31 15:38:53 +01:00
v_ptr = (vary*) (buffer + meta-> getOffset(& status, n));< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Now
2017-01-31 15:38:53 +01:00
we may print the value of a field:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > printf(“field
2017-01-31 15:38:53 +01:00
%s value is %*.*s\n”, meta-> getField(& status, n),
v_ptr-> vary_length, v_ptr-> vary_length, v_ptr-> vary_string);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > If
2017-01-31 15:38:53 +01:00
you need maximum performance it will be good idea to cache needed
metadata values like it's done in our samples 03.select.cpp and
04.print_table.cpp.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Using FB_MESSAGE macro for
static messages.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Working
2017-01-31 15:38:53 +01:00
with data using offsets is rather efficient but requires a lot of
code to be written. In C++ this problem can be solved using
templates, but even compared with them the most convenient way to
work with the message is to represent it in native (for given
language) way – structure in C/C++, record in Pascal, etc.
Certainly this works only if format of a message is known in advance.
To help building such structures in C++ firebird contains special
macro FB_MESSAGE.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_MESSAGE
2017-01-31 15:38:53 +01:00
has 3 arguments – message (struct) name, type of status wrapper and
list of fields. Usage of first and second is obvious, list of fields
contains pairs (field_type, field_name), where field_type is one of
the following:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BIGINT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BLOB< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_CHAR(len)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_DATE< / font > < / p >
2017-10-23 16:10:49 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_DECFIXED(scale)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_DECFLOAT16< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_DECFLOAT34< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_DOUBLE< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_FLOAT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_INTEGER< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_INTL_CHAR(len,
2017-01-31 15:38:53 +01:00
charSet)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_INTL_VARCHAR(len,
2017-01-31 15:38:53 +01:00
charSet)< / font > < / p >
2017-10-23 16:10:49 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_SCALED_BIGINT(scale)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_SCALED_INTEGER(scale)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_SCALED_SMALLINT(scale)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_SMALLINT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_TIME< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_TIMESTAMP< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_VARCHAR(len)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
generated by preprocessor structure integer and float types are
matched with appropriate C types, date and time – with classes
< a href = "#FbDate" > FbDate< / a > and < a href = "#FbTime" > FbTime< / a > (all
mentioned here classes are in 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 –
< / font > < font size = "4" style = "font-size: 14pt" > < i > name< / i > < / font > < font size = "4" style = "font-size: 14pt" > for
field/parameter value and < / font > < font size = "4" style = "font-size: 14pt" > < i > nameNull< / i > < / font >
< font size = "4" style = "font-size: 14pt" > for NULL indicator. Message
constructor has 2 parameters – pointer to status wrapper and master
interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > FB_MESSAGE(Output,
2017-01-31 15:38:53 +01:00
ThrowStatusWrapper,< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > (FB_SMALLINT,
2017-01-31 15:38:53 +01:00
relationId)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > (FB_CHAR(31),
2017-01-31 15:38:53 +01:00
relationName)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > (FB_VARCHAR(100),
2017-01-31 15:38:53 +01:00
description)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > )
2017-01-31 15:38:53 +01:00
output(& status, master);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > For
2017-01-31 15:38:53 +01:00
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 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > rs
2017-01-31 15:38:53 +01:00
= att-> openCursor(& status, tra, 0, sqlText,< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > SQL_DIALECT_V6,
2017-01-31 15:38:53 +01:00
NULL, NULL, output.getMetadata(), NULL, 0);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > and
2017-01-31 15:38:53 +01:00
used to work with values of individual fields:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > while
2016-04-07 18:45:09 +02:00
(rs-> fetchNext(& status, output.getData()) ==
2017-01-31 15:38:53 +01:00
IStatus::RESULT_OK)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > printf(" %4d
2016-04-07 18:45:09 +02:00
%31.31s %*.*s\n" , output-> relationId,
2017-01-31 15:38:53 +01:00
output-> relationName.str,< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > output-> descriptionNull
2017-01-31 15:38:53 +01:00
? 0 : output-> description.length,< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > output-> descriptionNull
2017-01-31 15:38:53 +01:00
? 0 : output-> description.length, output-> description.str);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > An
2017-01-31 15:38:53 +01:00
example of using macro FB_MESSAGE to work with messages is in the
sample 06.fb_message.cpp.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Working with blobs.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > For
2017-01-31 15:38:53 +01:00
blobs in message buffer firebird stores blob identifier – an 8-byte
entity which should be aligned on 4-byte boundary. Identifier has
ISC_QUAD type. Interface < a href = "#Attachment" > IAttachment< / a > has 2
methods to work with blobs – openBlob() and createBlob(), both
returning interface < a href = "#Blob" > IBlob< / a > and having same set of
parameters, but performing somewhat contrary actions: openBlob()
takes blob identifier from the message and prepares blob for reading
but createBlob() creates new blob, puts it's identifier into message
and prepares blob for writing. < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
work with blobs one must first of all include blob identifier into
the message. If you get metadata from firebird engine field of
appropriate type will be already present. You just use it's offset
(assuming variable blobFieldNumber contains number of blob field)
(and appropriate null offset to check for nulls or set null flag) to
obtain pointer into the message buffer:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ISC_QUAD*
2017-01-31 15:38:53 +01:00
blobPtr = (ISC_QUAD*) & buffer[metadata-> getOffset(& status,
blobFieldNumber)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ISC_SHORT*
2017-01-31 15:38:53 +01:00
blobNullPtr = (ISC_SHORT*) & buffer[metadata-> getNullOffset(& status,
blobFieldNumber)];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > If
2017-01-31 15:38:53 +01:00
you use static messages and FB_MESSAGE macro blob field is declared
as having FB_BLOB type:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > FB_MESSAGE(Msg,
2017-01-31 15:38:53 +01:00
ThrowStatusWrapper,< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > (FB_BLOB,
2017-01-31 15:38:53 +01:00
b)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > )
2017-01-31 15:38:53 +01:00
message(& status, master);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ISC_QUAD*
2017-01-31 15:38:53 +01:00
blobPtr = & message-> b;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ISC_SHORT*
2017-01-31 15:38:53 +01:00
blobNullPtr = & message-> bNull;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
create new blob invoke createBlob() method:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#Blob" > IBlob< / a > *
2017-01-31 15:38:53 +01:00
blob = att-> createBlob(status, tra, blobPtr, 0, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Last
2017-01-31 15:38:53 +01:00
two parameters are required only if you want to use blob filters or
use stream blob, that's out of scope here.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Blob
2017-01-31 15:38:53 +01:00
interface is ready to accept data into blob. Use putSegment() method
to send data to engine:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > void*
2017-01-31 15:38:53 +01:00
segmentData;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
2017-01-31 15:38:53 +01:00
segmentLength;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > while
2017-01-31 15:38:53 +01:00
(userFunctionProvidingBlobData(& segmentData, & segmentLength))< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > blob-> putSegment(& status,
2017-01-31 15:38:53 +01:00
segmentLength, segmentData);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > After
2017-01-31 15:38:53 +01:00
sending some data to blob do not forget to close blob interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > blob-> close(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Make
2017-01-31 15:38:53 +01:00
sure that null flag is not set (not required if you nullified all
message buffer before creating blob):< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > *blobNullPtr
2017-01-31 15:38:53 +01:00
= 0;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > and
2017-01-31 15:38:53 +01:00
message, containing blob, may be used in insert or update statement.
After execution of that statement new blob will be stored in
database.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
read a blob begin with getting containing it's identifier message
from firebird engine. This may be done using fetch() or execute()
methods. After it use openBlob() attachment's method:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#Blob" > IBlob< / a > *
2017-01-31 15:38:53 +01:00
blob = att-> openBlob(status, tra, blobPtr, 0, NULL);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Blob
2017-01-31 15:38:53 +01:00
interface is ready to provide blob data. Use getSegment() method to
receive data from engine:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > char
2017-01-31 15:38:53 +01:00
buffer[BUFSIZE];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
2017-01-31 15:38:53 +01:00
actualLength;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > for(;;)< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > switch
2016-04-07 18:45:09 +02:00
(blob-> getSegment(& status, sizeof(buffer), buffer,
2017-01-31 15:38:53 +01:00
& actualLength))< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > case
2017-01-31 15:38:53 +01:00
IStatus::RESULT_OK:< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > userFunctionAcceptingBlobData(buffer,
2017-01-31 15:38:53 +01:00
actualLength, true);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > continue;< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > case
2017-01-31 15:38:53 +01:00
IStatus::RESULT_SEGMENT:< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > userFunctionAcceptingBlobData(buffer,
2017-01-31 15:38:53 +01:00
actualLength, false);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > continue;< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > default:< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > break;< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Last
2017-01-31 15:38:53 +01:00
parameter in userFunctionAcceptingBlobData() is a flag that end of
segment is reached – when getSegment() returns RESULT_SEGMENT
completion code that function is notified (by passing false as last
parameter) that segment was not read completely and continuation is
expected at next call.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > After
2017-10-23 16:10:49 +02:00
finishing with blob do not forget to close it:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > blob-> close(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
2017-10-23 16:10:49 +02:00
< / p >
< h1 > < a name = "Modifying data in a batch" > < / a > < font size = "4" style = "font-size: 14pt" > Modifying
data in a batch.< / font > < / h1 >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Since
version 4 firebird supports batch execution of statements with input
parameters – that means sending more than single set of parameters
when executing statement. < a href = "#Batch" > Batch< / a > interface is
designed (first of all) in order to satisfy JDBC requirements for
prepared statement’ s batch processing but has some serious
differences:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > -
like all operations with data in firebird it’ s oriented on
messages, not single field;< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > -
as an important extension out batch interface supports inline use of
blobs (specially efficient when working with small blobs);< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > -
execute() method returns not plain array of integers but special
< a href = "#BatchCompletionState" > BatchCompletionState< / a > interface
which can (depending upon batch creation parameters) contain both
update records info and in addition to error flag detailed status
vectors for messages that caused execution errors.< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
< / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < a href = "#Batch" > Batch< / a >
(exactly like < a href = "#ResultSet" > ResultSet< / a > ) may be created in 2
ways – using < a href = "#Statement" > Statement< / a > or < a href = "#Attachment" > Attachment< / a >
interface, in both cases createBatch() method of appropriate
interface is called. In second case text of SQL statement to be
executed in a batch is passed directly to createBatch(). Tuning of
batch operation is performed using < a href = "#Batch_PB" > Batch
parameters block< / a > which has format more or less similar to DPB v.2
– tag in the beginning (IBatch::CURRENT_VERSION) followed by the
set of wide clumplets: 1-byte tag, 4-byte length, length-byte value.
Possible tags are < a href = "#Batch_PB" > described< / a > in batch
interface. The simplest (and recommended) way to create parameters
block for batch creation is to use appropriate < a href = "#XpbBuilder" > XpbBuilder< / a >
interface:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IXpbBuilder*
pb = utl-> getXpbBuilder(& status, IXpbBuilder::BATCH, NULL, 0);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > pb-> insertInt(& status,
IBatch::RECORD_COUNTS, 1);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Use
of such parameters block directs batch to account number of updated
records on per-message basis.< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
create batch interface with desired parameters pass parameters block
to createBatch() call:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IBatch*
batch = att-> createBatch(& status, tra, 0, sqlStmtText,
SQL_DIALECT_V6, NULL,< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > pb-> getBufferLength(& status),
pb-> getBuffer(& status));< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
this sample batch interface is created with default format of
messages cause NULL is passed instead input metadata format.< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
< / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
order to proceed with created batch interface we need to know format
of messages in it. It can be obtained using getMetadata() method:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IMessageMetadata*
meta = batch-> getMetadata(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Certainly
if you have passed your own format of messages to the batch you may
simply use it.< / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > In the former text I suppose
that some function fillNextMessage(unsigned char* data,
IMessageMetadata* metadata) is present and can fill buffer ‘ data’
according to passed format ‘ metadata’ . In order to work with
messages we need a buffer for a data:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
char* data = new unsigned char[meta-> getMessageLength(& status)];< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > Now we can add some messages
full of data to the batch:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > fillNextMessage(data,
meta);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > batch-> add(& status,
1, data);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > fillNextMessage(data,
meta);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > batch-> add(& status,
1, data);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > An alternative way of working
with messages (using FB_MESSAGE macro) is present in the sample of
using batch interface 11.batch.cpp.< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
< / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > Finally batch should be
executed:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < a href = "#BatchCompletionState" > IBatchCompletionState< / a > *
cs = batch-> execute(& status, tra);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > We
requested accounting of the number of modified (inserted, updated or
deleted) records per message. To print it we must use
< a href = "#BatchCompletionState" > BatchCompletionState< / a > interface.
Determine total number of messages processed by batch (it can be less
than the number of messages passed to the batch if error happened and
an option enabling multiple errors during batch processing was not
turned on):< / span > < / font > < / span > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > < span style = "background: #ffffff" > unsigned
total = cs-> getSize(& status);< / span > < / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > Now print the state of each
message:< / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > < span style = "background: #ffffff" > for
(unsigned p = 0; p < total; ++p) printf(“Msg %u state %d\n”,
p, cs-> getState(& status, p));< / span > < / i > < / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "background: #ffffff" > When
finished analyzing completion state don’ t forget to dispose it:< / span > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > < span style = "background: #ffffff" > cs-> dispose();< / span > < / i > < / font > < / p >
< p > < font color = "#000000" > < font size = "4" style = "font-size: 14pt" > < span style = "background: #ffffff" > Full
sample of printing contents< / span > < / font > < / font > < font color = "#000000" > < span style = "background: #ffffff" >
of < / span > < / font > < span style = "font-variant: normal" > < font color = "#000000" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > < span style = "background: #ffffff" > < a href = "#BatchCompletionState" > BatchCompletionState< / a >
is in print_cs() function in sample 11.batch.cpp.< / span > < / span > < / font > < / font > < / span > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "background: #ffffff" > If
for some reason you want to make batch buffers empty not executing it
(i.e. prepare for new portion of messages to process) use cancel()
method:< / span > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < span style = "background: #ffffff" > batch-> cancel(& status);< / span > < / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > < span style = "background: #ffffff" > Being
reference counted Batch does not have special method to close it –
standard release() call:< / span > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > < span style = "background: #ffffff" > batch-> release();< / span > < / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > < span style = "background: #ffffff" > Described
methods help to implement all what one needs for JDBC-style prepared
statement batch operations. < / span > < / font >
< / p >
< p > < br / >
< br / >
< / p >
< p > < font size = "4" style = "font-size: 14pt" > One can add more than
single message in one call to the batch. When doing it please
remember – messages should be appropriately aligned for this
feature to work correctly. Required alignment and aligned size of the
message should be obtained from < a href = "#MessageMetadata" > MessageMetadata< / a >
interface, for example:< / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > unsigned aligned =
meta-> getAlignedLength(& status);< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > Later that size will be
useful when allocating an array of messages and working with it:< / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > unsigned char* data =
new unsigned char[aligned * N]; // N is desired number of messages< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > for (int n = 0; n <
N; ++n) fillNextMessage(& data[aligned * n], meta);< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > batch-> add(& status,
N, data);< / i > < / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > After
it batch may be executed or next portion of messages added to it.< / font > < / p >
< p > < br / >
< br / >
< / p >
< p > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > Blobs
in general are not compatible with batches – batch is efficient
when one needs to pass a lot of small data to the server in single
step, blobs are treated as large objects and therefore in general it
makes no sense to use them in batches. But on practice it often
happens that blobs are not too big – and in this case use of
traditional blob API (create blob, pass segments to the server, close
blob, pass blobs ID in the message) kills performance, specially when
used over WAN. Therefore in firebird batch supports passing blobs to
server inline, together with other messages. To use that feature
first of all < a href = "#Batch_Blob_Policy" > blob usage policy< / a > for a
batch to be created should be set (as an option in < a href = "#Batch_PB" > parameters
block< / a > ):< / span > < / font > < / span > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > pb-> insertInt(& status,
IBatch::BLOB_IDS, IBatch::BLOB_IDS_ENGINE);< / i > < / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > In
this example temporal blob IDs needed to keep a link between blob and
a message where it’ s used will be generated by firebird engine –
that’ s the simplest and rather common usage. Imagine that the
message is described as follows:< / font > < / p >
< p style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < i > FB_MESSAGE(Msg,
ThrowStatusWrapper,< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > (FB_VARCHAR(5), id)< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > (FB_VARCHAR(10), name)< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > (FB_BLOB, desc)< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > ) project(& status,
master);< / i > < / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > In
that case to send a message containing blob to the server one can do
something like this:< / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > project-> id =
++idCounter;< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > project-> name.set(currentName);< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > batch-> addBlob(& status,
descriptionSize, descriptionText, & project-> desc);< / i > < / font > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > batch-> add(& status,
1, project.getData());< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > If some blob happened to be
big enough not to fit into your existing buffer you may instead
reallocating buffer use appendBlobData() method. It appends more data
to last added blob. < / font >
< / p >
< p style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < i > batch-> addBlob(& status,
descriptionSize, descriptionText, & project→desc, bpbLength,
bpb);< / i > < / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > After
adding first part of blob get next portion of data into
descriptionText, update descriptionSize and:< / font > < / p >
< p style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < i > batch-> appendBlobData(& status,
descriptionSize, descriptionText);< / i > < / font > < / p >
< p > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > This
may be done in a loop but take care not to overflow internal batch
buffers – it’ s size is controlled by < a href = "#Batch_PB" > BUFFER_BYTES_SIZE< / a >
option when creating batch interface but can’ t exceed 40Mb (default
is 10Mb). If you need to process such big blob (for example on the
background of a lot of small one – this can explain use of batch)
just use standard blob API and < a href = "#Batch::registerBlob" > registerBlob< / a >
method of < a href = "#Batch" > Batch< / a > interface.< / span > < / font > < / span > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > One
more possible choice of blob policy is BLOB_IDS_USER. Usage at the
first look does not change much – before calling addBlob() correct
and unique per batch execution ID should be placed to the memory
referenced by last parameter. Certainly same ID should be passed in
the data message to the blob. Taking into an account that generation
of blob IDs by engine is very fast such policy may seem useless but
imagine a case when you get blobs and other data in relatively
independent streams (blocks in a file for example) and some good IDs
are already present in them. In such case use of user-supplied blob
IDs can greatly simplify your code.< / font > < / p >
< p > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > Please
take into an account – unlike blobs created using regular
< a href = "#Attachment" > createBlob< / a > () blobs created by < a href = "#Batch" > Batch< / a >
interface are by default stream, not segmented. Segmented blobs
provide nothing interesting compared with stream one and therefore
not recommended to be used in new development, we support that format
only for backward compatibility reasons. If you really need segmented
blobs this default may be overridden by calling:< / span > < / font > < / span > < / p >
< p > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < i > batch-> setDefaultBpb(& status,< / i > < / font > < / span > < span style = "font-variant: normal" >
< / span > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < i > bpbLength,
bpb);< / i > < / font > < / span > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > Certainly
passed BPB may contain any other blob creation parameters too. As you
may have already noticed you may also pass BPB directly to addBlob()
but if most of blobs you are going to add have same non-default
format use of setDefaultBpb() is slightly more efficient. Returning
to segmented blobs – call to addBlob() will add first segment to
the blob, following calls to appendBlobData() will add more segments.
Do not forget that segment size is limited to 64Kb – 1, an attempt
to pass more data in a single call with cause an error.< / font > < / p >
< p > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > Next
step when working with existing blob streams is use of
addBlobStream() method. Using it one can add more than one blob to
the batch per single call. Blob stream is a sequence of blobs, each
starts with blob header. Header should be appropriately aligned -
< a href = "#Batch" > Batch< / a > interface provides special call for this
purpose:< / span > < / font > < / span > < / p >
< p style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
alignment = batch-> getBlobAlignment(& status);< / i > < / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > It’ s
supposed that all components of blob stream in a batch should be
aligned at least at alignment boundary, including size of stream
potions passed to addBlobStream() which should be a multiple of this
alignment. Header contains 3 fields – 8-byte blob ID (must be
non-zero), 4-byte total blob size and 4 byte BPB size. Total blob
size includes BPB inside, i.e. one will always find next blob in the
stream in blob-size bytes after the header (taking into account the
alignment). BPB (if present, i.e. if BPB size is not zero) is placed
right after the header. After BPB blob data goes, it’ s format
depends upon blob type – stream or segmented. In case of stream
blob it’ s a plain sequence of bytes having size blob-size –
BPB-size. With segmented blob things are a bit more compicated: blob
data is a set of segments where each segment has the following format
– 2-bytes size of segment (this should be aligned at
IBatch::BLOB_SEGHDR_ALIGN boundary) followed by stored in this 2
bytes number of bytes.< / font > < / p >
< p style = "font-variant: normal; font-style: normal" > < font size = "4" style = "font-size: 14pt" > When
big blob is added to the stream it’ s size is not always known in
advance. In order not to have too big buffer for that blob (remember,
size should be provided in blob header, before blob data) blob
continuation record may be used. In blob header you leave blob size
at a value known when creating that header and add continuation
record that has format absolutely same as blob header, but here blob
ID must be zero and BPB size must always be zero too. Typically you
will want to have one continuation record per addBlobStream() call.< / font > < / p >
< p > < a name = "Batch::registerBlob" > < / a > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > Last
method used to work with blobs stands alone from the first three that
pass blob data inline with the rest of batch data < / span > < / font > < / span > < span style = "font-variant: normal" > –
< / span > < span style = "font-variant: normal" > < font size = "4" style = "font-size: 14pt" > < span style = "font-style: normal" > it’ s
needed to register in a batch ID of a blob created using standard
blob API. This may be unavoidable if one needs to pass to a batch
really big blob. Do not use ID of such blob in batch directly –
that will cause invalid blob ID error during batch execution. Instead
do:< / span > < / font > < / span > < / p >
< p > < font size = "4" style = "font-size: 14pt" > < i > batch-> registerBlob(& status,
& realId, & msg-> desc);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > If blob policy makes firebird
engine generate blob IDs this code is enough to correctly register
existing blob in a batch. In other cases you will have to assign
correct (from batch POV) ID to msg-> desc.< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
< / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
< font size = "4" style = "font-size: 14pt" > Almost all mentioned methods
are used in 11.batch.cpp – please use it to see an alive sample of
batching in firebird.< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Working with events.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Events
2017-01-31 15:38:53 +01:00
interface was not 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 < / font > < font size = "4" style = "font-size: 14pt" > < i > FPTR_EVENT_CALLBACK
ast< / i > < / font > < font size = "4" style = "font-size: 14pt" > and < / font > < font size = "4" style = "font-size: 14pt" > < i > void*
arg< / i > < / font > < font size = "4" style = "font-size: 14pt" > , required to
2017-01-09 18:28:11 +01:00
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
2017-01-31 15:38:53 +01:00
handler) this function returns reference counted interface < a href = "#Events" > IEvents< / a >
2017-01-09 18:28:11 +01:00
having method cancel() used when waiting for event should be stopped.
Unlike identifier which is automatically destroyed when event arrives
2016-04-07 18:45:09 +02:00
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
2017-01-31 15:38:53 +01:00
interface < a href = "#Events" > IEvents< / a > must be explicitly released
2016-04-07 18:45:09 +02:00
after receiving an event. This may be done for example right before
2017-01-31 15:38:53 +01:00
queuing for an event next time:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > events-> release();< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > events
2017-01-31 15:38:53 +01:00
= NULL;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > events
2017-01-31 15:38:53 +01:00
= attachment-> queEvents(& status, this, eveLen, eveBuffer);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Setting
2017-01-31 15:38:53 +01:00
interface pointer to NULL is useful in case of exception during
queEvents. In other aspects events handling did not change compared
with ISC API. Please use for additional details our sample
08.events.cpp. < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Using services.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
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 is used later to talk to service. To prepare SPB to
attach to service manager one can use IXpbBuilder:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IXpbBuilder*
2017-01-31 15:38:53 +01:00
spb1 = utl-> getXpbBuilder(& status, IXpbBuilder::SPB_ATTACH,
NULL, 0);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > spb1-> insertString(& status,
2017-01-31 15:38:53 +01:00
isc_spb_user_name, “sysdba”);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > spb1-> insertString(& status,
2017-01-31 15:38:53 +01:00
isc_spb_password, “masterkey”);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > and
2017-01-31 15:38:53 +01:00
proceed with attach:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < a href = "#Service" > IService< / a > *
2016-04-07 18:45:09 +02:00
svc = prov-> attachServiceManager(& status, “service_mgr”,
2017-01-31 15:38:53 +01:00
spb1-> getBufferLength(& status), spb1-> getBuffer(& status));< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Using
2017-01-31 15:38:53 +01:00
IService one can perform both available for services actions –
start services and query various information about started utilities
and server in general. When querying information one limitation takes
place – formats of parameter blocks, used by query() method, in
Firebird 3 are not supported by IXpbBuilder. Support will be probably
added in later versions, in Firebird 3 you will have to build and
analyze that blocks manually. Format of that blocks matches old
format (used in ISC API) one to one. < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
start service one should first of all create appropriate SPB:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IXpbBuilder*
2017-01-31 15:38:53 +01:00
spb2 = utl-> getXpbBuilder(& status, IXpbBuilder::SPB_START,
NULL, 0);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > and
2017-01-31 15:38:53 +01:00
add required items to it. For example, to print encryption statistics
for database employee the following should be placed into SPB:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > spb2-> insertTag(& status,
2017-01-31 15:38:53 +01:00
isc_action_svc_db_stats);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > spb2-> insertString(& status,
2017-01-31 15:38:53 +01:00
isc_spb_dbname, " employee" );< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > spb2-> insertInt(& status,
2017-01-31 15:38:53 +01:00
isc_spb_options, isc_spb_sts_encryption);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > After
2017-01-31 15:38:53 +01:00
it service can be started using start() method of < a href = "#Service" > IService< / a >
interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > svc-> start(& status,
2017-01-31 15:38:53 +01:00
spb2-> getBufferLength(& status), spb2-> getBuffer(& status));< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Many
2017-01-31 15:38:53 +01:00
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 < 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 passed to stdin of service utility or
may be empty in the simplest case. Receive block must contain list of
tags you want to receive from service. For most of utilities this is
single isc_info_svc_line:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > const
2017-01-31 15:38:53 +01:00
unsigned char receiveItems1[] = {isc_info_svc_line};< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
query information one also needs a buffer for that information:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > unsigned
2017-01-31 15:38:53 +01:00
char results[1024];< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > After
2017-01-31 15:38:53 +01:00
that preliminary steps we are ready to query service in a loop (each
line returned in a single call to query()):< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > do< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > svc-> query(& status,
2016-04-07 18:45:09 +02:00
0, NULL, sizeof(receiveItems1), receiveItems1, sizeof(results),
2017-01-31 15:38:53 +01:00
results);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }
2017-01-31 15:38:53 +01:00
while (printInfo(results, sizeof(results)));< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
this example we suppose that printInfo() function returns TRUE as
long as service returns results block containing next output line
(i.e. till end of data stream from service). Format of results block
varies from service to service, and some services like gsec produce
historical formats that are not trivial for parse – but this is out
of our scope here. A minimum working sample of printInfo() is present
in example 09.service.cpp.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Same
2017-01-31 15:38:53 +01:00
query method is used to retrieve information about server but in this
case query function is not invoked in a loop, i.e. buffer must be big
enough to fit all information at once. This is not too hard –
typically such calls do not return much data. As in previous case
begin with receive block placing required items in it – in our
example it's isc_info_svc_server_version:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
unsigned char receiveItems2[] = {isc_info_svc_server_version};< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Existing
2017-01-31 15:38:53 +01:00
from previous call results buffer may be reused. No loop is needed
here:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > svc-> query(& status,
2016-04-07 18:45:09 +02:00
0, NULL, sizeof(receiveItems2), receiveItems2, sizeof(results),
2017-01-31 15:38:53 +01:00
results);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > printInfo(results,
2017-01-31 15:38:53 +01:00
sizeof(results));< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > After
2017-01-31 15:38:53 +01:00
finishing with services tasks do not forget to close an interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > svc-> detach(& status);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid" >
2017-01-31 15:38:53 +01:00
< font face = "Albany, sans-serif" > < font size = "5" style = "font-size: 18pt" > Writing
plugins.< / font > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > To
2017-01-31 15:38:53 +01:00
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 < / font > < font size = "4" style = "font-size: 14pt" > < i > plugin
module< / i > < / font > < font size = "4" style = "font-size: 14pt" > or just
< / font > < font size = "4" style = "font-size: 14pt" > < i > module< / i > < / font > < font size = "4" style = "font-size: 14pt" > .
2018-05-10 17:18:24 +02:00
In most cases single plugin is placed< / font > < font size = "4" style = "font-size: 14pt" > into< / font >
< font size = "4" style = "font-size: 14pt" > dynamic library but in common
case multiple plugins may coexist in single dynamic library. 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
2016-09-05 12:23:30 +02:00
entrypoint firebird_plugin() which name is defined in include file
2017-01-31 15:38:53 +01:00
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
previous part of this text we were mostly describing how to use
existing interfaces, here main attention will be paid to implementing
interfaces yourself. Certainly to do it one can and should use
already existing interfaces both generic needed for accessing
firebird databases (already described) and some more interfaces
specifically designed for plugins.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Following
2017-01-31 15:38:53 +01:00
text is actively using example of database encryption plugin
2016-04-07 18:45:09 +02:00
examples/dbcrypt/DbCrypt.cpp. It will be good idea to compile this
2017-01-31 15:38:53 +01:00
sample yourself and learn it when reading later.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Implementation of plugin
module.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Plugins
2017-01-31 15:38:53 +01:00
actively interact with special firebird component called < / font > < font size = "4" style = "font-size: 14pt" > < i > plugin
manager< / i > < / font > < font size = "4" style = "font-size: 14pt" > . 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" style = "font-size: 14pt" > < i > < span style = "font-weight: normal" > fbclient< / span > < / i > < / font >
< font size = "4" style = "font-size: 14pt" > 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 some reason a lot of OS-dependent
actions is performed and some of that actions may be used to detect
this fact in the program. When writing plugins distributed with
firebird we always use invocation of destructor of global variable.
The big “plus” for this method is that it is OS independent
(though something like atexit() function maybe also used
successfully). But use of destructor makes it possible to easily
concentrate almost everything related with unload detection in single
class implementing at the same time < a href = "#PluginModule" > IPluginModule< / a >
interface.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Minimum
2017-01-31 15:38:53 +01:00
implementation looks as follows:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > class
2017-01-31 15:38:53 +01:00
PluginModule : public IPluginModuleImpl< PluginModule,
CheckStatusWrapper> < / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > private:< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IPluginManager*
2017-01-31 15:38:53 +01:00
pluginManager;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > public:< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > PluginModule()< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > :
2017-01-31 15:38:53 +01:00
pluginManager(NULL)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {
2017-01-31 15:38:53 +01:00
}< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ~PluginModule()< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > if
2017-01-31 15:38:53 +01:00
(pluginManager)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > pluginManager-> unregisterModule(this);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > doClean();< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > void
2017-01-31 15:38:53 +01:00
registerMe(IPluginManager* m)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > pluginManager
2017-01-31 15:38:53 +01:00
= m;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > pluginManager-> registerModule(this);< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > void
2017-01-31 15:38:53 +01:00
doClean()< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > pluginManager
2017-01-31 15:38:53 +01:00
= NULL;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > };< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > The
2017-01-31 15:38:53 +01:00
only data member is plugin manager interface < a href = "#PluginManager" > IPluginManager< / a > .
2016-04-07 18:45:09 +02:00
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
2017-01-31 15:38:53 +01:00
parameter. Variable < / font > < font size = "4" style = "font-size: 14pt" > < i > pluginManager
< / i > < / font > < font size = "4" style = "font-size: 14pt" > 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 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Implementing
2017-01-31 15:38:53 +01:00
plugin's interface IPluginModule we met with first interface required
to implement plugins – < a href = "#PluginManager" > IPluginManager< / a > .
It will be actively used later, the rest of internals of this class
will hardly be required to you after copying it to your program. Just
2016-04-07 18:45:09 +02:00
don't forget to declare global variable of this type and call
2017-01-31 15:38:53 +01:00
registerMe() function from FB_PLUGIN_ENTRY_POINT.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Core interface of any
plugin.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Let's
2017-01-31 15:38:53 +01:00
start implementing plugin itself. The type of main interface depends
upon plugin type (which is obvious), but all of them are based on
common reference counted interface IPluginBase which performs common
for all plugins (and very simple) tasks. Each plugin has some (also
reference counted) object which < i > owns< / i > this plugin. In order to
perform smart plugin lifetime management any plugin must be able to
store that owner information and report it to plugin manager on
request. That means that each plugin must implement two trivial
methods setOwner() and getOwner() contained in IPluginBase interface.
2016-04-07 18:45:09 +02:00
Type-dependent methods are certainly more interesting - they are
2017-01-31 15:38:53 +01:00
discussed in interfaces description part.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Let's
2017-01-31 15:38:53 +01:00
take a look at typical part of any plugin implementation (here I
specially use non-existent type SomePlugin):< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > class
2017-01-31 15:38:53 +01:00
MyPlugin : public ISomePluginImpl< MyPlugin, CheckStatusWrapper> < / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > public:< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > explicit
2017-01-31 15:38:53 +01:00
MyPlugin(< a href = "#PluginConfig" > IPluginConfig< / a > * cnf) throw()< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > :
2017-01-31 15:38:53 +01:00
config(cnf), refCounter(0), owner(NULL)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > config-> addRef();< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > 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 interface in your
plugin and use it later. This will let you use common for all
firebird configuration style letting users have 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 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ~MyPlugin()< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > config-> release();< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > 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 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > //
2017-01-31 15:38:53 +01:00
IRefCounted implementation< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > int
2017-01-31 15:38:53 +01:00
release()< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > if
2017-01-31 15:38:53 +01:00
(--refCounter == 0)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > delete
2017-01-31 15:38:53 +01:00
this;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > return
2017-01-31 15:38:53 +01:00
0;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > return
2017-01-31 15:38:53 +01:00
1;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > void
2017-01-31 15:38:53 +01:00
addRef()< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > ++refCounter;< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > Absolutely typical
implementation of reference counted object.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > //
2017-01-31 15:38:53 +01:00
IPluginBase implementation< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > void
2017-01-31 15:38:53 +01:00
setOwner(IReferenceCounted* o)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > owner
2017-01-31 15:38:53 +01:00
= o;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IReferenceCounted*
2017-01-31 15:38:53 +01:00
getOwner()< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > return
2017-01-31 15:38:53 +01:00
owner;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > As it was promised
implementation of IPluginBase is trivial.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > //
2017-01-31 15:38:53 +01:00
ISomePlugin implementation< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > //
2017-01-31 15:38:53 +01:00
… here go various methods required for particular plugin type< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > private:< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IPluginConfig*
2017-01-31 15:38:53 +01:00
config;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > FbSampleAtomic
2017-01-31 15:38:53 +01:00
refCounter;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IReferenceCounted*
2017-01-31 15:38:53 +01:00
owner;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > };< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > With
2017-01-31 15:38:53 +01:00
this sample formal part of main plugin interface implementation is
over. After adding type-specific methods (and writing probably a
lo-o-o-ot of code to make them useful) interface is ready.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Plugin's factory.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > One
2017-01-31 15:38:53 +01:00
more interface required for plugin to work is < a href = "#PluginFactory" > IPluginFactory< / a > .
2016-04-07 18:45:09 +02:00
Factory creates instances of plugin and returns them to plugin
2017-01-31 15:38:53 +01:00
manager. Factory typically looks this way:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > class
2017-01-31 15:38:53 +01:00
Factory : public IPluginFactoryImpl< Factory, CheckStatusWrapper> < / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > public:< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > IPluginBase*
2016-04-07 18:45:09 +02:00
createPlugin(CheckStatusWrapper* status, IPluginConfig*
2017-01-31 15:38:53 +01:00
factoryParameter)< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > {< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > MyPlugin*
2017-01-31 15:38:53 +01:00
p = new MyPlugin(factoryParameter);< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > p-> addRef();< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > return
2017-01-31 15:38:53 +01:00
p;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > }< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > };< / i > < / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm; font-variant: normal; font-style: normal" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > Here attention should be payed
to the fact that even in a case when code in a function may throw
exceptions (operator new may throw in a case when memory exhausted)
one need not always manually define try/catch block –
implementation of firebird interfaces does this job for you, in
implementation of IPluginFactory it's placed into template
2016-04-07 18:45:09 +02:00
IPluginFactoryImpl. Take into an account that default status wrappers
perform meaning-full processing only for FbException. But if you
(that definitely makes sense if you work on some big project) define
your own wrapper you can handle any type of C++ exception and pass
2017-01-31 15:38:53 +01:00
useful information about it from your plugin.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Plugin module
initialization entrypoint.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > When
2017-01-31 15:38:53 +01:00
plugin manager loads plugin module it invokes module initializing
routine – the only exported from plugin function
FB_PLUGIN_ENTRY_POINT. To wrote it's code one will need two global
variables – plugin module and plugin factory. In our case that is:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > PluginModule
2017-01-31 15:38:53 +01:00
module;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < i > Factory
2017-01-31 15:38:53 +01:00
factory;< / i > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > If
2017-01-31 15:38:53 +01:00
you module contains more than one plugin you will need a factory per
each plugin.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > For
2017-01-31 15:38:53 +01:00
FB_PLUGIN_ENTRY_POINT we should not forget that it should be exported
from plugin module, and it requires taking into an account some OS
specifics. We do it using macro FB_DLL_EXPORT defined in
2016-04-07 18:45:09 +02:00
examples/interfaces/ifaceExamples.h. If you are sure you write plugin
only for some specific OS you can make this place a bit simpler. In
minimum case the function should register module and all factories in
2017-01-31 15:38:53 +01:00
plugin manager:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > extern
2017-01-31 15:38:53 +01:00
" C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster*
master)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > {< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IPluginManager*
2017-01-31 15:38:53 +01:00
pluginManager = master-> getPluginManager();< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > module.registerMe(pluginManager);< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > pluginManager-> registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
2017-01-31 15:38:53 +01:00
" DbCrypt_example" , & factory);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > }< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > First
2017-01-31 15:38:53 +01:00
of all we call written by us not long ago PluginModule::registerMe()
function which will saves IPluginManager for future use and registers
our plugin module. Next time to register factory (or factories in
case of multiple plugins per module) takes place. We must pass
correct plugin type (valid types are enumerated in interface
IPluginManager) and a name under which plugin will be registered. In
simple case it should match with the name of dynamic library with
plugin module. Following last rule will help you avoid configuring
your plugin manually in plugins.conf.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Pay
2017-01-31 15:38:53 +01:00
attention - unlike applications plugins should not use
fb_get_master_interface() to obtain IMaster. Instance, passed to
FB_PLUGIN_ENTRY_POINT, should be used instead. If you ever need
master interface in your plugin take care about saving it in this
function.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid" >
2017-01-31 15:38:53 +01:00
< font face = "Albany, sans-serif" > < font size = "5" style = "font-size: 18pt" > Interfaces:
from A to Z< / font > < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > In
2017-01-31 15:38:53 +01:00
this glossary we do not list interfaces that are not actively used
(like IRequest, needed first of all to support legacy ISC API
requests). Same reference may be made for a number of methods (like
compileRequest() in IAttachment). For interfaces / methods, having
direct analogue in old API, that analogue is provided.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Generic interfaces.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Attachment" > < / a > < font size = "4" style = "font-size: 14pt" > Attachment
2017-01-31 15:38:53 +01:00
interface – replaces isc_db_handle:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
getInfo(StatusType* status, unsigned itemsLength, const unsigned
2016-04-07 18:45:09 +02:00
char* items, unsigned bufferLength, unsigned char* buffer) –
2017-01-31 15:38:53 +01:00
replaces isc_database_info().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-03-03 16:03:27 +01:00
startTransaction(StatusType* status, unsigned tpbLength, const
2016-04-07 18:45:09 +02:00
unsigned char* tpb) – partially replaces isc_start_multiple(), to
2017-01-31 15:38:53 +01:00
start > 1 transaction < a href = "#Dtc" > distributed transactions
coordinator< / a > should be used, also possible to < a href = "#Transaction" > join< / a >
2 transactions into single distributed transaction.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-03-03 16:03:27 +01:00
reconnectTransaction(StatusType* status, unsigned length, const
2016-04-07 18:45:09 +02:00
unsigned char* id) – makes it possible to connect to a transaction
in limbo. Id parameter contains transaction number in network format
2017-01-31 15:38:53 +01:00
of given length.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IRequest*
2016-03-03 16:03:27 +01:00
compileRequest(StatusType* status, unsigned blrLength, const
2017-01-31 15:38:53 +01:00
unsigned char* blr) – support of ISC API.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
transactRequest(StatusType* status, ITransaction* transaction,
unsigned blrLength, const unsigned char* blr, unsigned inMsgLength,
const unsigned char* inMsg, unsigned outMsgLength, unsigned char*
2017-01-31 15:38:53 +01:00
outMsg) – support of ISC API.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IBlob*
2016-03-03 16:03:27 +01:00
createBlob(StatusType* status, ITransaction* transaction, ISC_QUAD*
2016-04-07 18:45:09 +02:00
id, unsigned bpbLength, const unsigned char* bpb) – creates new
2017-01-31 15:38:53 +01:00
blob, stores it's identifier in id, replaces isc_create_blob2().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IBlob*
2016-03-03 16:03:27 +01:00
openBlob(StatusType* status, ITransaction* transaction, ISC_QUAD*
2016-04-07 18:45:09 +02:00
id, unsigned bpbLength, const unsigned char* bpb) – opens existing
2017-01-31 15:38:53 +01:00
blob, replaces isc_open_blob2().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-03-03 16:03:27 +01:00
getSlice(StatusType* status, ITransaction* transaction, ISC_QUAD*
id, unsigned sdlLength, const unsigned char* sdl, unsigned
paramLength, const unsigned char* param, int sliceLength, unsigned
2017-01-31 15:38:53 +01:00
char* slice) - support of ISC API.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
putSlice(StatusType* status, ITransaction* transaction, ISC_QUAD*
id, unsigned sdlLength, const unsigned char* sdl, unsigned
paramLength, const unsigned char* param, int sliceLength, unsigned
2017-01-31 15:38:53 +01:00
char* slice) - support of ISC API.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
executeDyn(StatusType* status, ITransaction* transaction, unsigned
2017-01-31 15:38:53 +01:00
length, const unsigned char* dyn) - support of ISC API.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IStatement*
2016-03-03 16:03:27 +01:00
prepare(StatusType* status, ITransaction* tra, unsigned stmtLength,
2016-04-07 18:45:09 +02:00
const char* sqlStmt, unsigned dialect, unsigned flags) – replaces
isc_dsql_prepare(). Additional parameter flags makes it possible to
control what information will be preloaded from engine at once (i.e.
2017-01-31 15:38:53 +01:00
in single network packet for remote operation).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-03-03 16:03:27 +01:00
execute(StatusType* status, ITransaction* transaction, unsigned
stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata*
inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void*
2016-04-07 18:45:09 +02:00
outBuffer) – executes any SQL statement except returning multiple
rows of data. Partial analogue of isc_dsql_execute2() - in and out
XSLQDAs replaced with input and output messages with appropriate
2017-01-31 15:38:53 +01:00
buffers.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IResultSet*
2016-03-03 16:03:27 +01:00
openCursor(StatusType* status, ITransaction* transaction, unsigned
stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata*
inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const
2016-04-07 18:45:09 +02:00
char* cursorName, unsigned cursorFlags) – executes SQL statement
2017-01-31 15:38:53 +01:00
potentially returning multiple rows of data. Returns < a href = "#ResultSet" > ResultSet< / a >
2016-04-07 18:45:09 +02:00
interface which should be used to fetch that data. Format of output
data is defined by outMetadata parameter, leaving it NULL default
format may be used. Parameter cursorName specifies name of opened
cursor (analogue of isc_dsql_set_cursor_name()). Parameter
cursorFlags is needed to open bidirectional cursor setting it's
2017-01-31 15:38:53 +01:00
value to Istatement::CURSOR_TYPE_SCROLLABLE.< / font > < / p >
< li / >
2017-10-23 16:10:49 +02:00
< p > < font size = "4" style = "font-size: 14pt" > I< / font > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > Batch*
createBatch(StatusType* status, ITransaction* transaction, unsigned
stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata*
inMetadata, unsigned< / font > < / font > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > parLength,
const unsigned char* par) – prepares sqlStmt and creates < a href = "#Batch" > Batch< / a >
interface ready to accept multiple sets of input parameters in
inMetadata format. Leaving inMetadata< / font > < / font > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > NULL
makes batch use default format for sqlStmt. Parameters block may be
passed to createBatch() making it possible to adjust batch behavior.< / font > < / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IEvents*
2016-03-03 16:03:27 +01:00
queEvents(StatusType* status, IEventCallback* callback, unsigned
2016-04-07 18:45:09 +02:00
length, const unsigned char* events) – replaces isc_que_events()
call. Instead callback function with void* parameter callback
2017-01-31 15:38:53 +01:00
interface is used.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
cancelOperation(StatusType* status, int option) – replaces
2017-01-31 15:38:53 +01:00
fb_cancel_operation().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
ping(StatusType* status) – check connection status. If test fails
the only operation possible with attachment is to close it.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
detach(StatusType* status) – replaces isc_detach_database(). On
2017-01-31 15:38:53 +01:00
success releases interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
dropDatabase(StatusType* status) - replaces isc_drop_database(). On
2017-01-31 15:38:53 +01:00
success releases interface.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-23 16:10:49 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Batch" > < / a > < font size = "4" style = "font-size: 14pt" > Batch
interface – makes it possible to process multiple sets of
parameters in single statement execution.< / font > < / p >
< ol >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
add(StatusType* status, unsigned< / font > < font size = "4" style = "font-size: 14pt" > count,
const void* inBuffer) – adds count messages from inBuffer to the
batch. Total size of messages that can be added to the batch is
limited by BUFFER_BYTES_SIZE < a href = "#Batch_PB" > parameter< / a > of
batch creation.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
addBlob(StatusType* status, unsigned< / font > < font size = "4" style = "font-size: 14pt" > length,
2018-05-10 17:18:24 +02:00
const void* inBuffer, ISC_QUAD* blobId, unsigned bpbLength, const
unsigned char* bpb) – adds single blob having length bytes from
inBuffer to the batch, blob identifier is located at blobId address.
If blob should be created with non-default parameters BPB may be
passed (format matches one used in < a href = "#Attachment" > Attachment< / a > ::createBlob).Total
size of inline blobs that can be added to the batch (including
2017-10-23 16:10:49 +02:00
optional BPBs, blob headers, segment sizes and taking into an
2018-05-10 17:18:24 +02:00
accoount alignment) is limited by BUFFER_BYTES_SIZE < a href = "#Batch_PB" > parameter< / a >
of batch creation (affects all blob-oriented methods except
2017-10-23 16:10:49 +02:00
registerBlob()). < / font >
< / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
appendBlobData(StatusType* status, unsigned length, const void*
inBuffer) – extend last added blob: append length bytes taken from
inBuffer address to it.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
addBlobStream(StatusType* status, unsigned length, const void*
inBuffer) – adds blob data (this can be multiple objects or part
of single blob) to the batch. Header of each blob in the stream is
aligned at getBlobAlignment() boundary and contains 3 fields: first
- 8-bytes blob identifier (in ISC_QUAD format), second - 4-bytes
length of blob, third – 4-bytes length of BPB. Blob header should
not cross boundaries of buffer in this function call. BPB data is
placed right after header, blob data goes next. Length of blob
includes BPB (if it present). All data may be distributed between
multiple addBlobStream() calls. Blob data in turn may be structured
in case of segmented blob, see chapter “< a href = "#Modifying data in a batch" > Modifying
data in a batch< / a > ”.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
registerBlob(StatusType* status, const ISC_QUAD* existingBlob,
ISC_QUAD* blobId) – makes it possible to use in batch blobs added
using standard < a href = "#Blob" > Blob< / a > interface. This function
contains 2 ISC_QUAD* parameters, it’ s important not to mix them –
second parameter (existingBlob) is a pointer to blob identifier,
already added out of batch scope, third (blobId) points to blob
identifier that will be placed in a message in this batch.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > < a href = "#BatchCompletionState" > IBatchCompletionState< / a > *
execute(StatusType* status, ITransaction* transaction) – execute
batch with parameters passed to it in the messages. If parameter
MULTIERROR is not set in < a href = "#Batch_PB" > parameters block< / a >
when creating the batch execution will be stopped after first error,
in MULTIERROR mode an unlimited number of errors can happen, after
an error execution is continued from the next message. This function
returns BatchCompletionState interface that contains all requested
nformation about the results of batch execution.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
cancel(StatusType* status) – clear messages and blobs buffers,
return batch to a state it had right after creation. Notice –
being reference counted interface batch does not contain any special
function to close it, please use release() for this purposes. < / font >
< / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
getBlobAlignment(StatusType* status) – returns required alignment
for the data placed into the buffer of addBlobStream().< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IMessageMetadata*
getMetadata(StatusType* status) – return format of metadata used
in batch’ s messages.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
setDefaultBpb(StatusType* status, unsigned parLength, const unsigned
char* par) – sets BPB which will be used for all blobs missing
non-default BPB. Must be called before adding any message or blob to
batch.< / font > < / p >
< / ol >
< p style = "margin-bottom: 0cm" > < a name = "Batch_PB" > < / a > < font size = "4" style = "font-size: 14pt" > Tag
for parameters block:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > VERSION1< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Tags
for clumplets in parameters block:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > MULTIERROR
(0/1) – can have > 1 message with errors< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > RECORD_COUNTS
(0/1) - per-message modified records accounting< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BUFFER_BYTES_SIZE
(integer) - maximum possible buffer size (default 10Mb, maximum 40Mb)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BLOB_IDS
- < a href = "#Batch_Blob_Policy" > policy< / a > used to store blobs< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DETAILED_ERRORS
(integer) - how many vectors with detailed error info are stored in
completion state (default 64, maximum 256)< / font > < / p >
< p style = "margin-bottom: 0cm" > < a name = "Batch_Blob_Policy" > < / a > < font size = "4" style = "font-size: 14pt" > Policies
used to store blobs:< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BLOB_IDS_NONE
– inline blobs can't be used (registerBlob() works anyway)< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BLOB_IDS_ENGINE
- blobs are added one by one, IDs are generated by firebird engine< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BLOB_IDS_USER
- blobs are added one by one, IDs are generated by user< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BLOB_IDS_STREAM
- blobs are added in a stream, IDs are generated by user< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
< / p >
< p style = "margin-bottom: 0cm" > < a name = "BatchCompletionState" > < / a > < font size = "4" style = "font-size: 14pt" > BatchCompletionState
– disposable interface, always returned by execute() method of
< a href = "#Batch" > Batch< / a > interface. It contains more or less
(depending upon parameters passed when < a href = "#Batch" > Batch< / a > was
created) detailed information about the results of batch execution.< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > {< / font > < / p >
< ol >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > uint
getSize(StatusType* status) – returns the total number of
processed messages.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
getState(StatusType* status, uint pos) – returns the result of
execution of message number ‘ pos’ . On any error with the message
this is EXECUTE_FAILED constant, value returned on success depends
upon presence of RECORD_COUNTS < a href = "#Batch_PB" > parameter< / a > of
batch creation. When it present and has non-zero value number of
records inserted, updated or deleted during particular message
processing is returned, else SUCCESS_NO_INFO constant is returned.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > uint
findError(StatusType* status, uint pos) – finds next (starting
with pos) message which processing caused an error. When such
message is missing NO_MORE_ERRORS constant is returned. Number of
status vectors, returned in this interface, is limited by the value
of DETAILED_ERRORS < a href = "#Batch_PB" > parameter< / a > of batch
creation.< / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
getStatus(StatusType* status, IStatus* to, uint pos) – returns
detailed information (full status vector) about an error that took
place when processing ‘ pos’ message. In order to distinguish
between errors (in < a href = "#Batch" > Batch< / a > ::execute() or in
< a href = "#BatchCompletionState" > BatchCompletionState< / a > ::getStatus())
that status is returned in separate ‘ to’ parameter unlike errors
in this call that are placed into ‘ status’ parameter.< / font > < / p >
< / ol >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Special
values returned by getState():< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > EXECUTE_FAILED
- error happened when processing this message< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > SUCCESS_NO_INFO
- record update info was not collected< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Special
value returned by findError():< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > NO_MORE_ERRORS
– no more messages with errors in this batch< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Blob" > < / a > < font size = "4" style = "font-size: 14pt" > Blob
2017-01-31 15:38:53 +01:00
interface – replaces isc_blob_handle:< / font > < / p >
< ol >
2017-10-23 16:10:49 +02:00
< li value = "1" / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
getInfo(StatusType* status, unsigned itemsLength, const unsigned
char* items, unsigned bufferLength, unsigned char* buffer) –
2017-01-31 15:38:53 +01:00
replaces isc_blob_info().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
getSegment(StatusType* status, unsigned bufferLength, void* buffer,
unsigned* segmentLength) – replaces isc_get_segment(). Unlike it
never returns isc_segstr_eof and isc_segment errors (that are
2017-01-31 15:38:53 +01:00
actually not errors), instead returns < a href = "#Completion codes" > completion
codes< / a > IStatus::RESULT_NO_DATA and IStatus::RESULT_SEGMENT,
normal return is IStatus::RESULT_OK.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
putSegment(StatusType* status, unsigned length, const void* buffer)
2017-01-31 15:38:53 +01:00
– replaces isc_put_segment().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
cancel(StatusType* status) – replaces isc_cancel_blob(). On
2017-01-31 15:38:53 +01:00
success releases interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
close(StatusType* status) – replaces isc_close_blob(). On success
2017-01-31 15:38:53 +01:00
releases interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2017-01-31 15:38:53 +01:00
seek(StatusType* status, int mode, int offset) – replaces
isc_seek_blob().< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Config" > < / a > < font size = "4" style = "font-size: 14pt" > Config
2017-01-31 15:38:53 +01:00
interface – generic configuration file interface:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfigEntry*
2017-01-31 15:38:53 +01:00
find(StatusType* status, const char* name) – find entry by name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfigEntry*
2016-04-07 18:45:09 +02:00
findValue(StatusType* status, const char* name, const char* value) –
2017-01-31 15:38:53 +01:00
find entry by name and value.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfigEntry*
2016-04-07 18:45:09 +02:00
findPos(StatusType* status, const char* name, unsigned pos) – find
2017-01-31 15:38:53 +01:00
entry by name and position. If configuration file contains lines:< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Db=DBA< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Db=DBB< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Db=DBC< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > call
2017-01-31 15:38:53 +01:00
to findPos(status, “Db”, 2) will return entry with value DBB.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "ConfigManager" > < / a > < font size = "4" style = "font-size: 14pt" > ConfigManager
2016-04-07 18:45:09 +02:00
interface – generic interface to access various configuration
2017-01-31 15:38:53 +01:00
objects:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getDirectory(unsigned code) – returns location of
appropriate directory in current firebird instance. See codes for
this call a < a href = "#Directory codes" > few lines later< / a > .< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IFirebirdConf*
2016-04-07 18:45:09 +02:00
getFirebirdConf() - returns interface to access default
2017-01-31 15:38:53 +01:00
configuration values (from firebird.conf).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IFirebirdConf*
2016-04-07 18:45:09 +02:00
getDatabaseConf(const char* dbName) - returns interface to access
db-specific configuration (takes into an account firebird.conf and
2017-01-31 15:38:53 +01:00
appropriate part of databases.conf).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfig*
2016-04-07 18:45:09 +02:00
getPluginConfig(const char* configuredPlugin) – returns interface
2017-01-31 15:38:53 +01:00
to access named plugin configuration.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getInstallDirectory() - returns directory where firebird is
installed.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getRootDirectory() - returns root directory of current
instance, in single-instance case usually matches install directory.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Directory codes" > < / a > < font size = "4" style = "font-size: 14pt" > Directory
2017-01-31 15:38:53 +01:00
codes:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_BIN
2017-01-31 15:38:53 +01:00
– bin (utilities like isql, gbak, gstat)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_SBIN
2017-01-31 15:38:53 +01:00
– sbin (fbguard and firebird server)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_CONF
2017-01-31 15:38:53 +01:00
– configuration files (firebird.conf, databases.conf, plugins.conf)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_LIB
2017-01-31 15:38:53 +01:00
– lib (fbclient, ib_util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_INC
2017-01-31 15:38:53 +01:00
– include (ibase.h, firebird/Interfaces.h)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_DOC
2017-01-31 15:38:53 +01:00
- documentation< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_UDF
2017-01-31 15:38:53 +01:00
– UDF (ib_udf, fbudf)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_SAMPLE
2017-01-31 15:38:53 +01:00
- samples< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_SAMPLEDB
2017-01-31 15:38:53 +01:00
– samples database (employee.fdb)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_HELP
2017-01-31 15:38:53 +01:00
– qli help (help.fdb)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_INTL
2017-01-31 15:38:53 +01:00
– international libraries (fbintl)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_MISC
2017-01-31 15:38:53 +01:00
– miscellaneous files (like uninstall manifest and something else)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_SECDB
2017-01-31 15:38:53 +01:00
– where security database is stored (securityN.fdb)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_MSG
2017-01-31 15:38:53 +01:00
– where messages file is stored (firebird.msg)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_LOG
2017-01-31 15:38:53 +01:00
– where log file is stored (firebird.log)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_GUARD
2017-01-31 15:38:53 +01:00
– where guardian lock is stored (fb_guard)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DIR_PLUGINS
2017-01-31 15:38:53 +01:00
– plugins directory ([lib]Engine13.{dll|so})< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "ConfigEntry" > < / a > < font size = "4" style = "font-size: 14pt" > ConfigEntry
2016-04-07 18:45:09 +02:00
interface – represents an entry (Key = Values with probably
2017-01-31 15:38:53 +01:00
sub-entries) in firebird configuration file:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getName() - returns key name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getValue() - returns value as character string.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_INT64
2017-01-31 15:38:53 +01:00
getIntValue() - treats value as integer and returns it.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2017-01-31 15:38:53 +01:00
getBoolValue() - treats value as boolean and returns it.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfig*
2016-04-07 18:45:09 +02:00
getSubConfig(StatusType* status) – treats sub-entries as separate
2017-01-31 15:38:53 +01:00
configuration file and returns Config interface for it.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Dtc" > < / a > < font size = "4" style = "font-size: 14pt" > Dtc
2016-04-07 18:45:09 +02:00
interface – distributed transactions coordinator. Used to start
distributed (working with 2 or more attachments) transaction. Unlike
pre-FB3 approach where distributed transaction must be started in
this way from the most beginning FB3's distributed transactions
coordinator makes it also possible to join already started
2017-01-31 15:38:53 +01:00
transactions into single distributed transaction.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-04-07 18:45:09 +02:00
join(StatusType* status, ITransaction* one, ITransaction* two) –
joins 2 independent transactions into distributed transaction. On
success both transactions passed to join() are released and pointers
2017-01-31 15:38:53 +01:00
to them should not be used any more.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IDtcStart*
2017-01-31 15:38:53 +01:00
startBuilder(StatusType* status) – returns < a href = "#DtcStart" > DtcStart< / a >
interface.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "DtcStart" > < / a > < font size = "4" style = "font-size: 14pt" > DtcStart
2016-04-07 18:45:09 +02:00
interface – replaces array of struct TEB (passed to
isc_start_multiple() in ISC API). This interface accumulates
attachments (and probably appropriate TPBs) for which dustributed
2017-01-31 15:38:53 +01:00
transaction should be started.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
addAttachment(StatusType* status, IAttachment* att) – adds
2017-01-31 15:38:53 +01:00
attachment, transaction for it will be started with default TPB.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
addWithTpb(StatusType* status, IAttachment* att, unsigned length,
2016-04-07 18:45:09 +02:00
const unsigned char* tpb) - adds attachment and TPB which will be
2017-01-31 15:38:53 +01:00
used to start transaction for this attachment.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-04-07 18:45:09 +02:00
start(StatusType* status) – start distributed transaction for
accumulated attachments. On successful return DtcStart interface is
2017-01-31 15:38:53 +01:00
disposed automatically.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "EventCallback" > < / a > < font size = "4" style = "font-size: 14pt" > EventCallback
2016-04-07 18:45:09 +02:00
interface – replaces callback function used in isc_que_events()
call. Should be implemented by user to monitor events with
2017-01-31 15:38:53 +01:00
IAttachment::queEvents() method.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
eventCallbackFunction(unsigned length, const unsigned char* events)
2017-01-31 15:38:53 +01:00
– is called each time event happens.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Events" > < / a > < font size = "4" style = "font-size: 14pt" > Events
2016-04-07 18:45:09 +02:00
interface – replaces event identifier when working with events
2017-01-31 15:38:53 +01:00
monitoring.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
cancel(StatusType* status) - cancels events monitoring started by
2017-01-31 15:38:53 +01:00
IAttachment::queEvents().< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FirebirdConf
2017-01-31 15:38:53 +01:00
interface – access to main firebird configuration. Used for both
default configuration, set by firebird.conf, and per-database
configuration, adjusted by databases.conf. In order to speed up
access to configuration values calls accessing actual values use
integer key instead symbolic parameter name. Key is stable during
server run (i.e. plugin can get it once and than use to get
configuration value for different databases). < / font >
< / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getKey(const char* name) – get key for parameter name. ~0 (all
bits are 1) is returned in a case when there is no such parameter.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_INT64
2017-01-31 15:38:53 +01:00
asInteger(unsigned key) – return value of integer parameter.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* asString(unsigned key) - return value of string parameter.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2016-04-07 18:45:09 +02:00
asBoolean(unsigned key) - return value of boolean parameter.
Standard abbreviations (1/true/t/yes/y) are treated as “true”,
2017-01-31 15:38:53 +01:00
all other cases – false.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Master" > < / a > < font size = "4" style = "font-size: 14pt" > Master
2016-04-07 18:45:09 +02:00
interface – main interface from which start all operations with
2017-01-31 15:38:53 +01:00
firebird API.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IStatus*
2017-01-31 15:38:53 +01:00
getStatus() - get instance if < a href = "#Status" > Status< / a >
interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IProvider*
2017-01-31 15:38:53 +01:00
getDispatcher() - get instance of < a href = "#Provider" > Provider< / a >
interface, implemented by yValve (main provider instance).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IPluginManager*
2017-01-31 15:38:53 +01:00
getPluginManager() - get instance of < a href = "#PluginManager" > PluginManager< / a >
interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITimerControl*
2017-01-31 15:38:53 +01:00
getTimerControl() - get instance of < a href = "#TimerControl" > TimerControl< / a >
interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IDtc*
2017-01-31 15:38:53 +01:00
getDtc() - get instance of < a href = "#Dtc" > Dtc< / a > interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IUtil*
2017-01-31 15:38:53 +01:00
getUtilInterface() - get instance of < a href = "#Util" > Util< / a >
interface.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfigManager*
2017-01-31 15:38:53 +01:00
getConfigManager() - get instance of < a href = "#ConfigManager" > ConfigManager< / a >
interface.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "MessageMetadata" > < / a > < font size = "4" style = "font-size: 14pt" > MessageMetadata
2016-04-07 18:45:09 +02:00
interface – partial analogue of XSQLDA (does not contain message
data, only message format info is present). Used in a calls related
2017-01-31 15:38:53 +01:00
with execution of SQL statements.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getCount(StatusType* status) – returns number of fields/parameters
in a message. In all calls, containing index parameter, it's value
2017-01-31 15:38:53 +01:00
should be: 0 < = index < getCount().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getField(StatusType* status, unsigned index) – returns field
name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getRelation(StatusType* status, unsigned index) – returns
relation name (from which given field is selected).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getOwner(StatusType* status, unsigned index) - returns
relation's owner name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getAlias(StatusType* status, unsigned index) - returns field
alias.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getType(StatusType* status, unsigned index) - returns field SQL
2017-01-31 15:38:53 +01:00
type.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2016-04-07 18:45:09 +02:00
isNullable(StatusType* status, unsigned index) - returns true if
2017-01-31 15:38:53 +01:00
field is nullable.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
getSubType(StatusType* status, unsigned index) - returns blof field
2017-01-31 15:38:53 +01:00
subtype (0 – binary, 1 – text, etc.).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getLength(StatusType* status, unsigned index) - returns maximum
2017-01-31 15:38:53 +01:00
field length.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
getScale(StatusType* status, unsigned index) - returns scale factor
2017-01-31 15:38:53 +01:00
for numeric field.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getCharSet(StatusType* status, unsigned index) - returns character
2017-01-31 15:38:53 +01:00
set for character field and text blob.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getOffset(StatusType* status, unsigned index) - returns offset of
field data in message buffer (use it to access data in message
2017-01-31 15:38:53 +01:00
buffer).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getNullOffset(StatusType* status, unsigned index) - returns offset
2017-01-31 15:38:53 +01:00
of null indicator for a field in message buffer.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IMetadataBuilder*
2017-01-31 15:38:53 +01:00
getBuilder(StatusType* status) - returns < a href = "#MessageMetadata" > MetadataBuilder< / a >
interface initialized with this message metadata.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getMessageLength(StatusType* status) - returns length of message
2018-05-10 17:18:24 +02:00
buffer (use it to allocate memory for the buffer).< / font > < / p >
2017-10-23 16:10:49 +02:00
< li / >
< p > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > < span style = "background: #ffffff" > unsigned
getAlignment(StatusType* status) – returns alignment required for
message buffer.< / span > < / font > < / font > < / p >
< li / >
< p > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > unsigned< / font > < / font >
< font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > getAlignedLength(StatusType*
status) – returns length of message buffer taking into an account
alignment requirements (use it to allocate memory for an array of
buffers and navigate through that array).< / font > < / font > < / p >
2017-01-31 15:38:53 +01:00
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "MetadataBuilder" > < / a > < font size = "4" style = "font-size: 14pt" > MetadataBuilder
2016-04-07 18:45:09 +02:00
interface – makes it possible to coerce datatypes in existing
2017-01-31 15:38:53 +01:00
message or construct metadata from the beginning.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setType(StatusType* status, unsigned index, unsigned type) – set
2017-01-31 15:38:53 +01:00
SQL type of a field.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setSubType(StatusType* status, unsigned index, int subType) – set
2017-01-31 15:38:53 +01:00
blof field subtype.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setLength(StatusType* status, unsigned index, unsigned length) –
2017-01-31 15:38:53 +01:00
set maximum length of character field.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setCharSet(StatusType* status, unsigned index, unsigned charSet) –
2017-01-31 15:38:53 +01:00
set character set for character field and text blob.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setScale(StatusType* status, unsigned index, unsigned scale) – set
2017-01-31 15:38:53 +01:00
scale factor for numeric field < / font >
< / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
truncate(StatusType* status, unsigned count) – truncate message to
2017-01-31 15:38:53 +01:00
contain not more than count fields.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
moveNameToIndex(StatusType* status, const char* name, unsigned
2016-04-07 18:45:09 +02:00
index) – reorganize fields in a message – move field “name”
2017-01-31 15:38:53 +01:00
to given position.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
remove(StatusType* status, unsigned index) – remove field.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
addField(StatusType* status) – add field.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IMessageMetadata*
2017-01-31 15:38:53 +01:00
getMetadata(StatusType* status) – get < a href = "#10. MessageMetadata" > MessageMetadata< / a >
interface built by this builder.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "OffsetsCallback" > < / a > < font size = "4" style = "font-size: 14pt" > OffsetsCallback
2017-01-31 15:38:53 +01:00
interface:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > setOffset(StatusType*
2016-04-07 18:45:09 +02:00
status, unsigned index, unsigned offset, unsigned nullOffset) –
notifies that offsets for field/parameter number “index” should
be set to passed values. Should be implemented by user when
2017-01-31 15:38:53 +01:00
implementing < a href = "#MessageMetadata" > MessageMetadata< / a >
interface and using < a href = "#Util" > Util< / a > ::setOffsets().< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "PluginConfig" > < / a > < font size = "4" style = "font-size: 14pt" > PluginConfig
2016-04-07 18:45:09 +02:00
interface – passed to plugin's factory when plugin instance (with
2017-01-31 15:38:53 +01:00
particular configuration) to be created.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getConfigFileName() - recommended file name where
configuration for plugin is expected to be stored.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfig*
2016-04-07 18:45:09 +02:00
getDefaultConfig(StatusType* status) – plugin configuration loaded
2017-01-31 15:38:53 +01:00
with default rules.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IFirebirdConf*
2016-04-07 18:45:09 +02:00
getFirebirdConf(StatusType* status) – master firebird
configuration taking into an account per-database settings for a
2017-01-31 15:38:53 +01:00
database with which will work new instance of plugin.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setReleaseDelay(StatusType* status, ISC_UINT64 microSeconds) –
used by plugin to configure recommended delay during which plugin
module will not be unloaded by plugin manager after release of last
2017-01-31 15:38:53 +01:00
plugin instance from that module.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "PluginFactory" > < / a > < font size = "4" style = "font-size: 14pt" > PluginFactory
2016-04-07 18:45:09 +02:00
interface – should be implemented by plugin author when writing
2017-01-31 15:38:53 +01:00
plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IPluginBase*
2016-04-07 18:45:09 +02:00
createPlugin(StatusType* status, IPluginConfig* factoryParameter) –
creates new instance of plugin with passed recommended
2017-01-31 15:38:53 +01:00
configuration.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "PluginManager" > < / a > < font size = "4" style = "font-size: 14pt" > PluginManager
2017-01-31 15:38:53 +01:00
interface – API of plugin manager.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
registerPluginFactory(unsigned pluginType, const char* defaultName,
IPluginFactory* factory) – registers named factory of plugins of
2017-01-31 15:38:53 +01:00
given type.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
registerModule(IPluginModule* cleanup) – registers plugin module.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
unregisterModule(IPluginModule* cleanup) – unregisters plugin
2017-01-31 15:38:53 +01:00
module (in case of unexpected unload by OS).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IPluginSet*
2016-04-07 18:45:09 +02:00
getPlugins(StatusType* status, unsigned pluginType, const char*
namesList, IFirebirdConf* firebirdConf) – returns PluginSet
interface providing access to list of plugins of given type. Names
of plugins to be included are taken from namesList, when missing
(NULL) – from configuration setting for given pluginType. If
firebirdConf parameter is specified it is used for all configuration
purporses (including getting list of plugins and passing to
2017-01-31 15:38:53 +01:00
< a href = "#PluginFactory" > PluginFactory< / a > ::createPlugin() method),
2016-04-07 18:45:09 +02:00
if missing (NULL) – default configuration (from firebird.conf) is
2017-01-31 15:38:53 +01:00
used.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IConfig*
2016-04-07 18:45:09 +02:00
getConfig(StatusType* status, const char* filename) – returns
Config interface for given configuration file name. Can be used by
plugins to access configuration files with standard format but
2017-01-31 15:38:53 +01:00
non-default name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
releasePlugin(IPluginBase* plugin) – release given plugin. Should
be used for plugins instead simple release() due to need to perform
2017-01-31 15:38:53 +01:00
additional actions with plugin owner before actual release.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Constants
2017-01-31 15:38:53 +01:00
defined by PluginManager interface (plugin types):< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_PROVIDER< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_AUTH_SERVER< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_AUTH_CLIENT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_AUTH_USER_MANAGEMENT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_EXTERNAL_ENGINE< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_TRACE< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_WIRE_CRYPT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_DB_CRYPT< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TYPE_KEY_HOLDER< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "PluginModule" > < / a > < font size = "4" style = "font-size: 14pt" > PluginModule
2016-04-07 18:45:09 +02:00
interface – represents plugin module (dynamic library). Should be
implemented by plugin author in each plugin module (one instance per
2017-01-31 15:38:53 +01:00
module).< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
doClean() - called by plugin manager before normal unload of plugin
module.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PluginSet
2017-01-31 15:38:53 +01:00
interface – represents set of plugins of given type. Typically used
by internal firebird code but recommended for use in plugins loading
other plugins.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getName() - get name of current plugin in a set.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getModuleName() - get name of a module of current plugin in a
set (in simple case matches plugin name).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IPluginBase*
2016-04-07 18:45:09 +02:00
getPlugin(StatusType* status) – get an instance of current plugin,
returned interface should be casted to main interface of plugin of
2017-01-31 15:38:53 +01:00
requested in < a href = "#PluginManager" > PluginManager< / a > ::getPlugins()
2016-04-07 18:45:09 +02:00
type. Returns NULL if set does not contain any more plugins.
Reference counter of plugin, returned by this function, is
incremented on return – do not forget to use releasePlugin()
2017-01-31 15:38:53 +01:00
method of < a href = "#PluginManager" > PluginManager< / a > for plugins
returned by this method.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
next(StatusType* status) – make set to switch to next plugin from
the list.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
set(StatusType* status, const char* list) – reset interface: make
it work with list of plugins provided by list parameter. Type of
plugins remains unchanged.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Provider" > < / a > < font size = "4" style = "font-size: 14pt" > Provider
2017-01-31 15:38:53 +01:00
interface – main interface to start database / service access.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IAttachment*
2016-02-26 17:10:48 +01:00
attachDatabase(StatusType* status, const char* fileName, unsigned
2016-04-07 18:45:09 +02:00
dpbLength, const unsigned char* dpb) – replaces
2017-01-31 15:38:53 +01:00
isc_attach_database().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IAttachment*
2016-02-26 17:10:48 +01:00
createDatabase(StatusType* status, const char* fileName, unsigned
2016-04-07 18:45:09 +02:00
dpbLength, const unsigned char* dpb) – replaces
2017-01-31 15:38:53 +01:00
isc_create_database().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IService*
2016-02-26 17:10:48 +01:00
attachServiceManager(StatusType* status, const char* service,
2016-04-07 18:45:09 +02:00
unsigned spbLength, const unsigned char* spb) – replaces
2017-01-31 15:38:53 +01:00
isc_service_attach().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
shutdown(StatusType* status, unsigned timeout, const int reason) –
2017-01-31 15:38:53 +01:00
replaces fb_shutdown().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
setDbCryptCallback(StatusType* status, ICryptKeyCallback*
2016-04-07 18:45:09 +02:00
cryptCallback) – sets database encryption callback interface that
will be used for following database and service attachments. See …
2017-01-31 15:38:53 +01:00
for details.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "ResultSet" > < / a > < font size = "4" style = "font-size: 14pt" > ResultSet
2016-04-07 18:45:09 +02:00
interface – replaces (with extended functionality) some functions
of isc_stmt_handle. This interface is returned by openCursor() call
2017-01-31 15:38:53 +01:00
in < a href = "#Attachment" > IAttachment< / a > or < a href = "#Statement" > IStatement< / a > .
2016-04-07 18:45:09 +02:00
All fetch calls except fetchNext() work only for bidirectional
2017-01-31 15:38:53 +01:00
(opened with CURSOR_TYPE_SCROLLABLE flag) result set.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
fetchNext(StatusType* status, void* message) – fetch next record,
replaces isc_dsql_fetch(). This method (and other fetch methods)
2017-01-31 15:38:53 +01:00
returns < a href = "#Completion codes" > completion code< / a >
2016-04-07 18:45:09 +02:00
Status::RESULT_NO_DATA when EOF is reached, Status::RESULT_OK on
2017-01-31 15:38:53 +01:00
success.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
fetchPrior(StatusType* status, void* message) – fetch previous
2017-01-31 15:38:53 +01:00
record.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
fetchFirst(StatusType* status, void* message) – fetch first
2017-01-31 15:38:53 +01:00
record.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2017-01-31 15:38:53 +01:00
fetchLast(StatusType* status, void* message) – fetch last record.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
fetchAbsolute(StatusType* status, int position, void* message) –
2017-01-31 15:38:53 +01:00
fetch record by it's absolute position in result set.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
fetchRelative(StatusType* status, int offset, void* message) –
2017-01-31 15:38:53 +01:00
fetch record by position relative to current.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2017-01-31 15:38:53 +01:00
isEof(StatusType* status) – check for EOF.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2017-01-31 15:38:53 +01:00
isBof(StatusType* status) – check for BOF.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IMessageMetadata*
2016-04-07 18:45:09 +02:00
getMetadata(StatusType* status) – get metadata for messages in
result set, specially useful when result set is opened by
2017-01-31 15:38:53 +01:00
< a href = "#Attachment" > IAttachment< / a > ::openCursor() call with NULL
2016-04-07 18:45:09 +02:00
output metadata format parameter (this is the only way to obtain
2017-01-31 15:38:53 +01:00
message format in this case).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
close(StatusType* status) – close result set, releases interface
2017-01-31 15:38:53 +01:00
on success.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Service" > < / a > < font size = "4" style = "font-size: 14pt" > Service
2017-01-31 15:38:53 +01:00
interface – replaces isc_svc_handle.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
detach(StatusType* status) – close attachment to services manager,
2017-01-31 15:38:53 +01:00
on success releases interface. Replaces isc_service_detach().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
query(StatusType* status, unsigned sendLength, const unsigned char*
sendItems, unsigned receiveLength, const unsigned char*
receiveItems, unsigned bufferLength, unsigned char* buffer) – send
and request information to/from service, with different receiveItems
may be used for both running services and to obtain various
2017-01-31 15:38:53 +01:00
server-wide information. Replaces isc_service_query().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
start(StatusType* status, unsigned spbLength, const unsigned char*
spb) – start utility in services manager. Replaces
2017-01-31 15:38:53 +01:00
isc_service_start().< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Statement" > < / a > < font size = "4" style = "font-size: 14pt" > Statement
2017-01-31 15:38:53 +01:00
interface – replaces (partially) isc_stmt_handle.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
getInfo(StatusType* status, unsigned itemsLength, const unsigned
2016-04-07 18:45:09 +02:00
char* items, unsigned bufferLength, unsigned char* buffer) –
2017-01-31 15:38:53 +01:00
replaces isc_dsql_sql_info().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getType(StatusType* status) – statement type, currently can be
2017-01-31 15:38:53 +01:00
found only in firebird sources in dsql/dsql.h.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getPlan(StatusType* status, FB_BOOLEAN detailed) – returns
statement execution plan.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_UINT64
2016-04-07 18:45:09 +02:00
getAffectedRecords(StatusType* status) – returns number of records
2017-01-31 15:38:53 +01:00
affected by statement.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IMessageMetadata*
2016-04-07 18:45:09 +02:00
getInputMetadata(StatusType* status) – returns parameters
2017-01-31 15:38:53 +01:00
metadata.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IMessageMetadata*
2016-04-07 18:45:09 +02:00
getOutputMetadata(StatusType* status) – returns output values
2017-01-31 15:38:53 +01:00
metadata.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-03-03 16:03:27 +01:00
execute(StatusType* status, ITransaction* transaction,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata*
2016-04-07 18:45:09 +02:00
outMetadata, void* outBuffer) – executes any SQL statement except
returning multiple rows of data. Partial analogue of
isc_dsql_execute2() - in and out XSLQDAs replaced with input and
2018-05-10 17:18:24 +02:00
output messages with appropriate buffers.< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-23 16:10:49 +02:00
< p style = "margin-bottom: 0cm" > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > IResultSet*
2016-03-03 16:03:27 +01:00
openCursor(StatusType* status, ITransaction* transaction,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata*
2016-04-07 18:45:09 +02:00
outMetadata, unsigned flags) – executes SQL statement potentially
2017-10-23 16:10:49 +02:00
returning multiple rows of data. Returns < a href = "#ResultSet" > ResultSet< / a >
interface which should be used to fetch that data. Format of output
data is defined by outMetadata parameter, leaving it NULL default
format may be used. Parameter flags is needed to open bidirectional
cursor setting it's value to Istatement::CURSOR_TYPE_SCROLLABLE.< / font > < / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > IBatch*
createBatch(StatusType* status, IMessageMetadata* inMetadata, uint
parLength, const uchar* par) – creates < a href = "#Batch" > Batch< / a >
interface to SQL statement with input parameters making it possible
to execute that statement with multiple sets of parameters. Format
of input data is defined by inMetadata parameter, leaving it NULL
makes batch use default format from this interface. Parameters block
may be passed to createBatch() making it possible to adjust batch
behavior.< / font > < / font > < / p >
< li / >
< p style = "margin-bottom: 0cm" > < font face = "Liberation Serif, serif" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setCursorName(StatusType* status, const char* name) – replaces
2017-10-23 16:10:49 +02:00
isc_dsql_set_cursor_name(). < / font > < / font >
2017-01-31 15:38:53 +01:00
< / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
free(StatusType* status) – free statement, releases interface on
success.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getFlags(StatusType* status) – returns < a href = "#Values returned by getFlags" > flags< / a >
2016-04-07 18:45:09 +02:00
describing how this statement should be executed, simplified
2017-01-31 15:38:53 +01:00
replacement of getType() method.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Constants
2017-01-31 15:38:53 +01:00
defined by Statement interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IAttachment::prepare()
2017-01-31 15:38:53 +01:00
flags:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-left: 0.96cm; text-indent: -0.02cm; margin-bottom: 0cm; page-break-before: auto; page-break-after: auto" >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_NONE –
constant to pass no flags, 0 value.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > The
2017-01-31 15:38:53 +01:00
following flags may be OR-ed to get desired set of flags:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_TYPE< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_INPUT_PARAMETERS< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_OUTPUT_PARAMETERS< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_LEGACY_PLAN< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_DETAILED_PLAN< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_AFFECTED_RECORDS< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_FLAGS
2017-01-31 15:38:53 +01:00
(flags returned by getFlags() method)< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Frequently
2017-01-31 15:38:53 +01:00
used combinations of flags:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_METADATA< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > PREPARE_PREFETCH_ALL
2017-01-31 15:38:53 +01:00
< / font >
< / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Values returned by getFlags" > < / a >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > Values returned by getFlags()
method: < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FLAG_HAS_CURSOR
2017-01-31 15:38:53 +01:00
– use openCursor() to execute this statement, not execute()< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FLAG_REPEAT_EXECUTE
2017-01-31 15:38:53 +01:00
– when prepared statement may be executed many times with different
parameters< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Flags passed to openCursor" > < / a >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > Flags passed to openCursor():< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > CURSOR_TYPE_SCROLLABLE
2017-01-31 15:38:53 +01:00
– open bidirectional cursor.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Status" > < / a > < font size = "4" style = "font-size: 14pt" > Status
2016-04-07 18:45:09 +02:00
interface – replaces ISC_STATUS_ARRAY. Functionality is extended –
Status has separate access to errors and warnings vectors, can hold
vectors of unlimited length, itself stores strings used in vectors
avoiding need in circular strings buffer. In C++ Status is always
2017-01-31 15:38:53 +01:00
used under status wrapper, C++ API provides two different < a href = "#Status Wrapper" > wrappers< / a >
2016-04-07 18:45:09 +02:00
having different behavior when error is returned from API call.
Interface is on purpose minimized (methods like convert it to text
2017-01-31 15:38:53 +01:00
are moved to < a href = "#Util" > Util< / a > interface) in order to simplify
it's implementation by users when needed.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
init() - cleanup interface, set it to initial state.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getState() - get current state of interface, returns < a href = "#returned by getState" > state
flags< / a > , may be OR-ed.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setErrors2(unsigned length, const intptr_t* value) – set contents
2017-01-31 15:38:53 +01:00
of errors vector with length explicitly specified in a call.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setWarnings2(unsigned length, const intptr_t* value) – set
contents of warnings vector with length explicitly specified in a
2017-01-31 15:38:53 +01:00
call.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
setErrors(const intptr_t* value) – set contents of errors vector,
length is defined by value context.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setWarnings(const intptr_t* value) – set contents of warnings
2017-01-31 15:38:53 +01:00
vector, length is defined by value context.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
intptr_t* getErrors() - get errors vector.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
intptr_t* getWarnings() - get warnings vector.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IStatus*
2017-01-31 15:38:53 +01:00
clone() - create clone of current interface.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Constants
2017-01-31 15:38:53 +01:00
defined by Status interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "returned by getState" > < / a > < font size = "4" style = "font-size: 14pt" > Flags
2017-01-31 15:38:53 +01:00
set in the value, returned by getState() method:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > STATE_WARNINGS< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > STATE_ERRORS< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Completion codes" > < / a > < font size = "4" style = "font-size: 14pt" > Completion
2017-01-31 15:38:53 +01:00
codes:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > RESULT_ERROR< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > RESULT_OK< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > RESULT_NO_DATA< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > RESULT_SEGMENT< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Timer" > < / a > < font size = "4" style = "font-size: 14pt" > Timer
2016-04-07 18:45:09 +02:00
interface – user timer. Callback interface which should be
2017-01-31 15:38:53 +01:00
implemented by user to use firebird timer.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
handler() - method is called when timer rings (or when server is
shutting down).< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "TimerControl" > < / a > < font size = "4" style = "font-size: 14pt" > TimerControl
2016-04-07 18:45:09 +02:00
interface – very simple and not too precise implementation of
timer. Arrived here because existing timers are very much OS
dependent and may be used in programs that require to be portable and
do not need really high precision timer. Particularly execution of
given timer may be delayed if another one has not completed at the
2017-01-31 15:38:53 +01:00
moment when given timer should alarm.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
start(StatusType* status, ITimer* timer, ISC_UINT64 microSeconds) –
2017-01-31 15:38:53 +01:00
start < a href = "#Timer" > ITimer< / a > to alarm after given delay (in
microseconds, 10< / font > < sup > < font size = "4" style = "font-size: 14pt" > -6< / font > < / sup >
< font size = "4" style = "font-size: 14pt" > seconds). Timer will be waked
up only once after this call.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
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 races between stop() and timer alarm.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Transaction" > < / a > < font size = "4" style = "font-size: 14pt" > Transaction
2017-01-31 15:38:53 +01:00
interface – replaces isc_tr_handle.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
getInfo(StatusType* status, unsigned itemsLength, const unsigned
2016-04-07 18:45:09 +02:00
char* items, unsigned bufferLength, unsigned char* buffer) –
2017-01-31 15:38:53 +01:00
replaces isc_transaction_info().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-03-03 16:03:27 +01:00
prepare(StatusType* status, unsigned msgLength, const unsigned char*
2017-01-31 15:38:53 +01:00
message) – replaces isc_prepare_transaction2().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
commit(StatusType* status) – replaces isc_commit_transaction().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
commitRetaining(StatusType* status) – replaces
2017-01-31 15:38:53 +01:00
isc_commit_retaining().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
rollback(StatusType* status) – replaces
2017-01-31 15:38:53 +01:00
isc_rollback_transaction().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
rollbackRetaining(StatusType* status) – replaces
2017-01-31 15:38:53 +01:00
isc_rollback_retaining().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
disconnect(StatusType* status) – replaces
2017-01-31 15:38:53 +01:00
fb_disconnect_transaction().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-04-07 18:45:09 +02:00
join(StatusType* status, ITransaction* transaction) – joins
current transaction and passed as parameter transaction into single
2017-01-31 15:38:53 +01:00
distributed transaction (using < a href = "#Dtc" > Dtc< / a > ). On success
2016-04-07 18:45:09 +02:00
both current transaction and passed as parameter transaction are
2017-01-31 15:38:53 +01:00
released and should not be used any more.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-04-07 18:45:09 +02:00
validate(StatusType* status, IAttachment* attachment) – this
2017-01-31 15:38:53 +01:00
method is used to support distributed transactions coordinator.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ITransaction*
2016-04-07 18:45:09 +02:00
enterDtc(StatusType* status) – this method is used to support
2017-01-31 15:38:53 +01:00
distributed transactions coordinator.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "VersionCallback" > < / a > < font size = "4" style = "font-size: 14pt" > VersionCallback
2017-01-31 15:38:53 +01:00
interface – callback for < a href = "#Util" > Util< / a > ::getFbVersion().< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
callback(StatusType* status, const char* text) – called by
firebird engine for each line in multiline version report. Makes it
possible to print that lines one by one, place them into message box
2017-01-31 15:38:53 +01:00
in any GUI, etc.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Util" > < / a > < font size = "4" style = "font-size: 14pt" > Util
2017-01-31 15:38:53 +01:00
interface – various helper methods required here or there.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
getFbVersion(StatusType* status, IAttachment* att, IVersionCallback*
2016-04-07 18:45:09 +02:00
callback) – produce long and beautiful report about firebird
2017-01-31 15:38:53 +01:00
version used. It may be seen in ISQL when invoked with -Z switch.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
loadBlob(StatusType* status, ISC_QUAD* blobId, IAttachment* att,
2016-04-07 18:45:09 +02:00
ITransaction* tra, const char* file, FB_BOOLEAN txt) – load blob
2017-01-31 15:38:53 +01:00
from file.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
dumpBlob(StatusType* status, ISC_QUAD* blobId, IAttachment* att,
2016-04-07 18:45:09 +02:00
ITransaction* tra, const char* file, FB_BOOLEAN txt) – save blob
2017-01-31 15:38:53 +01:00
to file.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
getPerfCounters(StatusType* status, IAttachment* att, const char*
2016-04-07 18:45:09 +02:00
countersSet, ISC_INT64* counters) – get statistics for given
2017-01-31 15:38:53 +01:00
attachment.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IAttachment*
2016-02-26 17:10:48 +01:00
executeCreateDatabase(StatusType* status, unsigned stmtLength, const
char* creatDBstatement, unsigned dialect, FB_BOOLEAN*
2016-04-07 18:45:09 +02:00
stmtIsCreateDb) – execute “CREATE DATABASE ...” statement –
2017-01-31 15:38:53 +01:00
ISC trick with NULL statement handle does not work with interfaces.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
decodeDate(ISC_DATE date, unsigned* year, unsigned* month, unsigned*
2017-01-31 15:38:53 +01:00
day) – replaces isc_decode_sql_date().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
decodeTime(ISC_TIME time, unsigned* hours, unsigned* minutes,
2016-04-07 18:45:09 +02:00
unsigned* seconds, unsigned* fractions) – replaces
2017-01-31 15:38:53 +01:00
isc_decode_sql_time().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_DATE
2016-04-07 18:45:09 +02:00
encodeDate(unsigned year, unsigned month, unsigned day) – replaces
2017-01-31 15:38:53 +01:00
isc_encode_sql_date().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_TIME
2016-02-26 17:10:48 +01:00
encodeTime(unsigned hours, unsigned minutes, unsigned seconds,
2017-01-31 15:38:53 +01:00
unsigned fractions) – replaces isc_encode_sql_time().< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
formatStatus(char* buffer, unsigned bufferSize, IStatus* status) –
2016-09-05 12:23:30 +02:00
replaces fb_interpret(). Size of buffer, passed into this method,
2017-01-31 15:38:53 +01:00
should not be less than 50 bytes.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getClientVersion() – returns integer, containing major version in
2017-01-31 15:38:53 +01:00
byte 0 and minor version in byte 1.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IXpbBuilder*
2016-02-26 17:10:48 +01:00
getXpbBuilder(StatusType* status, unsigned kind, const unsigned
2017-01-31 15:38:53 +01:00
char* buf, unsigned len) – returns < a href = "#XpbBuilder" > XpbBuilder< / a >
interface. Valid < a href = "#Valid builder types" > kinds< / a > are
enumerated in < a href = "#XpbBuilder" > XpbBuilder< / a > .< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-02-26 17:10:48 +01:00
setOffsets(StatusType* status, IMessageMetadata* metadata,
2016-04-07 18:45:09 +02:00
IOffsetsCallback* callback) – sets valid offsets in
2017-01-31 15:38:53 +01:00
< a href = "#MessageMetadata" > MessageMetadata< / a > . Performs calls to
callback in < a href = "#OffsetsCallback" > OffsetsCallback< / a > for each
field/parameter.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "XpbBuilder" > < / a > < font size = "4" style = "font-size: 14pt" > XpbBuilder
2017-01-31 15:38:53 +01:00
methods:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
clear(StatusType* status) – reset builder to empty state.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
removeCurrent(StatusType* status) – removes current clumplet.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
insertInt(StatusType* status, unsigned char tag, int value) –
inserts a clumplet with value representing integer in network
2017-01-31 15:38:53 +01:00
format.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
insertBigInt(StatusType* status, unsigned char tag, ISC_INT64 value)
– inserts a clumplet with value representing integer in network
2017-01-31 15:38:53 +01:00
format.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-02-26 17:10:48 +01:00
insertBytes(StatusType* status, unsigned char tag, const void*
2016-04-07 18:45:09 +02:00
bytes, unsigned length) - inserts a clumplet with value containing
2017-01-31 15:38:53 +01:00
passed bytes.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
insertTag(StatusType* status, unsigned char tag) – inserts a
2017-01-31 15:38:53 +01:00
clumplet without a value.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2016-04-07 18:45:09 +02:00
isEof(StatusType* status) – checks that there is no current
2017-01-31 15:38:53 +01:00
clumplet.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
moveNext(StatusType* status) – moves to next clumplet.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
rewind(StatusType* status) – moves to first clumplet.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2016-04-07 18:45:09 +02:00
findFirst(StatusType* status, unsigned char tag) – finds first
2017-01-31 15:38:53 +01:00
clumplet with given tag.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2017-01-31 15:38:53 +01:00
findNext(StatusType* status) – finds next clumplet with given tag.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
char getTag(StatusType* status) – returns tag for current
clumplet.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getLength(StatusType* status) – returns length of current clumplet
2017-01-31 15:38:53 +01:00
value.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
getInt(StatusType* status) – returns value of current clumplet as
2017-01-31 15:38:53 +01:00
integer.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_INT64
2016-04-07 18:45:09 +02:00
getBigInt(StatusType* status) – returns value of current clumplet
2017-01-31 15:38:53 +01:00
as 64-bit integer.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getString(StatusType* status) – returns value of current
clumplet as pointer to zero-terminated string (pointer is valid till
next call to this method).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
unsigned char* getBytes(StatusType* status) – returns value of
current clumplet as pointer to unsigned char.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
getBufferLength(StatusType* status) – returns length of parameters
2017-01-31 15:38:53 +01:00
block.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
unsigned char* getBuffer(StatusType* status) – returns pointer to
parameters block.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Constants
2017-01-31 15:38:53 +01:00
defined by XpbBuilder interface:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Valid builder types" > < / a > < font size = "4" style = "font-size: 14pt" > Valid
2017-01-31 15:38:53 +01:00
builder types:< / font > < / p >
2017-10-23 16:10:49 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > BATCH< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > DPB< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > SPB_ATTACH< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > SPB_START< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > TPB< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Plugin, encrypting data
transferred over the wire.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Algorithms
2017-01-31 15:38:53 +01:00
performing encryption of data for different purposes are well known
for many years. The only “little” typical problem remaining is
where to get the top secret key to be used by that algorithm. Luckily
for network traffic encryption there is one good solution – unique
2016-04-07 18:45:09 +02:00
encryption key should be generated by authentication plugin. At least
default SRP plugin can produce such a key. And that key is resistant
to attacks, including man-in-the-middle. Therefore was chosen a
method of providing keys for wire crypt plugin: get it from
authentication plugin. (In case when used authentication plugin can
not provide a key a pseudo-plugin may be added in AuthClient and
AuthServer lists to produce keys, something like two asymmetric
2017-01-31 15:38:53 +01:00
private/public pairs.) < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > CryptKey
2017-01-31 15:38:53 +01:00
interface is used to store a key provided by authentication plugin
and pass it to wire crypt plugin. This interface should be used as
follows – when server or client authentication plugin is ready to
provide a key it asks < a href = "#ServerBlock" > ServerBlock< / a > or
< a href = "#ClientBlock" > ClientBlock< / a > to produce new CryptKey
interface and stores a key in it. Appropriate for < a href = "#WireCryptPlugin" > WireCryptPlugin< / a >
type of key will be selected by firebird and passed to that
interface.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setSymmetric(StatusType* status, const char* type, unsigned
2016-09-05 12:23:30 +02:00
keyLength, const void* key) – make it store symmetric key of given
2017-01-31 15:38:53 +01:00
type.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setAsymmetric(StatusType* status, const char* type, unsigned
encryptKeyLength, const void* encryptKey, unsigned decryptKeyLength,
const void* decryptKey) – make it store pair of asymmetric keys of
2017-01-31 15:38:53 +01:00
given type.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
void* getEncryptKey(unsigned* length) – get a key for encryption.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
void* getDecryptKey(unsigned* length) – get a key for decryption
(in case of symmetric key produces same result as getEncryptKey()).< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "WireCryptPlugin" > < / a > < font size = "4" style = "font-size: 14pt" > WireCryptPlugin
2016-04-07 18:45:09 +02:00
interface is main interface of network crypt plugin. Like any other
2017-01-31 15:38:53 +01:00
such interface it should be implemented by author of the plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getKnownTypes(StatusType* status) – returns
whitespace/tab/comma separated list of acceptable keys.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setKey(StatusType* status, ICryptKey* key) – plugin should use a
2017-01-31 15:38:53 +01:00
key passed to it by this call.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
encrypt(StatusType* status, unsigned length, const void* from, void*
2017-01-31 15:38:53 +01:00
to) – encrypts a packet to be sent over the wire.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
decrypt(StatusType* status, unsigned length, const void* from, void*
2017-01-31 15:38:53 +01:00
to) – decrypts a packet received from network.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Server side of
authentication plugin.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Authentication
2017-01-31 15:38:53 +01:00
plugin contains two required parts – client and server and may also
2016-04-07 18:45:09 +02:00
contain related third part - user manager. During authentication
process firebird client invokes client plugin and sends generated by
it data to server, next server invokes server plugin and sends
generated by it data to client. This process repeats as long as both
plugins return AUTH_MORE_DATA code. AUTH_SUCCESS returned at server
side means successful authentication, AUTH_FAILED at any side –
immediate abort of iterative process and failure reported to client,
AUTH_CONTINUE means that next plugin from the list of configured
2017-01-31 15:38:53 +01:00
authentication plugins should be tried.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > There
2017-01-31 15:38:53 +01:00
is no dedicated sample of authentication plugins but in firebird
sources in directory src/auth one can find AuthDbg plugin using which
one can learn on trivial example (no complex calculations like in Srp
and no calls to crazy WinAPI functions like in AuthSspi) how client
and server sides perform authentication handshake. < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Auth
2017-01-31 15:38:53 +01:00
interface does not contain methods, only some constants defining
codes return from authenticate() method of < a href = "#Client" > Client< / a >
and < a href = "#Server" > Server< / a > .< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > AUTH_FAILED< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > AUTH_SUCCESS< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > AUTH_MORE_DATA< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > AUTH_CONTINUE< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Writer" > < / a > < font size = "4" style = "font-size: 14pt" > Writer
2017-01-31 15:38:53 +01:00
interface – writes authentication parameters block.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
reset() - clear target block.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
add(StatusType* status, const char* name) – add login name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setType(StatusType* status, const char* value) – set type of added
2017-01-31 15:38:53 +01:00
login (user, group, etc).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setDb(StatusType* status, const char* value) – set security
2017-01-31 15:38:53 +01:00
database in which authentication was done.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "ServerBlock" > < / a > < font size = "4" style = "font-size: 14pt" > ServerBlock
2016-04-07 18:45:09 +02:00
interface is used by server side of authentication plugin to exchange
2017-01-31 15:38:53 +01:00
data with client.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getLogin() - get login name passed from client.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
unsigned char* getData(unsigned* length) – get authentication data
passed from client.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
putData(StatusType* status, unsigned length, const void* data) –
2017-01-31 15:38:53 +01:00
pass authentication data to client.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICryptKey*
2016-04-07 18:45:09 +02:00
newKey(StatusType* status) – create new wire crypt key and add it
2017-01-31 15:38:53 +01:00
to the list of available for wire crypt plugins.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Server" > < / a > < font size = "4" style = "font-size: 14pt" > Server
2017-01-31 15:38:53 +01:00
interface is main interface of server side of authentication plugin. < / font >
< / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
authenticate(StatusType* status, IServerBlock* sBlock, IWriter*
writerInterface) – perform single authentication step. Data
exchange with client is performed using sBlock interface. When some
authentication item is produced it should be added to authentication
block using writerInterface. Possible return values are defined in
2017-01-31 15:38:53 +01:00
< a href = "#Auth" > Auth< / a > interface.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Client side of
authentication plugin.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "ClientBlock" > < / a > < font size = "4" style = "font-size: 14pt" > ClientBlock
2016-04-07 18:45:09 +02:00
interface is used by client side of authentication plugin to exchange
2017-01-31 15:38:53 +01:00
data with server.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getLogin() - get login name if it is present in DPB.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* getPassword() - get password if it is present in DPB.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
unsigned char* getData(unsigned* length) – get authentication data
passed from server.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
putData(StatusType* status, unsigned length, const void* data) –
2017-01-31 15:38:53 +01:00
pass authentication data to server.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICryptKey*
2016-04-07 18:45:09 +02:00
newKey(StatusType* status) - create new wire crypt key and add it to
2017-01-31 15:38:53 +01:00
the list of available for wire crypt plugins.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Client" > < / a > < font size = "4" style = "font-size: 14pt" > Client
2017-01-31 15:38:53 +01:00
interface is main interface of client side of authentication plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
authenticate(StatusType* status, IClientBlock* cBlock)1. – perform
single authentication step. Data exchange with server is performed
using cBlock interface. Possible return values are defined in Auth
interface. AUTH_SUCCESS is treated by client side as AUTH_MORE_DATA
(i.e. client sends generated data to server and waits for an answer
2017-01-31 15:38:53 +01:00
from it).< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > User management plugin.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > This
2017-01-31 15:38:53 +01:00
plugin is actively related with server side of authentication – it
prepares users' list for authentication plugin. Not each
authentication plugin requires user manager – some may access list
of users created using non-firebird software (AuthSspi for example).
Record describing user consists of a number of fields and operation
which should be performed like add user, modify user, list user(s),
etc. Plugin must interpret commands received in < a href = "#User" > User< / a >
interface.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "UserField" > < / a > < font size = "4" style = "font-size: 14pt" > UserField
2016-04-07 18:45:09 +02:00
interface is not used as standalone interface, it's base for
2017-01-31 15:38:53 +01:00
CharUserField and IntUserField. < / font >
< / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2017-01-31 15:38:53 +01:00
entered() - returns non-zero if a value for a field was entered
(assigned).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2017-01-31 15:38:53 +01:00
specified() - return non-zero if NULL value was assigned to the
field.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setEntered(StatusType* status, int newValue) – sets entered flag
to 0/non-zero value for a field. There is no method to assign NULL
for a field cause it's never needed. NULLs if used are assigned by
the code implementing interfaces and therefore having full access to
2017-01-31 15:38:53 +01:00
internals of them.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "CharUserField" > < / a > < font size = "4" style = "font-size: 14pt" > CharUserField
2017-01-31 15:38:53 +01:00
interface:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* get() - get field's value as C-string (\0 terminated).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
set(StatusType* status, const char* newValue) – assigns value to
the field. Sets entered flag to true.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "IntUserField" > < / a > < font size = "4" style = "font-size: 14pt" > IntUserField
2017-01-31 15:38:53 +01:00
interface:< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2017-01-31 15:38:53 +01:00
get() - get field's value.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
set(StatusType* status, int newValue) – assigns value to the
field. Sets entered flag to true.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "User" > < / a > < font size = "4" style = "font-size: 14pt" > User
2016-04-07 18:45:09 +02:00
interface is a list of methods accessing fields included into record
2017-01-31 15:38:53 +01:00
about the user. < / font >
< / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
operation() - code of operation (see < a href = "#Constants defined by User interface" > list< / a >
below).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2017-01-31 15:38:53 +01:00
userName() - login name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2017-01-31 15:38:53 +01:00
password() - password. Always empty when listing users.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2017-01-31 15:38:53 +01:00
firstName() - this and 2 next are components of full user name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2017-01-31 15:38:53 +01:00
lastName()< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2017-01-31 15:38:53 +01:00
middleName()< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2017-01-31 15:38:53 +01:00
comment() - comment (from SQL operator COMMENT ON USER IS …).< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICharUserField*
2016-04-07 18:45:09 +02:00
attributes() - tags in a form tag1=val1, tag2=val2, …, tagN=valN.
2017-01-31 15:38:53 +01:00
Val may be empty – than means that tag will be deleted.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IIntUserField*
2017-01-31 15:38:53 +01:00
active() - changes ACTIVE/INACTIVE setting for user.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > IIntUserField*
2017-01-31 15:38:53 +01:00
admin() - sets/drops admin rights for the user.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
clear(StatusType* status) – sets all fields to not entered and not
2017-01-31 15:38:53 +01:00
specified.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Constants defined by User interface" > < / a >
2017-01-31 15:38:53 +01:00
< font size = "4" style = "font-size: 14pt" > Constants defined by User
interface – valid codes of operation.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > OP_USER_ADD
2017-01-31 15:38:53 +01:00
– create user< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > OP_USER_MODIFY
2017-01-31 15:38:53 +01:00
– alter user< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > OP_USER_DELETE
2017-01-31 15:38:53 +01:00
– drop user< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > OP_USER_DISPLAY
2017-01-31 15:38:53 +01:00
– show user< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > OP_USER_SET_MAP
2017-01-31 15:38:53 +01:00
– turn on mapping of windows admins to role rdb$admin< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > OP_USER_DROP_MAP
2017-01-31 15:38:53 +01:00
– turn off mapping of windows admins to role rdb$admin< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "ListUsers" > < / a > < font size = "4" style = "font-size: 14pt" > ListUsers
2016-04-07 18:45:09 +02:00
interface is callback used by authentication plugin when list users
2017-01-31 15:38:53 +01:00
operation is requested. Plugin fills < a href = "#User" > User< / a >
2016-04-07 18:45:09 +02:00
interface for all items in list of users one by one and for each user
2017-01-31 15:38:53 +01:00
calls list() method of this interface.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
list(StatusType* status, IUser* user) – callback function.
Implementation can do what it wants with received data. For example,
it may put data from user parameter into output stream of listing
service or place into special tables from SEC$ group.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "LogonInfo" > < / a > < font size = "4" style = "font-size: 14pt" > LogonInfo
2016-04-07 18:45:09 +02:00
interface contains data passed to user mamngement plugin to attach to
2017-01-31 15:38:53 +01:00
security database with valid credentials. Pres< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* name() - returns current attachment's login name.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* role() - returns current attachment's active role.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* networkProtocol() - returns current attachment's network
protocol. Currently not used by plugins.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
char* remoteAddress() - returns current attachment's remote address.
Currently not used by plugins.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-01-31 15:38:53 +01:00
unsigned char* authBlock(unsigned* length) – returns current
attachment's authentication block. When not NULL overrides login
name.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "Management" > < / a > < font size = "4" style = "font-size: 14pt" > Management
2017-01-31 15:38:53 +01:00
interface is main interface of user management plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
start(StatusType* status, ILogonInfo* logonInfo) – starts plugin,
if needed it attaches to security database to manage may be (it's
plugin-dependent solution use it or not) using credentials from
2017-01-31 15:38:53 +01:00
logonInfo. < / font >
< / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
execute(StatusType* status, IUser* user, IListUsers* callback) –
executes a command provided by operation() method of user parameter.
If needed callback interface will be used. Parameter callback may
2017-01-31 15:38:53 +01:00
have NULL value for commands not requiring users' listing.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
commit(StatusType* status) – commits changes done by calls to
2017-01-31 15:38:53 +01:00
execute() method.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
rollback(StatusType* status) – rollbacks changes done by calls to
2017-01-31 15:38:53 +01:00
execute() method.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Database encryption
plugin.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > An
2017-01-31 15:38:53 +01:00
ability to encrypt database was present in firebird since interbase
times but appropriate places in the code were commented.
Implementation was suspicious – crypt key was always sent from the
client in DPB, no attempt was made to hide it from the world and no
way was suggested to encrypt existing database. FB3 solves most of
the problems except probably the worst one – how to manage crypt
keys. We suggest a kind of solution but it requires efforts in
plugins, i.e. there is no beautiful way to work with keys like it is
for wire crypt plugins.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Before
2017-01-31 15:38:53 +01:00
starting with own db crypt plugin one should take into an account the
following. We see two main usages of database encryption – first,
it may be needed to avoid data loss if database server is physically
stolen, and second, it may be used to protect data in database which
is sailed together with special application accessing that data.
Requirements for this usages are quite different. In first case we
may trust database server that it is not modified to steal keys
passed to security plugin – i.e. we expect that key will not be
sent to inappropriate server. In second case server may be modified
in some way to steal keys (if they are passed from application to
plugin via server code) or even data (as the last resort to dump
blocks from the cache where they are in non-encrypted form).
Therefore your plugin should make sure that it's running with not
modified firebird binaries and your application before sending a key
to plugin should make sure it's really required plugin, may be asking
a kind of digital signature from it. Making sure that network line is
encrypted (parsing output of < a href = "#Util" > Util< / a > ::getFbVersion())
2016-04-07 18:45:09 +02:00
or using some own encryption of a key is also very good idea in case
when network access to the server is used. All this job should be
done in plugin (and application working with it) i.e. database block
encryption algorithm by itself may happen to be easiest part of db
2017-02-02 15:05:46 +01:00
crypt plugin, specially when some standard library is used for it.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "CryptKeyCallback" > < / a > < font size = "4" style = "font-size: 14pt" > CryptKeyCallback
2016-04-07 18:45:09 +02:00
interface should be provided by a side sending crypt key to db crypt
2017-01-31 15:38:53 +01:00
plugin or key holder plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2016-04-07 18:45:09 +02:00
callback(unsigned dataLength, const void* data, unsigned
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
2017-01-31 15:38:53 +01:00
buffer returning actual number of bytes placed into buffer.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
2017-02-02 15:05:46 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "DbCryptInfo" > < / a > < font size = "4" style = "font-size: 14pt" > DbCryptInfo
2017-02-02 15:05:46 +01:00
interface is passed to DbCryptPlugin by engine. Plugin may save this
interface and use when needed to obtain additional informatio about
database.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > const
2017-02-02 15:05:46 +01:00
char* getDatabaseFullPath(StatusType* status) – returns full
(including path) name of primary database file.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-02-02 15:05:46 +01:00
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "DbCryptPlugin" > < / a > < font size = "4" style = "font-size: 14pt" > DbCryptPlugin
2017-01-31 15:38:53 +01:00
interface is main interface of database crypt plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
setKey(StatusType* status, unsigned length, IKeyHolderPlugin**
sources, const char* keyName) – is used to provide to db crypt
plugin information about encryption key. Firebird never passes keys
2017-01-31 15:38:53 +01:00
for this type of plugin directly. Instead array of < a href = "#KeyHolderPlugin" > KeyHolderPlugins< / a >
2016-04-07 18:45:09 +02:00
of given length is passed to crypt plugin which must get from one of
2017-01-31 15:38:53 +01:00
it < a href = "#CryptKeyCallback" > CryptKeyCallback< / a > interface and
2016-04-07 18:45:09 +02:00
get a key using it. Parameter keyName is a name of a key like it was
2017-01-31 15:38:53 +01:00
entered in “ALTER DATABASE ENCRYPT …” operator.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
encrypt(StatusType* status, unsigned length, const void* from, void*
2017-01-31 15:38:53 +01:00
to) – encrypts data before writing block to database file.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2016-04-07 18:45:09 +02:00
decrypt(StatusType* status, unsigned length, const void* from, void*
2017-01-31 15:38:53 +01:00
to) – decrypts data after reading block from database file.< / font > < / p >
2017-02-02 15:05:46 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-02-02 15:05:46 +01:00
setInfo(StatusType* status, IDbCryptInfo* info) – in this method
crypt plugin typically saves informational interface for future use.< / font > < / p >
2017-01-31 15:38:53 +01:00
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Key holder for database
encryption plugin.< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > This
2017-01-31 15:38:53 +01:00
type of plugin is needed to delineate functionality – db crypt
plugin is dealing with actual encryption, key holder solves questions
related with providing it a key in secure way. Plugin may be received
from application or loaded in some other way (up to using flash
device inserted into server at firebird startup time).< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "KeyHolderPlugin" > < / a > < font size = "4" style = "font-size: 14pt" > KeyHolderPlugin
2017-01-31 15:38:53 +01:00
interface is main interface of database crypt key holder plugin.< / font > < / p >
< ol >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > int
2016-04-07 18:45:09 +02:00
keyCallback(StatusType* status, ICryptKeyCallback* callback) – is
2017-01-31 15:38:53 +01:00
used to pass attachment's < a href = "#CryptKeyCallback" > CryptKeyCallback< / a >
interface (if provided by user with < a href = "#Provider" > Provider< / a > ::setDbCryptCallback()
2016-04-07 18:45:09 +02:00
call). This call is always performed at database attach moment, and
some holders may reject attachment if satisfactory key was not
2018-05-10 17:18:24 +02:00
provided. < / font > < font size = "4" style = "font-size: 14pt" > Return value
of 0 means that key holder can not provide a key to crypt plugin,
non-zero – can.< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICryptKeyCallback*
2016-04-07 18:45:09 +02:00
keyHandle(StatusType* status, const char* keyName) – is intended
2017-01-31 15:38:53 +01:00
to be called by < a href = "#DbCryptPlugin" > DbCryptPlugin< / a > directly
2016-04-07 18:45:09 +02:00
to obtain callback interface for named key from key holder. This
makes it possible for open source firebird code to never touch
actual keys avoiding ability to steal a key changing firebird code.
2017-01-31 15:38:53 +01:00
After getting < a href = "#CryptKeyCallback" > CryptKeyCallback< / a >
2016-04-07 18:45:09 +02:00
interface crypt plugin starts data exchange using it. Key holder can
(for example) check digital signature of crypt plugin before sending
a key to it in order to avoid use of modified crypt plugin able to
2017-01-31 15:38:53 +01:00
steal secret key.< / font > < / p >
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FB_BOOLEAN
2017-01-31 15:38:53 +01:00
useOnlyOwnKeys(StatusType* status) – informs firebird engine
2018-05-10 17:18:24 +02:00
whether a key, provided by key holder, can be used in other
attachments. Makes sense only for SuperServer – only it can share
database crypt keys between attachments. Returning FB_TRUE from this
method enforces firebird to make sure that this particular key
holder (and therefore in turn attachment related to it) provides
correct crypt key for any other attachment to this database.< / font > < / p >
2017-01-31 15:38:53 +01:00
< li / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ICryptKeyCallback*
2017-02-02 15:05:46 +01:00
chainHandle(StatusType* status) – support of a chain of key
holders. In some cases key has to pass through more than single key
holder before it reaches db crypt plugin. This is needed (for
example) to support execute statement in encrypted database. This is
just a sample – chains are also used in some other cases. Callback
2017-01-31 15:38:53 +01:00
interface, returned by this method, may differ from one returned by
keyHandle() function (see above). Typically is should be able to
duplicate one-to-one keys, received by KeyHolderPlugin when
keyCallback() function is invoked.< / font > < / p >
< / ol >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< h1 > < font size = "4" style = "font-size: 14pt" > Non-interface objects used
by API (C++ specific header Message.h).< / font > < / h1 >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Following
2017-01-31 15:38:53 +01:00
3 classes are used to represent date, time and timestamp (datetime)
when using FB_MESSAGE macro. Members of data structure, representing
static message, correspondint to fields of types FB_DATE / FB_TIME /
2016-04-07 18:45:09 +02:00
FB_TIMESTAMP will have a type of one of this classes. Knowing methods
/ members (which are enough self-descriptive to avoid describing them
here) of this classes is needed to access date and time fields in
2017-01-31 15:38:53 +01:00
static messages.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "FbDate" > < / a > < font size = "4" style = "font-size: 14pt" > class
2017-01-31 15:38:53 +01:00
FbDate methods:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
decode(IUtil* util, unsigned* year, unsigned* month, unsigned* day)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getYear(IUtil* util) < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getMonth(IUtil* util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getDay(IUtil* util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
encode(IUtil* util, unsigned year, unsigned month, unsigned day)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "FbTime" > < / a > < font size = "4" style = "font-size: 14pt" > class
2017-01-31 15:38:53 +01:00
FbTime methods:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
decode(IUtil* util, unsigned* hours, unsigned* minutes, unsigned*
seconds, unsigned* fractions)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getHours(IUtil* util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getMinutes(IUtil* util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getSeconds(IUtil* util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > unsigned
2017-01-31 15:38:53 +01:00
getFractions(IUtil* util)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
encode(IUtil* util, unsigned hours, unsigned minutes, unsigned
seconds, unsigned fractions)< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > class
2017-01-31 15:38:53 +01:00
FbTimestamp members:< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FbDate
2017-01-31 15:38:53 +01:00
date;< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > FbTime
2017-01-31 15:38:53 +01:00
time;< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > Following
2017-01-31 15:38:53 +01:00
two templates are used in static messages to represent CHAR(N) and
VARCHAR(N) fields. < / font >
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > template
2017-01-31 15:38:53 +01:00
< unsigned N> < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "FbChar" > < / a > < font size = "4" style = "font-size: 14pt" > struct
2017-01-31 15:38:53 +01:00
FbChar< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > {< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > char
2017-01-31 15:38:53 +01:00
str[N];< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > };< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > template
2017-01-31 15:38:53 +01:00
< unsigned N> < / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < a name = "FbVarChar" > < / a > < font size = "4" style = "font-size: 14pt" > struct
2017-01-31 15:38:53 +01:00
FbVarChar< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > {< / font > < / p >
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > ISC_USHORT
2017-01-31 15:38:53 +01:00
length;< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > char
2017-01-31 15:38:53 +01:00
str[N];< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > void
2017-01-31 15:38:53 +01:00
set(const char* s);< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > };< / font > < / p >
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< hr / >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < font size = "4" style = "font-size: 14pt" > This
2017-01-31 15:38:53 +01:00
document is currently missing 2 types of plugins – ExternalEngine
and Trace. Information about them will be made available in next
release of it.< / font > < / p >
2017-10-17 12:16:29 +02:00
< p style = "margin-bottom: 0cm" > < br / >
2017-01-31 15:38:53 +01:00
< / p >
< / body >
< / html >