Using_OO_API.html 170 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <html>
  3. <head>
  4. <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
  5. <title></title>
  6. <meta name="generator" content="LibreOffice 6.3.4.2.0 (Linux)"/>
  7. <meta name="author" content="alex "/>
  8. <meta name="created" content="2013-05-31T00:00:00.010003100"/>
  9. <meta name="changed" content="2020-05-08T12:18:09.185599623"/>
  10. <meta name="created" content="00:00:00">
  11. <style type="text/css">
  12. @page { margin: 2.01cm }
  13. h1 { color: #000000 }
  14. p { margin-bottom: 0.2cm; color: #000000 }
  15. </style>
  16. </head>
  17. <body lang="en-US" text="#000000" dir="ltr"><p style="margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid">
  18. <font face="Albany, sans-serif"><font size="5" style="font-size: 18pt">Firebird
  19. interfaces.</font></font></p>
  20. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Firebird's
  21. OO API is based on use of interfaces. That interfaces, though looking
  22. in some aspects like OLE2 interfaces (some of them have addRef() and
  23. release() methods) are non standard and have features, missing in
  24. other widely used types of interfaces. First of all Firebird
  25. interfaces are </font><font size="4" style="font-size: 14pt"><b>language
  26. independent</b></font> – <font size="4" style="font-size: 14pt">that
  27. means that to define/use them one need not use language specific
  28. constructions like </font><font size="4" style="font-size: 14pt"><i>class</i></font>
  29. <font size="4" style="font-size: 14pt">in C++, interface may be
  30. defined using any language having concepts of array and pointer to
  31. 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>
  32. – <font size="4" style="font-size: 14pt">i.e. we support different
  33. versions of same interface. Binary layout of interfaces is designed
  34. to support that features very efficient (there is no need in
  35. 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>
  36. </strong><strong><font size="4" style="font-size: 14pt"><span style="font-weight: normal">but
  37. it's not convenient for direct use from most languages. Therefore
  38. language-specific wrappers should better be designed for different
  39. languages making use of API easier. Currently we have wrappers for
  40. C++ and Pascal, Java is coming soon. From end-user POV calls from C++
  41. and Pascal have absolutely no difference, though some additional
  42. language-specific features present in C++ (like ability to turn off
  43. automatic status check after API calls) are missing in Pascal.</span></font></strong></p>
  44. <p style="margin-bottom: 0cm"><br/>
  45. </p>
  46. <p style="margin-bottom: 0cm; font-weight: normal"><font size="4" style="font-size: 14pt">Typically
  47. database API is used to access data stored in database. Firebird OO
  48. API certainly performs this task but in addition it supports writing
  49. your own </font><font size="4" style="font-size: 14pt"><b>plugins</b></font>
  50. – <font size="4" style="font-size: 14pt">modules, making it
  51. possible to enhance Firebird capabilities according to your needs.
  52. Therefore this document contains 2 big parts – accessing databases
  53. and writing plugins. Certainly some interfaces (like status vector)
  54. are used in both parts of API, they will be discussed in data access
  55. part and freely referenced later when discussing plugins. Therefore
  56. even if you plan to write some plugin you should better start with
  57. the first part of this document. Moreover a lot of plugins need to
  58. access databases themselves and data access API is typically needed
  59. for it.</font></p>
  60. <p style="margin-bottom: 0cm"><br/>
  61. </p>
  62. <p style="margin-bottom: 0cm"><a name="result_box"></a><font size="4" style="font-size: 14pt"><span style="font-weight: normal">Firebird
  63. installation package contains a number of live samples of use of OO
  64. API – they are in examples/interfaces (database access) and
  65. examples/dbcrypt (plugin performing </span></font><font size="4" style="font-size: 14pt"><span lang="en-US">fictitious
  66. database encryption</span></font><font size="4" style="font-size: 14pt"><span style="font-weight: normal">)
  67. directories. It's supposed that the reader is familiar with ISC API
  68. used in Firebird since interbase times.</span></font></p>
  69. <p style="margin-bottom: 0cm"><br/>
  70. </p>
  71. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><span style="font-weight: normal">This
  72. document does not pretend to be a full Firebird 3 documentation –
  73. it just describes new object oriented API, and a reader should be
  74. familiar with main Firebird concepts, knowledge about ISC API is also
  75. much welcome. For example – when describing how to work with
  76. services there is no explanation what is service and why is it
  77. needed, only description of how to obtain <a href="#Service">IService</a>
  78. interface and how to use it. Also pay attention that samples of code
  79. do not use a lot of powerful features of C++. Not used reference
  80. counted pointers, not used other RAII holders, not used templates
  81. (except one present in firebird public headers), etc. Primary goal is
  82. to make this text usable not only to C++ people because our API is
  83. oriented to support not only C++ but other, more simple languages
  84. too.</span></font></p>
  85. <p style="margin-bottom: 0cm"><br/>
  86. </p>
  87. <p style="margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid">
  88. <font face="Albany, sans-serif"><font size="5" style="font-size: 18pt">Accessing
  89. databases.</font></font></p>
  90. <h1><font size="4" style="font-size: 14pt">Creating database and
  91. attaching to existing database.</font></h1>
  92. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">First
  93. of all we need to get access to <b>IMaster</b> interface. IMaster is
  94. primary Firebird interface, required to access all the rest of
  95. interfaces. Therefore there is a special way of accessing it – the
  96. only one needed to use OO API plain function called
  97. fb_get_master_interface(). This function has no parameters and always
  98. succeeds. There is one and only one instance of IMaster per Firebird
  99. client library, therefore one need not care about releasing memory,
  100. used by master interface. A simplest way to access it from your
  101. program is to have appropriate global or static variable:</font></p>
  102. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>static
  103. <a href="#Master">IMaster</a>* master = fb_get_master_interface();</i></font></p>
  104. <p style="margin-bottom: 0cm"><br/>
  105. </p>
  106. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">For
  107. a lot of methods, used in Firebird API, first parameter is <b>IStatus</b>
  108. interface. It's a logical replacement of ISC_STATUS_ARRAY, but works
  109. separately with errors and warnings (not mixing them in same array),
  110. can contain unlimited number of errors inside and (this will be
  111. important if you plan to implement IStatus yourself) always keeps
  112. strings, referenced by it, inside interface. Typically you need at
  113. least one instance of IStatus to call other methods. You obtain it
  114. from IMaster:</font></p>
  115. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#Status">IStatus</a>*
  116. st = master-&gt;getStatus();</i></font></p>
  117. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">If
  118. method getStatus() fails for some reason (OOM for example) it returns
  119. NULL – obviously we can't use generic error reporting method which
  120. is based on use of IStatus here.</font></p>
  121. <p style="margin-bottom: 0cm"><br/>
  122. </p>
  123. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Now
  124. we are going to deal with first interface, directly related to
  125. database calls. This is <a href="#Provider">IProvider</a> –
  126. interface called this way cause it's exactly that interface that must
  127. be implemented by any provider in Firebird. Firebird client library
  128. also has it's own implementation of IProvider, which must be used to
  129. start any database activity. To obtain it we call IMaster's method:</font></p>
  130. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IProvider*
  131. prov = master-&gt;getDispatcher();</i></font></p>
  132. <p style="margin-bottom: 0cm"><br/>
  133. </p>
  134. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">When
  135. attaching to existing database or moreover creating new one it's
  136. often necessary to pass a lot of additional parameters
  137. (logon/password, page size for new database, etc.) to API call.
  138. Having separate language-level parameters is close to unreal – we
  139. will have to modify a call too often to add new parameters, and
  140. number of them will be very big no matter of the fact that typically
  141. one needs to pass not too much of them. Therefore to pass additional
  142. parameters special in-memory data structure, called </font><font size="4" style="font-size: 14pt"><i>database
  143. parameters block</i></font> <font size="4" style="font-size: 14pt">(DPB)
  144. is used. Format of it is well defined, and it's possible to build DPB
  145. byte after byte. But it's much easier to use special interface
  146. </font><a href="#XpbBuilder"><font size="4" style="font-size: 14pt"><b>IXpbBuilder</b></font></a><font size="4" style="font-size: 14pt">,
  147. which simplifies creation of various parameters blocks. To obtain an
  148. instance of IXpbBuilder you must know one more generic-use interface
  149. 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">.
  150. It's a kind of placeholder for the calls that do not fit well in
  151. other places. So we do</font></p>
  152. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IUtil*
  153. utl = master-&gt;getUtilInterface();</i></font></p>
  154. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IXpbBuilder*
  155. dpb = utl-&gt;getXpbBuilder(&amp;status, IXpbBuilder::DPB, NULL, 0);</i></font></p>
  156. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">This
  157. creates empty parameters' block builder of DPB type. Now adding
  158. required parameter to it is trivial:</font></p>
  159. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>dpb-&gt;insertInt(&amp;status,
  160. isc_dpb_page_size, 4 * 1024);</i></font></p>
  161. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">will
  162. make firebird to create new database with pagesize equal to 4Kb and
  163. meaning of</font></p>
  164. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>dpb-&gt;insertString(&amp;status,
  165. isc_dpb_user_name, “sysdba”);</i></font></p>
  166. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>dpb-&gt;insertString(&amp;status,
  167. isc_dpb_password, “masterkey”);</i></font></p>
  168. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">is
  169. (I hope) obvious.</font></p>
  170. <p style="margin-bottom: 0cm"><br/>
  171. </p>
  172. <p style="margin-bottom: 0cm"><a name="Status Wrapper"></a><font size="4" style="font-size: 14pt"><u>The
  173. following is C++ specific: </u>We are almost ready to call
  174. createDatabase() method of IProvider, but before it a few words about
  175. concept of <b>Status Wrapper</b> should be said. Status wrapper is
  176. not an interface, it's very thin envelope for IStatus interface. It
  177. helps to customize behavior of C++ API (change a way how errors,
  178. returned in IStatus interface, are processed). For the first time we
  179. recommend use of <b>ThrowStatusWrapper</b>, which raises C++
  180. exception each time an error is returned in IStatus.</font></p>
  181. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>ThrowStatusWrapper
  182. status(st);</i></font></p>
  183. <p style="margin-bottom: 0cm"><br/>
  184. </p>
  185. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Now
  186. we may create new empty database:</font></p>
  187. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#Attachment">IAttachment</a>*
  188. att = prov-&gt;createDatabase(&amp;status, &quot;fbtests.fdb&quot;,
  189. dpb-&gt;getBufferLength(&amp;status), dpb-&gt;getBuffer(&amp;status));</i></font></p>
  190. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>printf(&quot;Database
  191. fbtests.fdb created\n&quot;);</i></font></p>
  192. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Pay
  193. attention that we do not check status after the call to
  194. createDatabase(), because in case of error C++ or Pascal exception
  195. will be raised (therefore it's very good idea to have
  196. try/catch/except syntax in your program). We also use two new
  197. functions from IXpbBuilder – getBufferLength() and getBuffer(),
  198. which extract data from interface in native parameters block format.
  199. As you can see there is no need to check explicitly for status of
  200. functions, returning intermediate results.</font></p>
  201. <p style="margin-bottom: 0cm"><br/>
  202. </p>
  203. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Detaching
  204. from just created database is trivial:</font></p>
  205. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>att-&gt;detach(&amp;status);</i></font></p>
  206. <p style="margin-bottom: 0cm"><br/>
  207. </p>
  208. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Now
  209. it remains to enclose all operators into <i>try</i> block and write a
  210. handler in catch block. When using ThrowStatusWrapper you should
  211. always catch defined in C++ API exception class FbException, in
  212. Pascal you must also work with class FbException. Exception handler
  213. block in simplest case may look this way:</font></p>
  214. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>catch
  215. (const FbException&amp; error)</i></font></p>
  216. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  217. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>char
  218. buf[256];</i></font></p>
  219. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>utl-&gt;formatStatus(buf,
  220. sizeof(buf), error.getStatus());</i></font></p>
  221. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>fprintf(stderr,
  222. &quot;%s\n&quot;, buf);</i></font></p>
  223. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  224. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Pay
  225. attention that here we use one more function from <a href="#Util">IUtil</a>
  226. – formatStatus(). It returns in buffer text, describing an error
  227. (warning), stored in IStatus parameter.</font></p>
  228. <p style="margin-bottom: 0cm"><br/>
  229. </p>
  230. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  231. attach to existing database just use attachDatabase() method of
  232. IProvider instead createDatabase(). All parameters are the same for
  233. both methods.</font></p>
  234. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>att
  235. = prov-&gt;attachDatabase(&amp;status, &quot;fbtests.fdb&quot;, 0,
  236. NULL);</i></font></p>
  237. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">This
  238. sample is using no additional DPB parameters. Take into account that
  239. without logon/password any remote connection will fail if no trusted
  240. authorization plugin is configured. Certainly login info may be also
  241. provided in environment (in ISC_USER and ISC_PASSWORD variables) like
  242. it was before.</font></p>
  243. <p style="margin-bottom: 0cm"><br/>
  244. </p>
  245. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Our
  246. examples contain complete samples, dedicated except others to
  247. creating databases – 01.create.cpp and 01.create.pas. When samples
  248. are present it will be very useful to build and try to run
  249. appropriate samples when reading this document.</font></p>
  250. <p style="margin-bottom: 0cm"><br/>
  251. </p>
  252. <h1><font size="4" style="font-size: 14pt">Working with transactions.</font></h1>
  253. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Only
  254. creating empty databases is definitely not enough to work with RDBMS.
  255. We want to be able to create various objects (like tables and so on)
  256. in database and insert data in that tables. Any operation within
  257. database is performed by firebird under transaction control.
  258. Therefore first of all we must learn to start transaction. Here we do
  259. not discuss distributed transactions (supported by <a href="#Dtc">IDtc</a>
  260. interface) to avoid unneeded to most users overcomplication. Starting
  261. of non-distributed transaction is very simple and done via attachment
  262. interface:</font></p>
  263. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#Transaction">ITransaction</a>*
  264. tra = att-&gt;startTransaction(&amp;status, 0, NULL);</i></font></p>
  265. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  266. this sample default transaction parameters are used – no TPB is
  267. passed to startTransaction() method. If you need non-default
  268. parameters you may create appropriate <a href="#XpbBuilder">IXpbBuilder</a>,
  269. add required items to it:</font></p>
  270. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#XpbBuilder">IXpbBuilder</a>*
  271. tpb = utl-&gt;getXpbBuilder(&amp;status, IXpbBuilder::TPB, NULL, 0);</i></font></p>
  272. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>tpb-&gt;insertTag(&amp;status,
  273. isc_tpb_read_committed);</i></font></p>
  274. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">and
  275. pass resulting TPB to startTransaction():</font></p>
  276. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>ITransaction*
  277. tra = att-&gt;startTransaction(&amp;status,
  278. tpb-&gt;getBufferLength(&amp;status), tpb-&gt;getBuffer(&amp;status));</i></font></p>
  279. <p style="margin-bottom: 0cm"><br/>
  280. </p>
  281. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Transaction
  282. interface is used as a parameter in a lot of other API calls but
  283. itself it does not perform any actions except commit/rollback
  284. transaction, may be retaining:</font></p>
  285. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>tra-&gt;commit(&amp;status);</i></font></p>
  286. <p style="margin-bottom: 0cm"><br/>
  287. </p>
  288. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">You
  289. may take a look at how to start and commit transaction in examples
  290. 01.create.cpp and 01.create.pas.</font></p>
  291. <p style="margin-bottom: 0cm"><br/>
  292. </p>
  293. <h1><font size="4" style="font-size: 14pt">Executing SQL operator
  294. without input parameters and returned rows.</font></h1>
  295. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">With
  296. started transaction we are ready to execute our first SQL operators.
  297. Used for it execute() method in <a href="#Attachment">IAttachment</a>
  298. is rather universal and may be also used to execute SQL operators
  299. with input and output parameters (which is typical for EXECUTE
  300. PROCEDURE statement), but right now we will use the simple most form
  301. of it. Both DDL and DML operators can be executed:</font></p>
  302. <p style="margin-bottom: 0cm; font-weight: normal"><font size="4" style="font-size: 14pt"><i>att-&gt;execute(&amp;status,
  303. tra, 0, &quot;create table dates_table (d1 date)&quot;,
  304. SQL_DIALECT_V6, NULL, NULL, NULL, NULL);</i></font></p>
  305. <p style="margin-bottom: 0cm; font-weight: normal"><font size="4" style="font-size: 14pt"><i>tra-&gt;commitRetaining(&amp;status);</i></font></p>
  306. <p style="margin-bottom: 0cm; font-weight: normal"><font size="4" style="font-size: 14pt"><i>att-&gt;execute(&amp;status,
  307. tra, 0, &quot;insert into dates_table values (CURRENT_DATE)&quot;,
  308. SQL_DIALECT_V6, NULL, NULL, NULL, NULL);</i></font></p>
  309. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">As
  310. you can see transaction interface is a required parameter for
  311. execute() method (must be NULL only if you execute START TRANSACTION
  312. statement). Next follows length of SQL operator (may be zero causing
  313. use of C rules to determine string length), text of operator and SQL
  314. dialect that should be used for it. The following for NULLs stand for
  315. metadata descriptions and buffers of input parameters and output
  316. data. Complete description of this method is provided in <a href="#Attachment">IAttachment</a>
  317. interface.</font></p>
  318. <p style="margin-bottom: 0cm"><br/>
  319. </p>
  320. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">You
  321. may take a look at how to start and commit transaction in examples
  322. 01.create.cpp and 01.create.pas.</font></p>
  323. <p style="margin-bottom: 0cm"><br/>
  324. </p>
  325. <h1><font size="4" style="font-size: 14pt">Executing SQL operator
  326. with input parameters.</font></h1>
  327. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">There
  328. are 2 ways to execute statement with input parameters. Choice of
  329. correct method depends upon do you need to execute it more than once
  330. and do you know in advance format of parameters. When that format is
  331. known and statement is needed to be run only once single call to
  332. IAttachment::execute() may be used. In other cases SQL statement
  333. should be prepared first and after it executed, may be many times
  334. with different parameters.</font></p>
  335. <p style="margin-bottom: 0cm"><br/>
  336. </p>
  337. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  338. prepare SQL statement for execution use prepare() method of
  339. <a href="#Attachment">IAttachment</a> interface:</font></p>
  340. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#Statement">IStatement</a>*
  341. stmt = att-&gt;prepare(&amp;status, tra, 0, “UPDATE department SET
  342. budget = ? * budget + budget WHERE dept_no = ?”,</i></font></p>
  343. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>SQL_DIALECT_V6,
  344. IStatement::PREPARE_PREFETCH_METADATA);</i></font></p>
  345. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">If
  346. you are not going to use parameters description from firebird (i.e.
  347. you can provide that information yourself) please use
  348. IStatement::PREPARE_PREFETCH_NONE instead PREPARE_PREFETCH_METADATA –
  349. this will save client/server traffic and server resources a bit.</font></p>
  350. <p style="margin-bottom: 0cm"><br/>
  351. </p>
  352. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  353. ISC API XSQLDA is used to describe format of statement parameters.
  354. New API does not use XSQLDA – instead interface IMessageMetadata is
  355. used. A set of input parameters (and also a row fetched from cursor)
  356. is described in firebird API in same way and later called message.
  357. <a href="#MessageMetadata">IMessageMetadata</a> is passed as a
  358. parameter to the methods performing message exchange between your
  359. program and database engine. There are many ways to have an instance
  360. of IMessageMetadata – one can:</font></p>
  361. <ul>
  362. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">get
  363. it from <a href="#Statement">IStatement</a>,</font></p>
  364. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">build
  365. using <a href="#MetadataBuilder">IMetadataBuilder</a> interface,</font></p>
  366. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">have
  367. your own implementation of this interface.</font></p>
  368. </ul>
  369. <p style="margin-bottom: 0cm"><br/>
  370. </p>
  371. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Getting
  372. metadata from prepared statement is very simple – method
  373. getInputMetadata() return interface describing input message (i.e.
  374. statement parameters), interface returned by getOutputMetadata()
  375. describes output message (i.e. row in selected data or values
  376. returned by procedure). In our case we can:</font></p>
  377. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#MessageMetadata">IMessageMetadata</a>*
  378. meta = stmt-&gt;getInputMetadata(&amp;status);</i></font></p>
  379. <p style="margin-bottom: 0cm"><br/>
  380. </p>
  381. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Or
  382. we can build message metadata ourself. First of all we need builder
  383. interface for it:</font></p>
  384. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#MetadataBuilder">IMetadataBuilder</a>*
  385. builder = master-&gt;getMetadataBuilder(&amp;status, 2);</i></font></p>
  386. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Second
  387. parameter is expected number of fields in the message, it can be
  388. changed later, i.e. that's just an optimization.</font></p>
  389. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Now
  390. it's necessary to set individual fields characteristics in the
  391. builder. An absolute minimum is field types and length for string
  392. fields:</font></p>
  393. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>builder-&gt;setType(&amp;status,
  394. 0, SQL_DOUBLE + 1);</i></font></p>
  395. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>builder-&gt;setType(&amp;status,
  396. 1, SQL_TEXT + 1);</i></font></p>
  397. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>builder-&gt;setLength(&amp;status,
  398. 1, 3);</i></font></p>
  399. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  400. <font size="4" style="font-size: 14pt">New API is using old constants
  401. for SQL types, smallest bit as earlier stands for nullability. In
  402. some case it may also make sense to set sub-type (for blobs),
  403. character set (for text fields) or scale (for numeric fields). And
  404. finally it's time to get an instance of IMessageMetadata:</font></p>
  405. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#MessageMetadata">IMessageMetadata</a>*
  406. meta = builder-&gt;getMetadata(&amp;status);</i></font></p>
  407. <p style="margin-bottom: 0cm"><br/>
  408. </p>
  409. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  410. <font size="4" style="font-size: 14pt">Here we do not discuss in
  411. details own implementation of IMessageMetadata. If one cares there is
  412. a sample 05.user_metadata.cpp.</font></p>
  413. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">So
  414. finally we have obtained (one or another way) an instance of metadata
  415. description of input parameters. But to work with a message we also
  416. need buffer for it. Buffer size is one of main message metadata
  417. characteristics and it's returned by method in IMessageMetadata:</font></p>
  418. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>char*
  419. buffer = new char[meta-&gt;getMessageLength(&amp;status)];</i></font></p>
  420. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  421. deal with individual values inside buffer offset to them should be
  422. taken into an account. IMessageMetadata is aware of offsets for all
  423. values in a message, using it we can create pointers to them:</font></p>
  424. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>double*
  425. percent_inc = (double*) &amp;buffer[meta-&gt;getOffset(&amp;status,
  426. 0)];</i></font></p>
  427. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>char*
  428. dept_no = &amp;buffer[meta-&gt;getOffset(&amp;status, 1)];</i></font></p>
  429. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Also
  430. let's do not forget to set to NOT NULL null flags:</font></p>
  431. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>short*
  432. flag = (short*)&amp;buffer[meta-&gt;getNullOffset(&amp;status, 0)];</i></font></p>
  433. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>*flag
  434. = 0;</i></font></p>
  435. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>flag
  436. = (short*) &amp;buffer[meta-&gt;getNullOffset(&amp;status, 1)];</i></font></p>
  437. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>*flag
  438. = 0;</i></font></p>
  439. <p style="margin-bottom: 0cm"><br/>
  440. </p>
  441. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">After
  442. finishing with offsets we are ready to execute statement with some
  443. parameters values:</font></p>
  444. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>getInputValues(dept_no,
  445. percent_inc);</i></font></p>
  446. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">and
  447. may execute prepared statement:</font></p>
  448. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>stmt-&gt;execute(&amp;status,
  449. tra, meta, buffer, NULL, NULL);</i></font></p>
  450. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Two
  451. more NULLs in the end of parameters stand for output message and is
  452. used typically for EXECUTE PROCEDURE statement.</font></p>
  453. <p style="margin-bottom: 0cm"><br/>
  454. </p>
  455. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">If
  456. you do not need to get metadata from statement and plan to execute it
  457. only once you may choose a simpler way – use method execute() in
  458. <a href="#Attachment">IAttachment</a> interface:</font></p>
  459. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>att-&gt;execute(&amp;status,
  460. tra, 0, &quot;UPDATE department SET budget = ? * budget + budget
  461. WHERE dept_no = ?&quot;, SQL_DIALECT_V6, meta, buffer, NULL, NULL);</i></font></p>
  462. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  463. that case you do not need to use <a href="#Statement">IStatement</a>
  464. at all.</font></p>
  465. <p style="margin-bottom: 0cm"><br/>
  466. </p>
  467. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">An
  468. example how to execute UPDATE with parameters is present in
  469. 02.update.cpp, you will also see how raised in trigger/procedure
  470. exception may be caught by C++ program.</font></p>
  471. <p style="margin-bottom: 0cm"><br/>
  472. </p>
  473. <h1><font size="4" style="font-size: 14pt">Opening cursor and
  474. fetching data from it.</font></h1>
  475. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">The
  476. only way to get rows of data, returned by SELECT operator, in OO API
  477. is to use <a href="#ResultSet">IResultSet</a> interface. This
  478. interface is returned by openCursor() method in both IAttachment and
  479. IStatement. openCursor() is in most aspects alike execute() and a
  480. choice how to open cursor (using prepared statement or directly from
  481. attachment interface) is the same. In the samples 03.select.cpp and
  482. 04.print_table.cpp both methods are used. Let's pay attention at one
  483. specific openCursor() feature compared with execute() - one does not
  484. pass buffer for output message into openCursor(), it will be passed
  485. later when data is fetched from cursor. This makes it possible to
  486. open cursor with unknown format of output message (NULL is passed
  487. instead output metadata). Firebird is using in this case default
  488. message format which may be requested from IResultSet interface:</font></p>
  489. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>const
  490. char* sql = &quot;select * from ...&quot;; // some select statement</i></font></p>
  491. <p style="margin-bottom: 0cm"><br/>
  492. </p>
  493. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#ResultSet">IResultSet</a>*
  494. curs = att-&gt;openCursor(&amp;status, tra, 0, sql, SQL_DIALECT_V6,
  495. NULL, NULL, NULL, NULL, 0);</i></font></p>
  496. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#MessageMetadata">IMessageMetadata</a>*
  497. meta = curs-&gt;getMetadata(&amp;status);</i></font></p>
  498. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Later
  499. this metadata may be used to allocate buffer for data and parse
  500. fetched rows.</font></p>
  501. <p style="margin-bottom: 0cm"><br/>
  502. </p>
  503. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">As
  504. an alternative one can first prepare statement, get metadata from
  505. prepared statement and after it open cursor. This is preferred way if
  506. cursor is likely to be opened &gt;1 times.</font></p>
  507. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><a href="#Statement">IStatement</a>*
  508. stmt = att-&gt;prepare(&amp;status, tra, 0, sql, SQL_DIALECT_V6,
  509. Istatement::PREPARE_PREFETCH_METADATA);</font></p>
  510. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><a href="#MessageMetadata">IMessageMetadata</a>*
  511. meta = stmt-&gt;getOutputMetadata(&amp;status);</font></p>
  512. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><a href="#ResultSet">IResultSet</a>*
  513. curs = stmt-&gt;openCursor(&amp;status, tra, NULL, NULL, NULL, 0);</font></p>
  514. <p style="margin-bottom: 0cm"><br/>
  515. </p>
  516. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">We
  517. have obtained (one or another way) an instance of metadata
  518. description of output fields (a row in a set). To work with a message
  519. we also need buffer for it:</font></p>
  520. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>unsigned
  521. char* buffer = new unsigned char[meta-&gt;getMessageLength(&amp;status)];</i></font></p>
  522. <p style="margin-bottom: 0cm"><br/>
  523. </p>
  524. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IResultSet
  525. has a lot of various fetch methods but when cursor is not opened with
  526. SCROLL option only fetchNext() works, i.e. one can navigate only
  527. forward record by record. In addition to errors and warnings in
  528. status fetchNext() returns completion code, which may have values
  529. RESULT_OK (when buffer is filled with values for next row) or
  530. RESULT_NO_DATA (when no more rows left in cursor). RESULT_NO_DATA is
  531. not error state, it's normal state after completion of the method,
  532. but we know that data in cursor is over. If status wrapper, not
  533. throwing exception in case of error return is used, one more value –
  534. RESULT_ERROR – may be returned, that means no data in buffer and
  535. error vector in status. Method fetchNext() is usually called in a
  536. cycle:</font></p>
  537. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>while
  538. (curs-&gt;fetchNext(&amp;status, buffer) == IStatus::RESULT_OK)</i></font></p>
  539. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  540. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>//
  541. row processing</i></font></p>
  542. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  543. <p style="margin-bottom: 0cm"><br/>
  544. </p>
  545. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">What
  546. is done during row processing depends upon your needs. To access
  547. particular field field's offset should be used:</font></p>
  548. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>unsigned
  549. char* field_N_ptr = buffer + meta-&gt;getOffset(&amp;status, n);</i></font></p>
  550. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  551. <font size="4" style="font-size: 14pt">where n is the number of a
  552. field in a message. That pointer should be casted to appropriate
  553. type, depending upon field type. For example, for a VARCHAR field
  554. cast to struct vary should be used:</font></p>
  555. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>vary*
  556. v_ptr = (vary*) (buffer + meta-&gt;getOffset(&amp;status, n));</i></font></p>
  557. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Now
  558. we may print the value of a field:</font></p>
  559. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>printf(“field
  560. %s value is %*.*s\n”, meta-&gt;getField(&amp;status, n),
  561. v_ptr-&gt;vary_length, v_ptr-&gt;vary_length, v_ptr-&gt;vary_string);</i></font></p>
  562. <p style="margin-bottom: 0cm"><br/>
  563. </p>
  564. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">If
  565. you need maximum performance it will be good idea to cache needed
  566. metadata values like it's done in our samples 03.select.cpp and
  567. 04.print_table.cpp.</font></p>
  568. <p style="margin-bottom: 0cm"><br/>
  569. </p>
  570. <h1><font size="4" style="font-size: 14pt">Using FB_MESSAGE macro for
  571. static messages.</font></h1>
  572. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Working
  573. with data using offsets is rather efficient but requires a lot of
  574. code to be written. In C++ this problem can be solved using
  575. templates, but even compared with them the most convenient way to
  576. work with the message is to represent it in native (for given
  577. language) way – structure in C/C++, record in Pascal, etc.
  578. Certainly this works only if format of a message is known in advance.
  579. To help building such structures in C++ firebird contains special
  580. macro FB_MESSAGE.</font></p>
  581. <p style="margin-bottom: 0cm"><br/>
  582. </p>
  583. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_MESSAGE
  584. has 3 arguments – message (struct) name, type of status wrapper and
  585. list of fields. Usage of first and second is obvious, list of fields
  586. contains pairs (field_type, field_name), where field_type is one of
  587. the following:</font></p>
  588. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BIGINT</font></p>
  589. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BLOB</font></p>
  590. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN</font></p>
  591. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_CHAR(len)</font></p>
  592. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_DATE</font></p>
  593. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_DOUBLE</font></p>
  594. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_FLOAT</font></p>
  595. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_INTEGER</font></p>
  596. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_INTL_CHAR(len,
  597. charSet)</font></p>
  598. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_INTL_VARCHAR(len,
  599. charSet)</font></p>
  600. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_SCALED_BIGINT(x)</font></p>
  601. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_SCALED_INTEGER(x)</font></p>
  602. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_SCALED_SMALLINT(x)</font></p>
  603. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_SMALLINT</font></p>
  604. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_TIME</font></p>
  605. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_TIMESTAMP</font></p>
  606. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_VARCHAR(len)</font></p>
  607. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  608. generated by preprocessor structure integer and float types are
  609. matched with appropriate C types, date and time – with classes
  610. <a href="#FbDate">FbDate</a> and <a href="#FbTime">FbTime</a> (all
  611. mentioned here classes are in namespace Firebird), timestamp – with
  612. class FbTimestamp, containing two public data members date and time
  613. of appropriate class, char - with struct <a href="#FbChar">FbChar</a>
  614. and varchar – with struct <a href="#FbVarChar">FbVarChar</a>. For
  615. each field preprocessor creates two data members in the message –
  616. </font><font size="4" style="font-size: 14pt"><i>name</i></font> <font size="4" style="font-size: 14pt">for
  617. field/parameter value and </font><font size="4" style="font-size: 14pt"><i>nameNull</i></font>
  618. <font size="4" style="font-size: 14pt">for NULL indicator. Message
  619. constructor has 2 parameters – pointer to status wrapper and master
  620. interface:</font></p>
  621. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>FB_MESSAGE(Output,
  622. ThrowStatusWrapper,</i></font></p>
  623. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>(FB_SMALLINT,
  624. relationId)</i></font></p>
  625. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>(FB_CHAR(31),
  626. relationName)</i></font></p>
  627. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>(FB_VARCHAR(100),
  628. description)</i></font></p>
  629. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>)
  630. output(&amp;status, master);</i></font></p>
  631. <p style="margin-bottom: 0cm"><br/>
  632. </p>
  633. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">For
  634. static messages use of FB_MESSAGE is sooner of all the best choice –
  635. they can be at the same time easily passed to execute, openCursor and
  636. fetch methods:</font></p>
  637. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>rs
  638. = att-&gt;openCursor(&amp;status, tra, 0, sqlText,</i></font></p>
  639. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>SQL_DIALECT_V6,
  640. NULL, NULL, output.getMetadata(), NULL, 0);</i></font></p>
  641. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">and
  642. used to work with values of individual fields:</font></p>
  643. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>while
  644. (rs-&gt;fetchNext(&amp;status, output.getData()) ==
  645. IStatus::RESULT_OK)</i></font></p>
  646. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  647. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>printf(&quot;%4d
  648. %31.31s %*.*s\n&quot;, output-&gt;relationId,
  649. output-&gt;relationName.str,</i></font></p>
  650. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>output-&gt;descriptionNull
  651. ? 0 : output-&gt;description.length,</i></font></p>
  652. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>output-&gt;descriptionNull
  653. ? 0 : output-&gt;description.length, output-&gt;description.str);</i></font></p>
  654. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  655. <p style="margin-bottom: 0cm"><br/>
  656. </p>
  657. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">An
  658. example of using macro FB_MESSAGE to work with messages is in the
  659. sample 06.fb_message.cpp.</font></p>
  660. <p style="margin-bottom: 0cm"><br/>
  661. </p>
  662. <h1><font size="4" style="font-size: 14pt">Working with blobs.</font></h1>
  663. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">For
  664. blobs in message buffer firebird stores blob identifier – an 8-byte
  665. entity which should be aligned on 4-byte boundary. Identifier has
  666. ISC_QUAD type. Interface <a href="#Attachment">IAttachment</a> has 2
  667. methods to work with blobs – openBlob() and createBlob(), both
  668. returning interface <a href="#Blob">IBlob</a> and having same set of
  669. parameters, but performing somewhat contrary actions: openBlob()
  670. takes blob identifier from the message and prepares blob for reading
  671. but createBlob() creates new blob, puts it's identifier into message
  672. and prepares blob for writing. </font>
  673. </p>
  674. <p style="margin-bottom: 0cm"><br/>
  675. </p>
  676. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  677. work with blobs one must first of all include blob identifier into
  678. the message. If you get metadata from firebird engine field of
  679. appropriate type will be already present. You just use it's offset
  680. (assuming variable blobFieldNumber contains number of blob field)
  681. (and appropriate null offset to check for nulls or set null flag) to
  682. obtain pointer into the message buffer:</font></p>
  683. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>ISC_QUAD*
  684. blobPtr = (ISC_QUAD*) &amp;buffer[metadata-&gt;getOffset(&amp;status,
  685. blobFieldNumber)];</i></font></p>
  686. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>ISC_SHORT*
  687. blobNullPtr = (ISC_SHORT*) &amp;buffer[metadata-&gt;getNullOffset(&amp;status,
  688. blobFieldNumber)];</i></font></p>
  689. <p style="margin-bottom: 0cm"><br/>
  690. </p>
  691. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">If
  692. you use static messages and FB_MESSAGE macro blob field is declared
  693. as having FB_BLOB type:</font></p>
  694. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>FB_MESSAGE(Msg,
  695. ThrowStatusWrapper,</i></font></p>
  696. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>(FB_BLOB,
  697. b)</i></font></p>
  698. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>)
  699. message(&amp;status, master);</i></font></p>
  700. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>ISC_QUAD*
  701. blobPtr = &amp;message-&gt;b;</i></font></p>
  702. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>ISC_SHORT*
  703. blobNullPtr = &amp;message-&gt;bNull;</i></font></p>
  704. <p style="margin-bottom: 0cm"><br/>
  705. </p>
  706. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  707. create new blob invoke createBlob() method:</font></p>
  708. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#Blob">IBlob</a>*
  709. blob = att-&gt;createBlob(status, tra, blobPtr, 0, NULL);</i></font></p>
  710. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Last
  711. two parameters are required only if you want to use blob filters or
  712. use stream blob, that's out of scope here.</font></p>
  713. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Blob
  714. interface is ready to accept data into blob. Use putSegment() method
  715. to send data to engine:</font></p>
  716. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>void*
  717. segmentData;</i></font></p>
  718. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>unsigned
  719. segmentLength;</i></font></p>
  720. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>while
  721. (userFunctionProvidingBlobData(&amp;segmentData, &amp;segmentLength))</i></font></p>
  722. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>blob-&gt;putSegment(&amp;status,
  723. segmentLength, segmentData);</i></font></p>
  724. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">After
  725. sending some data to blob do not forget to close blob interface:</font></p>
  726. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>blob-&gt;close(&amp;status);</i></font></p>
  727. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Make
  728. sure that null flag is not set (not required if you nullified all
  729. message buffer before creating blob):</font></p>
  730. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>*blobNullPtr
  731. = 0;</i></font></p>
  732. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">and
  733. message, containing blob, may be used in insert or update statement.
  734. After execution of that statement new blob will be stored in
  735. database.</font></p>
  736. <p style="margin-bottom: 0cm"><br/>
  737. </p>
  738. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  739. read a blob begin with getting containing it's identifier message
  740. from firebird engine. This may be done using fetch() or execute()
  741. methods. After it use openBlob() attachment's method:</font></p>
  742. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i><a href="#Blob">IBlob</a>*
  743. blob = att-&gt;openBlob(status, tra, blobPtr, 0, NULL);</i></font></p>
  744. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Blob
  745. interface is ready to provide blob data. Use getSegment() method to
  746. receive data from engine:</font></p>
  747. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>char
  748. buffer[BUFSIZE];</i></font></p>
  749. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>unsigned
  750. actualLength;</i></font></p>
  751. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>for(;;)</i></font></p>
  752. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  753. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>switch
  754. (blob-&gt;getSegment(&amp;status, sizeof(buffer), buffer,
  755. &amp;actualLength))</i></font></p>
  756. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  757. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>case
  758. IStatus::RESULT_OK:</i></font></p>
  759. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>userFunctionAcceptingBlobData(buffer,
  760. actualLength, true);</i></font></p>
  761. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>continue;</i></font></p>
  762. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>case
  763. IStatus::RESULT_SEGMENT:</i></font></p>
  764. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>userFunctionAcceptingBlobData(buffer,
  765. actualLength, false);</i></font></p>
  766. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>continue;</i></font></p>
  767. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>default:</i></font></p>
  768. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>break;</i></font></p>
  769. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  770. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  771. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Last
  772. parameter in userFunctionAcceptingBlobData() is a flag that end of
  773. segment is reached – when getSegment() returns RESULT_SEGMENT
  774. completion code that function is notified (by passing false as last
  775. parameter) that segment was not read completely and continuation is
  776. expected at next call.</font></p>
  777. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">After
  778. finishing with blob do not forget top close it:</font></p>
  779. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>blob-&gt;close(&amp;status);</i></font></p>
  780. <p style="margin-bottom: 0cm"><br/>
  781. </p>
  782. <h1><font size="4" style="font-size: 14pt">Working with events.</font></h1>
  783. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Events
  784. interface was not completed in FB3, we expect to have something more
  785. interesting in next version. The minimum existing support is as
  786. follows: <a href="#Attachment">IAttachment</a> contains call
  787. queEvents() which performs almost same functions as isc_que_events()
  788. call. Instead the pair of parameters </font><font size="4" style="font-size: 14pt"><i>FPTR_EVENT_CALLBACK
  789. ast</i></font> <font size="4" style="font-size: 14pt">and </font><font size="4" style="font-size: 14pt"><i>void*
  790. arg</i></font><font size="4" style="font-size: 14pt">, required to
  791. invoke user code when event happens in firebird engine, callback
  792. interface IEventCallback is used. This is traditional approach which
  793. helps to avoid non-safe casts from void* in user function. Another
  794. important difference is that instead event identifier (a kind of
  795. handler) this function returns reference counted interface <a href="#Events">IEvents</a>
  796. having method cancel() used when waiting for event should be stopped.
  797. Unlike identifier which is automatically destroyed when event arrives
  798. interface can not be automatically destroyed – in case when event
  799. is received right before canceling interface call to cancel() would
  800. cause segfault when interface is already destroyed. Therefore
  801. interface <a href="#Events">IEvents</a> must be explicitly released
  802. after receiving an event. This may be done for example right before
  803. queuing for an event next time:</font></p>
  804. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>events-&gt;release();</i></font></p>
  805. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>events
  806. = NULL;</i></font></p>
  807. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>events
  808. = attachment-&gt;queEvents(&amp;status, this, eveLen, eveBuffer);</i></font></p>
  809. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Setting
  810. interface pointer to NULL is useful in case of exception during
  811. queEvents. In other aspects events handling did not change compared
  812. with ISC API. Please use for additional details our sample
  813. 08.events.cpp. </font>
  814. </p>
  815. <p style="margin-bottom: 0cm"><br/>
  816. </p>
  817. <h1><font size="4" style="font-size: 14pt">Using services.</font></h1>
  818. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  819. begin to use services one should first of all connect to service
  820. manager. This is done using attachServiceManager() method of
  821. <a href="#Provider">IProvider</a>. This method returns <a href="#Service">IService</a>
  822. interface which is used later to talk to service. To prepare SPB to
  823. attach to service manager one can use IXpbBuilder:</font></p>
  824. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IXpbBuilder*
  825. spb1 = utl-&gt;getXpbBuilder(&amp;status, IXpbBuilder::SPB_ATTACH,
  826. NULL, 0);</i></font></p>
  827. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>spb1-&gt;insertString(&amp;status,
  828. isc_spb_user_name, “sysdba”);</i></font></p>
  829. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>spb1-&gt;insertString(&amp;status,
  830. isc_spb_password, “masterkey”);</i></font></p>
  831. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">and
  832. proceed with attach:</font></p>
  833. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><a href="#Service">IService</a>*
  834. svc = prov-&gt;attachServiceManager(&amp;status, “service_mgr”,
  835. spb1-&gt;getBufferLength(&amp;status), spb1-&gt;getBuffer(&amp;status));</font></p>
  836. <p style="margin-bottom: 0cm"><br/>
  837. </p>
  838. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Using
  839. IService one can perform both available for services actions –
  840. start services and query various information about started utilities
  841. and server in general. When querying information one limitation takes
  842. place – formats of parameter blocks, used by query() method, in
  843. Firebird 3 are not supported by IXpbBuilder. Support will be probably
  844. added in later versions, in Firebird 3 you will have to build and
  845. analyze that blocks manually. Format of that blocks matches old
  846. format (used in ISC API) one to one. </font>
  847. </p>
  848. <p style="margin-bottom: 0cm"><br/>
  849. </p>
  850. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  851. start service one should first of all create appropriate SPB:</font></p>
  852. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IXpbBuilder*
  853. spb2 = utl-&gt;getXpbBuilder(&amp;status, IXpbBuilder::SPB_START,
  854. NULL, 0);</font></p>
  855. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">and
  856. add required items to it. For example, to print encryption statistics
  857. for database employee the following should be placed into SPB:</font></p>
  858. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">spb2-&gt;insertTag(&amp;status,
  859. isc_action_svc_db_stats);</font></p>
  860. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">spb2-&gt;insertString(&amp;status,
  861. isc_spb_dbname, &quot;employee&quot;);</font></p>
  862. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">spb2-&gt;insertInt(&amp;status,
  863. isc_spb_options, isc_spb_sts_encryption);</font></p>
  864. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">After
  865. it service can be started using start() method of <a href="#Service">IService</a>
  866. interface:</font></p>
  867. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">svc-&gt;start(&amp;status,
  868. spb2-&gt;getBufferLength(&amp;status), spb2-&gt;getBuffer(&amp;status));</font></p>
  869. <p style="margin-bottom: 0cm"><br/>
  870. </p>
  871. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Many
  872. started services (including mentioned here gstat) return text
  873. information during execution. To display it one should query started
  874. service anout that information line by line. This is done by calling
  875. query() method of <a href="#Service">IService</a> interface with
  876. appropriate send and receive blocks of parameters. Send block may
  877. contain various helper information (like timeout when querying
  878. service) or information to be passed to stdin of service utility or
  879. may be empty in the simplest case. Receive block must contain list of
  880. tags you want to receive from service. For most of utilities this is
  881. single isc_info_svc_line:</font></p>
  882. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>const
  883. unsigned char receiveItems1[] = {isc_info_svc_line};</i></font></p>
  884. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  885. query information one also needs a buffer for that information:</font></p>
  886. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>unsigned
  887. char results[1024];</i></font></p>
  888. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">After
  889. that preliminary steps we are ready to query service in a loop (each
  890. line returned in a single call to query()):</font></p>
  891. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>do</i></font></p>
  892. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  893. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>svc-&gt;query(&amp;status,
  894. 0, NULL, sizeof(receiveItems1), receiveItems1, sizeof(results),
  895. results);</i></font></p>
  896. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}
  897. while (printInfo(results, sizeof(results)));</i></font></p>
  898. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  899. this example we suppose that printInfo() function returns TRUE as
  900. long as service returns results block containing next output line
  901. (i.e. till end of data stream from service). Format of results block
  902. varies from service to service, and some services like gsec produce
  903. historical formats that are not trivial for parse – but this is out
  904. of our scope here. A minimum working sample of printInfo() is present
  905. in example 09.service.cpp.</font></p>
  906. <p style="margin-bottom: 0cm"><br/>
  907. </p>
  908. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Same
  909. query method is used to retrieve information about server but in this
  910. case query function is not invoked in a loop, i.e. buffer must be big
  911. enough to fit all information at once. This is not too hard –
  912. typically such calls do not return much data. As in previous case
  913. begin with receive block placing required items in it – in our
  914. example it's isc_info_svc_server_version:</font></p>
  915. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  916. unsigned char receiveItems2[] = {isc_info_svc_server_version};</font></p>
  917. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Existing
  918. from previous call results buffer may be reused. No loop is needed
  919. here:</font></p>
  920. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>svc-&gt;query(&amp;status,
  921. 0, NULL, sizeof(receiveItems2), receiveItems2, sizeof(results),
  922. results);</i></font></p>
  923. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>printInfo(results,
  924. sizeof(results));</i></font></p>
  925. <p style="margin-bottom: 0cm"><br/>
  926. </p>
  927. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">After
  928. finishing with services tasks do not forget to close an interface:</font></p>
  929. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>svc-&gt;detach(&amp;status);</i></font></p>
  930. <p style="margin-bottom: 0cm"><br/>
  931. </p>
  932. <p style="margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid">
  933. <font face="Albany, sans-serif"><font size="5" style="font-size: 18pt">Writing
  934. plugins.</font></font></p>
  935. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">To
  936. write a plugin means to implement some interfaces and place your
  937. implementation into dynamic library (.dll in windows or .so in linux)
  938. later referenced as </font><font size="4" style="font-size: 14pt"><i>plugin
  939. module</i></font> <font size="4" style="font-size: 14pt">or just
  940. </font><font size="4" style="font-size: 14pt"><i>module</i></font><font size="4" style="font-size: 14pt">.
  941. In most cases single plugin is place in dynamic library but in common
  942. case. One of that interfaces – <a href="#PluginModule">IPluginModule</a>
  943. – is module-wide (as more or less clear from it's name), others are
  944. per plugin. Also each plugin module should contain special exported
  945. entrypoint firebird_plugin() which name is defined in include file
  946. firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</font></p>
  947. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  948. previous part of this text we were mostly describing how to use
  949. existing interfaces, here main attention will be paid to implementing
  950. interfaces yourself. Certainly to do it one can and should use
  951. already existing interfaces both generic needed for accessing
  952. firebird databases (already described) and some more interfaces
  953. specifically designed for plugins.</font></p>
  954. <p style="margin-bottom: 0cm"><br/>
  955. </p>
  956. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Following
  957. text is actively using example of database encryption plugin
  958. examples/dbcrypt/DbCrypt.cpp. It will be good idea to compile this
  959. sample yourself and learn it when reading later.</font></p>
  960. <p style="margin-bottom: 0cm"><br/>
  961. </p>
  962. <h1><font size="4" style="font-size: 14pt">Implementation of plugin
  963. module.</font></h1>
  964. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Plugins
  965. actively interact with special firebird component called </font><font size="4" style="font-size: 14pt"><i>plugin
  966. manager</i></font><font size="4" style="font-size: 14pt">. In
  967. particular plugin manager should be aware what plugin modules were
  968. loaded and must be notified if operating system tries to unload one
  969. of that modules without explicit plugin manager command (this may
  970. happen first of all when using embedded access – when exit() is
  971. 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>
  972. <font size="4" style="font-size: 14pt">is unloaded). Primary task of
  973. IPluginModule interface is that notification. First of all one must
  974. decide - how to detect that module is going to be unloaded? When
  975. dynamic library is unloaded for some reason a lot of OS-dependent
  976. actions is performed and some of that actions may be used to detect
  977. this fact in the program. When writing plugins distributed with
  978. firebird we always use invocation of destructor of global variable.
  979. The big “plus” for this method is that it is OS independent
  980. (though something like atexit() function maybe also used
  981. successfully). But use of destructor makes it possible to easily
  982. concentrate almost everything related with unload detection in single
  983. class implementing at the same time <a href="#PluginModule">IPluginModule</a>
  984. interface.</font></p>
  985. <p style="margin-bottom: 0cm"><br/>
  986. </p>
  987. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Minimum
  988. implementation looks as follows:</font></p>
  989. <p style="margin-bottom: 0cm"><br/>
  990. </p>
  991. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>class
  992. PluginModule : public IPluginModuleImpl&lt;PluginModule,
  993. CheckStatusWrapper&gt;</i></font></p>
  994. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  995. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>private:</i></font></p>
  996. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IPluginManager*
  997. pluginManager;</i></font></p>
  998. <p style="margin-bottom: 0cm"><br/>
  999. </p>
  1000. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>public:</i></font></p>
  1001. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>PluginModule()</i></font></p>
  1002. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>:
  1003. pluginManager(NULL)</i></font></p>
  1004. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{
  1005. }</i></font></p>
  1006. <p style="margin-bottom: 0cm"><br/>
  1007. </p>
  1008. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>~PluginModule()</i></font></p>
  1009. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1010. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>if
  1011. (pluginManager)</i></font></p>
  1012. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1013. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>pluginManager-&gt;unregisterModule(this);</i></font></p>
  1014. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>doClean();</i></font></p>
  1015. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1016. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1017. <p style="margin-bottom: 0cm"><br/>
  1018. </p>
  1019. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>void
  1020. registerMe(IPluginManager* m)</i></font></p>
  1021. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1022. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>pluginManager
  1023. = m;</i></font></p>
  1024. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>pluginManager-&gt;registerModule(this);</i></font></p>
  1025. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1026. <p style="margin-bottom: 0cm"><br/>
  1027. </p>
  1028. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>void
  1029. doClean()</i></font></p>
  1030. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1031. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>pluginManager
  1032. = NULL;</i></font></p>
  1033. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1034. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>};</i></font></p>
  1035. <p style="margin-bottom: 0cm"><br/>
  1036. </p>
  1037. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">The
  1038. only data member is plugin manager interface <a href="#PluginManager">IPluginManager</a>.
  1039. It's passed to registerModule() function and saved in private
  1040. variable, at the same time module is registered in plugin manager by
  1041. the call to registerModule() method with own address as a single
  1042. parameter. Variable </font><font size="4" style="font-size: 14pt"><i>pluginManager
  1043. </i></font><font size="4" style="font-size: 14pt">not only stores
  1044. pointer to interface, at the same time it serves as a flag that
  1045. module is registered. When destructor of registered module is invoked
  1046. it notifies plugin manager (yes, this is what for this class exists!)
  1047. about unexpected unload by the call to unregisterModule() passing
  1048. pointer to itself. When plugin manager is going to unload module in
  1049. regular way in first of all calls doClean() method changing module
  1050. state to unregistered and this avoiding call to unregisterModule()
  1051. when OS performs actual unload.</font></p>
  1052. <p style="margin-bottom: 0cm"><br/>
  1053. </p>
  1054. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Implementing
  1055. plugin's interface IPluginModule we met with first interface required
  1056. to implement plugins – <a href="#PluginManager">IPluginManager</a>.
  1057. It will be actively used later, the rest of internals of this class
  1058. will hardly be required to you after copying it to your program. Just
  1059. don't forget to declare global variable of this type and call
  1060. registerMe() function from FB_PLUGIN_ENTRY_POINT.</font></p>
  1061. <p style="margin-bottom: 0cm"><br/>
  1062. </p>
  1063. <h1><font size="4" style="font-size: 14pt">Core interface of any
  1064. plugin.</font></h1>
  1065. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Let's
  1066. start implementing plugin itself. The type of main interface depends
  1067. upon plugin type (which is obvious), but all of them are based on
  1068. common reference counted interface IPluginBase which performs common
  1069. for all plugins (and very simple) tasks. Each plugin has some (also
  1070. reference counted) object which <i>owns</i> this plugin. In order to
  1071. perform smart plugin lifetime management any plugin must be able to
  1072. store that owner information and report it to plugin manager on
  1073. request. That means that each plugin must implement two trivial
  1074. methods setOwner() and getOwner() contained in IPluginBase interface.
  1075. Type-dependent methods are certainly more interesting - they are
  1076. discussed in interfaces description part.</font></p>
  1077. <p style="margin-bottom: 0cm"><br/>
  1078. </p>
  1079. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Let's
  1080. take a look at typical part of any plugin implementation (here I
  1081. specially use non-existent type SomePlugin):</font></p>
  1082. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>class
  1083. MyPlugin : public ISomePluginImpl&lt;MyPlugin, CheckStatusWrapper&gt;</i></font></p>
  1084. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1085. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>public:</i></font></p>
  1086. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>explicit
  1087. MyPlugin(<a href="#PluginConfig">IPluginConfig</a>* cnf) throw()</i></font></p>
  1088. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>:
  1089. config(cnf), refCounter(0), owner(NULL)</i></font></p>
  1090. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1091. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>config-&gt;addRef();</i></font></p>
  1092. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1093. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  1094. <font size="4" style="font-size: 14pt">Constructor gets as parameter
  1095. plugin configuration interface. If you are going to have you plugin
  1096. configured in some way it's good idea to save this interface in your
  1097. plugin and use it later. This will let you use common for all
  1098. firebird configuration style letting users have familiar
  1099. configuration and minimize code written. Certainly when saving any
  1100. reference counted interface it's better not forget to add reference
  1101. to it. Also set reference counter to 0 and plugin owner to NULL.</font></p>
  1102. <p style="margin-bottom: 0cm"><br/>
  1103. </p>
  1104. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>~MyPlugin()</i></font></p>
  1105. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1106. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>config-&gt;release();</i></font></p>
  1107. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1108. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  1109. <font size="4" style="font-size: 14pt">Destructor releases config
  1110. interface. Pay attention – we do not change reference counter of
  1111. our owner cause it owns us, not we own it.</font></p>
  1112. <p style="margin-bottom: 0cm"><br/>
  1113. </p>
  1114. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>//
  1115. IRefCounted implementation</i></font></p>
  1116. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>int
  1117. release()</i></font></p>
  1118. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1119. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>if
  1120. (--refCounter == 0)</i></font></p>
  1121. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1122. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>delete
  1123. this;</i></font></p>
  1124. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>return
  1125. 0;</i></font></p>
  1126. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1127. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>return
  1128. 1;</i></font></p>
  1129. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1130. <p style="margin-bottom: 0cm"><br/>
  1131. </p>
  1132. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>void
  1133. addRef()</i></font></p>
  1134. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1135. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>++refCounter;</i></font></p>
  1136. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1137. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  1138. <font size="4" style="font-size: 14pt">Absolutely typical
  1139. implementation of reference counted object.</font></p>
  1140. <p style="margin-bottom: 0cm"><br/>
  1141. </p>
  1142. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>//
  1143. IPluginBase implementation</i></font></p>
  1144. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>void
  1145. setOwner(IReferenceCounted* o)</i></font></p>
  1146. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1147. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>owner
  1148. = o;</i></font></p>
  1149. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1150. <p style="margin-bottom: 0cm"><br/>
  1151. </p>
  1152. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IReferenceCounted*
  1153. getOwner()</i></font></p>
  1154. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1155. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>return
  1156. owner;</i></font></p>
  1157. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1158. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  1159. <font size="4" style="font-size: 14pt">As it was promised
  1160. implementation of IPluginBase is trivial.</font></p>
  1161. <p style="margin-bottom: 0cm"><br/>
  1162. </p>
  1163. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>//
  1164. ISomePlugin implementation</i></font></p>
  1165. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>//
  1166. … here go various methods required for particular plugin type</i></font></p>
  1167. <p style="margin-bottom: 0cm"><br/>
  1168. </p>
  1169. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>private:</i></font></p>
  1170. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IPluginConfig*
  1171. config;</i></font></p>
  1172. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>FbSampleAtomic
  1173. refCounter;</i></font></p>
  1174. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IReferenceCounted*
  1175. owner;</i></font></p>
  1176. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>};</i></font></p>
  1177. <p style="margin-bottom: 0cm"><br/>
  1178. </p>
  1179. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">With
  1180. this sample formal part of main plugin interface implementation is
  1181. over. After adding type-specific methods (and writing probably a
  1182. lo-o-o-ot of code to make them useful) interface is ready.</font></p>
  1183. <p style="margin-bottom: 0cm"><br/>
  1184. </p>
  1185. <h1><font size="4" style="font-size: 14pt">Plugin's factory.</font></h1>
  1186. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">One
  1187. more interface required for plugin to work is <a href="#PluginFactory">IPluginFactory</a>.
  1188. Factory creates instances of plugin and returns them to plugin
  1189. manager. Factory typically looks this way:</font></p>
  1190. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>class
  1191. Factory : public IPluginFactoryImpl&lt;Factory, CheckStatusWrapper&gt;</i></font></p>
  1192. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1193. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>public:</i></font></p>
  1194. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>IPluginBase*
  1195. createPlugin(CheckStatusWrapper* status, IPluginConfig*
  1196. factoryParameter)</i></font></p>
  1197. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>{</i></font></p>
  1198. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>MyPlugin*
  1199. p = new MyPlugin(factoryParameter);</i></font></p>
  1200. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>p-&gt;addRef();</i></font></p>
  1201. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>return
  1202. p;</i></font></p>
  1203. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>}</i></font></p>
  1204. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>};</i></font></p>
  1205. <p style="margin-bottom: 0cm"><br/>
  1206. </p>
  1207. <p style="margin-bottom: 0cm; font-variant: normal; font-style: normal">
  1208. <font size="4" style="font-size: 14pt">Here attention should be payed
  1209. to the fact that even in a case when code in a function may throw
  1210. exceptions (operator new may throw in a case when memory exhausted)
  1211. one need not always manually define try/catch block –
  1212. implementation of firebird interfaces does this job for you, in
  1213. implementation of IPluginFactory it's placed into template
  1214. IPluginFactoryImpl. Take into an account that default status wrappers
  1215. perform meaning-full processing only for FbException. But if you
  1216. (that definitely makes sense if you work on some big project) define
  1217. your own wrapper you can handle any type of C++ exception and pass
  1218. useful information about it from your plugin.</font></p>
  1219. <p style="margin-bottom: 0cm"><br/>
  1220. </p>
  1221. <h1><font size="4" style="font-size: 14pt">Plugin module
  1222. initialization entrypoint.</font></h1>
  1223. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">When
  1224. plugin manager loads plugin module it invokes module initializing
  1225. routine – the only exported from plugin function
  1226. FB_PLUGIN_ENTRY_POINT. To wrote it's code one will need two global
  1227. variables – plugin module and plugin factory. In our case that is:</font></p>
  1228. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>PluginModule
  1229. module;</i></font></p>
  1230. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt"><i>Factory
  1231. factory;</i></font></p>
  1232. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">If
  1233. you module contains more than one plugin you will need a factory per
  1234. each plugin.</font></p>
  1235. <p style="margin-bottom: 0cm"><br/>
  1236. </p>
  1237. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">For
  1238. FB_PLUGIN_ENTRY_POINT we should not forget that it should be exported
  1239. from plugin module, and it requires taking into an account some OS
  1240. specifics. We do it using macro FB_DLL_EXPORT defined in
  1241. examples/interfaces/ifaceExamples.h. If you are sure you write plugin
  1242. only for some specific OS you can make this place a bit simpler. In
  1243. minimum case the function should register module and all factories in
  1244. plugin manager:</font></p>
  1245. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">extern
  1246. &quot;C&quot; FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster*
  1247. master)</font></p>
  1248. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">{</font></p>
  1249. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager*
  1250. pluginManager = master-&gt;getPluginManager();</font></p>
  1251. <p style="margin-bottom: 0cm"><br/>
  1252. </p>
  1253. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">module.registerMe(pluginManager);</font></p>
  1254. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">pluginManager-&gt;registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
  1255. &quot;DbCrypt_example&quot;, &amp;factory);</font></p>
  1256. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">}</font></p>
  1257. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">First
  1258. of all we call written by us not long ago PluginModule::registerMe()
  1259. function which will saves IPluginManager for future use and registers
  1260. our plugin module. Next time to register factory (or factories in
  1261. case of multiple plugins per module) takes place. We must pass
  1262. correct plugin type (valid types are enumerated in interface
  1263. IPluginManager) and a name under which plugin will be registered. In
  1264. simple case it should match with the name of dynamic library with
  1265. plugin module. Following last rule will help you avoid configuring
  1266. your plugin manually in plugins.conf.</font></p>
  1267. <p style="margin-bottom: 0cm"><br/>
  1268. </p>
  1269. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Pay
  1270. attention - unlike applications plugins should not use
  1271. fb_get_master_interface() to obtain IMaster. Instance, passed to
  1272. FB_PLUGIN_ENTRY_POINT, should be used instead. If you ever need
  1273. master interface in your plugin take care about saving it in this
  1274. function.</font></p>
  1275. <p style="margin-bottom: 0cm"><br/>
  1276. </p>
  1277. <p style="margin-bottom: 0cm"><br/>
  1278. </p>
  1279. <p style="margin-top: 0.43cm; margin-bottom: 0.51cm; page-break-after: avoid">
  1280. <font face="Albany, sans-serif"><font size="5" style="font-size: 18pt">Interfaces:
  1281. from A to Z</font></font></p>
  1282. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
  1283. this glossary we do not list interfaces that are not actively used
  1284. (like IRequest, needed first of all to support legacy ISC API
  1285. requests). Same reference may be made for a number of methods (like
  1286. compileRequest() in IAttachment). For interfaces / methods, having
  1287. direct analogue in old API, that analogue is provided.</font></p>
  1288. <p style="margin-bottom: 0cm"><br/>
  1289. </p>
  1290. <h1><font size="4" style="font-size: 14pt">Generic interfaces.</font></h1>
  1291. <p style="margin-bottom: 0cm"><a name="Attachment"></a><font size="4" style="font-size: 14pt">Attachment
  1292. interface – replaces isc_db_handle:</font></p>
  1293. <ol>
  1294. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1295. getInfo(StatusType* status, unsigned itemsLength, const unsigned
  1296. char* items, unsigned bufferLength, unsigned char* buffer) –
  1297. replaces isc_database_info().</font></p>
  1298. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  1299. startTransaction(StatusType* status, unsigned tpbLength, const
  1300. unsigned char* tpb) – partially replaces isc_start_multiple(), to
  1301. start &gt;1 transaction <a href="#Dtc">distributed transactions
  1302. coordinator</a> should be used, also possible to <a href="#Transaction">join</a>
  1303. 2 transactions into single distributed transaction.</font></p>
  1304. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  1305. reconnectTransaction(StatusType* status, unsigned length, const
  1306. unsigned char* id) – makes it possible to connect to a transaction
  1307. in limbo. Id parameter contains transaction number in network format
  1308. of given length.</font></p>
  1309. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IRequest*
  1310. compileRequest(StatusType* status, unsigned blrLength, const
  1311. unsigned char* blr) – support of ISC API.</font></p>
  1312. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1313. transactRequest(StatusType* status, ITransaction* transaction,
  1314. unsigned blrLength, const unsigned char* blr, unsigned inMsgLength,
  1315. const unsigned char* inMsg, unsigned outMsgLength, unsigned char*
  1316. outMsg) – support of ISC API.</font></p>
  1317. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IBlob*
  1318. createBlob(StatusType* status, ITransaction* transaction, ISC_QUAD*
  1319. id, unsigned bpbLength, const unsigned char* bpb) – creates new
  1320. blob, stores it's identifier in id, replaces isc_create_blob2().</font></p>
  1321. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IBlob*
  1322. openBlob(StatusType* status, ITransaction* transaction, ISC_QUAD*
  1323. id, unsigned bpbLength, const unsigned char* bpb) – opens existing
  1324. blob, replaces isc_open_blob2().</font></p>
  1325. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1326. getSlice(StatusType* status, ITransaction* transaction, ISC_QUAD*
  1327. id, unsigned sdlLength, const unsigned char* sdl, unsigned
  1328. paramLength, const unsigned char* param, int sliceLength, unsigned
  1329. char* slice) - support of ISC API.</font></p>
  1330. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1331. putSlice(StatusType* status, ITransaction* transaction, ISC_QUAD*
  1332. id, unsigned sdlLength, const unsigned char* sdl, unsigned
  1333. paramLength, const unsigned char* param, int sliceLength, unsigned
  1334. char* slice) - support of ISC API.</font></p>
  1335. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1336. executeDyn(StatusType* status, ITransaction* transaction, unsigned
  1337. length, const unsigned char* dyn) - support of ISC API.</font></p>
  1338. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IStatement*
  1339. prepare(StatusType* status, ITransaction* tra, unsigned stmtLength,
  1340. const char* sqlStmt, unsigned dialect, unsigned flags) – replaces
  1341. isc_dsql_prepare(). Additional parameter flags makes it possible to
  1342. control what information will be preloaded from engine at once (i.e.
  1343. in single network packet for remote operation).</font></p>
  1344. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  1345. execute(StatusType* status, ITransaction* transaction, unsigned
  1346. stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata*
  1347. inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void*
  1348. outBuffer) – executes any SQL statement except returning multiple
  1349. rows of data. Partial analogue of isc_dsql_execute2() - in and out
  1350. XSLQDAs replaced with input and output messages with appropriate
  1351. buffers.</font></p>
  1352. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IResultSet*
  1353. openCursor(StatusType* status, ITransaction* transaction, unsigned
  1354. stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata*
  1355. inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const
  1356. char* cursorName, unsigned cursorFlags) – executes SQL statement
  1357. potentially returning multiple rows of data. Returns <a href="#ResultSet">ResultSet</a>
  1358. interface which should be used to fetch that data. Format of output
  1359. data is defined by outMetadata parameter, leaving it NULL default
  1360. format may be used. Parameter cursorName specifies name of opened
  1361. cursor (analogue of isc_dsql_set_cursor_name()). Parameter
  1362. cursorFlags is needed to open bidirectional cursor setting it's
  1363. value to Istatement::CURSOR_TYPE_SCROLLABLE.</font></p>
  1364. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IEvents*
  1365. queEvents(StatusType* status, IEventCallback* callback, unsigned
  1366. length, const unsigned char* events) – replaces isc_que_events()
  1367. call. Instead callback function with void* parameter callback
  1368. interface is used.</font></p>
  1369. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1370. cancelOperation(StatusType* status, int option) – replaces
  1371. fb_cancel_operation().</font></p>
  1372. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1373. ping(StatusType* status) – check connection status. If test fails
  1374. the only operation possible with attachment is to close it.</font></p>
  1375. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1376. detach(StatusType* status) – replaces isc_detach_database(). On
  1377. success releases interface.</font></p>
  1378. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1379. dropDatabase(StatusType* status) - replaces isc_drop_database(). On
  1380. success releases interface.</font></p>
  1381. </ol>
  1382. <p style="margin-bottom: 0cm"><br/>
  1383. </p>
  1384. <p style="margin-bottom: 0cm"><br/>
  1385. </p>
  1386. <p style="margin-bottom: 0cm"><a name="Blob"></a><font size="4" style="font-size: 14pt">Blob
  1387. interface – replaces isc_blob_handle:</font></p>
  1388. <ol>
  1389. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1390. getInfo(StatusType* status, unsigned itemsLength, const unsigned
  1391. char* items, unsigned bufferLength, unsigned char* buffer) –
  1392. replaces isc_blob_info().</font></p>
  1393. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1394. getSegment(StatusType* status, unsigned bufferLength, void* buffer,
  1395. unsigned* segmentLength) – replaces isc_get_segment(). Unlike it
  1396. never returns isc_segstr_eof and isc_segment errors (that are
  1397. actually not errors), instead returns <a href="#Completion codes">completion
  1398. codes</a> IStatus::RESULT_NO_DATA and IStatus::RESULT_SEGMENT,
  1399. normal return is IStatus::RESULT_OK.</font></p>
  1400. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1401. putSegment(StatusType* status, unsigned length, const void* buffer)
  1402. – replaces isc_put_segment().</font></p>
  1403. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1404. cancel(StatusType* status) – replaces isc_cancel_blob(). On
  1405. success releases interface.</font></p>
  1406. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1407. close(StatusType* status) – replaces isc_close_blob(). On success
  1408. releases interface.</font></p>
  1409. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1410. seek(StatusType* status, int mode, int offset) – replaces
  1411. isc_seek_blob().</font></p>
  1412. </ol>
  1413. <p style="margin-bottom: 0cm"><br/>
  1414. </p>
  1415. <p style="margin-bottom: 0cm"><br/>
  1416. </p>
  1417. <p style="margin-bottom: 0cm"><a name="Config"></a><font size="4" style="font-size: 14pt">Config
  1418. interface – generic configuration file interface:</font></p>
  1419. <ol>
  1420. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfigEntry*
  1421. find(StatusType* status, const char* name) – find entry by name.</font></p>
  1422. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfigEntry*
  1423. findValue(StatusType* status, const char* name, const char* value) –
  1424. find entry by name and value.</font></p>
  1425. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfigEntry*
  1426. findPos(StatusType* status, const char* name, unsigned pos) – find
  1427. entry by name and position. If configuration file contains lines:</font></p>
  1428. </ol>
  1429. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Db=DBA</font></p>
  1430. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Db=DBB</font></p>
  1431. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Db=DBC</font></p>
  1432. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">call
  1433. to findPos(status, “Db”, 2) will return entry with value DBB.</font></p>
  1434. <p style="margin-bottom: 0cm"><br/>
  1435. </p>
  1436. <p style="margin-bottom: 0cm"><br/>
  1437. </p>
  1438. <p style="margin-bottom: 0cm"><a name="ConfigManager"></a><font size="4" style="font-size: 14pt">ConfigManager
  1439. interface – generic interface to access various configuration
  1440. objects:</font></p>
  1441. <ol>
  1442. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1443. char* getDirectory(unsigned code) – returns location of
  1444. appropriate directory in current firebird instance. See codes for
  1445. this call a <a href="#Directory codes">few lines later</a>.</font></p>
  1446. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IFirebirdConf*
  1447. getFirebirdConf() - returns interface to access default
  1448. configuration values (from firebird.conf).</font></p>
  1449. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IFirebirdConf*
  1450. getDatabaseConf(const char* dbName) - returns interface to access
  1451. db-specific configuration (takes into an account firebird.conf and
  1452. appropriate part of databases.conf).</font></p>
  1453. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfig*
  1454. getPluginConfig(const char* configuredPlugin) – returns interface
  1455. to access named plugin configuration.</font></p>
  1456. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1457. char* getInstallDirectory() - returns directory where firebird is
  1458. installed.</font></p>
  1459. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1460. char* getRootDirectory() - returns root directory of current
  1461. instance, in single-instance case usually matches install directory.</font></p>
  1462. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1463. char* getDefaultSecurityDb() - returns default (i.e. not taking into
  1464. an account configuration files) pathname of security database, used
  1465. first of all internally to enable correct access to security
  1466. database on multi-provider server with zero configuration.</font></p>
  1467. </ol>
  1468. <p style="margin-bottom: 0cm"><a name="Directory codes"></a><font size="4" style="font-size: 14pt">Directory
  1469. codes:</font></p>
  1470. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_BIN
  1471. – bin (utilities like isql, gbak, gstat)</font></p>
  1472. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_SBIN
  1473. – sbin (fbguard and firebird server)</font></p>
  1474. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_CONF
  1475. – configuration files (firebird.conf, databases.conf, plugins.conf)</font></p>
  1476. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_LIB
  1477. – lib (fbclient, ib_util)</font></p>
  1478. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_INC
  1479. – include (ibase.h, firebird/Interfaces.h)</font></p>
  1480. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_DOC
  1481. - documentation</font></p>
  1482. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_UDF
  1483. – UDF (ib_udf, fbudf)</font></p>
  1484. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_SAMPLE
  1485. - samples</font></p>
  1486. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_SAMPLEDB
  1487. – samples database (employee.fdb)</font></p>
  1488. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_HELP
  1489. – qli help (help.fdb)</font></p>
  1490. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_INTL
  1491. – international libraries (fbintl)</font></p>
  1492. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_MISC
  1493. – miscellaneous files (like uninstall manifest and something else)</font></p>
  1494. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_SECDB
  1495. – where security database is stored (securityN.fdb)</font></p>
  1496. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_MSG
  1497. – where messages file is stored (firebird.msg)</font></p>
  1498. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_LOG
  1499. – where log file is stored (firebird.log)</font></p>
  1500. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_GUARD
  1501. – where guardian lock is stored (fb_guard)</font></p>
  1502. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DIR_PLUGINS
  1503. – plugins directory ([lib]Engine12.{dll|so})</font></p>
  1504. <p style="margin-bottom: 0cm"><br/>
  1505. </p>
  1506. <p style="margin-bottom: 0cm"><br/>
  1507. </p>
  1508. <p style="margin-bottom: 0cm"><a name="ConfigEntry"></a><font size="4" style="font-size: 14pt">ConfigEntry
  1509. interface – represents an entry (Key = Values with probably
  1510. sub-entries) in firebird configuration file:</font></p>
  1511. <ol>
  1512. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1513. char* getName() - returns key name.</font></p>
  1514. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1515. char* getValue() - returns value as character string.</font></p>
  1516. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_INT64
  1517. getIntValue() - treats value as integer and returns it.</font></p>
  1518. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  1519. getBoolValue() - treats value as boolean and returns it.</font></p>
  1520. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfig*
  1521. getSubConfig(StatusType* status) – treats sub-entries as separate
  1522. configuration file and returns Config interface for it.</font></p>
  1523. </ol>
  1524. <p style="margin-bottom: 0cm"><br/>
  1525. </p>
  1526. <p style="margin-bottom: 0cm"><br/>
  1527. </p>
  1528. <p style="margin-bottom: 0cm"><a name="Dtc"></a><font size="4" style="font-size: 14pt">Dtc
  1529. interface – distributed transactions coordinator. Used to start
  1530. distributed (working with 2 or more attachments) transaction. Unlike
  1531. pre-FB3 approach where distributed transaction must be started in
  1532. this way from the most beginning FB3's distributed transactions
  1533. coordinator makes it also possible to join already started
  1534. transactions into single distributed transaction.</font></p>
  1535. <ol>
  1536. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  1537. join(StatusType* status, ITransaction* one, ITransaction* two) –
  1538. joins 2 independent transactions into distributed transaction. On
  1539. success both transactions passed to join() are released and pointers
  1540. to them should not be used any more.</font></p>
  1541. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IDtcStart*
  1542. startBuilder(StatusType* status) – returns <a href="#DtcStart">DtcStart</a>
  1543. interface.</font></p>
  1544. </ol>
  1545. <p style="margin-bottom: 0cm"><br/>
  1546. </p>
  1547. <p style="margin-bottom: 0cm"><br/>
  1548. </p>
  1549. <p style="margin-bottom: 0cm"><a name="DtcStart"></a><font size="4" style="font-size: 14pt">DtcStart
  1550. interface – replaces array of struct TEB (passed to
  1551. isc_start_multiple() in ISC API). This interface accumulates
  1552. attachments (and probably appropriate TPBs) for which dustributed
  1553. transaction should be started.</font></p>
  1554. <ol>
  1555. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1556. addAttachment(StatusType* status, IAttachment* att) – adds
  1557. attachment, transaction for it will be started with default TPB.</font></p>
  1558. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1559. addWithTpb(StatusType* status, IAttachment* att, unsigned length,
  1560. const unsigned char* tpb) - adds attachment and TPB which will be
  1561. used to start transaction for this attachment.</font></p>
  1562. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  1563. start(StatusType* status) – start distributed transaction for
  1564. accumulated attachments. On successful return DtcStart interface is
  1565. disposed automatically.</font></p>
  1566. </ol>
  1567. <p style="margin-bottom: 0cm"><br/>
  1568. </p>
  1569. <p style="margin-bottom: 0cm"><br/>
  1570. </p>
  1571. <p style="margin-bottom: 0cm"><a name="EventCallback"></a><font size="4" style="font-size: 14pt">EventCallback
  1572. interface – replaces callback function used in isc_que_events()
  1573. call. Should be implemented by user to monitor events with
  1574. IAttachment::queEvents() method.</font></p>
  1575. <ol>
  1576. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1577. eventCallbackFunction(unsigned length, const unsigned char* events)
  1578. – is called each time event happens.</font></p>
  1579. </ol>
  1580. <p style="margin-bottom: 0cm"><br/>
  1581. </p>
  1582. <p style="margin-bottom: 0cm"><br/>
  1583. </p>
  1584. <p style="margin-bottom: 0cm"><a name="Events"></a><font size="4" style="font-size: 14pt">Events
  1585. interface – replaces event identifier when working with events
  1586. monitoring.</font></p>
  1587. <ol>
  1588. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1589. cancel(StatusType* status) - cancels events monitoring started by
  1590. IAttachment::queEvents().</font></p>
  1591. </ol>
  1592. <p style="margin-bottom: 0cm"><br/>
  1593. </p>
  1594. <p style="margin-bottom: 0cm"><br/>
  1595. </p>
  1596. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FirebirdConf
  1597. interface – access to main firebird configuration. Used for both
  1598. default configuration, set by firebird.conf, and per-database
  1599. configuration, adjusted by databases.conf. In order to speed up
  1600. access to configuration values calls accessing actual values use
  1601. integer key instead symbolic parameter name. Key is stable during
  1602. server run (i.e. plugin can get it once and than use to get
  1603. configuration value for different databases). </font>
  1604. </p>
  1605. <ol>
  1606. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1607. getKey(const char* name) – get key for parameter name. ~0 (all
  1608. bits are 1) is returned in a case when there is no such parameter.</font></p>
  1609. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_INT64
  1610. asInteger(unsigned key) – return value of integer parameter.</font></p>
  1611. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1612. char* asString(unsigned key) - return value of string parameter.</font></p>
  1613. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  1614. asBoolean(unsigned key) - return value of boolean parameter.
  1615. Standard abbreviations (1/true/t/yes/y) are treated as “true”,
  1616. all other cases – false.</font></p>
  1617. </ol>
  1618. <p style="margin-bottom: 0cm"><br/>
  1619. </p>
  1620. <p style="margin-bottom: 0cm"><br/>
  1621. </p>
  1622. <p style="margin-bottom: 0cm"><a name="Master"></a><font size="4" style="font-size: 14pt">Master
  1623. interface – main interface from which start all operations with
  1624. firebird API.</font></p>
  1625. <ol>
  1626. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IStatus*
  1627. getStatus() - get instance if <a href="#Status">Status</a>
  1628. interface.</font></p>
  1629. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IProvider*
  1630. getDispatcher() - get instance of <a href="#Provider">Provider</a>
  1631. interface, implemented by yValve (main provider instance).</font></p>
  1632. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager*
  1633. getPluginManager() - get instance of <a href="#PluginManager">PluginManager</a>
  1634. interface.</font></p>
  1635. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITimerControl*
  1636. getTimerControl() - get instance of <a href="#TimerControl">TimerControl</a>
  1637. interface.</font></p>
  1638. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IDtc*
  1639. getDtc() - get instance of <a href="#Dtc">Dtc</a> interface.</font></p>
  1640. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IUtil*
  1641. getUtilInterface() - get instance of <a href="#Util">Util</a>
  1642. interface.</font></p>
  1643. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfigManager*
  1644. getConfigManager() - get instance of <a href="#ConfigManager">ConfigManager</a>
  1645. interface.</font></p>
  1646. </ol>
  1647. <p style="margin-bottom: 0cm"><br/>
  1648. </p>
  1649. <p style="margin-bottom: 0cm"><br/>
  1650. </p>
  1651. <p style="margin-bottom: 0cm"><a name="MessageMetadata"></a><font size="4" style="font-size: 14pt">MessageMetadata
  1652. interface – partial analogue of XSQLDA (does not contain message
  1653. data, only message format info is present). Used in a calls related
  1654. with execution of SQL statements.</font></p>
  1655. <ol>
  1656. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1657. getCount(StatusType* status) – returns number of fields/parameters
  1658. in a message. In all calls, containing index parameter, it's value
  1659. should be: 0 &lt;= index &lt; getCount().</font></p>
  1660. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1661. char* getField(StatusType* status, unsigned index) – returns field
  1662. name.</font></p>
  1663. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1664. char* getRelation(StatusType* status, unsigned index) – returns
  1665. relation name (from which given field is selected).</font></p>
  1666. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1667. char* getOwner(StatusType* status, unsigned index) - returns
  1668. relation's owner name.</font></p>
  1669. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1670. char* getAlias(StatusType* status, unsigned index) - returns field
  1671. alias.</font></p>
  1672. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1673. getType(StatusType* status, unsigned index) - returns field SQL
  1674. type.</font></p>
  1675. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  1676. isNullable(StatusType* status, unsigned index) - returns true if
  1677. field is nullable.</font></p>
  1678. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1679. getSubType(StatusType* status, unsigned index) - returns blof field
  1680. subtype (0 – binary, 1 – text, etc.).</font></p>
  1681. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1682. getLength(StatusType* status, unsigned index) - returns maximum
  1683. field length.</font></p>
  1684. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1685. getScale(StatusType* status, unsigned index) - returns scale factor
  1686. for numeric field.</font></p>
  1687. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1688. getCharSet(StatusType* status, unsigned index) - returns character
  1689. set for character field and text blob.</font></p>
  1690. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1691. getOffset(StatusType* status, unsigned index) - returns offset of
  1692. field data in message buffer (use it to access data in message
  1693. buffer).</font></p>
  1694. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1695. getNullOffset(StatusType* status, unsigned index) - returns offset
  1696. of null indicator for a field in message buffer.</font></p>
  1697. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IMetadataBuilder*
  1698. getBuilder(StatusType* status) - returns <a href="#MessageMetadata">MetadataBuilder</a>
  1699. interface initialized with this message metadata.</font></p>
  1700. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1701. getMessageLength(StatusType* status) - returns length of message
  1702. buffer (use it to allocate memory for the buffer).</font></p>
  1703. </ol>
  1704. <p style="margin-bottom: 0cm"><br/>
  1705. </p>
  1706. <p style="margin-bottom: 0cm"><br/>
  1707. </p>
  1708. <p style="margin-bottom: 0cm"><a name="MetadataBuilder"></a><font size="4" style="font-size: 14pt">MetadataBuilder
  1709. interface – makes it possible to coerce datatypes in existing
  1710. message or construct metadata from the beginning.</font></p>
  1711. <ol>
  1712. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1713. setType(StatusType* status, unsigned index, unsigned type) – set
  1714. SQL type of a field.</font></p>
  1715. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1716. setSubType(StatusType* status, unsigned index, int subType) – set
  1717. blof field subtype.</font></p>
  1718. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1719. setLength(StatusType* status, unsigned index, unsigned length) –
  1720. set maximum length of character field.</font></p>
  1721. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1722. setCharSet(StatusType* status, unsigned index, unsigned charSet) –
  1723. set character set for character field and text blob.</font></p>
  1724. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1725. setScale(StatusType* status, unsigned index, unsigned scale) – set
  1726. scale factor for numeric field </font>
  1727. </p>
  1728. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1729. truncate(StatusType* status, unsigned count) – truncate message to
  1730. contain not more than count fields.</font></p>
  1731. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1732. moveNameToIndex(StatusType* status, const char* name, unsigned
  1733. index) – reorganize fields in a message – move field “name”
  1734. to given position.</font></p>
  1735. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1736. remove(StatusType* status, unsigned index) – remove field.</font></p>
  1737. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1738. addField(StatusType* status) – add field.</font></p>
  1739. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IMessageMetadata*
  1740. getMetadata(StatusType* status) – get <a href="#10. MessageMetadata">MessageMetadata</a>
  1741. interface built by this builder.</font></p>
  1742. </ol>
  1743. <p style="margin-bottom: 0cm"><br/>
  1744. </p>
  1745. <p style="margin-bottom: 0cm"><br/>
  1746. </p>
  1747. <p style="margin-bottom: 0cm"><a name="OffsetsCallback"></a><font size="4" style="font-size: 14pt">OffsetsCallback
  1748. interface:</font></p>
  1749. <ol>
  1750. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">setOffset(StatusType*
  1751. status, unsigned index, unsigned offset, unsigned nullOffset) –
  1752. notifies that offsets for field/parameter number “index” should
  1753. be set to passed values. Should be implemented by user when
  1754. implementing <a href="#MessageMetadata">MessageMetadata</a>
  1755. interface and using <a href="#Util">Util</a>::setOffsets().</font></p>
  1756. </ol>
  1757. <p style="margin-bottom: 0cm"><br/>
  1758. </p>
  1759. <p style="margin-bottom: 0cm"><br/>
  1760. </p>
  1761. <p style="margin-bottom: 0cm"><a name="PluginConfig"></a><font size="4" style="font-size: 14pt">PluginConfig
  1762. interface – passed to plugin's factory when plugin instance (with
  1763. particular configuration) to be created.</font></p>
  1764. <ol>
  1765. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1766. char* getConfigFileName() - recommended file name where
  1767. configuration for plugin is expected to be stored.</font></p>
  1768. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfig*
  1769. getDefaultConfig(StatusType* status) – plugin configuration loaded
  1770. with default rules.</font></p>
  1771. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IFirebirdConf*
  1772. getFirebirdConf(StatusType* status) – master firebird
  1773. configuration taking into an account per-database settings for a
  1774. database with which will work new instance of plugin.</font></p>
  1775. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1776. setReleaseDelay(StatusType* status, ISC_UINT64 microSeconds) –
  1777. used by plugin to configure recommended delay during which plugin
  1778. module will not be unloaded by plugin manager after release of last
  1779. plugin instance from that module.</font></p>
  1780. </ol>
  1781. <p style="margin-bottom: 0cm"><br/>
  1782. </p>
  1783. <p style="margin-bottom: 0cm"><br/>
  1784. </p>
  1785. <p style="margin-bottom: 0cm"><a name="PluginFactory"></a><font size="4" style="font-size: 14pt">PluginFactory
  1786. interface – should be implemented by plugin author when writing
  1787. plugin.</font></p>
  1788. <ol>
  1789. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginBase*
  1790. createPlugin(StatusType* status, IPluginConfig* factoryParameter) –
  1791. creates new instance of plugin with passed recommended
  1792. configuration.</font></p>
  1793. </ol>
  1794. <p style="margin-bottom: 0cm"><br/>
  1795. </p>
  1796. <p style="margin-bottom: 0cm"><br/>
  1797. </p>
  1798. <p style="margin-bottom: 0cm"><a name="PluginManager"></a><font size="4" style="font-size: 14pt">PluginManager
  1799. interface – API of plugin manager.</font></p>
  1800. <ol>
  1801. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1802. registerPluginFactory(unsigned pluginType, const char* defaultName,
  1803. IPluginFactory* factory) – registers named factory of plugins of
  1804. given type.</font></p>
  1805. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1806. registerModule(IPluginModule* cleanup) – registers plugin module.</font></p>
  1807. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1808. unregisterModule(IPluginModule* cleanup) – unregisters plugin
  1809. module (in case of unexpected unload by OS).</font></p>
  1810. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginSet*
  1811. getPlugins(StatusType* status, unsigned pluginType, const char*
  1812. namesList, IFirebirdConf* firebirdConf) – returns PluginSet
  1813. interface providing access to list of plugins of given type. Names
  1814. of plugins to be included are taken from namesList, when missing
  1815. (NULL) – from configuration setting for given pluginType. If
  1816. firebirdConf parameter is specified it is used for all configuration
  1817. purporses (including getting list of plugins and passing to
  1818. <a href="#PluginFactory">PluginFactory</a>::createPlugin() method),
  1819. if missing (NULL) – default configuration (from firebird.conf) is
  1820. used.</font></p>
  1821. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IConfig*
  1822. getConfig(StatusType* status, const char* filename) – returns
  1823. Config interface for given configuration file name. Can be used by
  1824. plugins to access configuration files with standard format but
  1825. non-default name.</font></p>
  1826. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1827. releasePlugin(IPluginBase* plugin) – release given plugin. Should
  1828. be used for plugins instead simple release() due to need to perform
  1829. additional actions with plugin owner before actual release.</font></p>
  1830. </ol>
  1831. <p style="margin-bottom: 0cm"><br/>
  1832. </p>
  1833. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Constants
  1834. defined by PluginManager interface (plugin types):</font></p>
  1835. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_PROVIDER</font></p>
  1836. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_AUTH_SERVER</font></p>
  1837. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_AUTH_CLIENT</font></p>
  1838. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_AUTH_USER_MANAGEMENT</font></p>
  1839. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_EXTERNAL_ENGINE</font></p>
  1840. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_TRACE</font></p>
  1841. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_WIRE_CRYPT</font></p>
  1842. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_DB_CRYPT</font></p>
  1843. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TYPE_KEY_HOLDER</font></p>
  1844. <p style="margin-bottom: 0cm"><br/>
  1845. </p>
  1846. <p style="margin-bottom: 0cm"><br/>
  1847. </p>
  1848. <p style="margin-bottom: 0cm"><a name="PluginModule"></a><font size="4" style="font-size: 14pt">PluginModule
  1849. interface – represents plugin module (dynamic library). Should be
  1850. implemented by plugin author in each plugin module (one instance per
  1851. module).</font></p>
  1852. <ol>
  1853. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1854. doClean() - called by plugin manager before normal unload of plugin
  1855. module.</font></p>
  1856. </ol>
  1857. <p style="margin-bottom: 0cm"><br/>
  1858. </p>
  1859. <p style="margin-bottom: 0cm"><br/>
  1860. </p>
  1861. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PluginSet
  1862. interface – represents set of plugins of given type. Typically used
  1863. by internal firebird code but recommended for use in plugins loading
  1864. other plugins.</font></p>
  1865. <ol>
  1866. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1867. char* getName() - get name of current plugin in a set.</font></p>
  1868. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1869. char* getModuleName() - get name of a module of current plugin in a
  1870. set (in simple case matches plugin name).</font></p>
  1871. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginBase*
  1872. getPlugin(StatusType* status) – get an instance of current plugin,
  1873. returned interface should be casted to main interface of plugin of
  1874. requested in <a href="#PluginManager">PluginManager</a>::getPlugins()
  1875. type. Returns NULL if set does not contain any more plugins.
  1876. Reference counter of plugin, returned by this function, is
  1877. incremented on return – do not forget to use releasePlugin()
  1878. method of <a href="#PluginManager">PluginManager</a> for plugins
  1879. returned by this method.</font></p>
  1880. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1881. next(StatusType* status) – make set to switch to next plugin from
  1882. the list.</font></p>
  1883. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1884. set(StatusType* status, const char* list) – reset interface: make
  1885. it work with list of plugins provided by list parameter. Type of
  1886. plugins remains unchanged.</font></p>
  1887. </ol>
  1888. <p style="margin-bottom: 0cm"><br/>
  1889. </p>
  1890. <p style="margin-bottom: 0cm"><br/>
  1891. </p>
  1892. <p style="margin-bottom: 0cm"><a name="Provider"></a><font size="4" style="font-size: 14pt">Provider
  1893. interface – main interface to start database / service access.</font></p>
  1894. <ol>
  1895. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IAttachment*
  1896. attachDatabase(StatusType* status, const char* fileName, unsigned
  1897. dpbLength, const unsigned char* dpb) – replaces
  1898. isc_attach_database().</font></p>
  1899. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IAttachment*
  1900. createDatabase(StatusType* status, const char* fileName, unsigned
  1901. dpbLength, const unsigned char* dpb) – replaces
  1902. isc_create_database().</font></p>
  1903. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IService*
  1904. attachServiceManager(StatusType* status, const char* service,
  1905. unsigned spbLength, const unsigned char* spb) – replaces
  1906. isc_service_attach().</font></p>
  1907. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1908. shutdown(StatusType* status, unsigned timeout, const int reason) –
  1909. replaces fb_shutdown().</font></p>
  1910. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1911. setDbCryptCallback(StatusType* status, ICryptKeyCallback*
  1912. cryptCallback) – sets database encryption callback interface that
  1913. will be used for following database and service attachments. See …
  1914. for details.</font></p>
  1915. </ol>
  1916. <p style="margin-bottom: 0cm"><br/>
  1917. </p>
  1918. <p style="margin-bottom: 0cm"><br/>
  1919. </p>
  1920. <p style="margin-bottom: 0cm"><a name="ResultSet"></a><font size="4" style="font-size: 14pt">ResultSet
  1921. interface – replaces (with extended functionality) some functions
  1922. of isc_stmt_handle. This interface is returned by openCursor() call
  1923. in <a href="#Attachment">IAttachment</a> or <a href="#Statement">IStatement</a>.
  1924. All fetch calls except fetchNext() work only for bidirectional
  1925. (opened with CURSOR_TYPE_SCROLLABLE flag) result set.</font></p>
  1926. <ol>
  1927. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1928. fetchNext(StatusType* status, void* message) – fetch next record,
  1929. replaces isc_dsql_fetch(). This method (and other fetch methods)
  1930. returns <a href="#Completion codes">completion code</a>
  1931. Status::RESULT_NO_DATA when EOF is reached, Status::RESULT_OK on
  1932. success.</font></p>
  1933. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1934. fetchPrior(StatusType* status, void* message) – fetch previous
  1935. record.</font></p>
  1936. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1937. fetchFirst(StatusType* status, void* message) – fetch first
  1938. record.</font></p>
  1939. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1940. fetchLast(StatusType* status, void* message) – fetch last record.</font></p>
  1941. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1942. fetchAbsolute(StatusType* status, int position, void* message) –
  1943. fetch record by it's absolute position in result set.</font></p>
  1944. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  1945. fetchRelative(StatusType* status, int offset, void* message) –
  1946. fetch record by position relative to current.</font></p>
  1947. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  1948. isEof(StatusType* status) – check for EOF.</font></p>
  1949. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  1950. isBof(StatusType* status) – check for BOF.</font></p>
  1951. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IMessageMetadata*
  1952. getMetadata(StatusType* status) – get metadata for messages in
  1953. result set, specially useful when result set is opened by
  1954. <a href="#Attachment">IAttachment</a>::openCursor() call with NULL
  1955. output metadata format parameter (this is the only way to obtain
  1956. message format in this case).</font></p>
  1957. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1958. close(StatusType* status) – close result set, releases interface
  1959. on success.</font></p>
  1960. </ol>
  1961. <p style="margin-bottom: 0cm"><br/>
  1962. </p>
  1963. <p style="margin-bottom: 0cm"><br/>
  1964. </p>
  1965. <p style="margin-bottom: 0cm"><a name="Service"></a><font size="4" style="font-size: 14pt">Service
  1966. interface – replaces isc_svc_handle.</font></p>
  1967. <ol>
  1968. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1969. detach(StatusType* status) – close attachment to services manager,
  1970. on success releases interface. Replaces isc_service_detach().</font></p>
  1971. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1972. query(StatusType* status, unsigned sendLength, const unsigned char*
  1973. sendItems, unsigned receiveLength, const unsigned char*
  1974. receiveItems, unsigned bufferLength, unsigned char* buffer) – send
  1975. and request information to/from service, with different receiveItems
  1976. may be used for both running services and to obtain various
  1977. server-wide information. Replaces isc_service_query().</font></p>
  1978. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1979. start(StatusType* status, unsigned spbLength, const unsigned char*
  1980. spb) – start utility in services manager. Replaces
  1981. isc_service_start().</font></p>
  1982. </ol>
  1983. <p style="margin-bottom: 0cm"><br/>
  1984. </p>
  1985. <p style="margin-bottom: 0cm"><br/>
  1986. </p>
  1987. <p style="margin-bottom: 0cm"><a name="Statement"></a><font size="4" style="font-size: 14pt">Statement
  1988. interface – replaces (partially) isc_stmt_handle.</font></p>
  1989. <ol>
  1990. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  1991. getInfo(StatusType* status, unsigned itemsLength, const unsigned
  1992. char* items, unsigned bufferLength, unsigned char* buffer) –
  1993. replaces isc_dsql_sql_info().</font></p>
  1994. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  1995. getType(StatusType* status) – statement type, currently can be
  1996. found only in firebird sources in dsql/dsql.h.</font></p>
  1997. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  1998. char* getPlan(StatusType* status, FB_BOOLEAN detailed) – returns
  1999. statement execution plan.</font></p>
  2000. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_UINT64
  2001. getAffectedRecords(StatusType* status) – returns number of records
  2002. affected by statement.</font></p>
  2003. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IMessageMetadata*
  2004. getInputMetadata(StatusType* status) – returns parameters
  2005. metadata.</font></p>
  2006. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IMessageMetadata*
  2007. getOutputMetadata(StatusType* status) – returns output values
  2008. metadata.</font></p>
  2009. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  2010. execute(StatusType* status, ITransaction* transaction,
  2011. IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata*
  2012. outMetadata, void* outBuffer) – executes any SQL statement except
  2013. returning multiple rows of data. Partial analogue of
  2014. isc_dsql_execute2() - in and out XSLQDAs replaced with input and
  2015. output messages with appropriate buffers.</font></p>
  2016. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IResultSet*
  2017. openCursor(StatusType* status, ITransaction* transaction,
  2018. IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata*
  2019. outMetadata, unsigned flags) – executes SQL statement potentially
  2020. returning multiple rows of data. Returns ResultSet interface which
  2021. should be used to fetch that data. Format of output data is defined
  2022. by outMetadata parameter, leaving it NULL default format may be
  2023. used. Parameter flags is needed to open bidirectional cursor setting
  2024. it's value to Istatement::CURSOR_TYPE_SCROLLABLE.</font></p>
  2025. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2026. setCursorName(StatusType* status, const char* name) – replaces
  2027. isc_dsql_set_cursor_name(). </font>
  2028. </p>
  2029. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2030. free(StatusType* status) – free statement, releases interface on
  2031. success.</font></p>
  2032. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2033. getFlags(StatusType* status) – returns <a href="#Values returned by getFlags">flags</a>
  2034. describing how this statement should be executed, simplified
  2035. replacement of getType() method.</font></p>
  2036. </ol>
  2037. <p style="margin-bottom: 0cm"><br/>
  2038. </p>
  2039. <p style="margin-bottom: 0cm"><br/>
  2040. </p>
  2041. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Constants
  2042. defined by Statement interface:</font></p>
  2043. <p style="margin-bottom: 0cm"><br/>
  2044. </p>
  2045. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IAttachment::prepare()
  2046. flags:</font></p>
  2047. <p style="margin-left: 0.96cm; text-indent: -0.02cm; margin-bottom: 0cm; page-break-before: auto; page-break-after: auto">
  2048. <font size="4" style="font-size: 14pt">PREPARE_PREFETCH_NONE –
  2049. constant to pass no flags, 0 value.</font></p>
  2050. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">The
  2051. following flags may be OR-ed to get desired set of flags:</font></p>
  2052. <ol>
  2053. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_TYPE</font></p>
  2054. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_INPUT_PARAMETERS</font></p>
  2055. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_OUTPUT_PARAMETERS</font></p>
  2056. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_LEGACY_PLAN</font></p>
  2057. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_DETAILED_PLAN</font></p>
  2058. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_AFFECTED_RECORDS</font></p>
  2059. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_FLAGS
  2060. (flags returned by getFlags() method)</font></p>
  2061. </ol>
  2062. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Frequently
  2063. used combinations of flags:</font></p>
  2064. <ol>
  2065. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_METADATA</font></p>
  2066. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">PREPARE_PREFETCH_ALL
  2067. </font>
  2068. </p>
  2069. </ol>
  2070. <p style="margin-bottom: 0cm"><br/>
  2071. </p>
  2072. <p style="margin-bottom: 0cm"><a name="Values returned by getFlags"></a>
  2073. <font size="4" style="font-size: 14pt">Values returned by getFlags()
  2074. method: </font>
  2075. </p>
  2076. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FLAG_HAS_CURSOR
  2077. – use openCursor() to execute this statement, not execute()</font></p>
  2078. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FLAG_REPEAT_EXECUTE
  2079. – when prepared statement may be executed many times with different
  2080. parameters</font></p>
  2081. <p style="margin-bottom: 0cm"><br/>
  2082. </p>
  2083. <p style="margin-bottom: 0cm"><a name="Flags passed to openCursor"></a>
  2084. <font size="4" style="font-size: 14pt">Flags passed to openCursor():</font></p>
  2085. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">CURSOR_TYPE_SCROLLABLE
  2086. – open bidirectional cursor.</font></p>
  2087. <p style="margin-bottom: 0cm"><br/>
  2088. </p>
  2089. <p style="margin-bottom: 0cm"><br/>
  2090. </p>
  2091. <p style="margin-bottom: 0cm"><a name="Status"></a><font size="4" style="font-size: 14pt">Status
  2092. interface – replaces ISC_STATUS_ARRAY. Functionality is extended –
  2093. Status has separate access to errors and warnings vectors, can hold
  2094. vectors of unlimited length, itself stores strings used in vectors
  2095. avoiding need in circular strings buffer. In C++ Status is always
  2096. used under status wrapper, C++ API provides two different <a href="#Status Wrapper">wrappers</a>
  2097. having different behavior when error is returned from API call.
  2098. Interface is on purpose minimized (methods like convert it to text
  2099. are moved to <a href="#Util">Util</a> interface) in order to simplify
  2100. it's implementation by users when needed.</font></p>
  2101. <ol>
  2102. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2103. init() - cleanup interface, set it to initial state.</font></p>
  2104. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2105. getState() - get current state of interface, returns <a href="#returned by getState">state
  2106. flags</a>, may be OR-ed.</font></p>
  2107. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2108. setErrors2(unsigned length, const intptr_t* value) – set contents
  2109. of errors vector with length explicitly specified in a call.</font></p>
  2110. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2111. setWarnings2(unsigned length, const intptr_t* value) – set
  2112. contents of warnings vector with length explicitly specified in a
  2113. call.</font></p>
  2114. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2115. setErrors(const intptr_t* value) – set contents of errors vector,
  2116. length is defined by value context.</font></p>
  2117. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2118. setWarnings(const intptr_t* value) – set contents of warnings
  2119. vector, length is defined by value context.</font></p>
  2120. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2121. intptr_t* getErrors() - get errors vector.</font></p>
  2122. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2123. intptr_t* getWarnings() - get warnings vector.</font></p>
  2124. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IStatus*
  2125. clone() - create clone of current interface.</font></p>
  2126. </ol>
  2127. <p style="margin-bottom: 0cm"><br/>
  2128. </p>
  2129. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Constants
  2130. defined by Status interface:</font></p>
  2131. <p style="margin-bottom: 0cm"><br/>
  2132. </p>
  2133. <p style="margin-bottom: 0cm"><a name="returned by getState"></a><font size="4" style="font-size: 14pt">Flags
  2134. set in the value, returned by getState() method:</font></p>
  2135. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">STATE_WARNINGS</font></p>
  2136. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">STATE_ERRORS</font></p>
  2137. <p style="margin-bottom: 0cm"><br/>
  2138. </p>
  2139. <p style="margin-bottom: 0cm"><a name="Completion codes"></a><font size="4" style="font-size: 14pt">Completion
  2140. codes:</font></p>
  2141. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">RESULT_ERROR</font></p>
  2142. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">RESULT_OK</font></p>
  2143. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">RESULT_NO_DATA</font></p>
  2144. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">RESULT_SEGMENT</font></p>
  2145. <p style="margin-bottom: 0cm"><br/>
  2146. </p>
  2147. <p style="margin-bottom: 0cm"><br/>
  2148. </p>
  2149. <p style="margin-bottom: 0cm"><a name="Timer"></a><font size="4" style="font-size: 14pt">Timer
  2150. interface – user timer. Callback interface which should be
  2151. implemented by user to use firebird timer.</font></p>
  2152. <ol>
  2153. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2154. handler() - method is called when timer rings (or when server is
  2155. shutting down).</font></p>
  2156. </ol>
  2157. <p style="margin-bottom: 0cm"><br/>
  2158. </p>
  2159. <p style="margin-bottom: 0cm"><br/>
  2160. </p>
  2161. <p style="margin-bottom: 0cm"><a name="TimerControl"></a><font size="4" style="font-size: 14pt">TimerControl
  2162. interface – very simple and not too precise implementation of
  2163. timer. Arrived here because existing timers are very much OS
  2164. dependent and may be used in programs that require to be portable and
  2165. do not need really high precision timer. Particularly execution of
  2166. given timer may be delayed if another one has not completed at the
  2167. moment when given timer should alarm.</font></p>
  2168. <ol>
  2169. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2170. start(StatusType* status, ITimer* timer, ISC_UINT64 microSeconds) –
  2171. start <a href="#Timer">ITimer</a> to alarm after given delay (in
  2172. microseconds, 10</font><sup><font size="4" style="font-size: 14pt">-6</font></sup>
  2173. <font size="4" style="font-size: 14pt">seconds). Timer will be waked
  2174. up only once after this call.</font></p>
  2175. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2176. stop(StatusType* status, ITimer* timer) – stop <a href="#Timer">ITimer</a>.
  2177. It's not an error to stop not started timer thus avoiding problems
  2178. with races between stop() and timer alarm.</font></p>
  2179. </ol>
  2180. <p style="margin-bottom: 0cm"><br/>
  2181. </p>
  2182. <p style="margin-bottom: 0cm"><a name="Transaction"></a><font size="4" style="font-size: 14pt">Transaction
  2183. interface – replaces isc_tr_handle.</font></p>
  2184. <ol>
  2185. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2186. getInfo(StatusType* status, unsigned itemsLength, const unsigned
  2187. char* items, unsigned bufferLength, unsigned char* buffer) –
  2188. replaces isc_transaction_info().</font></p>
  2189. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2190. prepare(StatusType* status, unsigned msgLength, const unsigned char*
  2191. message) – replaces isc_prepare_transaction2(), with zero
  2192. msgLength behaves like isc_prepare_transaction() automatically
  2193. generating appropriate message.</font></p>
  2194. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2195. commit(StatusType* status) – replaces isc_commit_transaction().</font></p>
  2196. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2197. commitRetaining(StatusType* status) – replaces
  2198. isc_commit_retaining().</font></p>
  2199. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2200. rollback(StatusType* status) – replaces
  2201. isc_rollback_transaction().</font></p>
  2202. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2203. rollbackRetaining(StatusType* status) – replaces
  2204. isc_rollback_retaining().</font></p>
  2205. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2206. disconnect(StatusType* status) – replaces
  2207. fb_disconnect_transaction().</font></p>
  2208. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  2209. join(StatusType* status, ITransaction* transaction) – joins
  2210. current transaction and passed as parameter transaction into single
  2211. distributed transaction (using <a href="#Dtc">Dtc</a>). On success
  2212. both current transaction and passed as parameter transaction are
  2213. released and should not be used any more.</font></p>
  2214. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  2215. validate(StatusType* status, IAttachment* attachment) – this
  2216. method is used to support distributed transactions coordinator.</font></p>
  2217. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ITransaction*
  2218. enterDtc(StatusType* status) – this method is used to support
  2219. distributed transactions coordinator.</font></p>
  2220. </ol>
  2221. <p style="margin-bottom: 0cm"><br/>
  2222. </p>
  2223. <p style="margin-bottom: 0cm"><br/>
  2224. </p>
  2225. <p style="margin-bottom: 0cm"><a name="VersionCallback"></a><font size="4" style="font-size: 14pt">VersionCallback
  2226. interface – callback for <a href="#Util">Util</a>::getFbVersion().</font></p>
  2227. <ol>
  2228. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2229. callback(StatusType* status, const char* text) – called by
  2230. firebird engine for each line in multiline version report. Makes it
  2231. possible to print that lines one by one, place them into message box
  2232. in any GUI, etc.</font></p>
  2233. </ol>
  2234. <p style="margin-bottom: 0cm"><br/>
  2235. </p>
  2236. <p style="margin-bottom: 0cm"><br/>
  2237. </p>
  2238. <p style="margin-bottom: 0cm"><a name="Util"></a><font size="4" style="font-size: 14pt">Util
  2239. interface – various helper methods required here or there.</font></p>
  2240. <ol>
  2241. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2242. getFbVersion(StatusType* status, IAttachment* att, IVersionCallback*
  2243. callback) – produce long and beautiful report about firebird
  2244. version used. It may be seen in ISQL when invoked with -Z switch.</font></p>
  2245. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2246. loadBlob(StatusType* status, ISC_QUAD* blobId, IAttachment* att,
  2247. ITransaction* tra, const char* file, FB_BOOLEAN txt) – load blob
  2248. from file.</font></p>
  2249. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2250. dumpBlob(StatusType* status, ISC_QUAD* blobId, IAttachment* att,
  2251. ITransaction* tra, const char* file, FB_BOOLEAN txt) – save blob
  2252. to file.</font></p>
  2253. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2254. getPerfCounters(StatusType* status, IAttachment* att, const char*
  2255. countersSet, ISC_INT64* counters) – get statistics for given
  2256. attachment.</font></p>
  2257. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IAttachment*
  2258. executeCreateDatabase(StatusType* status, unsigned stmtLength, const
  2259. char* creatDBstatement, unsigned dialect, FB_BOOLEAN*
  2260. stmtIsCreateDb) – execute “CREATE DATABASE ...” statement –
  2261. ISC trick with NULL statement handle does not work with interfaces.</font></p>
  2262. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2263. decodeDate(ISC_DATE date, unsigned* year, unsigned* month, unsigned*
  2264. day) – replaces isc_decode_sql_date().</font></p>
  2265. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2266. decodeTime(ISC_TIME time, unsigned* hours, unsigned* minutes,
  2267. unsigned* seconds, unsigned* fractions) – replaces
  2268. isc_decode_sql_time().</font></p>
  2269. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_DATE
  2270. encodeDate(unsigned year, unsigned month, unsigned day) – replaces
  2271. isc_encode_sql_date().</font></p>
  2272. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_TIME
  2273. encodeTime(unsigned hours, unsigned minutes, unsigned seconds,
  2274. unsigned fractions) – replaces isc_encode_sql_time().</font></p>
  2275. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2276. formatStatus(char* buffer, unsigned bufferSize, IStatus* status) –
  2277. replaces fb_interpret(). Size of buffer, passed into this method,
  2278. should not be less than 50 bytes.</font></p>
  2279. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2280. getClientVersion() – returns integer, containing major version in
  2281. byte 0 and minor version in byte 1.</font></p>
  2282. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IXpbBuilder*
  2283. getXpbBuilder(StatusType* status, unsigned kind, const unsigned
  2284. char* buf, unsigned len) – returns <a href="#XpbBuilder">XpbBuilder</a>
  2285. interface. Valid <a href="#Valid builder types">kinds</a> are
  2286. enumerated in <a href="#XpbBuilder">XpbBuilder</a>.</font></p>
  2287. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2288. setOffsets(StatusType* status, IMessageMetadata* metadata,
  2289. IOffsetsCallback* callback) – sets valid offsets in
  2290. <a href="#MessageMetadata">MessageMetadata</a>. Performs calls to
  2291. callback in <a href="#OffsetsCallback">OffsetsCallback</a> for each
  2292. field/parameter.</font></p>
  2293. </ol>
  2294. <p style="margin-bottom: 0cm"><br/>
  2295. </p>
  2296. <p style="margin-bottom: 0cm"><br/>
  2297. </p>
  2298. <p style="margin-bottom: 0cm"><a name="XpbBuilder"></a><font size="4" style="font-size: 14pt">XpbBuilder
  2299. methods:</font></p>
  2300. <ol>
  2301. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2302. clear(StatusType* status) – reset builder to empty state.</font></p>
  2303. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2304. removeCurrent(StatusType* status) – removes current clumplet.</font></p>
  2305. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2306. insertInt(StatusType* status, unsigned char tag, int value) –
  2307. inserts a clumplet with value representing integer in network
  2308. format.</font></p>
  2309. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2310. insertBigInt(StatusType* status, unsigned char tag, ISC_INT64 value)
  2311. – inserts a clumplet with value representing integer in network
  2312. format.</font></p>
  2313. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2314. insertBytes(StatusType* status, unsigned char tag, const void*
  2315. bytes, unsigned length) - inserts a clumplet with value containing
  2316. passed bytes.</font></p>
  2317. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2318. insertTag(StatusType* status, unsigned char tag) – inserts a
  2319. clumplet without a value.</font></p>
  2320. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  2321. isEof(StatusType* status) – checks that there is no current
  2322. clumplet.</font></p>
  2323. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2324. moveNext(StatusType* status) – moves to next clumplet.</font></p>
  2325. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2326. rewind(StatusType* status) – moves to first clumplet.</font></p>
  2327. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  2328. findFirst(StatusType* status, unsigned char tag) – finds first
  2329. clumplet with given tag.</font></p>
  2330. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  2331. findNext(StatusType* status) – finds next clumplet with given tag.</font></p>
  2332. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2333. char getTag(StatusType* status) – returns tag for current
  2334. clumplet.</font></p>
  2335. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2336. getLength(StatusType* status) – returns length of current clumplet
  2337. value.</font></p>
  2338. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2339. getInt(StatusType* status) – returns value of current clumplet as
  2340. integer.</font></p>
  2341. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_INT64
  2342. getBigInt(StatusType* status) – returns value of current clumplet
  2343. as 64-bit integer.</font></p>
  2344. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2345. char* getString(StatusType* status) – returns value of current
  2346. clumplet as pointer to zero-terminated string (pointer is valid till
  2347. next call to this method).</font></p>
  2348. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2349. unsigned char* getBytes(StatusType* status) – returns value of
  2350. current clumplet as pointer to unsigned char.</font></p>
  2351. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2352. getBufferLength(StatusType* status) – returns length of parameters
  2353. block.</font></p>
  2354. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2355. unsigned char* getBuffer(StatusType* status) – returns pointer to
  2356. parameters block.</font></p>
  2357. </ol>
  2358. <p style="margin-bottom: 0cm"><br/>
  2359. </p>
  2360. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Constants
  2361. defined by XpbBuilder interface:</font></p>
  2362. <p style="margin-bottom: 0cm"><br/>
  2363. </p>
  2364. <p style="margin-bottom: 0cm"><a name="Valid builder types"></a><font size="4" style="font-size: 14pt">Valid
  2365. builder types:</font></p>
  2366. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">DPB</font></p>
  2367. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">SPB_ATTACH</font></p>
  2368. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">SPB_START</font></p>
  2369. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">TPB</font></p>
  2370. <p style="margin-bottom: 0cm"><br/>
  2371. </p>
  2372. <h1><font size="4" style="font-size: 14pt">Plugin, encrypting data
  2373. transferred over the wire.</font></h1>
  2374. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Algorithms
  2375. performing encryption of data for different purposes are well known
  2376. for many years. The only “little” typical problem remaining is
  2377. where to get the top secret key to be used by that algorithm. Luckily
  2378. for network traffic encryption there is one good solution – unique
  2379. encryption key should be generated by authentication plugin. At least
  2380. default SRP plugin can produce such a key. And that key is resistant
  2381. to attacks, including man-in-the-middle. Therefore was chosen a
  2382. method of providing keys for wire crypt plugin: get it from
  2383. authentication plugin. (In case when used authentication plugin can
  2384. not provide a key a pseudo-plugin may be added in AuthClient and
  2385. AuthServer lists to produce keys, something like two asymmetric
  2386. private/public pairs.) </font>
  2387. </p>
  2388. <p style="margin-bottom: 0cm"><br/>
  2389. </p>
  2390. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">CryptKey
  2391. interface is used to store a key provided by authentication plugin
  2392. and pass it to wire crypt plugin. This interface should be used as
  2393. follows – when server or client authentication plugin is ready to
  2394. provide a key it asks <a href="#ServerBlock">ServerBlock</a> or
  2395. <a href="#ClientBlock">ClientBlock</a> to produce new CryptKey
  2396. interface and stores a key in it. Appropriate for <a href="#WireCryptPlugin">WireCryptPlugin</a>
  2397. type of key will be selected by firebird and passed to that
  2398. interface.</font></p>
  2399. <ol>
  2400. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2401. setSymmetric(StatusType* status, const char* type, unsigned
  2402. keyLength, const void* key) – make it store symmetric key of given
  2403. type.</font></p>
  2404. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2405. setAsymmetric(StatusType* status, const char* type, unsigned
  2406. encryptKeyLength, const void* encryptKey, unsigned decryptKeyLength,
  2407. const void* decryptKey) – make it store pair of asymmetric keys of
  2408. given type.</font></p>
  2409. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2410. void* getEncryptKey(unsigned* length) – get a key for encryption.</font></p>
  2411. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2412. void* getDecryptKey(unsigned* length) – get a key for decryption
  2413. (in case of symmetric key produces same result as getEncryptKey()).</font></p>
  2414. </ol>
  2415. <p style="margin-bottom: 0cm"><br/>
  2416. </p>
  2417. <p style="margin-bottom: 0cm"><a name="WireCryptPlugin"></a><font size="4" style="font-size: 14pt">WireCryptPlugin
  2418. interface is main interface of network crypt plugin. Like any other
  2419. such interface it should be implemented by author of the plugin.</font></p>
  2420. <ol>
  2421. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2422. char* getKnownTypes(StatusType* status) – returns
  2423. whitespace/tab/comma separated list of acceptable keys.</font></p>
  2424. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2425. setKey(StatusType* status, ICryptKey* key) – plugin should use a
  2426. key passed to it by this call.</font></p>
  2427. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2428. encrypt(StatusType* status, unsigned length, const void* from, void*
  2429. to) – encrypts a packet to be sent over the wire.</font></p>
  2430. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2431. decrypt(StatusType* status, unsigned length, const void* from, void*
  2432. to) – decrypts a packet received from network.</font></p>
  2433. </ol>
  2434. <p style="margin-bottom: 0cm"><br/>
  2435. </p>
  2436. <h1><font size="4" style="font-size: 14pt">Server side of
  2437. authentication plugin.</font></h1>
  2438. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Authentication
  2439. plugin contains two required parts – client and server and may also
  2440. contain related third part - user manager. During authentication
  2441. process firebird client invokes client plugin and sends generated by
  2442. it data to server, next server invokes server plugin and sends
  2443. generated by it data to client. This process repeats as long as both
  2444. plugins return AUTH_MORE_DATA code. AUTH_SUCCESS returned at server
  2445. side means successful authentication, AUTH_FAILED at any side –
  2446. immediate abort of iterative process and failure reported to client,
  2447. AUTH_CONTINUE means that next plugin from the list of configured
  2448. authentication plugins should be tried.</font></p>
  2449. <p style="margin-bottom: 0cm"><br/>
  2450. </p>
  2451. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">There
  2452. is no dedicated sample of authentication plugins but in firebird
  2453. sources in directory src/auth one can find AuthDbg plugin using which
  2454. one can learn on trivial example (no complex calculations like in Srp
  2455. and no calls to crazy WinAPI functions like in AuthSspi) how client
  2456. and server sides perform authentication handshake. </font>
  2457. </p>
  2458. <p style="margin-bottom: 0cm"><br/>
  2459. </p>
  2460. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Auth
  2461. interface does not contain methods, only some constants defining
  2462. codes return from authenticate() method of <a href="#Client">Client</a>
  2463. and <a href="#Server">Server</a>.</font></p>
  2464. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">AUTH_FAILED</font></p>
  2465. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">AUTH_SUCCESS</font></p>
  2466. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">AUTH_MORE_DATA</font></p>
  2467. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">AUTH_CONTINUE</font></p>
  2468. <p style="margin-bottom: 0cm"><br/>
  2469. </p>
  2470. <p style="margin-bottom: 0cm"><a name="Writer"></a><font size="4" style="font-size: 14pt">Writer
  2471. interface – writes authentication parameters block.</font></p>
  2472. <ol>
  2473. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2474. reset() - clear target block.</font></p>
  2475. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2476. add(StatusType* status, const char* name) – add login name.</font></p>
  2477. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2478. setType(StatusType* status, const char* value) – set type of added
  2479. login (user, group, etc).</font></p>
  2480. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2481. setDb(StatusType* status, const char* value) – set security
  2482. database in which authentication was done.</font></p>
  2483. </ol>
  2484. <p style="margin-bottom: 0cm"><br/>
  2485. </p>
  2486. <p style="margin-bottom: 0cm"><a name="ServerBlock"></a><font size="4" style="font-size: 14pt">ServerBlock
  2487. interface is used by server side of authentication plugin to exchange
  2488. data with client.</font></p>
  2489. <ol>
  2490. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2491. char* getLogin() - get login name passed from client.</font></p>
  2492. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2493. unsigned char* getData(unsigned* length) – get authentication data
  2494. passed from client.</font></p>
  2495. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2496. putData(StatusType* status, unsigned length, const void* data) –
  2497. pass authentication data to client.</font></p>
  2498. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKey*
  2499. newKey(StatusType* status) – create new wire crypt key and add it
  2500. to the list of available for wire crypt plugins.</font></p>
  2501. </ol>
  2502. <p style="margin-bottom: 0cm"><br/>
  2503. </p>
  2504. <p style="margin-bottom: 0cm"><a name="Server"></a><font size="4" style="font-size: 14pt">Server
  2505. interface is main interface of server side of authentication plugin. </font>
  2506. </p>
  2507. <ol>
  2508. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2509. authenticate(StatusType* status, IServerBlock* sBlock, IWriter*
  2510. writerInterface) – perform single authentication step. Data
  2511. exchange with client is performed using sBlock interface. When some
  2512. authentication item is produced it should be added to authentication
  2513. block using writerInterface. Possible return values are defined in
  2514. <a href="#Auth">Auth</a> interface.</font></p>
  2515. </ol>
  2516. <p style="margin-bottom: 0cm"><br/>
  2517. </p>
  2518. <h1><font size="4" style="font-size: 14pt">Client side of
  2519. authentication plugin.</font></h1>
  2520. <p style="margin-bottom: 0cm"><a name="ClientBlock"></a><font size="4" style="font-size: 14pt">ClientBlock
  2521. interface is used by client side of authentication plugin to exchange
  2522. data with server.</font></p>
  2523. <ol>
  2524. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2525. char* getLogin() - get login name if it is present in DPB.</font></p>
  2526. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2527. char* getPassword() - get password if it is present in DPB.</font></p>
  2528. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2529. unsigned char* getData(unsigned* length) – get authentication data
  2530. passed from server.</font></p>
  2531. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2532. putData(StatusType* status, unsigned length, const void* data) –
  2533. pass authentication data to server.</font></p>
  2534. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKey*
  2535. newKey(StatusType* status) - create new wire crypt key and add it to
  2536. the list of available for wire crypt plugins.</font></p>
  2537. </ol>
  2538. <p style="margin-bottom: 0cm"><br/>
  2539. </p>
  2540. <p style="margin-bottom: 0cm"><a name="Client"></a><font size="4" style="font-size: 14pt">Client
  2541. interface is main interface of client side of authentication plugin.</font></p>
  2542. <ol>
  2543. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2544. authenticate(StatusType* status, IClientBlock* cBlock)1. – perform
  2545. single authentication step. Data exchange with server is performed
  2546. using cBlock interface. Possible return values are defined in Auth
  2547. interface. AUTH_SUCCESS is treated by client side as AUTH_MORE_DATA
  2548. (i.e. client sends generated data to server and waits for an answer
  2549. from it).</font></p>
  2550. </ol>
  2551. <p style="margin-bottom: 0cm"><br/>
  2552. </p>
  2553. <h1><font size="4" style="font-size: 14pt">User management plugin.</font></h1>
  2554. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">This
  2555. plugin is actively related with server side of authentication – it
  2556. prepares users' list for authentication plugin. Not each
  2557. authentication plugin requires user manager – some may access list
  2558. of users created using non-firebird software (AuthSspi for example).
  2559. Record describing user consists of a number of fields and operation
  2560. which should be performed like add user, modify user, list user(s),
  2561. etc. Plugin must interpret commands received in <a href="#User">User</a>
  2562. interface.</font></p>
  2563. <p style="margin-bottom: 0cm"><br/>
  2564. </p>
  2565. <p style="margin-bottom: 0cm"><a name="UserField"></a><font size="4" style="font-size: 14pt">UserField
  2566. interface is not used as standalone interface, it's base for
  2567. CharUserField and IntUserField. </font>
  2568. </p>
  2569. <ol>
  2570. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2571. entered() - returns non-zero if a value for a field was entered
  2572. (assigned).</font></p>
  2573. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2574. specified() - return non-zero if NULL value was assigned to the
  2575. field.</font></p>
  2576. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2577. setEntered(StatusType* status, int newValue) – sets entered flag
  2578. to 0/non-zero value for a field. There is no method to assign NULL
  2579. for a field cause it's never needed. NULLs if used are assigned by
  2580. the code implementing interfaces and therefore having full access to
  2581. internals of them.</font></p>
  2582. </ol>
  2583. <p style="margin-bottom: 0cm"><br/>
  2584. </p>
  2585. <p style="margin-bottom: 0cm"><a name="CharUserField"></a><font size="4" style="font-size: 14pt">CharUserField
  2586. interface:</font></p>
  2587. <ol>
  2588. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2589. char* get() - get field's value as C-string (\0 terminated).</font></p>
  2590. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2591. set(StatusType* status, const char* newValue) – assigns value to
  2592. the field. Sets entered flag to true.</font></p>
  2593. </ol>
  2594. <p style="margin-bottom: 0cm"><br/>
  2595. </p>
  2596. <p style="margin-bottom: 0cm"><a name="IntUserField"></a><font size="4" style="font-size: 14pt">IntUserField
  2597. interface:</font></p>
  2598. <ol>
  2599. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2600. get() - get field's value.</font></p>
  2601. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2602. set(StatusType* status, int newValue) – assigns value to the
  2603. field. Sets entered flag to true.</font></p>
  2604. </ol>
  2605. <p style="margin-bottom: 0cm"><br/>
  2606. </p>
  2607. <p style="margin-bottom: 0cm"><a name="User"></a><font size="4" style="font-size: 14pt">User
  2608. interface is a list of methods accessing fields included into record
  2609. about the user. </font>
  2610. </p>
  2611. <ol>
  2612. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2613. operation() - code of operation (see <a href="#Constants defined by User interface">list</a>
  2614. below).</font></p>
  2615. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2616. userName() - login name.</font></p>
  2617. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2618. password() - password. Always empty when listing users.</font></p>
  2619. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2620. firstName() - this and 2 next are components of full user name.</font></p>
  2621. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2622. lastName()</font></p>
  2623. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2624. middleName()</font></p>
  2625. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2626. comment() - comment (from SQL operator COMMENT ON USER IS …).</font></p>
  2627. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICharUserField*
  2628. attributes() - tags in a form tag1=val1, tag2=val2, …, tagN=valN.
  2629. Val may be empty – than means that tag will be deleted.</font></p>
  2630. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IIntUserField*
  2631. active() - changes ACTIVE/INACTIVE setting for user.</font></p>
  2632. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IIntUserField*
  2633. admin() - sets/drops admin rights for the user.</font></p>
  2634. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2635. clear(StatusType* status) – sets all fields to not entered and not
  2636. specified.</font></p>
  2637. </ol>
  2638. <p style="margin-bottom: 0cm"><br/>
  2639. </p>
  2640. <p style="margin-bottom: 0cm"><a name="Constants defined by User interface"></a>
  2641. <font size="4" style="font-size: 14pt">Constants defined by User
  2642. interface – valid codes of operation.</font></p>
  2643. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">OP_USER_ADD
  2644. – create user</font></p>
  2645. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">OP_USER_MODIFY
  2646. – alter user</font></p>
  2647. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">OP_USER_DELETE
  2648. – drop user</font></p>
  2649. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">OP_USER_DISPLAY
  2650. – show user</font></p>
  2651. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">OP_USER_SET_MAP
  2652. – turn on mapping of windows admins to role rdb$admin</font></p>
  2653. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">OP_USER_DROP_MAP
  2654. – turn off mapping of windows admins to role rdb$admin</font></p>
  2655. <p style="margin-bottom: 0cm"><br/>
  2656. </p>
  2657. <p style="margin-bottom: 0cm"><a name="ListUsers"></a><font size="4" style="font-size: 14pt">ListUsers
  2658. interface is callback used by authentication plugin when list users
  2659. operation is requested. Plugin fills <a href="#User">User</a>
  2660. interface for all items in list of users one by one and for each user
  2661. calls list() method of this interface.</font></p>
  2662. <ol>
  2663. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2664. list(StatusType* status, IUser* user) – callback function.
  2665. Implementation can do what it wants with received data. For example,
  2666. it may put data from user parameter into output stream of listing
  2667. service or place into special tables from SEC$ group.</font></p>
  2668. </ol>
  2669. <p style="margin-bottom: 0cm"><br/>
  2670. </p>
  2671. <p style="margin-bottom: 0cm"><a name="LogonInfo"></a><font size="4" style="font-size: 14pt">LogonInfo
  2672. interface contains data passed to user mamngement plugin to attach to
  2673. security database with valid credentials. Pres</font></p>
  2674. <ol>
  2675. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2676. char* name() - returns current attachment's login name.</font></p>
  2677. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2678. char* role() - returns current attachment's active role.</font></p>
  2679. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2680. char* networkProtocol() - returns current attachment's network
  2681. protocol. Currently not used by plugins.</font></p>
  2682. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2683. char* remoteAddress() - returns current attachment's remote address.
  2684. Currently not used by plugins.</font></p>
  2685. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2686. unsigned char* authBlock(unsigned* length) – returns current
  2687. attachment's authentication block. When not NULL overrides login
  2688. name.</font></p>
  2689. </ol>
  2690. <p style="margin-bottom: 0cm"><br/>
  2691. </p>
  2692. <p style="margin-bottom: 0cm"><a name="Management"></a><font size="4" style="font-size: 14pt">Management
  2693. interface is main interface of user management plugin.</font></p>
  2694. <ol>
  2695. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2696. start(StatusType* status, ILogonInfo* logonInfo) – starts plugin,
  2697. if needed it attaches to security database to manage may be (it's
  2698. plugin-dependent solution use it or not) using credentials from
  2699. logonInfo. </font>
  2700. </p>
  2701. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2702. execute(StatusType* status, IUser* user, IListUsers* callback) –
  2703. executes a command provided by operation() method of user parameter.
  2704. If needed callback interface will be used. Parameter callback may
  2705. have NULL value for commands not requiring users' listing.</font></p>
  2706. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2707. commit(StatusType* status) – commits changes done by calls to
  2708. execute() method.</font></p>
  2709. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2710. rollback(StatusType* status) – rollbacks changes done by calls to
  2711. execute() method.</font></p>
  2712. </ol>
  2713. <p style="margin-bottom: 0cm"><br/>
  2714. </p>
  2715. <h1><font size="4" style="font-size: 14pt">Database encryption
  2716. plugin.</font></h1>
  2717. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">An
  2718. ability to encrypt database was present in firebird since interbase
  2719. times but appropriate places in the code were commented.
  2720. Implementation was suspicious – crypt key was always sent from the
  2721. client in DPB, no attempt was made to hide it from the world and no
  2722. way was suggested to encrypt existing database. FB3 solves most of
  2723. the problems except probably the worst one – how to manage crypt
  2724. keys. We suggest a kind of solution but it requires efforts in
  2725. plugins, i.e. there is no beautiful way to work with keys like it is
  2726. for wire crypt plugins.</font></p>
  2727. <p style="margin-bottom: 0cm"><br/>
  2728. </p>
  2729. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Before
  2730. starting with own db crypt plugin one should take into an account the
  2731. following. We see two main usages of database encryption – first,
  2732. it may be needed to avoid data loss if database server is physically
  2733. stolen, and second, it may be used to protect data in database which
  2734. is sailed together with special application accessing that data.
  2735. Requirements for this usages are quite different. In first case we
  2736. may trust database server that it is not modified to steal keys
  2737. passed to security plugin – i.e. we expect that key will not be
  2738. sent to inappropriate server. In second case server may be modified
  2739. in some way to steal keys (if they are passed from application to
  2740. plugin via server code) or even data (as the last resort to dump
  2741. blocks from the cache where they are in non-encrypted form).
  2742. Therefore your plugin should make sure that it's running with not
  2743. modified firebird binaries and your application before sending a key
  2744. to plugin should make sure it's really required plugin, may be asking
  2745. a kind of digital signature from it. Making sure that network line is
  2746. encrypted (parsing output of <a href="#Util">Util</a>::getFbVersion())
  2747. or using some own encryption of a key is also very good idea in case
  2748. when network access to the server is used. All this job should be
  2749. done in plugin (and application working with it) i.e. database block
  2750. encryption algorithm by itself may happen to be easiest part of db
  2751. crypt plugin, specially when some standard library is used for it.</font></p>
  2752. <p style="margin-bottom: 0cm"><br/>
  2753. </p>
  2754. <p style="margin-bottom: 0cm"><a name="CryptKeyCallback"></a><font size="4" style="font-size: 14pt">CryptKeyCallback
  2755. interface should be provided by a side sending crypt key to db crypt
  2756. plugin or key holder plugin.</font></p>
  2757. <ol>
  2758. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2759. callback(unsigned dataLength, const void* data, unsigned
  2760. bufferLength, void* buffer) – when performing callback information
  2761. is passed in both directions. The source of a key receives
  2762. dataLength bytes of data and may send up to bufferLength bytes into
  2763. buffer returning actual number of bytes placed into buffer.</font></p>
  2764. </ol>
  2765. <p style="margin-bottom: 0cm"><br/>
  2766. </p>
  2767. <p style="margin-bottom: 0cm"><a name="DbCryptInfo"></a><font size="4" style="font-size: 14pt">DbCryptInfo
  2768. interface is passed to DbCryptPlugin by engine. Plugin may save this
  2769. interface and use when needed to obtain additional informatio about
  2770. database.</font></p>
  2771. <ol>
  2772. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">const
  2773. char* getDatabaseFullPath(StatusType* status) – returns full
  2774. (including path) name of primary database file.</font></p>
  2775. </ol>
  2776. <p style="margin-bottom: 0cm"><br/>
  2777. </p>
  2778. <p style="margin-bottom: 0cm"><a name="DbCryptPlugin"></a><font size="4" style="font-size: 14pt">DbCryptPlugin
  2779. interface is main interface of database crypt plugin.</font></p>
  2780. <ol>
  2781. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2782. setKey(StatusType* status, unsigned length, IKeyHolderPlugin**
  2783. sources, const char* keyName) – is used to provide to db crypt
  2784. plugin information about encryption key. Firebird never passes keys
  2785. for this type of plugin directly. Instead array of <a href="#KeyHolderPlugin">KeyHolderPlugins</a>
  2786. of given length is passed to crypt plugin which must get from one of
  2787. it <a href="#CryptKeyCallback">CryptKeyCallback</a> interface and
  2788. get a key using it. Parameter keyName is a name of a key like it was
  2789. entered in “ALTER DATABASE ENCRYPT …” operator.</font></p>
  2790. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2791. encrypt(StatusType* status, unsigned length, const void* from, void*
  2792. to) – encrypts data before writing block to database file.</font></p>
  2793. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2794. decrypt(StatusType* status, unsigned length, const void* from, void*
  2795. to) – decrypts data after reading block from database file.</font></p>
  2796. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2797. setInfo(StatusType* status, IDbCryptInfo* info) – in this method
  2798. crypt plugin typically saves informational interface for future use.</font></p>
  2799. </ol>
  2800. <p style="margin-bottom: 0cm"><br/>
  2801. </p>
  2802. <h1><font size="4" style="font-size: 14pt">Key holder for database
  2803. encryption plugin.</font></h1>
  2804. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">This
  2805. type of plugin is needed to delineate functionality – db crypt
  2806. plugin is dealing with actual encryption, key holder solves questions
  2807. related with providing it a key in secure way. Plugin may be received
  2808. from application or loaded in some other way (up to using flash
  2809. device inserted into server at firebird startup time).</font></p>
  2810. <p style="margin-bottom: 0cm"><br/>
  2811. </p>
  2812. <p style="margin-bottom: 0cm"><a name="KeyHolderPlugin"></a><font size="4" style="font-size: 14pt">KeyHolderPlugin
  2813. interface is main interface of database crypt key holder plugin.</font></p>
  2814. <ol>
  2815. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">int
  2816. keyCallback(StatusType* status, ICryptKeyCallback* callback) – is
  2817. used to pass attachment's <a href="#CryptKeyCallback">CryptKeyCallback</a>
  2818. interface (if provided by user with <a href="#Provider">Provider</a>::setDbCryptCallback()
  2819. call). This call is always performed at database attach moment, and
  2820. some holders may reject attachment if satisfactory key was not
  2821. provided.</font></p>
  2822. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
  2823. keyHandle(StatusType* status, const char* keyName) – is intended
  2824. to be called by <a href="#DbCryptPlugin">DbCryptPlugin</a> directly
  2825. to obtain callback interface for named key from key holder. This
  2826. makes it possible for open source firebird code to never touch
  2827. actual keys avoiding ability to steal a key changing firebird code.
  2828. After getting <a href="#CryptKeyCallback">CryptKeyCallback</a>
  2829. interface crypt plugin starts data exchange using it. Key holder can
  2830. (for example) check digital signature of crypt plugin before sending
  2831. a key to it in order to avoid use of modified crypt plugin able to
  2832. steal secret key.</font></p>
  2833. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
  2834. useOnlyOwnKeys(StatusType* status) – informs firebird engine
  2835. whether a key, provided by key holder, can be used in other
  2836. attachments. Makes sense only for SuperServer – only it can share
  2837. database crypt keys between attachments. Returning FB_TRUE from this
  2838. method enforces firebird to make sure that this particular key
  2839. holder (and therefore in turn attachment related to it) provides
  2840. correct crypt key for any other attachment to this database.</font></p>
  2841. <li><p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
  2842. chainHandle(StatusType* status) – support of a chain of key
  2843. holders. In some cases key has to pass through more than single key
  2844. holder before it reaches db crypt plugin. This is needed (for
  2845. example) to support execute statement in encrypted database. This is
  2846. just a sample – chains are also used in some other cases. Callback
  2847. interface, returned by this method, may differ from one returned by
  2848. keyHandle() function (see above). Typically is should be able to
  2849. duplicate one-to-one keys, received by KeyHolderPlugin when
  2850. keyCallback() function is invoked.</font></p>
  2851. </ol>
  2852. <p style="margin-bottom: 0cm"><br/>
  2853. </p>
  2854. <h1><font size="4" style="font-size: 14pt">Non-interface objects used
  2855. by API (C++ specific header Message.h).</font></h1>
  2856. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Following
  2857. 3 classes are used to represent date, time and timestamp (datetime)
  2858. when using FB_MESSAGE macro. Members of data structure, representing
  2859. static message, correspondint to fields of types FB_DATE / FB_TIME /
  2860. FB_TIMESTAMP will have a type of one of this classes. Knowing methods
  2861. / members (which are enough self-descriptive to avoid describing them
  2862. here) of this classes is needed to access date and time fields in
  2863. static messages.</font></p>
  2864. <p style="margin-bottom: 0cm"><br/>
  2865. </p>
  2866. <p style="margin-bottom: 0cm"><a name="FbDate"></a><font size="4" style="font-size: 14pt">class
  2867. FbDate methods:</font></p>
  2868. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2869. decode(IUtil* util, unsigned* year, unsigned* month, unsigned* day)</font></p>
  2870. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2871. getYear(IUtil* util) </font>
  2872. </p>
  2873. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2874. getMonth(IUtil* util)</font></p>
  2875. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2876. getDay(IUtil* util)</font></p>
  2877. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2878. encode(IUtil* util, unsigned year, unsigned month, unsigned day)</font></p>
  2879. <p style="margin-bottom: 0cm"><br/>
  2880. </p>
  2881. <p style="margin-bottom: 0cm"><a name="FbTime"></a><font size="4" style="font-size: 14pt">class
  2882. FbTime methods:</font></p>
  2883. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2884. decode(IUtil* util, unsigned* hours, unsigned* minutes, unsigned*
  2885. seconds, unsigned* fractions)</font></p>
  2886. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2887. getHours(IUtil* util)</font></p>
  2888. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2889. getMinutes(IUtil* util)</font></p>
  2890. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2891. getSeconds(IUtil* util)</font></p>
  2892. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
  2893. getFractions(IUtil* util)</font></p>
  2894. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2895. encode(IUtil* util, unsigned hours, unsigned minutes, unsigned
  2896. seconds, unsigned fractions)</font></p>
  2897. <p style="margin-bottom: 0cm"><br/>
  2898. </p>
  2899. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">class
  2900. FbTimestamp members:</font></p>
  2901. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FbDate
  2902. date;</font></p>
  2903. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FbTime
  2904. time;</font></p>
  2905. <p style="margin-bottom: 0cm"><br/>
  2906. </p>
  2907. <p style="margin-bottom: 0cm"><br/>
  2908. </p>
  2909. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">Following
  2910. two templates are used in static messages to represent CHAR(N) and
  2911. VARCHAR(N) fields. </font>
  2912. </p>
  2913. <p style="margin-bottom: 0cm"><br/>
  2914. </p>
  2915. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">template
  2916. &lt;unsigned N&gt;</font></p>
  2917. <p style="margin-bottom: 0cm"><a name="FbChar"></a><font size="4" style="font-size: 14pt">struct
  2918. FbChar</font></p>
  2919. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">{</font></p>
  2920. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">char
  2921. str[N];</font></p>
  2922. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">};</font></p>
  2923. <p style="margin-bottom: 0cm"><br/>
  2924. </p>
  2925. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">template
  2926. &lt;unsigned N&gt;</font></p>
  2927. <p style="margin-bottom: 0cm"><a name="FbVarChar"></a><font size="4" style="font-size: 14pt">struct
  2928. FbVarChar</font></p>
  2929. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">{</font></p>
  2930. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ISC_USHORT
  2931. length;</font></p>
  2932. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">char
  2933. str[N];</font></p>
  2934. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
  2935. set(const char* s);</font></p>
  2936. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">};</font></p>
  2937. <p style="margin-bottom: 0cm"><br/>
  2938. </p>
  2939. <p style="margin-bottom: 0cm"><br/>
  2940. </p>
  2941. <hr/>
  2942. <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">This
  2943. document is currently missing 2 types of plugins – ExternalEngine
  2944. and Trace. Information about them will be made available in next
  2945. release of it.</font></p>
  2946. <p style="margin-bottom: 0cm"><br/>
  2947. </p>
  2948. </body>
  2949. </html>