Initial commit
[yaz4j-moved-to-github.git] / dependencies / yaz-2.1.28 / 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.70.1"><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="id2570826"></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     Z_IdAuthentication *auth;
28     ODR stream;                /* encoding stream */
29     ODR print;                 /* printing stream */
30     Z_ReferenceId *referenceId;/* reference ID */
31     char *peer_name;           /* dns host of peer (client) */
32
33     char *implementation_id;
34     char *implementation_name;
35     char *implementation_version;
36     int (*bend_sort) (void *handle, bend_sort_rr *rr);
37     int (*bend_search) (void *handle, bend_search_rr *rr);
38     int (*bend_fetch) (void *handle, bend_fetch_rr *rr);
39     int (*bend_present) (void *handle, bend_present_rr *rr);
40     int (*bend_esrequest) (void *handle, bend_esrequest_rr *rr);
41     int (*bend_delete)(void *handle, bend_delete_rr *rr);
42     int (*bend_scan)(void *handle, bend_scan_rr *rr);
43     int (*bend_segment)(void *handle, bend_segment_rr *rr);
44
45     ODR decode;                 /* decoding stream */
46     /* character set and language negotiation - see include/yaz/z-charneg.h */
47     Z_CharSetandLanguageNegotiation *charneg_request;
48     Z_External *charneg_response;
49     int (*bend_srw_explain)(void *handle, bend_explain_rr *rr);
50     int (*bend_srw_scan)(void *handle, bend_scan_rr *rr);
51 } bend_initrequest;
52
53 typedef struct bend_initresult
54 {
55     int errcode;       /* 0==OK */
56     char *errstring;   /* system error string or NULL */
57     void *handle;      /* private handle to the backend module */
58 } bend_initresult;
59     </pre><p>
60      In general, the server frontend expects that the
61      <code class="literal">bend_*result</code> pointer that you return is valid at
62      least until the next call to a <code class="literal">bend_* function</code>.
63      This applies to all of the functions described herein. The parameter
64      structure passed to you in the call belongs to the server frontend, and
65      you should not make assumptions about its contents after the current
66      function call has completed. In other words, if you want to retain any
67      of the contents of a request structure, you should copy them.
68     </p><p>
69      The <code class="literal">errcode</code> should be zero if the initialization of
70      the backend went well. Any other value will be interpreted as an error.
71      The <code class="literal">errstring</code> isn't used in the current version, but
72      one option would be to stick it in the initResponse as a VisibleString.
73      The <code class="literal">handle</code> is the most important parameter. It should
74      be set to some value that uniquely identifies the current session to
75      the backend implementation. It is used by the frontend server in any
76      future calls to a backend function.
77      The typical use is to set it to point to a dynamically allocated state
78      structure that is private to your backend module.
79     </p><p>
80      The <code class="literal">auth</code> member holds the authentication information
81      part of the Z39.50 Initialize Request. Interpret this if your serves
82      requires authentication. 
83     </p><p>
84      The members <code class="literal">peer_name</code>,
85      <code class="literal">implementation_id</code>,
86      <code class="literal">implementation_name</code> and
87      <code class="literal">implementation_version</code> holds
88      DNS of client, ID of implementor, name
89      of client (Z39.50) implementation - and version.
90     </p><p>
91      The <code class="literal">bend_</code> - members are set to NULL when
92      <code class="function">bend_init</code> is called. Modify the pointers by
93      setting them to point to backend functions.
94     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2571032"></a>5.2. Search and retrieve</h3></div></div></div><p>We now describe the handlers that are required to support search -
95      and retrieve. You must support two functions - one for search - and one
96      for fetch (retrieval of one record). If desirable you can provide a
97      third handler which is called when a present request is received which
98      allows you to optimize retrieval of multiple-records.
99     </p><pre class="synopsis">
100 int (*bend_search) (void *handle, bend_search_rr *rr);
101
102 typedef struct {
103     char *setname;             /* name to give to this set */
104     int replace_set;           /* replace set, if it already exists */
105     int num_bases;             /* number of databases in list */
106     char **basenames;          /* databases to search */
107     Z_ReferenceId *referenceId;/* reference ID */
108     Z_Query *query;            /* query structure */
109     ODR stream;                /* encode stream */
110     ODR decode;                /* decode stream */
111     ODR print;                 /* print stream */
112
113     bend_request request;
114     bend_association association;
115     int *fd;
116     int hits;                  /* number of hits */
117     int errcode;               /* 0==OK */
118     char *errstring;           /* system error string or NULL */
119     Z_OtherInformation *search_info;
120 } bend_search_rr;
121     </pre><p>
122      The <code class="function">bend_search</code> handler is a fairly close
123      approximation of a protocol Z39.50 Search Request - and Response PDUs
124      The <code class="literal">setname</code> is the resultSetName from the protocol.
125      You are required to establish a mapping between the set name and whatever
126      your backend database likes to use.
127      Similarly, the <code class="literal">replace_set</code> is a boolean value
128      corresponding to the resultSetIndicator field in the protocol.
129      <code class="literal">num_bases/basenames</code> is a length of/array of character
130      pointers to the database names provided by the client.
131      The <code class="literal">query</code> is the full query structure as defined in
132      the protocol ASN.1 specification.
133      It can be either of the possible query types, and it's up to you to
134      determine if you can handle the provided query type.
135      Rather than reproduce the C interface here, we'll refer you to the
136      structure definitions in the file
137      <code class="filename">include/yaz/z-core.h</code>. If you want to look at the
138      attributeSetId OID of the RPN query, you can either match it against
139      your own internal tables, or you can use the
140      <code class="literal">oid_getentbyoid</code> function provided by YAZ.
141     </p><p>
142      The structure contains a number of hits, and an
143      <code class="literal">errcode/errstring</code> pair. If an error occurs
144      during the search, or if you're unhappy with the request, you should
145      set the errcode to a value from the BIB-1 diagnostic set. The value
146      will then be returned to the user in a nonsurrogate diagnostic record
147      in the response. The <code class="literal">errstring</code>, if provided, will
148      go in the addinfo field. Look at the protocol definition for the
149      defined error codes, and the suggested uses of the addinfo field.
150     </p><p>
151      The <code class="function">bend_search</code> handler is also called when
152      the frontend server receives a SRU SearchRetrieveRequest.
153      For SRU, a CQL query is usually provided by the client.
154      The CQL query is available as part of <code class="literal">Z_Query</code>
155      structure (note that CQL is now part of Z39.50 via an external).
156      To support CQL in existing implementations that only do Type-1,
157      we refer to the CQL-to-PQF tool described
158      <a href="tools.html#tools.cql.pqf" title="1.3.3. CQL to PQF conversion">here</a>.
159     </p><p>
160      To maintain backwards compatibility, the frontend server
161      of yaz always assume that error codes are BIB-1 diagnostics.
162      For SRU operation, a Bib-1 diagnostic code is mapped to
163      SRU diagnostic.
164     </p><pre class="synopsis">
165 int (*bend_fetch) (void *handle, bend_fetch_rr *rr);
166
167 typedef struct bend_fetch_rr {
168     char *setname;             /* set name */
169     int number;                /* record number */
170     Z_ReferenceId *referenceId;/* reference ID */
171     oid_value request_format;  /* One of the CLASS_RECSYN members */
172     int *request_format_raw;   /* same as above (raw OID) */
173     Z_RecordComposition *comp; /* Formatting instructions */
174     ODR stream;                /* encoding stream - memory source if req */
175     ODR print;                 /* printing stream */
176
177     char *basename;            /* name of database that provided record */
178     int len;                   /* length of record or -1 if structured */
179     char *record;              /* record */
180     int last_in_set;           /* is it?  */
181     oid_value output_format;   /* format */
182     int *output_format_raw;    /* used instead of above if not-null */
183     int errcode;               /* 0==success */
184     char *errstring;           /* system error string or NULL */
185     int surrogate_flag;        /* surrogate diagnostic */
186     char *schema;              /* string record schema input/output */
187 } bend_fetch_rr;
188     </pre><p>
189      The frontend server calls the <code class="function">bend_fetch</code> handler
190      when it needs database records to fulfill a Z39.50 Search Request, a
191      Z39.50 Present Request or a SRU SearchRetrieveRequest.
192      The <code class="literal">setname</code> is simply the name of the result set
193      that holds the reference to the desired record.
194      The <code class="literal">number</code> is the offset into the set (with 1
195      being the first record in the set). The <code class="literal">format</code> field
196      is the record format requested by the client (See
197      <a href="asn.oid.html" title="3. Object Identifiers">Section 3, &#8220;Object Identifiers&#8221;</a>).
198      The value <code class="literal">VAL_NONE</code> indicates that the client did
199      not request a specific format. The <code class="literal">stream</code> argument
200      is an <acronym class="acronym">ODR</acronym> stream which should be used for
201      allocating space for structured data records.
202      The stream will be reset when all records have been assembled, and
203      the response package has been transmitted.
204      For unstructured data, the backend is responsible for maintaining a
205      static or dynamic buffer for the record between calls.
206     </p><p>
207      If a SRU SearchRetrieveRequest is received by the frontend server,
208      the <code class="literal">referenceId</code> is NULL and the
209      <code class="literal">request_format</code> (transfer syntax) is XML (OID name 
210      <code class="literal">VAL_TEXT_XML</code>).
211      The schema for SRU is stored in both the
212      <code class="literal">Z_RecordComposition</code>
213      structure and <code class="literal">schema</code> (simple string).
214     </p><p>
215      In the structure, the <code class="literal">basename</code> is the name of the
216      database that holds the
217      record. <code class="literal">len</code> is the length of the record returned, in
218      bytes, and <code class="literal">record</code> is a pointer to the record.
219      <code class="literal">last_in_set</code> should be nonzero only if the record
220      returned is the last one in the given result set.
221      <code class="literal">errcode</code> and <code class="literal">errstring</code>, if
222      given, will be interpreted as a global error pertaining to the
223      set, and will be returned in a non-surrogate-diagnostic.
224      If you wish to return the error as a surrogate-diagnostic
225      (local error) you can do this by setting
226      <code class="literal">surrogate_flag</code> to 1 also.
227     </p><p>
228      If the <code class="literal">len</code> field has the value -1, then
229      <code class="literal">record</code> is assumed to point to a constructed data
230      type. The <code class="literal">format</code> field will be used to determine
231      which encoder should be used to serialize the data.
232     </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
233       If your backend generates structured records, it should use
234       <code class="function">odr_malloc()</code> on the provided stream for allocating
235       data: This allows the frontend server to keep track of the record sizes.
236      </p></div><p>
237      The <code class="literal">format</code> field is mapped to an object identifier
238      in the direct reference of the resulting EXTERNAL representation
239      of the record.
240     </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
241       The current version of YAZ only supports the direct reference mode.
242      </p></div><pre class="synopsis">
243 int (*bend_present) (void *handle, bend_present_rr *rr);
244
245 typedef struct {
246     char *setname;             /* set name */
247     int start;
248     int number;                /* record number */
249     oid_value format;          /* One of the CLASS_RECSYN members */
250     Z_ReferenceId *referenceId;/* reference ID */
251     Z_RecordComposition *comp; /* Formatting instructions */
252     ODR stream;                /* encoding stream */
253     ODR print;                 /* printing stream */
254     bend_request request;
255     bend_association association;
256
257     int hits;                  /* number of hits */
258     int errcode;               /* 0==OK */
259     char *errstring;           /* system error string or NULL */
260 } bend_present_rr;
261     </pre><p>
262      The <code class="function">bend_present</code> handler is called when
263      the server receives a Z39.50 Present Request.
264      The <code class="literal">setname</code>,
265      <code class="literal">start</code> and <code class="literal">number</code> is the
266      name of the result set - start position - and number of records to
267      be retrieved respectively. <code class="literal">format</code> and
268      <code class="literal">comp</code> is the preferred transfer syntax and element
269      specifications of the present request.
270     </p><p>
271      Note that this is handler serves as a supplement for
272      <code class="function">bend_fetch</code> and need not to be defined in order to
273      support search - and retrieve. 
274     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2571502"></a>5.3. Delete</h3></div></div></div><p>
275      For back-ends that supports delete of a result set only one handler
276      must be defined.
277     </p><pre class="synopsis">
278 int (*bend_delete)(void *handle, bend_delete_rr *rr);
279
280 typedef struct bend_delete_rr {
281     int function;
282     int num_setnames;
283     char **setnames;
284     Z_ReferenceId *referenceId;
285     int delete_status;      /* status for the whole operation */
286     int *statuses;          /* status each set - indexed as setnames */
287     ODR stream;
288     ODR print; 
289 } bend_delete_rr;
290     </pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
291       The delete set function definition is rather primitive, mostly because
292       we have had no practical need for it as of yet. If someone wants
293       to provide a full delete service, we'd be happy to add the
294       extra parameters that are required. Are there clients out there
295       that will actually delete sets they no longer need?
296      </p></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2571537"></a>5.4. scan</h3></div></div></div><p>
297      For servers that wish to offer the scan service one handler
298      must be defined.
299     </p><pre class="synopsis">
300 int (*bend_delete)(void *handle, bend_delete_rr *rr);
301
302 typedef enum {
303     BEND_SCAN_SUCCESS,  /* ok */
304     BEND_SCAN_PARTIAL   /* not all entries could be found */
305 } bend_scan_status;
306
307 typedef struct bend_scan_rr {
308     int num_bases;      /* number of elements in database list */
309     char **basenames;   /* databases to search */
310     oid_value attributeset;
311     Z_ReferenceId *referenceId; /* reference ID */
312     Z_AttributesPlusTerm *term;
313     ODR stream;         /* encoding stream - memory source if required */
314     ODR print;          /* printing stream */
315
316     int *step_size;     /* step size */
317     int term_position;  /* desired index of term in result list/returned */
318     int num_entries;    /* number of entries requested/returned */
319
320     struct scan_entry *entries;
321     bend_scan_status status;
322     int errcode;
323     char *errstring;
324     char *scanClause;   /* CQL scan clause */
325 } bend_scan_rr;
326     </pre><p>
327     This backend server handles both Z39.50 scan 
328     and SRU scan. In order for a handler to distinguish between SRU (CQL) scan 
329     Z39.50 Scan , it must check for a non-NULL value of 
330     <code class="literal">scanClause</code>.
331    </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
332      if designed today, it would be a choice using a union or similar,
333      but that would break binary compatibility with existing servers.
334     </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>