2
0

Using_OO_API.html 211 KB

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