Mention VS 2013
[yazpp-moved-to-github.git] / doc / book.xml
1 <?xml version="1.0" standalone="no"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3     "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
4 [
5      <!ENTITY % local SYSTEM "local.ent">
6      %local;
7      <!ENTITY % entities SYSTEM "entities.ent">
8      %entities;
9      <!ENTITY % idcommon SYSTEM "common/common.ent">
10      %idcommon;
11 ]>
12 <book id="yazpp">
13  <bookinfo>
14   <title>YAZ++ User's Guide and Reference</title>
15   <authorgroup>
16    <author><firstname>Mike</firstname><surname>Taylor</surname></author>
17    <author><firstname>Adam</firstname><surname>Dickmeiss</surname></author>
18    </authorgroup>
19   <copyright>
20    <year>&copyright-year;</year>
21    <holder>Index Data Aps</holder>
22   </copyright>
23   <abstract>
24    <simpara>
25     <ulink url="&url.yazplusplus;">YAZ++</ulink>
26     is a set of libraries and header files that make it easier
27     to use the popular C-language
28     <ulink url="&url.yaz;">YAZ toolkit</ulink>
29     from C++, together with some utilities written using these
30     libraries.  It includes an implementation of the C++ binding for
31     ZOOM (<link linkend="zoom">ZOOM-C++</link>).
32    </simpara>
33    <simpara>
34     This manual covers version &version;.
35     </simpara>
36    <simpara>
37    </simpara>
38    <simpara>
39     <inlinemediaobject>
40      <imageobject>
41       <imagedata fileref="common/id.png" format="PNG"/>
42      </imageobject>
43     </inlinemediaobject>
44    </simpara>
45   </abstract>
46  </bookinfo>
47  <chapter id="introduction">
48   <title>Introduction</title>
49   <para>
50    <ulink url="&url.yazplusplus;">YAZ++</ulink>
51    is a C++ layer for YAZ and implements the ANSI
52    <ulink url="&url.z39.50;">Z39.50</ulink> protocol for information
53    retrieval (client and server side).
54   </para>
55   <para>
56    The YAZ++ packages also features a ZOOM interface for C++ (
57    <ulink url="&url.zoom.bind.cplusplus;">ZOOM C++</ulink>).
58   </para>
59   <para>
60    Later versions (0.7+) of YAZ++ also supports SRU.
61   </para>
62   <section id="licensing">
63    <title>Licensing</title>
64    <para>
65     YAZ++ and ZOOM-C++ is is covered
66     by Revised <link linkend="license">BSD License</link>.
67    </para>
68   </section>
69  </chapter>
70 <chapter id="installation">
71   <title>Installation</title>
72   <para>
73    You need a C++ compiler to compile and use YAZ++.
74    The software was implemented using <ulink url="&url.gcc;">GCC</ulink>
75    so we know that works well with YAZ++. From time to time the
76    software is compiled on Windows using Visual C++.
77    Other compilers should work too. Let us know of portability
78    problems, etc. with your system.
79   </para>
80   <para>
81    YAZ++ is built on top of the
82    <ulink url="&url.yaz;">YAZ</ulink>
83    toolkit.
84    You need to install that first.
85    For some platforms there are binary packages for YAZ.
86   </para>
87   <section id="unix">
88    <title>Installation on Unix (from source)</title>
89    <para>On UNIX, the software is compiled as follows:
90     <screen>
91      $ ./configure
92      $ make
93      $ su
94      # make install
95     </screen>
96    </para>
97    <para>
98     You can supply options for the <literal>configure</literal> script.
99     The most useful ones are:
100     <variablelist>
101      <varlistentry>
102       <term><literal>--prefix </literal>directory</term>
103       <listitem><para>
104         Specifies installation prefix. By default
105         <filename>/usr/local</filename> is used.
106        </para></listitem>
107      </varlistentry>
108      <varlistentry>
109       <term><literal>--with-yaz </literal>directory</term>
110       <listitem><para>
111         Specifies the location of <filename>yaz-config</filename>.
112         The <filename>yaz-config</filename> program is generated in
113         the source directory of YAZ as well as the binaries
114         directory when YAZ is installed (via make install).
115         </para>
116        <para>
117         If you don't supply this option, <literal>configure</literal> will
118         look for <filename>yaz-config</filename> in directories of the
119         <envar>PATH</envar> environment - which is nearly always
120         what you want.
121        </para></listitem>
122      </varlistentry>
123     </variablelist>
124     For the whole list of <literal>configure</literal> options, refer
125     to the help:
126     <literal>./configure --help</literal>.
127    </para>
128    <para>
129     Configure uses GNU's C/C++ compiler if available. To specify another
130     compiler, set <literal>CXX</literal>. To use other compiler flags,
131     specify <literal>CXXFLAGS</literal>. To use <literal>CC</literal>
132     with debugging you could use:
133     <screen>
134      CXXFLAGS="-g" CXX=CC ./configure
135     </screen>
136    </para>
137    <para>
138     This is what you have after successful compilation:
139     <variablelist>
140      <varlistentry>
141       <term><filename>src/libyazpp.la</filename></term>
142       <listitem><para>
143        The YAZ++ library.
144        This library gets installed in your libraries directory
145        (<parameter>prefix</parameter><filename>/lib</filename>).
146       </para></listitem>
147      </varlistentry>
148      <varlistentry>
149       <term><filename>src/libzoompp.la</filename></term>
150       <listitem><para>
151        The <link linkend="zoom">ZOOM-C++</link> library.
152        This library gets installed in your libraries directory
153        (<parameter>prefix</parameter><filename>/lib</filename>).
154       </para></listitem>
155      </varlistentry>
156      <varlistentry>
157       <term><filename>include/yazpp/*.h</filename></term>
158       <listitem><para>
159        Various C++ header files, which you'll need for YAZ++
160        development. All these are installed in your header files area
161        (<parameter>prefix</parameter><filename>/include/yazpp</filename>).
162       </para></listitem>
163      </varlistentry>
164      <varlistentry>
165       <term><filename>yazpp-config</filename></term>
166       <listitem><para>
167        A Bourne shell-script utility that returns the values of the
168        <envar>CFLAGS</envar> and <envar>LIBS</envar>
169        environment variables
170        needed in order to compile your applications with the YAZ++
171        library.  This script gets installed in your binaries directory
172        (<parameter>prefix</parameter><filename>/bin</filename>).
173       </para></listitem>
174      </varlistentry>
175      <varlistentry>
176       <term><filename>zoom/zclient</filename></term>
177       <listitem><para>
178        ZOOM C++ demonstration client that uses the ZOOM C++ classes.
179        This client does not get installed in the system directories.
180       </para></listitem>
181      </varlistentry>
182      <varlistentry>
183       <term><filename>src/yaz-my-client</filename></term>
184       <listitem><para>
185        YAZ C++ demonstration client. This client does not
186        get installed in the system directories.
187       </para></listitem>
188      </varlistentry>
189      <varlistentry>
190       <term><filename>src/yaz-my-server</filename></term>
191       <listitem><para>
192         YAZ C++ demonstration server. This server does not
193         get installed in the system directories.
194        </para></listitem>
195      </varlistentry>
196     </variablelist>
197    </para>
198   </section>
199   <section id="windows">
200    <title>Installation on Windows</title>
201    <para>
202     YAZ++ is shipped with "makefiles" for the NMAKE tool that comes
203     with <ulink url="&url.vstudio;">Microsoft Visual Studio</ulink>.
204     Version 2003 (7), 2005 (8) and 2013 (12) has been tested.
205    </para>
206    <para>
207     Start a command prompt and switch the sub directory
208     <filename>WIN</filename> where the file <filename>makefile</filename>
209     is located. Customize the installation by editing the
210     <filename>makefile</filename> file (for example by using notepad).
211    </para>
212    <para>
213     The following summarizes the most important settings in that file:
214     <variablelist>
215      <varlistentry><term><literal>DEBUG</literal></term>
216       <listitem><para>
217         If set to 1, the software is
218         compiled with debugging libraries (code generation is
219         multi-threaded debug DLL).
220         If set to 0, the software is compiled with release libraries
221         (code generation is multi-threaded DLL).
222        </para></listitem>
223      </varlistentry>
224      <varlistentry><term><filename>YAZ_DIR</filename></term>
225       <listitem><para>
226         Specifies the directory of the YAZ source.
227        </para></listitem>
228      </varlistentry>
229     </variablelist>
230    </para>
231    <para>
232     When satisfied with the settings in the makefile, type
233     <screen>
234      nmake
235     </screen>
236    </para>
237    <tip>
238     <para>
239      If the <filename>nmake</filename> command is not found on your system
240      you probably haven't defined the environment variables required to
241      use that tool. To fix that, find and run the batch file
242      <filename>vcvars32.bat</filename>. You need to run it from within
243      the command prompt or set the environment variables "globally";
244      otherwise it doesn't work.
245     </para>
246    </tip>
247    <para>
248     If you wish to recompile YAZ++ - for example if you modify
249     settings in the <filename>makefile</filename> you can delete
250     object files, etc by running.
251     <screen>
252      nmake clean
253     </screen>
254    </para>
255    <para>
256     The following files are generated upon successful compilation:
257     <variablelist>
258      <varlistentry>
259       <term><filename>bin/yazpp5.dll</filename></term>
260       <listitem><para>
261        YAZ++ DLL . Includes ZOOM C++ as well.
262        For the debug version <filename>lib/yazpp5d.dll</filename>
263        is created instead.
264      </para></listitem></varlistentry>
265      <varlistentry>
266       <term><filename>lib/yazpp5.lib</filename></term>
267       <listitem><para>
268        Import library for <filename>yazpp5.dll</filename>.
269        For the debug version <filename>lib/yazpp5d.lib</filename>
270        is created instead.
271      </para></listitem></varlistentry>
272      <varlistentry>
273       <term><filename>bin/yaz-my-client.exe</filename></term>
274       <listitem><para>
275        Z39.50 client demonstrating the YAZ++ API.
276      </para></listitem></varlistentry>
277      <varlistentry>
278       <term><filename>bin/yaz-my-server.exe</filename></term>
279       <listitem><para>
280        Z39.50 server demonstrating the YAZ++ API.
281      </para></listitem></varlistentry>
282      <varlistentry>
283       <term><filename>bin/zclient.exe</filename></term>
284       <listitem><para>
285        ZOOM C++ demo client. A simple WIN32 console application.
286      </para></listitem></varlistentry>
287     </variablelist>
288    </para>
289   </section>
290  </chapter>
291  <chapter id="zoom">
292   <title>ZOOM-C++</title>
293   <sect1 id="zoom-introduction">
294    <title>Introduction</title>
295    <para>
296     <ulink url="&url.zoom;">ZOOM</ulink>
297     is the emerging standard API for information retrieval programming
298     using the Z39.50 protocol.  ZOOM's
299     <ulink url="&url.zoom.api;">Abstract API</ulink>
300     specifies semantics for classes representing key IR concepts such as
301     connections, queries, result sets and records; and there are various
302     <ulink url="&url.zoom.bind;">bindings</ulink>
303     specifying how those concepts should be represented in various
304     programming languages.
305    </para>
306    <para>
307     The YAZ++ library includes an implementation of the <ulink
308     url="&url.zoom.bind.cplusplus;">C++ binding</ulink>
309     for ZOOM, enabling quick, easy development of client applications.
310    </para>
311    <para>
312     For example, here is a tiny Z39.50 client that fetches and displays
313     the MARC record for Farlow &amp; Brett Surman's
314     <citetitle>The Complete Dinosaur</citetitle>
315     from the Library of Congress's Z39.50 server:
316    </para>
317    <programlisting>
318     #include &lt;iostream&gt;
319     #include &lt;yazpp/zoom.h&gt;
320
321     using namespace ZOOM;
322
323     int main(int argc, char **argv)
324     {
325         connection conn("z3950.loc.gov", 7090);
326         conn.option("databaseName", "Voyager");
327         conn.option("preferredRecordSyntax", "USMARC");
328         resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
329         const record *rec = rs.getRecord(0);
330         cout &lt;&lt; rec-&gt;render() &lt;&lt; endl;
331     }
332    </programlisting>
333    <note>
334     <para>
335      For the sake of simplicity, this program does not check
336      for errors: we show a more robust version of the same program
337      <link linkend="revised-sample">later</link>.)
338     </para>
339    </note>
340    <para>
341     YAZ++'s implementation of the C++ binding is a thin layer over YAZ's
342     implementation of the C binding.  For information on the supported
343     options and other such details, see the ZOOM-C documentation, which
344     can be found on-line at
345     <ulink url="&url.yaz.zoom;"/>
346    </para>
347    <para>
348     All of the classes defined by ZOOM-C++ are in the
349     <literal>ZOOM</literal> namespace.  We will now consider
350     the five main classes in turn:
351     <itemizedlist>
352      <listitem>
353       <para>
354        <literal>connection</literal>
355       </para>
356      </listitem>
357      <listitem>
358       <para>
359        <literal>query</literal> and its subclasses
360        <literal>prefixQuery</literal> and
361        <literal>CCLQuery</literal>
362       </para>
363      </listitem>
364      <listitem>
365       <para>
366        <literal>resultSet</literal>
367       </para>
368      </listitem>
369      <listitem>
370       <para>
371        <literal>record</literal>
372       </para>
373      </listitem>
374      <listitem>
375       <para>
376        <literal>exception</literal> and its subclasses
377        <literal>systemException</literal>,
378        <literal>bib1Exception</literal> and
379        <literal>queryException</literal>
380       </para>
381      </listitem>
382     </itemizedlist>
383    </para>
384   </sect1>
385   <sect1 id="zoom-connection">
386    <title><literal>ZOOM::connection</literal></title>
387    <para>
388     A <literal>ZOOM::connection</literal> object represents an open
389     connection to a Z39.50 server.  Such a connection is forged by
390     constructing a <literal>connection</literal> object.
391    </para>
392    <para>
393     The class has this declaration:
394    </para>
395    <synopsis>
396     class connection {
397     public:
398       connection (const char *hostname, int portnum);
399       ~connection ();
400       const char *option (const char *key) const;
401       const char *option (const char *key, const char *val);
402     };
403    </synopsis>
404    <para>
405     When a new <literal>connection</literal> is created, the hostname
406     and port number of a Z39.50 server must be supplied, and the
407     network connection is forged and wrapped in the new object.  If the
408     connection can't be established - perhaps because the hostname
409     couldn't be resolved, or there is no server listening on the
410     specified port - then an
411     <link linkend="zoom-exception"><literal>exception</literal></link>
412     is thrown.
413    </para>
414    <para>
415     The only other methods on a <literal>connection</literal> object
416     are for getting and setting options.  Any name-value pair of
417     strings may be set as options, and subsequently retrieved, but
418     certain options have special meanings which are understood by the
419     ZOOM code and affect the behaviour of the object that carries
420     them.  For example, the value of the
421     <literal>databaseName</literal> option is used as the name of the
422     database to query when a search is executed against the
423     <literal>connection</literal>.  For a full list of such special
424     options, see the ZOOM abstract API and the ZOOM-C documentation
425     (links below).
426    </para>
427    <sect2 id="connection.references">
428     <title>References</title>
429     <itemizedlist>
430      <listitem>
431       <para>
432        <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.2">
433        Section 3.2 (Connection) of the ZOOM Abstract API</ulink>
434       </para>
435      </listitem>
436      <listitem>
437       <para>
438        <ulink url="&url.yaz.zoom.connections;">
439        The Connections section f the ZOOM-C documentation</ulink>
440       </para>
441      </listitem>
442     </itemizedlist>
443    </sect2>
444   </sect1>
445   <sect1 id="zoom-query">
446    <title><literal>ZOOM::query</literal> and subclasses</title>
447    <para>
448     The <literal>ZOOM::query</literal> class is a virtual base class,
449     representing a query to be submitted to a server.  This class has
450     no methods, but two (so far) concrete subclasses, each implementing
451     a specific query notation.
452    </para>
453    <sect2 id="zoom-prefixQuery">
454     <title><literal>ZOOM::prefixQuery</literal></title>
455     <synopsis>
456     class prefixQuery : public query {
457     public:
458       prefixQuery (const char *pqn);
459       ~prefixQuery ();
460     };
461     </synopsis>
462     <para>
463      This class enables a query to be created by compiling YAZ's
464      cryptic but powerful
465      <ulink url="&url.yaz.pqf;">Prefix Query Notation (PQN)</ulink>.
466     </para>
467    </sect2>
468    <sect2 id="zoom-CCLQuery">
469     <title><literal>ZOOM::CCLQuery</literal></title>
470     <synopsis>
471     class CCLQuery : public query {
472     public:
473       CCLQuery (const char *ccl, void *qualset);
474       ~CCLQuery ();
475     };
476     </synopsis>
477     <para>
478      This class enables a query to be created using the simpler but
479      less expressive
480      <ulink url="&url.yaz.ccl;">Common Command Language (CCL)</ulink>.
481      The qualifiers recognised by the CCL parser are specified in an
482      external configuration file in the format described by the YAZ
483      documentation.
484     </para>
485     <para>
486      If query construction fails for either type of
487      <literal>query</literal> object - typically because the query
488      string itself is not valid PQN or CCL - then an
489      <link linkend="zoom-exception"><literal>exception</literal></link>
490      is thrown.
491     </para>
492    </sect2>
493    <sect2 id="queries.discussion">
494     <title>Discussion</title>
495     <para>
496      It will be readily recognised that these objects have no methods
497      other than their constructors: their only role in life is to be
498      used in searching, by being passed to the
499      <literal>resultSet</literal> class's constructor.
500     </para>
501     <para>
502      Given a suitable set of CCL qualifiers, the following pairs of
503      queries are equivalent:
504     </para>
505     <screen>
506      prefixQuery("dinosaur");
507      CCLQuery("dinosaur");
508
509      prefixQuery("@and complete dinosaur");
510      CCLQuery("complete and dinosaur");
511
512      prefixQuery("@and complete @or dinosaur pterosaur");
513      CCLQuery("complete and (dinosaur or pterosaur)");
514
515      prefixQuery("@attr 1=7 0253333490");
516      CCLQuery("isbn=0253333490");
517     </screen>
518    </sect2>
519    <sect2 id="query.references">
520     <title>References</title>
521     <itemizedlist>
522      <listitem>
523       <para>
524        <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.3">
525         Section 3.3 (Query) of the ZOOM Abstract API
526        </ulink>
527       </para>
528     </listitem>
529     <listitem>
530      <para>
531       <ulink url="&url.yaz.zoom.query;">
532        The Queries section of the ZOOM-C documentation
533       </ulink>
534      </para>
535     </listitem>
536     </itemizedlist>
537    </sect2>
538   </sect1>
539   <sect1 id="zoom-resultset">
540    <title><literal>ZOOM::resultSet</literal></title>
541    <para>
542     A <literal>ZOOM::resultSet</literal> object represents a set of
543     records identified by a query that has been executed against a
544     particular connection.  The sole purpose of both
545     <literal>connection</literal> and <literal>query</literal> objects
546     is that they can be used to create new
547     <literal>resultSet</literal>s - that is, to perform a search on the
548     server on the remote end of the connection.
549    </para>
550    <para>
551     The class has this declaration:
552    </para>
553    <synopsis>
554     class resultSet {
555     public:
556       resultSet (connection &amp;c, const query &amp;q);
557       ~resultSet ();
558       const char *option (const char *key) const;
559       const char *option (const char *key, const char *val);
560       size_t size () const;
561       const record *getRecord (size_t i) const;
562     };
563    </synopsis>
564    <para>
565     New <literal>resultSet</literal>s are created by the constructor,
566     which is passed a <literal>connection</literal>, indicating the
567     server on which the search is to be performed, and a
568     <literal>query</literal>, indicating what search to perform.  If
569     the search fails - for example, because the query uses attributes
570     that the server doesn't implement - then an
571     <link linkend="zoom-exception"><literal>exception</literal></link>
572     is thrown.
573    </para>
574    <para>
575     Like <literal>connection</literal>s, <literal>resultSet</literal>
576     objects can carry name-value options.  The special options which
577     affect ZOOM-C++'s behaviour are the same as those for ZOOM-C and
578     are described in its documentation (link below).  In particular,
579     the <literal>preferredRecordSyntax</literal> option may be set to
580     a string such as ``USMARC'', ``SUTRS'' etc. to indicate what the
581     format in which records should be retrieved; and the
582     <literal>elementSetName</literal> option indicates whether brief
583     records (``B''), full records (``F'') or some other composition
584     should be used.
585    </para>
586    <para>
587     The <literal>size()</literal> method returns the number of records
588     in the result set.  Zero is a legitimate value: a search that finds
589     no records is not the same as a search that fails.
590    </para>
591    <para>
592     Finally, the <literal>getRecord</literal> method returns the
593     <parameter>i</parameter>th record from the result set, where
594     <parameter>i</parameter> is zero-based: that is, legitmate values
595     range from zero up to one less than the result-set size.  If the
596     method fails, for example because the requested record is out of
597     range, it <literal>throw</literal>s an
598     <link linkend="zoom-exception"><literal>exception</literal></link>.
599    </para>
600    <sect2 id="resultset.references">
601     <title>References</title>
602     <itemizedlist>
603      <listitem>
604       <para>
605        <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.4"
606               >Section 3.4 (Result Set) of the ZOOM Abstract API</ulink>
607       </para>
608      </listitem>
609      <listitem>
610       <para>
611        <ulink url="&url.yaz.zoom.resultsets;"
612               >The Result Sets section of the ZOOM-C documentation</ulink>
613       </para>
614      </listitem>
615     </itemizedlist>
616    </sect2>
617   </sect1>
618   <sect1 id="zoom-record">
619    <title><literal>ZOOM::record</literal></title>
620    <para>
621     A <literal>ZOOM::record</literal> object represents a chunk of data
622     from a <literal>resultSet</literal> returned from a server.
623    </para>
624    <para>
625     The class has this declaration:
626    </para>
627    <synopsis>
628     class record {
629     public:
630       ~record ();
631       enum syntax {
632         UNKNOWN, GRS1, SUTRS, USMARC, UKMARC, XML
633       };
634       record *clone () const;
635       syntax recsyn () const;
636       const char *render () const;
637       const char *rawdata () const;
638     };
639    </synopsis>
640    <para>
641     Records returned from Z39.50 servers are encoded using a record
642     syntax: the various national MARC formats are commonly used for
643     bibliographic data, GRS-1 or XML for complex structured data, SUTRS
644     for simple human-readable text, etc.  The
645     <literal>record::syntax</literal> enumeration specifies constants
646     representing common record syntaxes, and the
647     <literal>recsyn()</literal> method returns the value corresponding
648     to the record-syntax of the record on which it is invoked.
649     <note>
650      <para>
651       Because this interface uses an enumeration, it is difficult to
652       extend to other record syntaxes - for example, DANMARC, the MARC
653       variant widely used in Denmark.  We might either grow the
654       enumeration substantially, or change the interface to return
655       either an integer or a string.
656      </para>
657     </note>
658    </para>
659    <para>
660     The simplest thing to do with a retrieved record is simply to
661     <literal>render()</literal> it.  This returns a human-readable, but
662     not necessarily very pretty, representation of the contents of the
663     record.  This is useful primarily for testing and debugging, since
664     the application has no control over how the record appears.
665     (The application must <emphasis>not</emphasis>
666     <literal>delete</literal> the returned string - it is ``owned'' by
667     the record object.)
668    </para>
669    <para>
670     More sophisticated applications will want to deal with the raw data
671     themselves: the <literal>rawdata()</literal> method returns it.
672     Its format will vary depending on the record syntax: SUTRS, MARC
673     and XML records are returned ``as is'', and GRS-1 records as a
674     pointer to their top-level node, which is a
675     <literal>Z_GenericRecord</literal> structure as defined in the
676     <literal>&lt;yaz/z-grs.h&gt;</literal> header file.
677     (The application must <emphasis>not</emphasis>
678     <literal>delete</literal> the returned data - it is ``owned'' by
679     the record object.)
680    </para>
681    <para>
682     Perceptive readers will notice that there are no methods for access
683     to individual fields within a record.  That's because the different
684     record syntaxes are so different that there is no even a uniform
685     notion of what a field is across them all, let alone a sensible way
686     to implement such a function.  Fetch the raw data instead, and pick
687     it apart ``by hand''.
688    </para>
689    <sect2 id="zoom.memory.management">
690     <title>Memory Management</title>
691     <para>
692      The <literal>record</literal> objects returned from
693      <literal>resultSet::getRecord()</literal> are ``owned'' by the
694      result set object: that means that the application is not
695      responsible for <literal>delete</literal>ing them - each
696      <literal>record</literal> is automatically deallocated when the
697      <literal>resultSet</literal> that owns it is
698      <literal>delete</literal>d.
699     </para>
700     <para>
701      Usually that's what you want: it means that you can easily fetch a
702      record, use it and forget all about it, like this:
703     </para>
704     <programlisting>
705      resultSet rs(conn, query);
706      cout &lt;&lt; rs.getRecord(0)-&gt;render();
707     </programlisting>
708     <para>
709      But sometimes you want a <literal>record</literal> to live on past
710      the lifetime of the <literal>resultSet</literal> from which it was
711      fetched.  In this case, the <literal>clone(f)</literal> method can
712      be used to make an autonomous copy.  The application must
713      <literal>delete</literal> it when it doesn't need it any longer:
714     </para>
715     <programlisting>
716     record *rec;
717     {
718         resultSet rs(conn, query);
719         rec = rs.getRecord(0)-&gt;clone();
720         // `rs' goes out of scope here, and is deleted
721     }
722     cout &lt;&lt; rec-&gt;render();
723     delete rec;
724     </programlisting>
725    </sect2>
726    <sect2 id="record.references">
727     <title>References</title>
728     <itemizedlist>
729      <listitem>
730       <para>
731        <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.5"
732               >Section 3.5 (Record) of the ZOOM Abstract API</ulink>
733       </para>
734      </listitem>
735      <listitem>
736       <para>
737        <ulink url="&url.yaz.zoom.records;"
738               >The Records section of the ZOOM-C documentation</ulink>
739       </para>
740      </listitem>
741     </itemizedlist>
742    </sect2>
743   </sect1>
744   <sect1 id="zoom-exception">
745    <title><literal>ZOOM::exception</literal> and subclasses</title>
746    <para>
747     The <literal>ZOOM::exception</literal> class is a virtual base
748     class, representing a diagnostic generated by the ZOOM-C++ library
749     or returned from a server.  Its subclasses represent particular
750     kinds of error.
751    </para>
752    <para>
753     When any of the ZOOM methods fail, they respond by
754     <literal>throw</literal>ing an object of type
755     <literal>exception</literal> or one of its subclasses.  This most
756     usually happens with the <literal>connection</literal> constructor,
757     the various query constructors, the <literal>resultSet</literal>
758     constructor (which is actually the searching method) and
759     <literal>resultSet::getRecord()</literal>.
760    </para>
761    <para>
762     The base class has this declaration:
763    </para>
764    <synopsis>
765     class exception {
766     public:
767       exception (int code);
768       int errcode () const;
769       const char *errmsg () const;
770     };
771    </synopsis>
772    <para>
773     It has three concrete subclasses:
774    </para>
775    <sect2 id="zoom-systemException">
776     <title><literal>ZOOM::systemException</literal></title>
777     <synopsis>
778      class systemException: public exception {
779      public:
780        systemException ();
781        int errcode () const;
782        const char *errmsg () const;
783      };
784     </synopsis>
785     <para>
786      Represents a ``system error'', typically indicating that a system
787      call failed - often in the low-level networking code that
788      underlies Z39.50.  <literal>errcode()</literal> returns the value
789      that the system variable <literal>errno</literal> had at the time
790      the exception was constructed; and <literal>errmsg()</literal>
791      returns a human-readable error-message corresponidng to that error
792      code.
793     </para>
794    </sect2>
795    <sect2 id="zoom-bib1Exception">
796     <title><literal>ZOOM::bib1Exception</literal></title>
797     <synopsis>
798      class bib1Exception: public exception {
799      public:
800        bib1Exception (int errcode, const char *addinfo);
801        int errcode () const;
802        const char *errmsg () const;
803        const char *addinfo () const;
804      };
805     </synopsis>
806     <para>
807      Represents an error condition communicated by a Z39.50 server.
808      <literal>errcode()</literal> returns the BIB-1 diagnostic code of
809      the error, and <literal>errmsg()</literal> a human-readable error
810      message corresponding to that code.  <literal>addinfo()</literal>
811      returns any additional information associated with the error.
812     </para>
813     <para>
814      For example, if a ZOOM application tries to search in the
815      ``Voyager'' database of a server that does not have a database of
816      that name, a <literal>bib1Exception</literal> will be thrown in
817      which <literal>errcode()</literal> returns 109,
818      <literal>errmsg()</literal> returns the corresponding error
819      message ``Database unavailable'' and <literal>addinfo()</literal>
820      returns the name of the requested, but unavailable, database.
821     </para>
822    </sect2>
823    <sect2 id="zoom-queryException">
824     <title><literal>ZOOM::queryException</literal></title>
825     <synopsis>
826      class queryException: public exception {
827      public:
828        static const int PREFIX = 1;
829        static const int CCL = 2;
830        queryException (int qtype, const char *source);
831        int errcode () const;
832        const char *errmsg () const;
833        const char *addinfo () const;
834      };
835     </synopsis>
836     <para>
837      This class represents an error in parsing a query into a form that
838      a Z39.50 can understand.  It must be created with the
839      <literal>qtype</literal> parameter equal to one of the query-type
840      constants, which can be retrieved via the
841      <literal>errcode()</literal> method; <literal>errmsg()</literal>
842      returns an error-message specifying which kind of query was
843      malformed; and <literal>addinfo()</literal> returns a copy of the
844      query itself (that is, the value of <literal>source</literal> with
845      which the exception object was created.)
846     </para>
847    </sect2>
848    <sect2 id="revised-sample">
849     <title>Revised Sample Program</title>
850     <para>
851      Now we can revise the sample program from the
852      <link linkend="zoom-introduction">introduction</link>
853      to catch exceptions and report any errors:
854     </para>
855     <programlisting>
856     /* g++ -o zoom-c++-hw zoom-c++-hw.cpp -lzoompp -lyaz */
857
858     #include &lt;iostream&gt;
859     #include &lt;yazpp/zoom.h&gt;
860
861     using namespace ZOOM;
862
863     int main(int argc, char **argv)
864     {
865         try {
866             connection conn("z3950.loc.gov", 7090);
867             conn.option("databaseName", "Voyager");
868             conn.option("preferredRecordSyntax", "USMARC");
869             resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
870             const record *rec = rs.getRecord(0);
871             cout &lt;&lt; rec-&gt;render() &lt;&lt; endl;
872         } catch (systemException &amp;e) {
873             cerr &lt;&lt; "System error " &lt;&lt;
874                 e.errcode() &lt;&lt; " (" &lt;&lt; e.errmsg() &lt;&lt; ")" &lt;&lt; endl;
875         } catch (bib1Exception &amp;e) {
876             cerr &lt;&lt; "BIB-1 error " &lt;&lt; 
877                 e.errcode() &lt;&lt; " (" &lt;&lt; e.errmsg() &lt;&lt; "): " &lt;&lt; e.addinfo() &lt;&lt; endl;
878         } catch (queryException &amp;e) {
879             cerr &lt;&lt; "Query error " &lt;&lt;
880                 e.errcode() &lt;&lt; " (" &lt;&lt; e.errmsg() &lt;&lt; "): " &lt;&lt; e.addinfo() &lt;&lt; endl;
881         } catch (exception &amp;e) {
882             cerr &lt;&lt; "Error " &lt;&lt;
883                 e.errcode() &lt;&lt; " (" &lt;&lt; e.errmsg() &lt;&lt; ")" &lt;&lt; endl;
884         }
885     }
886     </programlisting>
887     <para>
888      The heart of this program is the same as in the original version,
889      but it's now wrapped in a <literal>try</literal> block followed by
890      several <literal>catch</literal> blocks which try to give helpful
891      diagnostics if something goes wrong.
892     </para>
893     <para>
894      The first such block diagnoses system-level errors such as memory
895      exhaustion or a network connection being broken by a server's
896      untimely death; the second catches errors at the Z39.50 level,
897      such as a server's report that it can't provide records in USMARC
898      syntax; the third is there in case there's something wrong with
899      the syntax of the query (although in this case it's correct); and
900      finally, the last <literal>catch</literal> block is a
901      belt-and-braces measure to be sure that nothing escapes us.
902     </para>
903    </sect2>
904    <sect2 id="exception.references">
905     <title>References</title>
906     <itemizedlist>
907      <listitem>
908       <para>
909        <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.7"
910               >Section 3.7 (Exception) of the ZOOM Abstract API</ulink>
911       </para>
912      </listitem>
913      <listitem>
914       <para>
915        <ulink url="&url.z39.50.diagnostics;">Bib-1 Diagnostics</ulink> on the
916        <ulink url="&url.z39.50;">Z39.50 Maintenance Agency</ulink> site.
917       </para>
918      </listitem>
919     </itemizedlist>
920     <para>
921      Because C does not support exceptions, ZOOM-C has no API element
922      that corresponds directly with ZOOM-C++'s
923      <literal>exception</literal> class and its subclasses.  The
924      closest thing is the <literal>ZOOM_connection_error</literal>
925      function described in
926      <ulink url="&url.yaz.zoom.connections;"
927             >The Connections section</ulink> of the documentation.
928     </para>
929    </sect2>
930   </sect1>
931  </chapter>
932  <chapter id="api">
933   <title>YAZ C++ API</title>
934   <para>
935    The YAZ C++ API is an client - and server API that exposes
936    all YAZ features. The API doesn't hide YAZ C data structures, but
937    provides a set of useful high-level objects for creating clients -
938    and servers.
939   </para>
940   <para>
941    All definitions from YAZ++ are part of namespace
942    <literal>yazpp_1</literal>.
943   </para>
944   <para>
945    The following sections include a short description of the
946    interfaces and implementations (concrete classes).
947   </para>
948   <para>
949    In order to understand the structure, you should look at the
950    example client <filename>yaz-my-client.cpp</filename> and
951    the example server <filename>yaz-my-server.cpp</filename>.
952    If that is too easy, you can always turn to the implementation
953    of the proxy itself and send us a patch if you implement a new
954    useful feature.
955   </para>
956   <note>
957    <para>
958     The documentation here is very limited. We plan to enhance it -
959     provided there is interest for it.
960    </para>
961   </note>
962   <section id="interfaces"><title>Interfaces</title>
963    <section id="ISocketObservable"><title>ISocketObservable</title>
964     <para>
965      This interface is capable of observing sockets.
966      When a socket even occurs it invokes an object implementing the
967      <link linkend="ISocketObserver">ISocketObserver</link>
968      interface.
969     </para>
970     <synopsis>
971      #include &lt;yazpp/socket-observer.h>
972
973      class my_socketobservable : public ISocketObservable {
974         // Add an observer interested in socket fd
975         virtual void addObserver(int fd, ISocketObserver *observer) = 0;
976         // Delete an observer
977         virtual void deleteObserver(ISocketObserver *observer) = 0;
978         // Delete all observers
979         virtual void deleteObservers() = 0;
980         // Specify the events that the observer is interested in.
981         virtual void maskObserver(ISocketObserver *observer,
982                                   int mask) = 0;
983         // Specify timeout
984         virtual void timeoutObserver(ISocketObserver *observer,
985                                      int timeout)=0;
986      };
987     </synopsis>
988    </section>
989    <section id="ISocketObserver">
990     <title>ISocketObserver</title>
991     <para>
992      This interface is interested in socket events supporting
993      the <link linkend="ISocketObservable">ISocketObservable</link>
994      interface.
995     </para>
996     <synopsis>
997      #include &lt;yazpp/socket-observer.h>
998
999      class my_socketobserver : public ISocketObserver {
1000          public:
1001           // Notify the observer that something happened to socket
1002           virtual void socketNotify(int event) = 0;
1003      }
1004     </synopsis>
1005    </section>
1006    <section id="IPDU_Observable">
1007     <title>IPDU_Observable</title>
1008     <para>
1009      This interface is is responsible for sending - and receiving PDUs over
1010      the network (YAZ COMSTACK). When events occur, an instance
1011      implementing <link linkend="IPDU_Observer">IPDU_Observer</link>
1012      is notified.
1013     </para>
1014     <synopsis>
1015      #include &lt;yazpp/pdu-observer.h>
1016
1017      class my_pduobservable : public IPDU_Observable {
1018        public:
1019          // Send encoded PDU buffer of specified length
1020          virtual int send_PDU(const char *buf, int len) = 0;
1021          // Connect with server specified by addr.
1022          virtual void connect(IPDU_Observer *observer,
1023                      const char *addr) = 0;
1024          // Listen on address addr.
1025          virtual void listen(IPDU_Observer *observer, const char *addr)=0;
1026          // Close connection
1027          virtual void close() = 0;
1028          // Make clone of this object using this interface
1029          virtual IPDU_Observable *clone() = 0;
1030          // Destroy completely
1031          virtual void destroy() = 0;
1032          // Set Idle Time
1033          virtual void idleTime (int timeout) = 0;
1034          // Get peername
1035          virtual const char *getpeername() = 0;
1036
1037          virtual ~IPDU_Observable();
1038      };
1039     </synopsis>
1040    </section>
1041    <section id="IPDU_Observer">
1042     <title>IPDU_Observer</title>
1043     <para>
1044      This interface is interested in PDUs and using an object implementing
1045      <link linkend="IPDU_Observable">IPDU_Observable</link>.
1046     </para>
1047     <synopsis>
1048      #include &lt;yazpp/pdu-observer.h>
1049
1050      class my_pduobserver : public IPDU_Observer {
1051        public:
1052          // A PDU has been received
1053          virtual void recv_PDU(const char *buf, int len) = 0;
1054          // Called when Iyaz_PDU_Observable::connect was successful.
1055          virtual void connectNotify() = 0;
1056          // Called whenever the connection was closed
1057          virtual void failNotify() = 0;
1058          // Called whenever there is a timeout
1059          virtual void timeoutNotify() = 0;
1060          // Make clone of observer using IPDU_Observable interface
1061          virtual IPDU_Observer *sessionNotify(
1062          IPDU_Observable *the_PDU_Observable, int fd) = 0;
1063      };
1064     </synopsis>
1065    </section>
1066    <section id="query">
1067     <title>Yaz_Query</title>
1068     <para>
1069      Abstract query.
1070     </para>
1071     <synopsis>
1072      #include &lt;yazpp/query.h>
1073      class my_query : public Yaz_Query {
1074        public:
1075          // Print query in buffer described by str and len
1076          virtual void print (char *str, int len) = 0;
1077      };
1078     </synopsis>
1079    </section>
1080   </section>
1081   <section id="implementations">
1082    <title>Implementations</title>
1083    <section id="Yaz_SocketManager">
1084     <title>Yaz_SocketManager</title>
1085     <para>
1086      This class implements the <link linkend="ISocketObservable">
1087      ISocketObservable</link> interface and is a portable
1088      socket wrapper around the select call.
1089      This implementation is useful for daemons,
1090      command line clients, etc.
1091     </para>
1092     <synopsis>
1093      #include &lt;yazpp/socket-manager.h>
1094
1095      class SocketManager : public ISocketObservable {
1096        public:
1097          // Add an observer
1098          virtual void addObserver(int fd, ISocketObserver *observer);
1099          // Delete an observer
1100          virtual void deleteObserver(ISocketObserver *observer);
1101          // Delete all observers
1102          virtual void deleteObservers();
1103          // Set event mask for observer
1104          virtual void maskObserver(ISocketObserver *observer, int mask);
1105          // Set timeout
1106          virtual void timeoutObserver(ISocketObserver *observer,
1107                                   unsigned timeout);
1108          // Process one event. return > 0 if event could be processed;
1109          int processEvent();
1110          SocketManager();
1111          virtual ~SocketManager();
1112      };
1113     </synopsis>
1114    </section>
1115    <section id="PDU_Assoc">
1116     <title>PDU_Assoc</title>
1117     <para>
1118      This class implements the interfaces
1119      <link linkend="IPDU_Observable">IPDU_Observable</link>
1120      and
1121      <link linkend="ISocketObserver">ISocketObserver</link>.
1122      This object implements a non-blocking client/server channel
1123      that transmits BER encoded PDUs (or those offered by YAZ COMSTACK).
1124     </para>
1125     <synopsis>
1126      #include &lt;yazpp/pdu-assoc.h>
1127
1128      class PDU_Assoc : public IPDU_Observable,
1129                                  ISocketObserver {
1130        public:
1131          COMSTACK comstack(const char *type_and_host, void **vp);
1132          // Create object using specified socketObservable
1133          PDU_Assoc(ISocketObservable *socketObservable);
1134          // Create Object using existing comstack
1135          PDU_Assoc(ISocketObservable *socketObservable,
1136                   COMSTACK cs);
1137          // Close socket and destroy object.
1138          virtual ~PDU_Assoc();
1139          // Clone the object
1140          IPDU_Observable *clone();
1141          // Send PDU
1142          int send_PDU(const char *buf, int len);
1143          // connect to server (client role)
1144          void connect(IPDU_Observer *observer, const char *addr);
1145          // listen for clients (server role)
1146          void listen(IPDU_Observer *observer, const char *addr);
1147          // Socket notification
1148          void socketNotify(int event);
1149          // Close socket
1150          void close();
1151          // Close and destroy
1152          void destroy();
1153          // Set Idle Time
1154          void idleTime (int timeout);
1155          // Child start...
1156          virtual void childNotify(COMSTACK cs);
1157      };
1158     </synopsis>
1159    </section>
1160    <section id="Z_Assoc">
1161     <title>Z_Assoc</title>
1162     <para>
1163      This class implements the interface
1164      <link linkend="IPDU_Observer">IPDU_Obserer</link>.
1165      This object implements a Z39.50 client/server channel AKA
1166      Z-Association.
1167     </para>
1168     <synopsis>
1169      #include &lt;yazpp/z-assoc.h>
1170
1171      class Z_Assoc : public IPDU_Observer {
1172        public:
1173          // Create object using the PDU Observer specified
1174          Z_Assoc(IPDU_Observable *the_PDU_Observable);
1175          // Destroy association and close PDU Observer
1176          virtual ~Z_Assoc();
1177          // Receive PDU
1178          void recv_PDU(const char *buf, int len);
1179          // Connect notification
1180          virtual void connectNotify() = 0;
1181          // Failure notification
1182          virtual void failNotify() = 0;
1183          // Timeout notification
1184          virtual void timeoutNotify() = 0;
1185          // Timeout specify
1186          void timeout(int timeout);
1187          // Begin Z39.50 client role
1188          void client(const char *addr);
1189          // Begin Z39.50 server role
1190          void server(const char *addr);
1191          // Close connection
1192          void close();
1193
1194          // Decode Z39.50 PDU.
1195          Z_APDU *decode_Z_PDU(const char *buf, int len);
1196          // Encode Z39.50 PDU.
1197          int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len);
1198          // Send Z39.50 PDU
1199          int send_Z_PDU(Z_APDU *apdu);
1200          // Receive Z39.50 PDU
1201          virtual void recv_Z_PDU(Z_APDU *apdu) = 0;
1202          // Create Z39.50 PDU with reasonable defaults
1203          Z_APDU *create_Z_PDU(int type);
1204          // Request Alloc
1205          ODR odr_encode ();
1206          ODR odr_decode ();
1207          ODR odr_print ();
1208          void set_APDU_log(const char *fname);
1209          const char *get_APDU_log();
1210
1211          // OtherInformation
1212          void get_otherInfoAPDU(Z_APDU *apdu, Z_OtherInformation ***oip);
1213          Z_OtherInformationUnit *update_otherInformation (
1214                Z_OtherInformation **otherInformationP, int createFlag,
1215                int *oid, int categoryValue, int deleteFlag);
1216          void set_otherInformationString (
1217                Z_OtherInformation **otherInformationP,
1218                int *oid, int categoryValue,
1219                const char *str);
1220          void set_otherInformationString (
1221                Z_OtherInformation **otherInformation,
1222                int oidval, int categoryValue,
1223                const char *str);
1224          void set_otherInformationString (
1225                Z_APDU *apdu,
1226                int oidval, int categoryValue,
1227                const char *str);
1228
1229          Z_ReferenceId *getRefID(char* str);
1230          Z_ReferenceId **get_referenceIdP(Z_APDU *apdu);
1231          void transfer_referenceId(Z_APDU *from, Z_APDU *to);
1232
1233          const char *get_hostname();
1234      };
1235     </synopsis>
1236    </section>
1237    <section id="IR_Assoc">
1238     <title>IR_Assoc</title>
1239     <para>
1240      This object is just a specialization of
1241      <link linkend="Z_Assoc">Z_Assoc</link> and provides
1242      more facilities for the Z39.50 client role.
1243     </para>
1244     <synopsis>
1245      #include &lt;yazpp/ir-assoc.h>
1246
1247      class IR_Assoc : public Z_Assoc {
1248        ...
1249      };
1250     </synopsis>
1251     <para>
1252      The example client, <filename>yaz-my-client.cpp</filename>,
1253      uses this class.
1254     </para>
1255    </section>
1256    <section id="Z_Server">
1257     <title>Z_Server</title>
1258     <para>
1259      This object is just a specialization of
1260      <link linkend="Z_Assoc">Z_Assoc</link> and provides
1261      more facilities for the Z39.50 server role.
1262     </para>
1263     <synopsis>
1264      #include &lt;yazpp/z-server.h>
1265
1266      class My_Server : public Z_Server {
1267        ...
1268      };
1269     </synopsis>
1270     <para>
1271      The example server, <filename>yaz-my-server.cpp</filename>,
1272      uses this class.
1273     </para>
1274    </section>
1275   </section>
1276  </chapter>
1277  <appendix id="license">
1278   <title>License</title>
1279   <para>
1280    Copyright &copy; &copyright-year; Index Data.
1281   </para>
1282   <para>
1283    All rights reserved.
1284   </para>
1285   <para>
1286    Redistribution and use in source and binary forms, with or without
1287    modification, are permitted provided that the following conditions are met:
1288   </para>
1289   <itemizedlist>
1290    <listitem>
1291     <para>
1292      Redistributions of source code must retain the above copyright
1293      notice, this list of conditions and the following disclaimer.
1294     </para>
1295    </listitem>
1296    <listitem>
1297     <para>
1298      Redistributions in binary form must reproduce the above copyright
1299      notice, this list of conditions and the following disclaimer in the
1300      documentation and/or other materials provided with the distribution.
1301     </para>
1302    </listitem>
1303    <listitem>
1304     <para>
1305      Neither the name of Index Data nor the names of its contributors
1306      may be used to endorse or promote products derived from this
1307      software without specific prior written permission.
1308     </para>
1309    </listitem>
1310   </itemizedlist>
1311   <para>
1312    THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
1313    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1314    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1315    DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR
1316    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1317    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1318    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1319    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1320    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1321    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1322    SUCH DAMAGE.
1323   </para>
1324  </appendix>
1325 </book>
1326
1327 <!-- Keep this comment at the end of the file
1328 Local variables:
1329 mode: nxml
1330 nxml-child-indent: 1
1331 End:
1332 -->
1333