Initial commit
[yaz4j-moved-to-github.git] / dependencies / yaz_3.0.14 / doc / server.backendfunctions.html
1 <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>5. The Backend Functions</title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2"><link rel="start" href="index.html" title="YAZ User's Guide and Reference"><link rel="up" href="server.html" title="Chapter 4. Generic server"><link rel="prev" href="server.main.html" title="4. Your main() Routine"><link rel="next" href="server.invocation.html" title="6. Application Invocation"></head><body><link rel="stylesheet" type="text/css" href="common/style1.css"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">5. The Backend Functions</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="server.main.html">Prev</a> </td><th width="60%" align="center">Chapter 4. Generic server</th><td width="20%" align="right"> <a accesskey="n" href="server.invocation.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="server.backendfunctions"></a>5. The Backend Functions</h2></div></div></div><p>
2     For each service of the protocol, the backend interface declares one or
3     two functions. You are required to provide implementations of the
4     functions representing the services that you wish to implement.
5    </p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="server.init"></a>5.1. Init</h3></div></div></div><pre class="synopsis">
6 bend_initresult (*bend_init)(bend_initrequest *r);
7     </pre><p>
8      This handler is called once for each new connection request, after
9      a new process/thread has been created, and an Initialize Request has
10      been received from the client. The pointer to the
11      <code class="function">bend_init</code> handler is passed in the call to
12      <code class="function">statserv_start</code>.
13     </p><p>
14      This handler is also called when operating in SRU mode - when
15      a connection has been made (even though SRU does not offer
16      this service).
17     </p><p>
18      Unlike previous versions of YAZ, the <code class="function">bend_init</code> also
19      serves as a handler that defines the Z39.50 services that the backend
20      wish to support. Pointers to <span class="emphasis"><em>all</em></span> service handlers,
21      including search - and fetch must be specified here in this handler.
22     </p><p>
23      The request  - and result structures are defined as
24     </p><pre class="synopsis">
25 typedef struct bend_initrequest
26 {
27     /** \brief user/name/password to be read */
28     Z_IdAuthentication *auth; 
29     /** \brief encoding stream (for results) */
30     ODR stream;
31     /** \brief printing stream */
32     ODR print;
33     /** \brief decoding stream (use stream for results) */
34     ODR decode; 
35     /** \brief reference ID */
36     Z_ReferenceId *referenceId;
37     /** \brief peer address of client */
38     char *peer_name;           
39     
40     /** \brief character set and language negotiation 
41
42     see include/yaz/z-charneg.h 
43     */
44     Z_CharSetandLanguageNegotiation *charneg_request;
45
46     /** \brief character negotiation response */
47     Z_External *charneg_response;
48
49     /** \brief character set (encoding) for query terms 
50         
51     This is NULL by default. It should be set to the native character
52     set that the backend assumes for query terms */
53     char *query_charset;      
54
55     /** \brief whehter query_charset also applies to recors 
56     
57     Is 0 (No) by default. Set to 1 (yes) if records is in the same
58     character set as queries. If in doubt, use 0 (No).
59     */
60     int records_in_same_charset;
61
62     char *implementation_id;
63     char *implementation_name;
64     char *implementation_version;
65
66     /** \brief Z39.50 sort handler */
67     int (*bend_sort)(void *handle, bend_sort_rr *rr);
68     /** \brief SRU/Z39.50 search handler */
69     int (*bend_search)(void *handle, bend_search_rr *rr);
70     /** \brief SRU/Z39.50 fetch handler */
71     int (*bend_fetch)(void *handle, bend_fetch_rr *rr);
72     /** \brief SRU/Z39.50 present handler */
73     int (*bend_present)(void *handle, bend_present_rr *rr);
74     /** \brief Z39.50 extended services handler */
75     int (*bend_esrequest) (void *handle, bend_esrequest_rr *rr);
76     /** \brief Z39.50 delete result set handler */
77     int (*bend_delete)(void *handle, bend_delete_rr *rr);
78     /** \brief Z39.50 scan handler */
79     int (*bend_scan)(void *handle, bend_scan_rr *rr);
80     /** \brief Z39.50 segment facility handler */
81     int (*bend_segment)(void *handle, bend_segment_rr *rr);
82     /** \brief SRU explain handler */
83     int (*bend_explain)(void *handle, bend_explain_rr *rr);
84     /** \brief SRU scan handler */
85     int (*bend_srw_scan)(void *handle, bend_scan_rr *rr);
86     /** \brief SRU record update handler */
87     int (*bend_srw_update)(void *handle, bend_update_rr *rr);
88
89 } bend_initrequest;
90
91 typedef struct bend_initresult
92 {
93     int errcode;               /* 0==OK */
94     char *errstring;           /* system error string or NULL */
95     void *handle;              /* private handle to the backend module */
96 } bend_initresult;
97     </pre><p>
98      In general, the server frontend expects that the
99      <code class="literal">bend_*result</code> pointer that you return is valid at
100      least until the next call to a <code class="literal">bend_* function</code>.
101      This applies to all of the functions described herein. The parameter
102      structure passed to you in the call belongs to the server frontend, and
103      you should not make assumptions about its contents after the current
104      function call has completed. In other words, if you want to retain any
105      of the contents of a request structure, you should copy them.
106     </p><p>
107      The <code class="literal">errcode</code> should be zero if the initialization of
108      the backend went well. Any other value will be interpreted as an error.
109      The <code class="literal">errstring</code> isn't used in the current version, but
110      one option would be to stick it in the initResponse as a VisibleString.
111      The <code class="literal">handle</code> is the most important parameter. It should
112      be set to some value that uniquely identifies the current session to
113      the backend implementation. It is used by the frontend server in any
114      future calls to a backend function.
115      The typical use is to set it to point to a dynamically allocated state
116      structure that is private to your backend module.
117     </p><p>
118      The <code class="literal">auth</code> member holds the authentication information
119      part of the Z39.50 Initialize Request. Interpret this if your serves
120      requires authentication. 
121     </p><p>
122      The members <code class="literal">peer_name</code>,
123      <code class="literal">implementation_id</code>,
124      <code class="literal">implementation_name</code> and
125      <code class="literal">implementation_version</code> holds
126      DNS of client, ID of implementor, name
127      of client (Z39.50) implementation - and version.
128     </p><p>
129      The <code class="literal">bend_</code> - members are set to NULL when
130      <code class="function">bend_init</code> is called. Modify the pointers by
131      setting them to point to backend functions.
132     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="server.search.retrieve"></a>5.2. Search and Retrieve</h3></div></div></div><p>We now describe the handlers that are required to support search -
133      and retrieve. You must support two functions - one for search - and one
134      for fetch (retrieval of one record). If desirable you can provide a
135      third handler which is called when a present request is received which
136      allows you to optimize retrieval of multiple-records.
137     </p><pre class="synopsis">
138 int (*bend_search) (void *handle, bend_search_rr *rr);
139
140 typedef struct {
141     char *setname;             /* name to give to this set */
142     int replace_set;           /* replace set, if it already exists */
143     int num_bases;             /* number of databases in list */
144     char **basenames;          /* databases to search */
145     Z_ReferenceId *referenceId;/* reference ID */
146     Z_Query *query;            /* query structure */
147     ODR stream;                /* encode stream */
148     ODR decode;                /* decode stream */
149     ODR print;                 /* print stream */
150
151     bend_request request;
152     bend_association association;
153     int *fd;
154     int hits;                  /* number of hits */
155     int errcode;               /* 0==OK */
156     char *errstring;           /* system error string or NULL */
157     Z_OtherInformation *search_info; /* additional search info */
158     char *srw_sortKeys;        /* holds SRU/SRW sortKeys info */
159     char *srw_setname;         /* holds SRU/SRW generated resultsetID */
160     int *srw_setnameIdleTime;  /* holds SRU/SRW life-time */
161     int estimated_hit_count;   /* if hit count is estimated */
162     int partial_resultset;     /* if result set is partial */
163 } bend_search_rr;
164     </pre><p>
165      The <code class="function">bend_search</code> handler is a fairly close
166      approximation of a protocol Z39.50 Search Request - and Response PDUs
167      The <code class="literal">setname</code> is the resultSetName from the protocol.
168      You are required to establish a mapping between the set name and whatever
169      your backend database likes to use.
170      Similarly, the <code class="literal">replace_set</code> is a boolean value
171      corresponding to the resultSetIndicator field in the protocol.
172      <code class="literal">num_bases/basenames</code> is a length of/array of character
173      pointers to the database names provided by the client.
174      The <code class="literal">query</code> is the full query structure as defined in
175      the protocol ASN.1 specification.
176      It can be either of the possible query types, and it's up to you to
177      determine if you can handle the provided query type.
178      Rather than reproduce the C interface here, we'll refer you to the
179      structure definitions in the file
180      <code class="filename">include/yaz/z-core.h</code>. If you want to look at the
181      attributeSetId OID of the RPN query, you can either match it against
182      your own internal tables, or you can use the
183      <code class="literal">oid_getentbyoid</code> function provided by YAZ.
184     </p><p>
185      The structure contains a number of hits, and an
186      <code class="literal">errcode/errstring</code> pair. If an error occurs
187      during the search, or if you're unhappy with the request, you should
188      set the errcode to a value from the BIB-1 diagnostic set. The value
189      will then be returned to the user in a nonsurrogate diagnostic record
190      in the response. The <code class="literal">errstring</code>, if provided, will
191      go in the addinfo field. Look at the protocol definition for the
192      defined error codes, and the suggested uses of the addinfo field.
193     </p><p>
194      The <code class="function">bend_search</code> handler is also called when
195      the frontend server receives a SRU SearchRetrieveRequest.
196      For SRU, a CQL query is usually provided by the client.
197      The CQL query is available as part of <code class="literal">Z_Query</code>
198      structure (note that CQL is now part of Z39.50 via an external).
199      To support CQL in existing implementations that only do Type-1,
200      we refer to the CQL-to-PQF tool described
201      <a class="link" href="tools.html#cql.to.pqf" title="1.3.3. CQL to PQF conversion">here</a>.
202     </p><p>
203      To maintain backwards compatibility, the frontend server
204      of yaz always assume that error codes are BIB-1 diagnostics.
205      For SRU operation, a Bib-1 diagnostic code is mapped to
206      SRU diagnostic.
207     </p><pre class="synopsis">
208 int (*bend_fetch) (void *handle, bend_fetch_rr *rr);
209
210 typedef struct bend_fetch_rr {
211     char *setname;             /* set name */
212     int number;                /* record number */
213     Z_ReferenceId *referenceId;/* reference ID */
214     Odr_oid *request_format;        /* format, transfer syntax (OID) */
215     Z_RecordComposition *comp; /* Formatting instructions */
216     ODR stream;                /* encoding stream - memory source if req */
217     ODR print;                 /* printing stream */
218
219     char *basename;            /* name of database that provided record */
220     int len;                   /* length of record or -1 if structured */
221     char *record;              /* record */
222     int last_in_set;           /* is it?  */
223     Odr_oid *output_format;        /* response format/syntax (OID) */
224     int errcode;               /* 0==success */
225     char *errstring;           /* system error string or NULL */
226     int surrogate_flag;        /* surrogate diagnostic */
227     char *schema;              /* string record schema input/output */
228 } bend_fetch_rr;
229     </pre><p>
230      The frontend server calls the <code class="function">bend_fetch</code> handler
231      when it needs database records to fulfill a Z39.50 Search Request, a
232      Z39.50 Present Request or a SRU SearchRetrieveRequest.
233      The <code class="literal">setname</code> is simply the name of the result set
234      that holds the reference to the desired record.
235      The <code class="literal">number</code> is the offset into the set (with 1
236      being the first record in the set). The <code class="literal">format</code> field
237      is the record format requested by the client (See
238      <a class="xref" href="asn.oid.html" title="3. Object Identifiers (YAZ 2)">Section 3, &#8220;Object Identifiers (YAZ 2)&#8221;</a>).
239      A value of NULL for <code class="literal">format</code> indicates that the
240      client did not request a specific format.
241      The <code class="literal">stream</code> argument is an <acronym class="acronym">ODR</acronym> stream which
242      should be used for allocating space for structured data records.
243      The stream will be reset when all records have been assembled, and
244      the response package has been transmitted.
245      For unstructured data, the backend is responsible for maintaining a
246      static or dynamic buffer for the record between calls.
247     </p><p>
248      If a SRU SearchRetrieveRequest is received by the frontend server,
249      the <code class="literal">referenceId</code> is NULL and the
250      <code class="literal">format</code> (transfer syntax) is the OID for XML.
251      The schema for SRU is stored in both the
252      <code class="literal">Z_RecordComposition</code>
253      structure and <code class="literal">schema</code> (simple string).
254     </p><p>
255      In the structure, the <code class="literal">basename</code> is the name of the
256      database that holds the
257      record. <code class="literal">len</code> is the length of the record returned, in
258      bytes, and <code class="literal">record</code> is a pointer to the record.
259      <code class="literal">last_in_set</code> should be nonzero only if the record
260      returned is the last one in the given result set.
261      <code class="literal">errcode</code> and <code class="literal">errstring</code>, if
262      given, will be interpreted as a global error pertaining to the
263      set, and will be returned in a non-surrogate-diagnostic.
264      If you wish to return the error as a surrogate-diagnostic
265      (local error) you can do this by setting
266      <code class="literal">surrogate_flag</code> to 1 also.
267     </p><p>
268      If the <code class="literal">len</code> field has the value -1, then
269      <code class="literal">record</code> is assumed to point to a constructed data
270      type. The <code class="literal">format</code> field will be used to determine
271      which encoder should be used to serialize the data.
272     </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
273       If your backend generates structured records, it should use
274       <code class="function">odr_malloc()</code> on the provided stream for allocating
275       data: This allows the frontend server to keep track of the record sizes.
276      </p></div><p>
277      The <code class="literal">format</code> field is mapped to an object identifier
278      in the direct reference of the resulting EXTERNAL representation
279      of the record.
280     </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
281       The current version of YAZ only supports the direct reference mode.
282      </p></div><pre class="synopsis">
283 int (*bend_present) (void *handle, bend_present_rr *rr);
284
285 typedef struct {
286     char *setname;             /* set name */
287     int start;
288     int number;                /* record number */
289     Odr_oid *format;           /* format, transfer syntax (OID) */
290     Z_ReferenceId *referenceId;/* reference ID */
291     Z_RecordComposition *comp; /* Formatting instructions */
292     ODR stream;                /* encoding stream - memory source if required */
293     ODR print;                 /* printing stream */
294     bend_request request;
295     bend_association association;
296
297     int hits;                  /* number of hits */
298     int errcode;               /* 0==OK */
299     char *errstring;           /* system error string or NULL */
300 } bend_present_rr;
301     </pre><p>
302      The <code class="function">bend_present</code> handler is called when
303      the server receives a Z39.50 Present Request.
304      The <code class="literal">setname</code>,
305      <code class="literal">start</code> and <code class="literal">number</code> is the
306      name of the result set - start position - and number of records to
307      be retrieved respectively. <code class="literal">format</code> and
308      <code class="literal">comp</code> is the preferred transfer syntax and element
309      specifications of the present request.
310     </p><p>
311      Note that this is handler serves as a supplement for
312      <code class="function">bend_fetch</code> and need not to be defined in order to
313      support search - and retrieve. 
314     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="server.delete"></a>5.3. Delete</h3></div></div></div><p>
315      For back-ends that supports delete of a result set only one handler
316      must be defined.
317     </p><pre class="synopsis">
318 int (*bend_delete)(void *handle, bend_delete_rr *rr);
319
320 typedef struct bend_delete_rr {
321     int function;
322     int num_setnames;
323     char **setnames;
324     Z_ReferenceId *referenceId;
325     int delete_status;      /* status for the whole operation */
326     int *statuses;          /* status each set - indexed as setnames */
327     ODR stream;
328     ODR print; 
329 } bend_delete_rr;
330     </pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
331       The delete set function definition is rather primitive, mostly because
332       we have had no practical need for it as of yet. If someone wants
333       to provide a full delete service, we'd be happy to add the
334       extra parameters that are required. Are there clients out there
335       that will actually delete sets they no longer need?
336      </p></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="server.scan"></a>5.4. Scan</h3></div></div></div><p>
337      For servers that wish to offer the scan service one handler
338      must be defined.
339     </p><pre class="synopsis">
340 int (*bend_scan)(void *handle, bend_scan_rr *rr);
341
342 typedef enum {
343     BEND_SCAN_SUCCESS,  /* ok */
344     BEND_SCAN_PARTIAL   /* not all entries could be found */
345 } bend_scan_status;
346
347 typedef struct bend_scan_rr {
348     int num_bases;      /* number of elements in databaselist */
349     char **basenames;   /* databases to search */
350     Odr_oid *attributeset;
351     Z_ReferenceId *referenceId; /* reference ID */
352     Z_AttributesPlusTerm *term;
353     ODR stream;         /* encoding stream - memory source if required */
354     ODR print;          /* printing stream */
355
356     int *step_size;     /* step size */
357     int term_position;  /* desired index of term in result list/returned */
358     int num_entries;    /* number of entries requested/returned */
359
360     /* scan term entries. The called handler does not have
361        to allocate this. Size of entries is num_entries (see above) */
362     struct scan_entry *entries;
363     bend_scan_status status;
364     int errcode;
365     char *errstring;
366     char *scanClause;   /* CQL scan clause */
367     char *setname;      /* Scan in result set (NULL if omitted) */
368 } bend_scan_rr;
369     </pre><p>
370     This backend server handles both Z39.50 scan 
371     and SRU scan. In order for a handler to distinguish between SRU (CQL) scan 
372     Z39.50 Scan , it must check for a non-NULL value of 
373     <code class="literal">scanClause</code>.
374    </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
375      if designed today, it would be a choice using a union or similar,
376      but that would break binary compatibility with existing servers.
377     </p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="server.main.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="server.invocation.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. Your main() Routine </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 6. Application Invocation</td></tr></table></div></body></html>