Documentation for logging facilities.
[ZOOM-Perl-moved-to-github.git] / lib / ZOOM.pod
index eb9204f..bf706ea 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: ZOOM.pod,v 1.22 2005-12-13 16:46:59 mike Exp $
+# $Id: ZOOM.pod,v 1.27 2005-12-22 14:11:17 mike Exp $
 
 use strict;
 use warnings;
@@ -49,11 +49,15 @@ C<ZOOM::Record>,
 C<ZOOM::ScanSet>
 and
 C<ZOOM::Package>.
-Of these, the Query class is abstract, and has two concrete
+Of these, the Query class is abstract, and has three concrete
 subclasses:
-C<ZOOM::Query::CQL>
+C<ZOOM::Query::CQL>,
+C<ZOOM::Query::PQF>
 and
-C<ZOOM::Query::PQF>.
+C<ZOOM::Query::CQL2RPN>.
+Finally, it also provides a
+C<ZOOM::Query::Log>
+module which supplies a useful general-purpose logging facility.
 Many useful ZOOM applications can be built using only the Connection,
 ResultSet, Record and Exception classes, as in the example
 code-snippet above.
@@ -294,13 +298,18 @@ and it creates and returns a new ResultSet object representing the set
 of records resulting from the search.
 
 Since queries using PQF (Prefix Query Format) are so common, we make
-them a special case by providing a C<search_prefix()> method.  This is
+them a special case by providing a C<search_pqf()> method.  This is
 identical to C<search()> except that it accepts a string containing
 the query rather than an object, thereby obviating the need to create
 a C<ZOOM::Query::PQF> object.  See the documentation of that class for
 information about PQF.
 
-=head4 scan()
+=head4 scan() / scan_pqf()
+
+ $rs = $conn->scan(new ZOOM::Query::CQL('title=dinosaur'));
+ # The next two lines are equivalent
+ $rs = $conn->scan(new ZOOM::Query::PQF('@attr 1=4 dinosaur'));
+ $rs = $conn->scan_pqf('@attr 1=4 dinosaur');
 
 Many Z39.50 servers allow you to browse their indexes to find terms to
 search for.  This is done using the C<scan> method, which creates and
@@ -316,13 +325,11 @@ or single words (e.g. the title ``I<The Empire Strikes Back>'', or the
 four words ``Back'', ``Empire'', ``Strikes'' and ``The'', interleaved
 with words from other titles in the same index.
 
-All of this is done by using a single term from the PQF query as the
-C<scan()> argument.  (At present, only PQF is supported, although
-there is no reason in principle why CQL and other query syntaxes
-should not be supported in future).  The attributes associated with
+All of this is done by using a Query object representing a query of a
+single term as the C<scan()> argument.  The attributes associated with
 the term indicate which index is to be used, and the term itself
 indicates the point in the index at which to start the scan.  For
-example, if the argument is C<@attr 1=4 fish>, then
+example, if the argument is the query C<@attr 1=4 fish>, then
 
 =over 4
 
@@ -372,6 +379,12 @@ each one returned in the ScanSet.  By default, no terms are skipped,
 but overriding this can be useful to get a high-level overview of the
 index.
 
+Since scans using PQF (Prefix Query Format) are so common, we make
+them a special case by providing a C<scan_pqf()> method.  This is
+identical to C<scan()> except that it accepts a string containing the
+query rather than an object, thereby obviating the need to create a
+C<ZOOM::Query::PQF> object.
+
 =back
 
 =head4 package()
@@ -427,7 +440,7 @@ need the C<size()>, C<record()> and C<sort()> methods.
 
 There is no C<new()> method nor any other explicit constructor.  The
 only way to create a new ResultSet is by using C<search()> (or
-C<search_prefix()>) on a Connection.
+C<search_pqf()>) on a Connection.
 
 See the description of the C<Result Set> class in the ZOOM Abstract
 API at
@@ -925,7 +938,7 @@ types of query.  The sole purpose of a Query object is to be used in a
 C<search()> on a Connection; because PQF is such a common special
 case, the shortcut Connection method C<search_pqf()> is provided.
 
-The following Query subclasses are provided, both of the providing the
+The following Query subclasses are provided, each providing the
 same set of methods described below:
 
 =over 4
@@ -948,6 +961,19 @@ http://www.loc.gov/standards/sru/cql/
 and in a slight out-of-date but nevertheless useful tutorial at
 http://zing.z3950.org/cql/intro.html
 
+=item ZOOM::Query::CQL2RPN
+
+Implements CQL by compiling it on the client-side into a Z39.50
+Type-1 (RPN) query, and sending that.  This provides essentially the
+same functionality as C<ZOOM::Query::CQL>, but it will work against
+any standard Z39.50 server rather than only against the small subset
+that support CQL natively.  The drawback is that, because the
+compilation is done on the client side, a configuration file is
+required to direct the mapping of CQL constructs such as index names,
+relations and modifiers into Type-1 query attributes.  An example CQL
+configuration file is included in the ZOOM-Perl distribution, in the
+file C<samples/cql/pqf.properties>
+
 =back
 
 See the description of the C<Query> class in the ZOOM Abstract
@@ -958,14 +984,25 @@ http://zoom.z3950.org/api/zoom-current.html#3.3
 
 =head4 new()
 
- $q = new ZOOM::Query::CQL('title=dinosaur'));
- $q = new ZOOM::Query::PQF('@attr 1=4 dinosaur'));
+ $q = new ZOOM::Query::CQL('title=dinosaur');
+ $q = new ZOOM::Query::PQF('@attr 1=4 dinosaur');
 
 Creates a new query object, compiling the query passed as its argument
 according to the rules of the particular query-type being
 instantiated.  If compilation fails, an exception is thrown.
 Otherwise, the query may be passed to the C<Connection> method
-<search()>.
+C<search()>.
+
+ $conn->option(cqlfile => "samples/cql/pqf.properties");
+ $q = new ZOOM::Query::CQL2RPN('title=dinosaur', $conn);
+
+Note that for the C<ZOOM::Query::CQL2RPN> subclass, the Connection
+must also be passed into the constructor.  This is used for two
+purposes: first, its C<cqlfile> option is used to find the CQL
+configuration file that directs the translations into RPN; and second,
+if compilation fails, then diagnostic information is cached in the
+Connection and be retrieved using C<$conn-E<gt>errcode()> and related
+methods.
 
 =head4 sortby()
 
@@ -976,9 +1013,6 @@ is run on the query, the result is automatically sorted.  The sort
 specification language is the same as the C<yaz> sort-specification
 type of the C<ResultSet> method C<sort()>, described above.
 
-B<It ought to be possible to sort by CQL query, too, but at present
-limitations in the underlying ZOOM-C library make this impossible.>
-
 =head4 destroy()
 
  $p->destroy()
@@ -1151,9 +1185,10 @@ C<QUERY_CQL>,
 C<QUERY_PQF>,
 C<SORTBY>,
 C<CLONE>,
-C<PACKAGE>
+C<PACKAGE>,
+C<SCANTERM>
 and
-C<SCANTERM>,
+C<LOGLEVEL>,
 each of which specifies a client-side error.  These codes constitute
 the C<ZOOM> diagnostic set.
 
@@ -1184,6 +1219,111 @@ C<RECV_SEARCH>.
 You almost certainly don't need to know about this.  Frankly, I'm not
 sure how to use it myself.
 
+=head1 LOGGING
+
+ ZOOM::Log::init_level(ZOOM::Log::mask_str("zoom,myapp,-warn"));
+ ZOOM::Log::log("myapp", "starting up with pid ", $$);
+
+Logging facilities are provided by a set of functions in the
+C<ZOOM::Log> module.  Note that C<ZOOM::Log> is not a class, and it
+is not possible to create C<ZOOM::Log> objects: the API is imperative,
+reflecting that of the underlying YAZ logging facilities.  Although
+there are nine logging functions altogether, you can ignore nearly
+all of them: most applications that use logging will begin by calling
+C<mask_str()> and C<init_level()> once each, as above, and will then
+repeatedly call C<log()>.
+
+=head2 mask_str()
+
+ $level = ZOOM::Log::mask_str("zoom,myapp,-warn");
+
+Returns an integer corresponding to the log-level specified by the
+parameter.  This is a string of zero or more comma-separated
+module-names, each indicating an individual module to be either added
+to the default log-level or removed from it (for those components
+prefixed by a minus-sign).  The names may be those of either standard
+YAZ-logging modules such as C<fatal>, C<debug> and C<warn>, or custom
+modules such as C<myapp> in the example above.  The module C<zoom>
+requests logging from the ZOOM module itself, which may be helpful for
+debugging.
+
+Note that calling this function does not in any way change the logging
+state: it merely returns a value.  To change the state, this value
+must be passed to C<init_level()>.
+
+=head2 module_level()
+
+ $level = ZOOM::Log::module_level("zoom");
+ ZOOM::Log::log($level, "all systems clear: thrusters invogriated");
+
+Returns the integer corresponding to the single log-level specified as
+the parameter, or zero if that level has not been registered by a
+prior call to C<mask_str()>.  Since C<log()> accepts either a numeric
+log-level or a string, there is no reason to call this function; but,
+what the heck, maybe you enjoy that kind of thing.  Who are we to
+judge?
+
+=head2 init_level()
+
+ ZOOM::Log::init_level($level);
+
+Initialises the log-level to the specified integer, which is a bitmask
+of values, typically as returned from C<mask_str()>.  All subsequent
+calls to C<log()> made with a log-level that matches one of the bits
+in this mask will result in a log-message being emitted.  All logging
+can be turned off by calling C<init_level(0)>.
+
+=head2 init_prefix()
+
+ ZOOM::Log::init_prefix($0);
+
+Initialises a prefix string to be included in all log-messages.
+
+=head2 init_file()
+
+ ZOOM::Log::init_file("/tmp/myapp.log");
+
+Initialises the output file to be used for logging: subsequent
+log-messages are written to the nominated file.  If this function is
+not called, log-messages are written to the standard error stream.
+
+=head2 init()
+
+ ZOOM::Log::init($level, $0, "/tmp/myapp.log");
+
+Initialises the log-level, the logging prefix and the logging output
+file in a single operation.
+
+=head2 time_format()
+
+ ZOOM::Log::time_format("%Y-%m-%d %H:%M:%S");
+
+Sets the format in which log-messages' timestamps are emitted, by
+means of a format-string like that used in the C function
+C<strftime()>.  The example above emits year, month, day, hours,
+minutes and seconds in big-endian order, such that timestamps can be
+sorted lexicographically.
+
+=head2 init_max_size()
+
+(This doesn't seem to work, so I won't bother describing it.)
+
+=head2 log()
+
+ ZOOM::Log::log(8192, "reducing to warp-factor $wf");
+ ZOOM::Log::log("myapp", "starting up with pid ", $$);
+
+Provided that the first argument, log-level, is among the modules
+previously established by C<init_level()>, this function emits a
+log-message made up of a timestamp, the prefix supplied to
+C<init_prefix()>, if any, and the concatenation of all arguments after
+the first.  The message is written to the standard output stream, or
+to the file previous specified by C<init_file()> if this has been
+called.
+
+The log-level argument may be either a numeric value, as returned from
+C<module_level()>, or a string containing the module name.
+
 =head1 SEE ALSO
 
 The ZOOM abstract API,