4d47a1b3bf15f205859e154c9afbfafc9e59c1be
[yaz-moved-to-github.git] / doc / tools.xml
1 <!-- $Id: tools.xml,v 1.3 2001-07-20 21:34:36 adam Exp $ -->
2  <chapter><title>Supporting Tools</title>
3
4   <para>
5    In support of the service API - primarily the ASN module, which
6    provides the programmatic interface to the Z39.50 APDUs, YAZ contains
7    a collection of tools that support the development of applications.
8   </para>
9
10   <sect1><title>Query Syntax Parsers</title>
11
12    <para>
13     Since the type-1 (RPN) query structure has no direct, useful string
14     representation, every origin application needs to provide some form of
15     mapping from a local query notation or representation to a
16     <token>Z_RPNQuery</token> structure. Some programmers will prefer to
17     construct the query manually, perhaps using
18     <function>odr_malloc()</function> to simplify memory management.
19     The &yaz; distribution includes two separate, query-generating tools
20     that may be of use to you.
21    </para>
22
23    <sect2><title id="PQF">Prefix Query Format</title>
24
25     <para>
26      Since RPN or reverse polish notation is really just a fancy way of
27      describing a suffix notation format (operator follows operands), it
28      would seem that the confusion is total when we now introduce a prefix
29      notation for RPN. The reason is one of simple laziness - it's somewhat
30      simpler to interpret a prefix format, and this utility was designed
31      for maximum simplicity, to provide a baseline representation for use
32      in simple test applications and scripting environments (like Tcl). The
33      demonstration client included with YAZ uses the PQF.
34     </para>
35     <para>
36      The PQF is defined by the pquery module in the YAZ library. The
37      <filename>pquery.h</filename> file provides the declaration of the
38      functions
39     </para>
40     <screen>
41 Z_RPNQuery *p_query_rpn (ODR o, oid_proto proto, const char *qbuf);
42
43 Z_AttributesPlusTerm *p_query_scan (ODR o, oid_proto proto,
44           Odr_oid **attributeSetP, const char *qbuf);
45
46 int p_query_attset (const char *arg);
47     </screen>
48     <para>
49      The function <function>p_query_rpn()</function> takes as arguments an
50       &odr; stream (see section <link linkend="odr">The ODR Module</link>)
51      to provide a memory source (the structure created is released on
52      the next call to <function>odr_reset()</function> on the stream), a
53      protocol identifier (one of the constants <token>PROTO_Z3950</token> and
54      <token>PROTO_SR</token>), an attribute set
55      reference, and finally a null-terminated string holding the query
56      string.
57     </para>
58     <para>
59      If the parse went well, <function>p_query_rpn()</function> returns a
60      pointer to a <literal>Z_RPNQuery</literal> structure which can be
61      placed directly into a <literal>Z_SearchRequest</literal>.
62     </para>
63     <para>
64
65      The <literal>p_query_attset</literal> specifies which attribute set
66      to use if the query doesn't specify one by the
67      <literal>@attrset</literal> operator.
68      The <literal>p_query_attset</literal> returns 0 if the argument is a
69      valid attribute set specifier; otherwise the function returns -1.
70     </para>
71
72     <para>
73      The grammar of the PQF is as follows:
74     </para>
75
76     <screen>
77      Query ::= &lsqb; AttSet &rsqb; QueryStruct.
78
79      AttSet ::= string.
80
81      QueryStruct ::= { Attribute } Simple | Complex.
82
83      Attribute ::= '@attr' AttributeType '=' AttributeValue.
84
85      AttributeType ::= integer.
86
87      AttributeValue ::= integer.
88
89      Complex ::= Operator QueryStruct QueryStruct.
90
91      Operator ::= '@and' | '@or' | '@not' | '@prox' Proximity.
92
93      Simple ::= ResultSet | Term.
94
95      ResultSet ::= '@set' string.
96
97      Term ::= string | '"' string '"'.
98
99      Proximity ::= Exclusion Distance Ordered Relation WhichCode UnitCode.
100
101      Exclusion ::= '1' | '0' | 'void'.
102
103      Distance ::= integer.
104
105      Ordered ::= '1' | '0'.
106
107      Relation ::= integer.
108
109      WhichCode ::= 'known' | 'private' | integer.
110
111      UnitCode ::= integer.
112     </screen>
113
114     <para>
115      You will note that the syntax above is a fairly faithful
116      representation of RPN, except for the Attibute, which has been
117      moved a step away from the term, allowing you to associate one or more
118      attributes with an entire query structure. The parser will
119      automatically apply the given attributes to each term as required.
120     </para>
121
122     <para>
123      The following are all examples of valid queries in the PQF.
124     </para>
125
126     <screen>
127      dylan
128
129      "bob dylan"
130
131      @or "dylan" "zimmerman"
132
133      @set Result-1
134
135      @or @and bob dylan @set Result-1
136
137      @attr 4=1 @and @attr 1=1 "bob dylan" @attr 1=4 "slow train coming"
138
139      @attr 4=1 @attr 1=4 "self portrait"
140
141      @prox 0 3 1 2 k 2 dylan zimmerman
142     </screen>
143
144    </sect2>
145    <sect2><title id="CCL">Common Command Language</title>
146
147     <para>
148      Not all users enjoy typing in prefix query structures and numerical
149      attribute values, even in a minimalistic test client. In the library
150      world, the more intuitive Common Command Language (or ISO 8777) has
151      enjoyed some popularity - especially before the widespread
152      availability of graphical interfaces. It is still useful in
153      applications where you for some reason or other need to provide a
154      symbolic language for expressing boolean query structures.
155     </para>
156
157     <para>
158      The EUROPAGATE research project working under the Libraries programme
159      of the European Commission's DG XIII has, amongst other useful tools,
160      implemented a general-purpose CCL parser which produces an output
161      structure that can be trivially converted to the internal RPN
162      representation of YAZ (The <literal>Z_RPNQuery</literal> structure).
163      Since the CCL utility - along with the rest of the software
164      produced by EUROPAGATE - is made freely available on a liberal license, it
165      is included as a supplement to YAZ.
166     </para>
167
168     <sect3><title>CCL Syntax</title>
169
170      <para>
171       The CCL parser obeys the following grammar for the FIND argument.
172       The syntax is annotated by in the lines prefixed by
173       <literal>&dash;&dash;</literal>.
174      </para>
175
176      <screen>
177       CCL-Find ::= CCL-Find Op Elements
178                 | Elements.
179
180       Op ::= "and" | "or" | "not"
181       -- The above means that Elements are separated by boolean operators.
182
183       Elements ::= '(' CCL-Find ')'
184                 | Set
185                 | Terms
186                 | Qualifiers Relation Terms
187                 | Qualifiers Relation '(' CCL-Find ')'
188                 | Qualifiers '=' string '-' string
189       -- Elements is either a recursive definition, a result set reference, a
190       -- list of terms, qualifiers followed by terms, qualifiers followed
191       -- by a recursive definition or qualifiers in a range (lower - upper).
192
193       Set ::= 'set' = string
194       -- Reference to a result set
195
196       Terms ::= Terms Prox Term
197              | Term
198       -- Proximity of terms.
199
200       Term ::= Term string
201             | string
202       -- This basically means that a term may include a blank
203
204       Qualifiers ::= Qualifiers ',' string
205                   | string
206       -- Qualifiers is a list of strings separated by comma
207
208       Relation ::= '=' | '>=' | '<=' | '<>' | '>' | '<'
209       -- Relational operators. This really doesn't follow the ISO8777
210       -- standard.
211
212       Prox ::= '%' | '!'
213       -- Proximity operator
214
215      </screen>
216
217      <para>
218       The following queries are all valid:
219      </para>
220
221      <screen>
222       dylan
223
224       "bob dylan"
225
226       dylan or zimmerman
227
228       set=1
229
230       (dylan and bob) or set=1
231
232      </screen>
233      <para>
234       Assuming that the qualifiers <literal>ti</literal>, <literal>au</literal>
235       and <literal>date</literal> are defined we may use:
236      </para>
237
238      <screen>
239       ti=self portrait
240
241       au=(bob dylan and slow train coming)
242
243       date>1980 and (ti=((self portrait)))
244
245      </screen>
246
247     </sect3>
248     <sect3><title>CCL Qualifiers</title>
249
250      <para>
251       Qualifiers are used to direct the search to a particular searchable
252       index, such as title (ti) and author indexes (au). The CCL standard
253       itself doesn't specify a particular set of qualifiers, but it does
254       suggest a few short-hand notations. You can customize the CCL parser
255       to support a particular set of qualifiers to relect the current target
256       profile. Traditionally, a qualifier would map to a particular
257       use-attribute within the BIB-1 attribute set. However, you could also
258       define qualifiers that would set, for example, the
259       structure-attribute.
260      </para>
261
262      <para>
263       Consider a scenario where the target support ranked searches in the
264       title-index. In this case, the user could specify
265      </para>
266
267      <screen>
268       ti,ranked=knuth computer
269      </screen>
270      <para>
271       and the <literal>ranked</literal> would map to relation=relevance
272       (2=102) and the <literal>ti</literal> would map to title (1=4).
273      </para>
274
275      <para>
276       A "profile" with a set predefined CCL qualifiers can be read from a
277       file. The YAZ client reads its CCL qualifiers from a file named
278       <filename>default.bib</filename>. Each line in the file has the form:
279      </para>
280
281      <para>
282       <replaceable>qualifier-name</replaceable>  
283       <replaceable>type</replaceable>=<replaceable>val</replaceable>
284       <replaceable>type</replaceable>=<replaceable>val</replaceable> ...
285      </para>
286
287      <para>
288       where <replaceable>qualifier-name</replaceable> is the name of the
289       qualifier to be used (eg. <literal>ti</literal>),
290       <replaceable>type</replaceable> is a BIB-1 category type and
291       <replaceable>val</replaceable> is the corresponding BIB-1 attribute
292       value.
293       The <replaceable>type</replaceable> can be either numeric or it may be
294       either <literal>u</literal> (use), <literal>r</literal> (relation),
295       <literal>p</literal> (position), <literal>s</literal> (structure),
296       <literal>t</literal> (truncation) or <literal>c</literal> (completeness).
297       The <replaceable>qualifier-name</replaceable> <literal>term</literal>
298       has a special meaning.
299       The types and values for this definition is used when
300       <emphasis>no</emphasis> qualifiers are present.
301      </para>
302
303      <para>
304       Consider the following definition:
305      </para>
306
307      <screen>
308       ti       u=4 s=1
309       au       u=1 s=1
310       term     s=105
311      </screen>
312      <para>
313       Two qualifiers are defined, <literal>ti</literal> and
314       <literal>au</literal>.
315       They both set the structure-attribute to phrase (1).
316       <literal>ti</literal>
317       sets the use-attribute to 4. <literal>au</literal> sets the
318       use-attribute to 1.
319       When no qualifiers are used in the query the structure-attribute is
320       set to free-form-text (105).
321      </para>
322
323     </sect3>
324     <sect3><title>CCL API</title>
325      <para>
326       All public definitions can be found in the header file
327       <filename>ccl.h</filename>. A profile identifier is of type
328       <literal>CCL_bibset</literal>. A profile must be created with the call
329       to the function <function>ccl_qual_mk</function> which returns a profile
330       handle of type <literal>CCL_bibset</literal>.
331      </para>
332
333      <para>
334       To read a file containing qualifier definitions the function
335       <function>ccl_qual_file</function> may be convenient. This function
336       takes an already opened <literal>FILE</literal> handle pointer as
337       argument along with a <literal>CCL_bibset</literal> handle.
338      </para>
339
340      <para>
341       To parse a simple string with a FIND query use the function
342      </para>
343      <screen>
344 struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
345                                    int *error, int *pos);
346      </screen>
347      <para>
348       which takes the CCL profile (<literal>bibset</literal>) and query
349       (<literal>str</literal>) as input. Upon successful completion the RPN
350       tree is returned. If an error eccur, such as a syntax error, the integer
351       pointed to by <literal>error</literal> holds the error code and
352       <literal>pos</literal> holds the offset inside query string in which
353       the parsing failed.
354      </para>
355
356      <para>
357       An english representation of the error may be obtained by calling
358       the <literal>ccl_err_msg</literal> function. The error codes are
359       listed in <filename>ccl.h</filename>.
360      </para>
361
362      <para>
363       To convert the CCL RPN tree (type
364       <literal>struct ccl_rpn_node *</literal>)
365       to the Z_RPNQuery of YAZ the function <function>ccl_rpn_query</function>
366       must be used. This function which is part of YAZ is implemented in
367       <filename>yaz-ccl.c</filename>.
368       After calling this function the CCL RPN tree is probably no longer
369       needed. The <literal>ccl_rpn_delete</literal> destroys the CCL RPN tree.
370      </para>
371
372      <para>
373       A CCL profile may be destroyed by calling the
374       <function>ccl_qual_rm</function> function.
375      </para>
376
377      <para>
378       The token names for the CCL operators may be changed by setting the
379       globals (all type <literal>char *</literal>)
380       <literal>ccl_token_and</literal>, <literal>ccl_token_or</literal>,
381       <literal>ccl_token_not</literal> and <literal>ccl_token_set</literal>.
382       An operator may have aliases, i.e. there may be more than one name for
383       the operator. To do this, separate each alias with a space character.
384      </para>
385     </sect3>
386    </sect2>
387   </sect1>
388   <sect1><title>Object Identifiers</title>
389
390    <para>
391     The basic YAZ representation of an OID is an array of integers,
392     terminated with the value -1. The &odr; module provides two
393     utility-functions to create and copy this type of data elements:
394    </para>
395
396    <screen>
397     Odr_oid *odr_getoidbystr(ODR o, char *str);
398    </screen>
399
400    <para>
401     Creates an OID based on a string-based representation using dots (.)
402     to separate elements in the OID.
403    </para>
404
405    <screen>
406     Odr_oid *odr_oiddup(ODR odr, Odr_oid *o);
407    </screen>
408
409    <para>
410     Creates a copy of the OID referenced by the <emphasis>o</emphasis>
411     parameter.
412     Both functions take an &odr; stream as parameter. This stream is used to
413     allocate memory for the data elements, which is released on a
414     subsequent call to <function>odr_reset()</function> on that stream.
415    </para>
416
417    <para>
418     The OID module provides a higher-level representation of the
419     family of object identifers which describe the Z39.50 protocol and its
420     related objects. The definition of the module interface is given in
421     the <filename>oid.h</filename> file.
422    </para>
423
424    <para>
425     The interface is mainly based on the <literal>oident</literal> structure.
426     The definition of this structure looks like this:
427    </para>
428
429    <screen>
430 typedef struct oident
431 {
432     oid_proto proto;
433     oid_class oclass;
434     oid_value value;
435     int oidsuffix[OID_SIZE];
436     char *desc;
437 } oident;
438    </screen>
439
440    <para>
441     The proto field takes one of the values
442    </para>
443
444    <screen>
445     PROTO_Z3950
446     PROTO_SR
447    </screen>
448
449    <para>
450     If you don't care about talking to SR-based implementations (few
451     exist, and they may become fewer still if and when the ISO SR and ANSI
452     Z39.50 documents are merged into a single standard), you can ignore
453     this field on incoming packages, and always set it to PROTO_Z3950
454     for outgoing packages.
455    </para>
456    <para>
457
458     The oclass field takes one of the values
459    </para>
460
461    <screen>
462     CLASS_APPCTX
463     CLASS_ABSYN
464     CLASS_ATTSET
465     CLASS_TRANSYN
466     CLASS_DIAGSET
467     CLASS_RECSYN
468     CLASS_RESFORM
469     CLASS_ACCFORM
470     CLASS_EXTSERV
471     CLASS_USERINFO
472     CLASS_ELEMSPEC
473     CLASS_VARSET
474     CLASS_SCHEMA
475     CLASS_TAGSET
476     CLASS_GENERAL
477    </screen>
478
479    <para>
480     corresponding to the OID classes defined by the Z39.50 standard.
481
482     Finally, the value field takes one of the values
483    </para>
484
485    <screen>
486     VAL_APDU
487     VAL_BER
488     VAL_BASIC_CTX
489     VAL_BIB1
490     VAL_EXP1
491     VAL_EXT1
492     VAL_CCL1
493     VAL_GILS
494     VAL_WAIS
495     VAL_STAS
496     VAL_DIAG1
497     VAL_ISO2709
498     VAL_UNIMARC
499     VAL_INTERMARC
500     VAL_CCF
501     VAL_USMARC
502     VAL_UKMARC
503     VAL_NORMARC
504     VAL_LIBRISMARC
505     VAL_DANMARC
506     VAL_FINMARC
507     VAL_MAB
508     VAL_CANMARC
509     VAL_SBN
510     VAL_PICAMARC
511     VAL_AUSMARC
512     VAL_IBERMARC
513     VAL_EXPLAIN
514     VAL_SUTRS
515     VAL_OPAC
516     VAL_SUMMARY
517     VAL_GRS0
518     VAL_GRS1
519     VAL_EXTENDED
520     VAL_RESOURCE1
521     VAL_RESOURCE2
522     VAL_PROMPT1
523     VAL_DES1
524     VAL_KRB1
525     VAL_PRESSET
526     VAL_PQUERY
527     VAL_PCQUERY
528     VAL_ITEMORDER
529     VAL_DBUPDATE
530     VAL_EXPORTSPEC
531     VAL_EXPORTINV
532     VAL_NONE
533     VAL_SETM
534     VAL_SETG
535     VAL_VAR1
536     VAL_ESPEC1
537    </screen>
538
539    <para>
540     again, corresponding to the specific OIDs defined by the standard.
541    </para>
542
543    <para>
544     The desc field contains a brief, mnemonic name for the OID in question.
545    </para>
546
547    <para>
548     The function
549    </para>
550
551    <screen>
552     struct oident *oid_getentbyoid(int *o);
553    </screen>
554
555    <para>
556     takes as argument an OID, and returns a pointer to a static area
557     containing an <literal>oident</literal> structure. You typically use
558     this function when you receive a PDU containing an OID, and you wish
559     to branch out depending on the specific OID value.
560    </para>
561
562    <para>
563     The function
564    </para>
565
566    <screen>
567     int *oid_ent_to_oid(struct oident *ent, int *dst);
568    </screen>
569
570    <para>
571     Takes as argument an <literal>oident</literal> structure - in which
572     the <literal>proto</literal>, <literal>oclass</literal>/, and
573     <literal>value</literal> fields are assumed to be set correctly -
574     and returns a pointer to a the buffer as given by <literal>dst</literal>
575     containing the base
576     representation of the corresponding OID. The function returns
577     NULL and the array dst is unchanged if a mapping couldn't place.
578     The array <literal>dst</literal> should be at least of size
579     <literal>OID_SIZE</literal>.
580    </para>
581    <para>
582
583     The <function>oid_ent_to_oid()</function> function can be used whenever
584     you need to prepare a PDU containing one or more OIDs. The separation of
585     the <literal>protocol</literal> element from the remainer of the
586     OID-description makes it simple to write applications that can
587     communicate with either Z39.50 or OSI SR-based applications.
588    </para>
589
590    <para>
591     The function
592    </para>
593
594    <screen>
595     oid_value oid_getvalbyname(const char *name);
596    </screen>
597
598    <para>
599     takes as argument a mnemonic OID name, and returns the
600     <literal>/value</literal> field of the first entry in the database that 
601     contains the given name in its <literal>desc</literal> field.
602    </para>
603
604    <para>
605     Finally, the module provides the following utility functions, whose
606     meaning should be obvious:
607    </para>
608
609    <screen>
610     void oid_oidcpy(int *t, int *s);
611     void oid_oidcat(int *t, int *s);
612     int oid_oidcmp(int *o1, int *o2);
613     int oid_oidlen(int *o);
614    </screen>
615
616    <note>
617     <para>
618      The OID module has been criticized - and perhaps rightly so
619      - for needlessly abstracting the
620      representation of OIDs. Other toolkits use a simple
621      string-representation of OIDs with good results. In practice, we have
622      found the interface comfortable and quick to work with, and it is a
623      simple matter (for what it's worth) to create applications compatible
624      with both ISO SR and Z39.50. Finally, the use of the
625      <literal>/oident</literal> database is by no means mandatory.
626      You can easily create your own system for representing OIDs, as long
627      as it is compatible with the low-level integer-array representation
628      of the ODR module.
629     </para>
630    </note>
631
632   </sect1>
633
634   <sect1><title>Nibble Memory</title>
635
636    <para>
637     Sometimes when you need to allocate and construct a large,
638     interconnected complex of structures, it can be a bit of a pain to
639     release the associated memory again. For the structures describing the
640     Z39.50 PDUs and related structures, it is convenient to use the
641     memory-management system of the &odr; subsystem (see
642     <link linkend="odr-use">Using ODR</link>). However, in some circumstances
643     where you might otherwise benefit from using a simple nibble memory
644     management system, it may be impractical to use
645     <function>odr_malloc()</function> and <function>odr_reset()</function>.
646     For this purpose, the memory manager which also supports the &odr;
647     streams is made available in the NMEM module. The external interface
648     to this module is given in the <filename>nmem.h</filename> file.
649    </para>
650
651    <para>
652     The following prototypes are given:
653    </para>
654
655    <screen>
656     NMEM nmem_create(void);
657     void nmem_destroy(NMEM n);
658     void *nmem_malloc(NMEM n, int size);
659     void nmem_reset(NMEM n);
660     int nmem_total(NMEM n);
661     void nmem_init(void);
662    </screen>
663
664    <para>
665     The <function>nmem_create()</function> function returns a pointer to a
666     memory control handle, which can be released again by
667     <function>nmem_destroy()</function> when no longer needed.
668     The function <function>nmem_malloc()</function> allocates a block of
669     memory of the requested size. A call to <function>nmem_reset()</function>
670     or <function>nmem_destroy()</function> will release all memory allocated
671     on the handle since it was created (or since the last call to
672     <function>nmem_reset()</function>. The function
673     <function>nmem_total()</function> returns the number of bytes currently
674     allocated on the handle.
675    </para>
676
677    <note>
678     <para>
679      The nibble memory pool is shared amonst threads. POSIX
680      mutex'es and WIN32 Critical sections are introduced to keep the
681      module thread safe. On WIN32 function <function>nmem_init()</function>
682      initialises the Critical Section handle and should be called once
683      before any other nmem function is used.
684     </para>
685    </note>
686
687   </sect1>
688  </chapter>
689
690  <!-- Keep this comment at the end of the file
691  Local variables:
692  mode: sgml
693  sgml-omittag:t
694  sgml-shorttag:t
695  sgml-minimize-attributes:nil
696  sgml-always-quote-attributes:t
697  sgml-indent-step:1
698  sgml-indent-data:t
699  sgml-parent-document: "yaz.xml"
700  sgml-local-catalogs: "../../docbook/docbook.cat"
701  sgml-namecase-general:t
702  End:
703  -->