8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00
firebird-mirror/doc/Using_OO_API.html
asfernandes 703b59212f Typos.
2016-02-25 01:07:40 +00:00

211 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice 4.1.2 (Unix)">
<META NAME="AUTHOR" CONTENT="alex ">
<META NAME="CREATED" CONTENT="20130531;10003100">
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
<META NAME="CHANGED" CONTENT="20160224;18294800">
<STYLE TYPE="text/css">
<!--
@page { size: 8.5in 11in; margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</STYLE>
</HEAD>
<BODY LANG="en-US" DIR="LTR">
<P STYLE="margin-top: 0.17in; margin-bottom: 0.2in; page-break-after: avoid">
<FONT FACE="Albany, sans-serif"><FONT SIZE=4>Firebird interfaces.</FONT></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Firebird's 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 ither widely
used types of interfaces. First of all Firebird interfaces are
</FONT><FONT SIZE=4><B>language independent</B></FONT><FONT SIZE=4>
that means that to define/use them one need not use language specific
constructions like </FONT><FONT SIZE=4><I>class</I></FONT><FONT SIZE=4>
in C++, interface may be defined using any language having concepts
of array and pointer to procedure/function. Next interfaces are
</FONT><FONT SIZE=4><SPAN STYLE="font-style: normal"><B>versioned</B></SPAN></FONT><FONT SIZE=4>
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><SPAN STYLE="font-weight: normal">QueryInterface</SPAN></FONT></STRONG><STRONG><FONT SIZE=4>)</FONT></STRONG><STRONG><FONT SIZE=4><SPAN STYLE="font-weight: normal">
but it's not convenient for direct use from most languages. Therefore
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
language-specific features present in C++ (like automatic status check
after API calls) are missing in Pascal.</SPAN></FONT></STRONG></P>
<P STYLE="margin-bottom: 0in; font-weight: normal"><BR>
</P>
<P STYLE="margin-bottom: 0in; font-weight: normal"><FONT SIZE=4>Typically
database API is used to access data stored in database. Firebird OO
API certainly performs this task but in addition it supports writing
your own </FONT><FONT SIZE=4><B>plugins</B></FONT><FONT SIZE=4>
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>
<P STYLE="margin-bottom: 0in; font-weight: normal"><BR>
</P>
<P STYLE="margin-bottom: 0in"><A NAME="result_box"></A><FONT SIZE=4><SPAN STYLE="font-weight: normal">Firebird
installation package contains a number of live samples of use of OO
API they are in examples/interfaces (database access) and
examples/dbcrypt (plugin performing </SPAN></FONT><FONT SIZE=4><SPAN LANG="en">fictitious
database encryption</SPAN></FONT><FONT SIZE=4><SPAN STYLE="font-weight: normal">)
directories. It's supposed that the reader is familiar with ISC API
used in Firebird since interbase times.</SPAN></FONT></P>
<P STYLE="margin-bottom: 0in; font-weight: normal"><BR>
</P>
<P STYLE="margin-top: 0.17in; margin-bottom: 0.2in; page-break-after: avoid">
<FONT FACE="Albany, sans-serif"><FONT SIZE=4><FONT SIZE=4>Accessing
databases.</FONT></FONT></FONT></P>
<H1><FONT SIZE=4>Creating database and attaching to existing
database.</FONT></H1>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>First 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>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>static <A HREF="#Master">IMaster</A>*
master = fb_get_master_interface();</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>For 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>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>IStatus* st =
master-&gt;getStatus();</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>If 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>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Now 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>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>IProvider* prov =
master-&gt;getDispatcher();</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><U>The following is C++
specific: </U>We are almost ready to call attachDatabase() method of
IProvider, but before it a few words about concept of <B>Status
Wrapper</B> should be said. Status wrapper is 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 recommend use of
<B>ThrowStatusWrapper</B>, which raises C++ exception each time an
error is returned in IStatus.</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>ThrowStatusWrapper
status(st);</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><A NAME="Master"></A><FONT SIZE=4>Master
interface:</FONT></P>
<OL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IStatus* getStatus()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IProvider*
getDispatcher()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IPluginManager*
getPluginManager()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>ITimerControl*
getTimerControl()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IDtc* getDtc()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IUtil*
getUtilInterface()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IConfigManager*
getConfigManager()</FONT></P>
</OL>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><A NAME="Status"></A><FONT SIZE=4>Status
interface:</FONT></P>
<OL>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void init()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned getState()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void
setErrors2(unsigned length, const intptr_t* value)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void
setWarnings2(unsigned length, const intptr_t* value)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void setErrors(const
intptr_t* value)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void
setWarnings(const intptr_t* value)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>const intptr_t*
getErrors()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>const intptr_t*
getWarnings()</FONT></P>
<LI><P STYLE="margin-bottom: 0in"> <FONT SIZE=4>IStatus* clone()</FONT></P>
</OL>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Constants defined by
Status interface:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>STATE_WARNINGS - </FONT>
</P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>STATE_ERRORS</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>RESULT_ERROR = -1;</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>RESULT_OK = 0;</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>RESULT_NO_DATA =
1;</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>RESULT_SEGMENT =
2;</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><A NAME="Provider"></A><FONT SIZE=4>Provider
methods:</FONT></P>
<OL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IAttachment*
attachDatabase(StatusType* status, const char* fileName, unsigned
dpbLength, const unsigned char* dpb)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IAttachment*
createDatabase(StatusType* status, const char* fileName, unsigned
dpbLength, const unsigned char* dpb)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>IService*
attachServiceManager(StatusType* status, const char* service,
unsigned spbLength, const unsigned char* spb)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
shutdown(StatusType* status, unsigned timeout, const int reason)</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
setDbCryptCallback(StatusType* status, ICryptKeyCallback*
cryptCallback)</FONT></P>
</OL>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
</BODY>
</HTML>