Added method Hash2grs into GRS1 module.
[simpleserver-moved-to-github.git] / SimpleServer.pm
index d62c45a..523cf75 100644 (file)
@@ -1,3 +1,35 @@
+##
+##  Copyright (c) 2000, Index Data.
+##
+##  Permission to use, copy, modify, distribute, and sell this software and
+##  its documentation, in whole or in part, for any purpose, is hereby granted,
+##  provided that:
+##
+##  1. This copyright and permission notice appear in all copies of the
+##  software and its documentation. Notices of copyright or attribution
+##  which appear at the beginning of any file must remain unchanged.
+##
+##  2. The name of Index Data or the individual authors may not be used to
+##  endorse or promote products derived from this software without specific
+##  prior written permission.
+##
+##  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
+##  EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+##  WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+##  IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+##  INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
+##  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
+##  NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+##  LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+##  OF THIS SOFTWARE.
+##
+##
+
+## $Log: SimpleServer.pm,v $
+## Revision 1.6  2001-03-13 14:17:15  sondberg
+## Added support for GRS-1.
+##
+
 package Net::Z3950::SimpleServer;
 
 use strict;
@@ -37,6 +69,7 @@ sub new {
        $self->{SEARCH} = $args->{SEARCH} || croak "SimpleServer.pm: ERROR: Unspecified search handler";
        $self->{FETCH} = $args->{FETCH} || croak "SimpleServer.pm: ERROR: Unspecified fetch handler";
        $self->{CLOSE} = $args->{CLOSE};
+       $self->{PRESENT} = $args->{PRESENT};
 
        bless $self, $class;
        return $self;
@@ -55,6 +88,9 @@ sub launch_server {
        if (defined($self->{CLOSE})) {
                set_close_handler($self->{CLOSE});
        }
+       if (defined($self->{PRESENT})) {
+               set_present_handler($self->{PRESENT});
+       }
 
        start_server(@args);
 }
@@ -68,11 +104,11 @@ __END__
 
 =head1 NAME
 
-Zfront - Simple Perl API for building Z39.50 servers. 
+Net::Z3950::SimpleServer - Simple Perl API for building Z39.50 servers. 
 
 =head1 SYNOPSIS
 
-  use Zfront;
+  use Net::Z3950::SimpleServer;
 
   sub my_search_handler {
        my $args = shift;
@@ -95,7 +131,6 @@ Zfront - Simple Perl API for building Z39.50 servers.
        my $record = fetch_a_record($args->{OFFSET);
 
        $args->{RECORD} = $record;
-       $args->{LEN} = length($record);
        if (number_of_hits() == $args->{OFFSET}) {      ## Last record in set?
                $args->{LAST} = 1;
        } else {
@@ -106,16 +141,19 @@ Zfront - Simple Perl API for building Z39.50 servers.
 
   ## Register custom event handlers:
 
-  Zfront::set_search_handler(\&my_search_handler);
-  Zfront::set_fetch_handler(\&my_fetch_handler);
-
+  my $handle = Net::Z3950::SimpleServer->new({
+                                               INIT   =>  \&my_init_handler,
+                                               CLOSE  =>  \&my_close_handler,
+                                               SEARCH =>  \&my_search_handler,
+                                               FETCH  =>  \&my_fetch_handler
+                                            });
   ## Launch server:
 
-  Zfront::start_server("mytestserver", @ARGV);
+  $handle->launch_server("ztest.pl", @ARGV);
 
 =head1 DESCRIPTION
 
-The Zfront module is a tool for constructing Z39.50 "Information
+The SimpleServer module is a tool for constructing Z39.50 "Information
 Retrieval" servers in Perl. The module is easy to use, but it
 does help to have an understanding of the Z39.50 query
 structure and the construction of structured retrieval records.
@@ -141,6 +179,7 @@ of events:
 
   - Initialize request
   - Search request
+  - Present request
   - Fetching of records
   - Closing down connection
 
@@ -156,17 +195,19 @@ the entries of these hashes are to be considered input and others
 output parameters.
 
 The Perl programmer specifies the event handles for the server by
-means of the subroutines
+means of the the SimpleServer object constructor
 
-  Zfront::set_init_handler(\&my_init_handler);
-  Zfront::set_search_handler(\&my_search_handler);
-  Zfront::set_fetch_handler(\&my_fetch_handler);
-  Zfront::set_close_handler(\&my_close_handler);
+  my $handle = Net::Z3950::SimpleServer->new({
+               INIT    =>      \&my_init_handler,
+               CLOSE   =>      \&my_close_handler,
+               SEARCH  =>      \&my_search_handler,
+               PRESENT =>      \&my_present_handler,
+               FETCH   =>      \&my_fetch_handler });
 
-After each handle is declared, the server is launched by means of
-the subroutine
+After the custom event handles are declared, the server is launched
+by means of the method
 
-  Zfront::start_server($script_name, @ARGV);
+  $handle->launch_server("MyServer.pl", @ARGV);
 
 Notice, the first argument should be the name of your server
 script (for logging purposes), while the rest of the arguments
@@ -187,9 +228,9 @@ The argument hash passed to the init handler has the form
   $args = {
                                    ## Response parameters:
 
-            IMP_NAME  =>  ""       ## Z39.50 Implementation name
-            IMP_VER   =>  ""       ## Z39.50 Implementation version
-            ERR_CODE  =>  0        ## Error code, cnf. Z39.50 manual
+            IMP_NAME  =>  "",      ## Z39.50 Implementation name
+            IMP_VER   =>  "",      ## Z39.50 Implementation version
+            ERR_CODE  =>  0,       ## Error code, cnf. Z39.50 manual
             HANDLE    =>  undef    ## Handler of Perl data structure
          };
 
@@ -218,17 +259,17 @@ mous hash. The structure is the following:
   $args = {
                                    ## Request parameters:
 
-            HANDLE    =>  ref      ## Your session reference.
-            SETNAME   =>  "id"     ## ID of the result set
-            REPL_SET  =>  0        ## Replace set if already existing?
-            DATABASES =>  ["xxx"]  ## Reference to a list of data-
+            HANDLE    =>  ref,     ## Your session reference.
+            SETNAME   =>  "id",    ## ID of the result set
+            REPL_SET  =>  0,       ## Replace set if already existing?
+            DATABASES =>  ["xxx"], ## Reference to a list of data-
                                    ## bases to search
-            QUERY     =>  "query"  ## The query expression
+            QUERY     =>  "query", ## The query expression
 
                                    ## Response parameters:
 
-            ERR_CODE  =>  0        ## Error code (0=Succesful search)
-            ERR_STR   =>  ""       ## Error string
+            ERR_CODE  =>  0,       ## Error code (0=Succesful search)
+            ERR_STR   =>  "",      ## Error string
             HITS      =>  0        ## Number of matches
          };
 
@@ -268,6 +309,46 @@ it is perfectly legal to not accept boolean operators, but you SHOULD
 try to return good error codes if you run into something you can't or
 won't support.
 
+=head2 Present handler
+
+The presence of a present handler in a SimpleServer front-end is optional.
+Each time a client wishes to retrieve records, the present service is
+called. The present service allows the origin to request a certain number
+of records retrieved from a given result set.
+When the present handler is called, the front-end server should prepare a
+result set for fetching. In practice, this means to get access to the
+data from the backend database and store the data in a temporary fashion
+for fast and efficient fetching. The present handler does *not* fetch
+anything. This task is taken care of by the fetch handler, which will be
+called the correct number of times by the YAZ library. More about this
+below.
+If no present handler is implemented in the front-end, the YAZ toolkit
+will take care of a minimum of preparations itself. This default present
+handler is sufficient in many situations, where only a small amount of
+records are expected to be retrieved. If on the other hand, large result
+sets are likely to occur, the implementation of a reasonable present
+handler can gain performance significantly.
+
+The informations exchanged between client and present handle are:
+
+  $args = {
+                                   ## Client/server request:
+
+            HANDLE    =>  ref,     ## Reference to datastructure
+            SETNAME   =>  "id",    ## Result set ID
+            START     =>  xxx,     ## Start position
+            COMP      =>  "",      ## Desired record composition
+            NUMBER    =>  yyy,     ## Number of requested records
+
+
+                                   ## Respons parameters:
+
+            HITS      =>  zzz,     ## Number of returned records
+            ERR_CODE  =>  0,       ## Error code
+            ERR_STR   =>  ""       ## Error message
+          };
+
+
 =head2 Fetch handler
 
 The fetch handler is asked to retrieve a SINGLE record from a given
@@ -282,18 +363,18 @@ The parameters exchanged between the server and the fetch handler are
             HANDLE    =>  ref      ## Reference to data structure
             SETNAME   =>  "id"     ## ID of the requested result set
             OFFSET    =>  nnn      ## Record offset number
-            REQ_FORM  =>  "USMARC" ## Client requested record format
+            REQ_FORM  =>  "n.m.k.l"## Client requested format OID
+            COMP      =>  "xyz"    ## Formatting instructions
 
                                    ## Handler response:
 
             RECORD    =>  ""       ## Record string
-            LEN       =>  0        ## Length of record string
             BASENAME  =>  ""       ## Origin of returned record
             LAST      =>  0        ## Last record in set?
             ERR_CODE  =>  0        ## Error code
             ERR_STR   =>  ""       ## Error string
             SUR_FLAG  =>  0        ## Surrogate diagnostic flag
-            REP_FORM  =>  "USMARC" ## Provided record format
+            REP_FORM  =>  "n.m.k.l"## Provided format OID
          };
 
 The REP_FORM value has by default the REQ_FORM value but can be set to
@@ -305,12 +386,9 @@ indicate whether the error condition pertains to the record currently
 being retrieved, or whether it pertains to the operation as a whole
 (eg. the client has specified a result set which does not exist.)
 
-Record formats are currently carried as strings (eg. USMARC, TEXT_XML,
-SUTRS), but this will probably change to proper OID strings in the
-future (not to worry, though, the module will supply constant values
-for the common OIDs). If you need to return USMARC records, you might
-want to have a look at the MARC module on CPAN, if you don't already
-have a way of generating these.
+If you need to return USMARC records, you might want to have a look at
+the MARC module on CPAN, if you don't already have a way of generating
+these.
 
 NOTE: The record offset is 1-indexed - 1 is the offset of the first
 record in the set.