2 <!-- $Id: zoom.xml,v 1.6 2002-10-10 22:48:10 mike Exp $ -->
3 <title>ZOOM-C++</title>
6 <sect1 id="zoom-introduction">
7 <title>Introduction</title>
9 <ulink url="http://zoom.z3950.org/">ZOOM</ulink>
10 is the emerging standard API for information retrieval programming
11 using the Z39.50 protocol. ZOOM's
12 <ulink url="http://zoom.z3950.org/api/">Abstract API</ulink>
13 specifies semantics for classes representing key IR concepts such as
14 connections, queries, result sets and records; and there are various
15 <ulink url="http://zoom.z3950.org/bind/">bindings</ulink>
16 specifying how those concepts should be represented in various
17 programming languages.
20 The Yaz++ library includes an implementation of the <ulink
21 url="http://zoom.z3950.org/bind/cplusplus/"
23 for ZOOM, enabling quick, easy development of client applications.
26 For example, here is a tiny Z39.50 client that fetches and displays
27 the MARC record for Farlow & Brett Surman's
28 <!-- ### there must be a better way to mark up a book title? -->
29 <emphasis>The Complete Dinosaur</emphasis>
30 from the Library of Congress's Z39.50 server:
33 #include <iostream>
34 #include <yaz++/zoom.h>
38 int main(int argc, char **argv)
40 connection conn("z3950.loc.gov", 7090);
41 conn.option("databaseName", "Voyager");
42 resultSet rs(conn, prefixQuery("@attr attr 1=7 0253333490"));
43 const record *rec = rs.getRecord(0);
44 cout << rec->render() << endl;
48 (Note that, for the sake of simplicity, this does not check for
49 errors: we show a more realistic version of this program later.)
52 Yaz++'s implementation of the C++ binding is a thin layer over Yaz's
53 implementation of the C binding. For information on the supported
54 options and other such details, see the ZOOM-C documentation, which
55 can be found on-line at
56 <ulink url="http://www.indexdata.dk/yaz/doc/zoom.php"/>
59 All of the classes defined by ZOOM-C++ are in the
60 <literal>ZOOM</literal> namespace. We will now consider
61 the five main classes in turn:
66 <literal>connection</literal>
72 <literal>query</literal> and its subclasses
73 <literal>prefixQuery</literal> and
74 <literal>CCLQuery</literal>
80 <literal>resultSet</literal>
86 <literal>record</literal>
92 <literal>exception</literal> and its subclasses
93 <literal>systemException</literal>,
94 <literal>bib1Exception</literal> and
95 <literal>queryException</literal>
103 <sect1 id="zoom-connection">
104 <title><literal>ZOOM::connection</literal></title>
106 A <literal>ZOOM::connection</literal> object represents an open
107 connection to a Z39.50 server. Such a connection is forged by
108 constructing a <literal>connection</literal> object.
111 The class has this declaration:
116 connection (const char *hostname, int portnum);
118 const char *option (const char *key) const;
119 const char *option (const char *key, const char *val);
123 When a new <literal>connection</literal> is created, the hostname
124 and port number of a Z39.50 server must be supplied, and the
125 network connection is forged and wrapped in the new object. If the
126 connection can't be established - perhaps because the hostname
127 couldn't be resolved, or there is no server listening on the
128 specified port - then an
129 <link linkend="zoom-exception"><literal>exception</literal></link>
133 The only other methods on a <literal>connection</literal> object
134 are for getting and setting options. Any name-value pair of
135 strings may be set as options, and subsequently retrieved, but
136 certain options have special meanings which are understood by the
137 ZOOM code and affect the behaviour of the object that carries
138 them. For example, the value of the
139 <literal>databaseName</literal> option is used as the name of the
140 database to query when a search is executed against the
141 <literal>connection</literal>. For a full list of such special
142 options, see the ZOOM abstract API and the ZOOM-C documentation
147 <title>References</title>
151 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.2"
152 >Section 3.2 (Connection) of the ZOOM Abstract API</ulink>
157 <ulink url="http://www.indexdata.dk/yaz/doc/zoom.php#zoom.connections"
158 >The Connections section of the ZOOM-C documentation</ulink>
166 <sect1 id="zoom-query">
167 <title><literal>ZOOM::query</literal> and subclasses</title>
169 The <literal>ZOOM::query</literal> class is a virtual base class,
170 representing a query to be submitted to a server. This class has
171 no methods, but two (so far) concrete subclasses, each implementing
172 a specific query notation.
176 <title><literal>ZOOM::prefixQuery</literal></title>
178 class prefixQuery : public query {
180 prefixQuery (const char *pqn);
185 This class enables a query to be created by compiling Yaz's
187 <ulink url="http://www.indexdata.dk/yaz/doc/tools.php#PQF"
188 >Prefix Query Notation (PQN)</ulink>.
193 <title><literal>ZOOM::CCLQuery</literal></title>
195 class CCLQuery : public query {
197 CCLQuery (const char *ccl, void *qualset);
202 This class enables a query to be created using the simpler but
204 <ulink url="http://www.indexdata.dk/yaz/doc/tools.php#CCL"
205 >Common Command Language (CCL)</ulink>.
206 The qualifiers recognised by the CCL parser are specified in an
207 external configuration file in the format described by the Yaz
211 If query construction fails for either type of
212 <literal>query</literal> object - typically because the query
213 string itself is not valid PQN or CCL - then an
214 <link linkend="zoom-exception"><literal>exception</literal></link>
220 <title>Discussion</title>
222 It will be readily recognised that these objects have no methods
223 other than their constructors: their only role in life is to be
224 used in searching, by being passed to the
225 <literal>resultSet</literal> class's constructor.
228 Given a suitable set of CCL qualifiers, the following pairs of
229 queries are equivalent:
232 prefixQuery("dinosaur");
233 CCLQuery("dinosaur");
235 prefixQuery("@and complete dinosaur");
236 CCLQuery("complete and dinosaur");
238 prefixQuery("@and complete @or dinosaur pterosaur");
239 CCLQuery("complete and (dinosaur or pterosaur)");
241 prefixQuery("@attr 1=7 0253333490");
242 CCLQuery("isbn=0253333490");
247 <title>References</title>
251 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.3"
252 >Section 3.3 (Query) of the ZOOM Abstract API</ulink>
257 <ulink url="http://www.indexdata.dk/yaz/doc/zoom.query.php"
258 >The Queries section of the ZOOM-C documentation</ulink>
266 <sect1 id="zoom-resultset">
267 <title><literal>ZOOM::resultSet</literal></title>
269 A <literal>ZOOM::resultSet</literal> object represents a set of
270 records identified by a query that has been executed against a
271 particular connection. The sole purpose of both
272 <literal>connection</literal> and <literal>query</literal> objects
273 is that they can be used to create new
274 <literal>resultSet</literal>s - that is, to perform a search on the
275 server on the remote end of the connection.
278 The class has this declaration:
283 resultSet (connection &c, const query &q);
285 const char *option (const char *key) const;
286 const char *option (const char *key, const char *val);
287 size_t size () const;
288 const record *getRecord (size_t i) const;
292 New <literal>resultSet</literal>s are created by the constructor,
293 which is passed a <literal>connection</literal>, indicating the
294 server on which the search is to be performed, and a
295 <literal>query</literal>, indicating what search to perform. If
296 the search fails - for example, because the query uses attributes
297 that the server doesn't implement - then an
298 <link linkend="zoom-exception"><literal>exception</literal></link>
302 Like <literal>connection</literal>s, <literal>resultSet</literal>
303 objects can carry name-value options. The special options which
304 affect ZOOM-C++'s behaviour are the same as those for ZOOM-C and
305 are described in its documentation (link below). In particular,
306 the <literal>preferredRecordSyntax</literal> option may be set to
307 a string such as ``USMARC'', ``SUTRS'' etc. to indicate what the
308 format in which records should be retrieved; and the
309 <literal>elementSetName</literal> option indicates whether brief
310 records (``B''), full records (``F'') or some other composition
314 The <literal>size()</literal> method returns the number of records
315 in the result set. Zero is a legitimate value: a search that finds
316 no records is not the same as a search that fails.
319 Finally, the <literal>getRecord</literal> method returns the
320 <parameter>i</parameter>th record from the result set, where
321 <parameter>i</parameter> is zero-based: that is, legitmate values
322 range from zero up to one less than the result-set size. If the
323 method fails, for example because the requested record is out of
324 range, it <literal>throw</literal>s an
325 <link linkend="zoom-exception"><literal>exception</literal></link>.
329 <title>References</title>
333 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.4"
334 >Section 3.4 (Result Set) of the ZOOM Abstract API</ulink>
339 <ulink url="http://www.indexdata.dk/yaz/doc/zoom.resultsets.php"
340 >The Result Sets section of the ZOOM-C documentation</ulink>
348 <sect1 id="zoom-record">
349 <title><literal>ZOOM::record</literal></title>
351 A <literal>ZOOM::record</literal> object represents a chunk of data
352 from a <literal>resultSet</literal> returned from a server.
355 The class has this declaration:
362 UNKNOWN, GRS1, SUTRS, USMARC, UKMARC, XML
364 record *clone () const;
365 syntax recsyn () const;
366 const char *render () const;
367 const char *rawdata () const;
371 Records returned from Z39.50 servers are encoded using a record
372 syntax: the various national MARC formats are commonly used for
373 bibliographic data, GRS-1 or XML for complex structured data, SUTRS
374 for simple human-readable text, etc. The
375 <literal>record::syntax</literal> enumeration specifies constants
376 representing common record syntaxes, and the
377 <literal>recsyn()</literal> method returns the value corresponding
378 to the record-syntax of the record on which it is invoked.
381 Because this interface uses an enumeration, it is difficult to
382 extend to other record syntaxes - for example, DANMARC, the MARC
383 variant widely used in Denmark. We might either grow the
384 enumeration substantially, or change the interface to return
385 either an integer or a string.
390 The simplest thing to do with a retrieved record is simply to
391 <literal>render()</literal> it. This returns a human-readable, but
392 not necessarily very pretty, representation of the contents of the
393 record. This is useful primarily for testing and debugging, since
394 the application has no control over how the record appears.
395 (The application must <emphasis>not</emphasis>
396 <literal>delete</literal> the returned string - it is ``owned'' by
400 More sophisticated applications will want to deal with the raw data
401 themselves: the <literal>rawdata()</literal> method returns it.
402 Its format will vary depending on the record syntax: SUTRS, MARC
403 and XML records are returned ``as is'', and GRS-1 records as a
404 pointer to their top-level node, which is a
405 <literal>Z_GenericRecord</literal> structure as defined in the
406 <literal><yaz/z-grs.h></literal> header file.
407 (The application must <emphasis>not</emphasis>
408 <literal>delete</literal> the returned data - it is ``owned'' by
412 Perceptive readers will notice that there are no methods for access
413 to individual fields within a record. That's because the different
414 record syntaxes are so different that there is no even a uniform
415 notion of what a field is across them all, let alone a sensible way
416 to implement such a function. Fetch the raw data instead, and pick
417 it apart ``by hand''.
421 <title>Memory Management</title>
423 The <literal>record</literal> obejcts returned from
424 <literal>resultSet::getRecord()</literal> are ``owned'' by the
425 result set object: that means that the application is not
426 responsible for <literal>delete</literal>ing them - each
427 <literal>record</literal> is automatically deallocated when the
428 <literal>resultSet</literal> that owns it is
429 <literal>delete</literal>d.
432 Usually that's what you want: it means that you can easily fetch a
433 record, use it and forget all about it, like this:
436 resultSet rs(conn, query);
437 cout << rs.getRecord(0)->render();
440 But sometimes you want a <literal>record</literal> to live on past
441 the lifetime of the <literal>resultSet</literal> from which it was
442 fetched. In this case, the <literal>clone(f)</literal> method can
443 be used to make an autonomous copy. The application must
444 <literal>delete</literal> it when it doesn't need it any longer:
449 resultSet rs(conn, query);
450 rec = rs.getRecord(0)->clone();
451 // `rs' goes out of scope here, and is deleted
453 cout << rec->render();
459 <title>References</title>
463 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.5"
464 >Section 3.5 (Record) of the ZOOM Abstract API</ulink>
469 <ulink url="http://www.indexdata.dk/yaz/doc/zoom.records.php"
470 >The Records section of the ZOOM-C documentation</ulink>
478 <sect1 id="zoom-exception">
479 <title><literal>ZOOM::exception</literal> and subclasses</title>
481 The <literal>ZOOM::exception</literal> class is a virtual base
482 class, representing a diagnostic generated by the ZOOM-C++ library
483 or returned from a server. Its subclasses represent particular
487 When any of the ZOOM methods fail, they respond by
488 <literal>throw</literal>ing an object of type
489 <literal>exception</literal> or one of its subclasses. This most
490 usually happens with the <literal>connection</literal> constructor,
491 the various query constructors, the <literal>resultSet</literal>
492 constructor (which is actually the searching method) and
493 <literal>resultSet::getRecord()</literal>.
496 The base class has this declaration:
501 exception (int code);
502 int errcode () const;
503 const char *errmsg () const;
507 It has three concrete subclasses:
511 <title><literal>ZOOM::systemException</literal></title>
513 class systemException: public exception {
516 int errcode () const;
517 const char *errmsg () const;
521 Represents a ``system error'', typically indicating that a system
522 call failed - often in the low-level networking code that
523 underlies Z39.50. <literal>errcode()</literal> returns the value
524 that the system variable <literal>errno</literal> had at the time
525 the exception was constructed; and <literal>errmsg()</literal>
526 returns a human-readable error-message corresponidng to that error
532 <title><literal>ZOOM::bib1Exception</literal></title>
534 class bib1Exception: public exception {
536 bib1Exception (int errcode, const char *addinfo);
537 int errcode () const;
538 const char *errmsg () const;
539 const char *addinfo () const;
543 Represents an error condition communicated by a Z39.50 server.
544 <literal>errcode()</literal> returns the BIB-1 diagnostic code of
545 the error, and <literal>errmsg()</literal> a human-readable error
546 message corresponding to that code. <literal>addinfo()</literal>
547 returns any additional information associated with the error.
550 For example, if a ZOOM application tries to search in the
551 ``Voyager'' database of a server that does not have a database of
552 that name, a <literal>bib1Exception</literal> will be thrown in
553 which <literal>errcode()</literal> returns 109,
554 <literal>errmsg()</literal> returns the corresponding error
555 message ``Database unavailable'' and <literal>addinfo()</literal>
556 returns the name of the requested, but unavailable, database.
561 <title><literal>ZOOM::queryException</literal></title>
563 class queryException: public exception {
565 static const int PREFIX = 1;
566 static const int CCL = 2;
567 queryException (int qtype, const char *source);
568 int errcode () const;
569 const char *errmsg () const;
570 const char *addinfo () const;
574 This class represents an error in parsing a query into a form that
575 a Z39.50 can understand. It must be created with the
576 <literal>qtype</literal> parameter equal to one of the query-type
577 constants, which can be retrieved via the
578 <literal>errcode()</literal> method; <literal>errmsg()</literal>
579 returns an error-message specifying which kind of query was
580 malformed; and <literal>addinfo()</literal> returns a copy of the
581 query itself (that is, the value of <literal>source</literal> with
582 which the exception object was created.)
587 <title>References</title>
591 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.7"
592 >Section 3.7 (Exception) of the ZOOM Abstract API</ulink>
597 <ulink url="http://lcweb.loc.gov/z3950/agency/defns/bib1diag.html"
598 >Bib-1 Diagnostics</ulink> on the
599 <ulink url="http://lcweb.loc.gov/z3950/agency/"
600 >Z39.50 Maintenance Agency</ulink> site.
605 Because C does not support exceptions, ZOOM-C has no API element
606 that corresponds directly with ZOOM-C++'s
607 <literal>exception</literal> class and its subclasses. The
608 closest thing is the <literal>ZOOM_connection_error</literal>
609 function described in
610 <ulink url="http://www.indexdata.dk/yaz/doc/zoom.php#zoom.connections"
611 >The Connections section</ulink> of the documentation.
618 <!-- Keep this comment at the end of the file
623 sgml-minimize-attributes:nil
624 sgml-always-quote-attributes:t
627 sgml-parent-document: "zebra.xml"
628 sgml-local-catalogs: nil
629 sgml-namecase-general:t