For OIDs use Odr_oid type everywhere, i.e. do not assume Odr_oid=int.
[yaz-moved-to-github.git] / doc / tools.xml
index 9ca9e24..3e711d0 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: tools.xml,v 1.51 2006-10-05 08:26:58 adam Exp $ -->
+<!-- $Id: tools.xml,v 1.62 2007-05-08 08:22:35 adam Exp $ -->
  <chapter id="tools"><title>Supporting Tools</title>
   
   <para>
     <literallayout>
      query ::= top-set query-struct.
 
-     top-set ::= &lsqb; '@attrset' string &rsqb;
+     top-set ::= [ '@attrset' string ]
 
      query-struct ::= attr-spec | simple | complex | '@term' term-type query
 
-     attr-spec ::= '@attr' &lsqb; string &rsqb; string query-struct
+     attr-spec ::= '@attr' [ string ] string query-struct
 
      complex ::= operator query-struct query-struct.
 
      <para>
       The CCL parser obeys the following grammar for the FIND argument.
       The syntax is annotated by in the lines prefixed by
-      <literal>&dash;&dash;</literal>.
+      <literal>--</literal>.
      </para>
 
      <screen>
       </para>
       <para><literal>@</literal><replaceable>directive</replaceable> <replaceable>value</replaceable>
       </para>
-      <table id="ccl.directives">
+      <table id="ccl.directives.table">
        <title>CCL directives</title>
        <tgroup cols="3">
        <colspec colwidth="2*" colname="name"></colspec>
       </table>
      </sect4>
     </sect3>
-    <sect3 id="ccl.apid">
+    <sect3 id="ccl.api">
      <title>CCL API</title>
      <para>
       All public definitions can be found in the header file
@@ -1263,6 +1263,13 @@ int cql_transform_FILE(cql_transform_t ct,
       <replaceable>value</replaceable> the attribute value.
      </para>
      <para>
+      The character <literal>*</literal> (asterisk) has special meaning
+      when used in the RPN pattern.
+      Each occurrence of <literal>*</literal> is substituted with the
+      CQL matching name (index, relation, qualifier etc).
+      This facility can be used to copy a CQL name verbatim to the RPN result.
+     </para>
+     <para>
       The following CQL patterns are recognized:
       <variablelist>
        <varlistentry><term>
@@ -1283,6 +1290,11 @@ int cql_transform_FILE(cql_transform_t ct,
           <literal>http://www.loc.gov/zing/cql/cql-indexes/v1.0/</literal>.
           If this pattern is not defined, the mapping will fail.
          </para>
+         <para>
+          The pattern, 
+          <literal>index.</literal><replaceable>set</replaceable><literal>.*</literal>
+          is used when no other index pattern is matched.
+        </para>
         </listitem>
        </varlistentry>
        <varlistentry><term>
@@ -1385,28 +1397,41 @@ int cql_transform_FILE(cql_transform_t ct,
          </para>
         </listitem>
        </varlistentry>
+
+       <varlistentry><term>
+         <literal>set</literal>
+        </term>
+        <listitem>
+         <para>
+          This specification defines a default CQL context set for index names.
+          The value on the right hand side is the URI for the set.
+         </para>
+        </listitem>
+       </varlistentry>
+
       </variablelist>
      </para>
-     <example id="example.cql.to.rpn.mapping"><title>CQL to RPN mapping file</title>
+     <example id="example.cql.to.rpn.mapping">
+      <title>CQL to RPN mapping file</title>
       <para>
        This simple file defines two context sets, three indexes and three
        relations, a position pattern and a default structure.
       </para>
       <programlisting><![CDATA[
-       set.cql    = http://www.loc.gov/zing/cql/context-sets/cql/v1.1/
-       set.dc     = http://www.loc.gov/zing/cql/dc-indexes/v1.0/
+       set.cql  = http://www.loc.gov/zing/cql/context-sets/cql/v1.1/
+       set.dc   = http://www.loc.gov/zing/cql/dc-indexes/v1.0/
 
        index.cql.serverChoice = 1=1016
        index.dc.title         = 1=4
        index.dc.subject       = 1=21
   
-       relation.<                 = 2=1
-       relation.eq                = 2=3
-       relation.scr               = 2=3
+       relation.<             = 2=1
+       relation.eq            = 2=3
+       relation.scr           = 2=3
 
-       position.any               = 3=3 6=1
+       position.any           = 3=3 6=1
 
-       structure.*                = 4=1
+       structure.*            = 4=1
 ]]>
       </programlisting>
       <para>
@@ -1441,6 +1466,49 @@ int cql_transform_FILE(cql_transform_t ct,
        </screen>
       </para>
      </example>
+     <example id="example.cql.to.rpn.string">
+      <title>CQL to RPN string attributes</title>
+      <para>
+       In this example we allow any index to be passed to RPN as
+       a use attribute.
+      </para>
+      <programlisting><![CDATA[
+       # Identifiers for prefixes used in this file. (index.*)
+       set.cql  = info:srw/cql-context-set/1/cql-v1.1
+       set.rpn  = http://bogus/rpn
+       set      = http://bogus/rpn
+
+       # The default index when none is specified by the query
+       index.cql.serverChoice     = 1=any
+
+       index.rpn.*                = 1=*
+       relation.eq                = 2=3
+       structure.*                = 4=1
+       position.any               = 3=3
+]]>
+      </programlisting>
+      <para>
+       The <literal>http://bogus/rpn</literal> context set is also the default
+       so we can make queries such as
+       <screen>
+        title = a
+       </screen>
+       which is converted to
+       <screen>
+        @attr 2=3 @attr 4=1 @attr 3=3 @attr 1=title "a"
+       </screen>
+      </para>
+     </example>
+     <example id="example.cql.to.rpn.bathprofile">
+      <title>CQL to RPN using Bath Profile</title>
+      <para>
+       The file <filename>etc/pqf.properties</filename> has mappings from
+       the Bath Profile and Dublin Core to RPN.
+       If YAZ is installed as a package it's usually located
+       in <filename>/usr/share/yaz/etc</filename> and part of the
+       development package, such as <literal>libyaz-dev</literal>.
+      </para>
+     </example>
     </sect3>
     <sect3 id="cql.xcql"><title>CQL to XCQL conversion</title>
      <para>
@@ -1473,30 +1541,186 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
 
    <para>
     The basic YAZ representation of an OID is an array of integers,
-    terminated with the value -1. The &odr; module provides two
-    utility-functions to create and copy this type of data elements:
+    terminated with the value -1. This integer is of type 
+    <literal>Odr_oid</literal>.
    </para>
-
+   <para>
+    Fundamental OID operations and the type <literal>Odr_oid</literal>
+    are defined in <filename>yaz/oid_util.h</filename>.
+   </para>
+   <para>
+    An OID can either be declared as a automatic variable or it can
+    allocated using the memory utilities or ODR/NMEM. It's
+    guaranteed that an OID can fit in <literal>OID_SIZE</literal> integers.
+   </para>
+   <example id="tools.oid.bib1.1"><title>Create OID on stack</title>
+    <para>
+     We can create an OID for the Bib-1 attribute set with:
+     <screen>
+      Odr_oid bib1[OID_SIZE];
+      bib1[0] = 1;
+      bib1[1] = 2;
+      bib1[2] = 840;
+      bib1[3] = 10003;
+      bib1[4] = 3;
+      bib1[5] = 1;
+      bib1[6] = -1;
+     </screen>
+    </para>
+   </example>
+   <para>
+    And OID may also be filled from a string-based representation using
+    dots (.). This is achieved by function
+    <screen>
+     int oid_dotstring_to_oid(const char *name, Odr_oid *oid);
+    </screen>
+    This functions returns 0 if name could be converted; -1 otherwise.
+   </para>
+   <example id="tools.oid.bib1.2"><title>Using oid_oiddotstring_to_oid</title>
+    <para>
+     We can fill the Bib-1 attribute set OID easier with:
+     <screen>
+      Odr_oid bib1[OID_SIZE];
+      oid_oiddotstring_to_oid("1.2.840.10003.3.1", bib1);
+     </screen>
+   </para>
+   </example>
+   <para>
+    We can also allocate an OID dynamically on a ODR stream with:
    <screen>
-    Odr_oid *odr_getoidbystr(ODR o, char *str);
+    Odr_oid *odr_getoidbystr(ODR o, const char *str);
    </screen>
+    This creates an OID from string-based representation using dots.
+    This function take an &odr; stream as parameter. This stream is used to
+    allocate memory for the data elements, which is released on a
+    subsequent call to <function>odr_reset()</function> on that stream.
+   </para>
+
+   <example id="tools.oid.bib1.3"><title>Using odr_getoidbystr</title>
+    <para>
+     We can create a OID for the Bib-1 attribute set with:
+     <screen>
+      Odr_oid *bib1 = odr_getoidbystr(odr, "1.2.840.10003.3.1");
+     </screen>
+    </para>
+   </example>
 
    <para>
-    Creates an OID based on a string-based representation using dots (.)
-    to separate elements in the OID.
+    The function
+    <screen>
+     char *oid_oid_to_dotstring(const Odr_oid *oid, char *oidbuf)
+    </screen>
+    does the reverse of <function>oid_oiddotstring_to_oid</function>. It
+    converts an OID to the string-based representation using dots.
+    The supplied char buffer <literal>oidbuf</literal> holds the resulting
+    string and must be at least <literal>OID_STR_MAX</literal> in size.
    </para>
 
-   <screen>
-    Odr_oid *odr_oiddup(ODR odr, Odr_oid *o);
-   </screen>
-
    <para>
-    Creates a copy of the OID referenced by the <emphasis>o</emphasis>
-    parameter.
-    Both functions take an &odr; stream as parameter. This stream is used to
-    allocate memory for the data elements, which is released on a
-    subsequent call to <function>odr_reset()</function> on that stream.
+    OIDs can be copied with <function>oid_oidcpy</function> which takes
+    two OID lists as arguments. Alternativly, an OID copy can be allocated
+    on a ODR stream with:
+    <screen>
+     Odr_oid *odr_oiddup(ODR odr, const Odr_oid *o);
+    </screen>
+   </para>
+   
+   <para>
+    OIDs can be compared with <function>oid_oidcmp</function> which returns
+    zero if the two OIDs provided are identical; non-zero otherwise.
    </para>
+   <sect2 id="tools.oid.database"><title>OID database</title>
+    <para>
+     From YAZ version 3 and later, the oident system has been replaced
+     by an OID database. OID database is a misnomer .. the old odient
+     system was also a database.
+    </para>
+    <para>
+     The OID database is really just a map between named Object Identifiers
+     (string) and their OID raw equivalents. Most operations either
+     convert from string to OID or other way around.
+    </para>
+    <para>
+     Unfortunately, whenever we supply a string we must also specify the 
+     <emphasis>OID class</emphasis>. The class is necessary because some
+     strings correspond to multiple OIDs. An example of such a string is
+     <literal>Bib-1</literal> which may either be an attribute-set 
+     or a diagnostic-set.
+    </para>
+    <para>
+     Applications using the YAZ database should include 
+     <filename>yaz/oid_db.h</filename>.
+    </para>
+    <para>
+     A YAZ database handle is of type <literal>yaz_oid_db_t</literal>.
+     Actually that's a pointer. You need not think deal with that.
+     YAZ has a built-in database which can be considered "constant" for
+     most purposes. 
+     We can get hold that by using function <function>yaz_oid_std</function>.
+    </para>
+    <para>
+     All functions with prefix <function>yaz_string_to_oid</function>
+     converts from class + string to OID. We have variants of this
+     operation due to different memory allocation strategies.
+    </para>
+    <para>
+     All functions with prefix
+     <function>yaz_oid_to_string</function> converts from OID to string
+     + class.
+    </para>
+
+    <example id="tools.oid.bib1.4"><title>Create OID with YAZ DB</title>
+     <para>
+      We can create an OID for the Bib-1 attribute set on the ODR stream
+      odr with:
+     <screen>
+        Odr_oid *bib1 = 
+         yaz_string_to_oid_odr(yaz_oid_std(), CLASS_ATTSET, "Bib-1", odr);
+      </screen>
+      This is more complex than using <function>odr_getoidbystr</function>.
+      You would only use <function>yaz_string_to_oid_odr</function> when the
+      string (here Bib-1) is supplied by a user or configuration.
+     </para>
+    </example>
+
+   </sect2>
+   <sect2 id="tools.oid.std"><title>Standard OIDs</title>
+     
+    <para>
+     All the object identifers in the standard OID database as returned
+     by <function>yaz_oid_std</function> can referenced directly in a
+     program as a constant OID.
+     Each constant OID is prefixed with <literal>yaz_oid_</literal> -
+     followed by OID class (lowercase) - then by OID name (normalized and
+     lowercase).
+    </para>
+    <para>
+     See <xref linkend="list-oids"/> for list of all object identifiers
+     built into YAZ.
+     These are declared in <filename>yaz/oid_std.h</filename> but are
+     included by <filename>yaz/oid_db.h</filename> as well.
+    </para>
+
+    <example id="tools.oid.bib1.5"><title>Use a built-in OID</title>
+     <para>
+      We can allocate our own OID filled with the constant OID for
+      Bib-1 with:
+      <screen>
+        Odr_oid *bib1 = odr_oiddup(o, yaz_oid_attset_bib1);
+      </screen>
+     </para>
+    </example>
+   </sect2>
+
+   <sect2 id="tools.oid.oident"><title>OID oident</title>
+
+   <note>
+    <para>
+     The oident utility has been removed from YAZ version 3. This
+     sub section only applies to YAZ version 2.
+    </para>
+   </note>
 
    <para>
     The OID module provides a higher-level representation of the
@@ -1730,18 +1954,6 @@ typedef struct oident
     <literal>oidbuf</literal> and returning its address.
    </para>
 
-   <para>
-    Finally, the module provides the following utility functions, whose
-    meaning should be obvious:
-   </para>
-
-   <screen>
-    void oid_oidcpy(int *t, int *s);
-    void oid_oidcat(int *t, int *s);
-    int oid_oidcmp(int *o1, int *o2);
-    int oid_oidlen(int *o);
-   </screen>
-
    <note>
     <para>
      The OID module has been criticized - and perhaps rightly so
@@ -1758,8 +1970,8 @@ typedef struct oident
     </para>
    </note>
 
+   </sect2>
   </sect1>
-
   <sect1 id="tools.nmem"><title>Nibble Memory</title>
 
    <para>
@@ -2030,7 +2242,7 @@ typedef struct oident
      </varlistentry>
 
      <varlistentry>
-      <term>YAZ_MARC_MARXML</term>
+      <term>YAZ_MARC_MARCXML</term>
       <listitem>
        <para>
        The resulting record is converted to MARCXML.
@@ -2079,6 +2291,267 @@ typedef struct oident
    </example>
   </sect1>
 
+  <sect1 id="tools.retrieval">
+   <title>Retrieval Facility</title>
+   <para>
+    YAZ version 2.1.20 or later includes a Retrieval facility tool
+    which allows a SRU/Z39.50 to describe itself and perform record
+    conversions. The idea is the following:
+    
+    <itemizedlist>
+     <listitem>
+      <para>
+       An SRU/Z39.50 client sends a retrieval request which includes
+       a combination of the following parameters: syntax (format),
+       schema (or element set name).
+      </para>
+     </listitem>
+
+     <listitem>
+      <para>
+       The retrieval facility is invoked with parameters in a
+       server/proxy. The retrieval facility matches the parameters a set of
+       "supported" retrieval types.
+       If there is no match, the retrieval signals an error
+       (syntax and / or schema not supported).
+      </para>
+     </listitem>
+
+     <listitem>
+      <para>
+       For a successful match, the backend is invoked with the same
+       or altered retrieval parameters (syntax, schema). If
+       a record is received from the backend, it is converted to the
+       frontend name / syntax.
+      </para>
+     </listitem>
+
+     <listitem>
+      <para>
+       The resulting record is sent back the client and tagged with
+       the frontend syntax / schema.
+      </para>
+     </listitem>
+
+    </itemizedlist>
+   </para>
+   <para>
+    The Retrieval facility is driven by an XML configuration. The
+    configuration is neither Z39.50 ZeeRex or SRU ZeeRex. But it
+    should be easy to generate both of them from the XML configuration.
+    (unfortunately the two versions
+    of ZeeRex differ substantially in this regard).
+   </para>
+   <sect2 id="tools.retrieval.format">
+    <title>Retrieval XML format</title>
+    <para>
+     All elements should be covered by namespace 
+     <literal>http://indexdata.com/yaz</literal> .
+     The root element node must be <literal>retrievalinfo</literal>.
+    </para>
+    <para>
+     The <literal>retrievalinfo</literal> must include one or
+     more <literal>retrieval</literal> elements. Each 
+    <literal>retrieval</literal> defines specific combination of
+     syntax, name and identifier supported by this retrieval service.
+    </para>
+    <para>
+     The <literal>retrieval</literal> element may include any of the
+     following attributes:
+     <variablelist>
+      <varlistentry><term><literal>syntax</literal> (REQUIRED)</term>
+       <listitem>
+        <para>
+         Defines the record syntax. Possible values is any
+         of the names defined in YAZ' OID database or a raw
+         OID in (n.n ... n).
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry><term><literal>name</literal> (OPTIONAL)</term>
+       <listitem>
+        <para>
+         Defines the name of the retrieval format. This can be
+         any string. For SRU, the value, is equivalent to schema (short-hand);
+         for Z39.50 it's equivalent to simple element set name. 
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry><term><literal>identifier</literal> (OPTIONAL)</term>
+       <listitem>
+        <para>
+         Defines the URI schema name of the retrieval format. This can be
+         any string. For SRU, the value, is equivalent to URI schema.
+         For Z39.50, there is no equivalent.
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+    </para>
+    <para>
+     The <literal>retrieval</literal> may include one 
+     <literal>backend</literal> element. If a <literal>backend</literal>
+     element is given, it specifies how the records are retrieved by
+     some backend and how the records are converted from the backend to
+     the "frontend".
+    </para>
+    <para>
+     The attributes, <literal>name</literal> and <literal>syntax</literal>
+     may be specified for the <literal>backend</literal> element. These
+     semantics of these attributes is equivalent to those for the
+     <literal>retrieval</literal>. However, these values are passed to
+     the "backend".
+    </para>
+    <para>
+     The <literal>backend</literal> element may includes one or more
+     conversion instructions (as children elements). The supported
+     conversions are:
+     <variablelist>
+      <varlistentry><term><literal>marc</literal></term>
+       <listitem>
+        <para>
+         The <literal>marc</literal> element specifies a conversion 
+         to - and from ISO2709 encoded MARC and 
+         <ulink url="&url.marcxml;">&marcxml;</ulink>/MarcXchange.
+         The following attributes may be specified:
+
+         <variablelist>
+          <varlistentry><term><literal>inputformat</literal> (REQUIRED)</term>
+           <listitem>
+            <para>
+             Format of input. Supported values are 
+            <literal>marc</literal> (for ISO2709); and <literal>xml</literal>
+             for MARCXML/MarcXchange.
+            </para>
+           </listitem>
+          </varlistentry>
+
+          <varlistentry><term><literal>outputformat</literal> (REQUIRED)</term>
+           <listitem>
+            <para>
+             Format of output. Supported values are 
+            <literal>line</literal> (MARC line format); 
+            <literal>marcxml</literal> (for MARCXML),
+            <literal>marc</literal> (ISO2709),
+            <literal>marcxhcange</literal> (for MarcXchange).
+            </para>
+           </listitem>
+          </varlistentry>
+
+          <varlistentry><term><literal>inputcharset</literal> (OPTIONAL)</term>
+           <listitem>
+            <para>
+             Encoding of input. For XML input formats, this need not
+             be given, but for ISO2709 based inputformats, this should
+             be set to the encoding used. For MARC21 records, a common
+             inputcharset value  would be <literal>marc-8</literal>.
+            </para>
+           </listitem>
+          </varlistentry>
+
+          <varlistentry><term><literal>outputcharset</literal> (OPTIONAL)</term>
+           <listitem>
+            <para>
+             Encoding of output. If outputformat is XML based, it is
+             strongly recommened to use <literal>utf-8</literal>.
+            </para>
+           </listitem>
+          </varlistentry>
+
+         </variablelist>
+        </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry><term><literal>xslt</literal></term>
+       <listitem>
+        <para>
+         The <literal>xslt</literal> element specifies a conversion
+         via &xslt;. The following attributes may be specified:
+
+         <variablelist>
+          <varlistentry><term><literal>stylesheet</literal> (REQUIRED)</term>
+           <listitem>
+            <para>
+             Stylesheet file.
+            </para>
+           </listitem>
+          </varlistentry>
+         </variablelist>
+
+        </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+    </para>
+   </sect2>
+   <sect2 id="tools.retrieval.examples">
+    <title>Retrieval Facility Examples</title>
+    <example id="tools.retrieval.marc21">
+     <title>MARC21 backend</title>
+     <para>
+      A typical way to use the retrieval facility is to enable XML
+      for servers that only supports ISO2709 encoded MARC21 records.
+     </para>
+     <programlisting><![CDATA[
+     <retrievalinfo>
+       <retrieval syntax="usmarc" name="F"/>
+       <retrieval syntax="usmarc" name="B"/>
+       <retrieval syntax="xml" name="marcxml"
+                 identifier="info:srw/schema/1/marcxml-v1.1">
+         <backend syntax="usmarc" name="F">
+          <marc inputformat="marc" outputformat="marcxml"
+                inputcharset="marc-8"/>
+        </backend>
+       </retrieval>
+       <retrieval syntax="xml" name="dc">
+         <backend syntax="usmarc" name="F">
+          <marc inputformat="marc" outputformat="marcxml"
+                inputcharset="marc-8"/>
+           <xslt stylesheet="MARC21slim2DC.xsl"/>
+        </backend>
+       </retrieval>
+     </retrievalinfo>
+]]>
+     </programlisting>
+     <para>
+      This means that our frontend supports:
+      <itemizedlist>
+       <listitem>
+        <para>
+         MARC21 F(ull) records.
+        </para>
+       </listitem>
+       <listitem>
+        <para>
+         MARC21 B(rief) records.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         MARCXML records.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         Dublin core records.
+        </para>
+       </listitem>
+      </itemizedlist>
+     </para>
+    </example>
+   </sect2>
+   <sect2 id="tools.retrieval.api">
+    <title>API</title>
+    <para>
+     It should be easy to use the retrieval systems from applications. Refer
+     to the headers
+     <filename>yaz/retrieval.h</filename> and 
+     <filename>yaz/record_conv.h</filename>.
+    </para>
+   </sect2>
+  </sect1>
  </chapter>
  
  <!-- Keep this comment at the end of the file