Using_OO_API.html 212 KB

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