← Index
NYTProf Performance Profile   « line view »
For svc/members/upsert
  Run on Tue Jan 13 11:50:22 2015
Reported on Tue Jan 13 12:09:47 2015

Filename/usr/lib/x86_64-linux-gnu/perl5/5.20/ZOOM.pm
StatementsExecuted 19 statements in 9.52ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1112.60ms4.55msZOOM::Exception::::BEGIN@194 ZOOM::Exception::BEGIN@194
1111.90ms5.59msC4::Context::::BEGIN@4 C4::Context::BEGIN@4
11113µs135µsC4::Context::::BEGIN@3 C4::Context::BEGIN@3
11113µs28µsC4::Context::::BEGIN@1 C4::Context::BEGIN@1
11112µs20µsC4::Context::::BEGIN@2 C4::Context::BEGIN@2
11110µs33µsZOOM::Log::::mask_str ZOOM::Log::mask_str
1118µs41µsZOOM::Log::::BEGIN@1115 ZOOM::Log::BEGIN@1115
0000s0sZOOM::CCL::Error::::BAD_RELATION ZOOM::CCL::Error::BAD_RELATION
0000s0sZOOM::CCL::Error::::BAD_RP ZOOM::CCL::Error::BAD_RP
0000s0sZOOM::CCL::Error::::DOUBLE_QUAL ZOOM::CCL::Error::DOUBLE_QUAL
0000s0sZOOM::CCL::Error::::EQ_EXPECTED ZOOM::CCL::Error::EQ_EXPECTED
0000s0sZOOM::CCL::Error::::OK ZOOM::CCL::Error::OK
0000s0sZOOM::CCL::Error::::OP_EXPECTED ZOOM::CCL::Error::OP_EXPECTED
0000s0sZOOM::CCL::Error::::RP_EXPECTED ZOOM::CCL::Error::RP_EXPECTED
0000s0sZOOM::CCL::Error::::SETNAME_EXPECTED ZOOM::CCL::Error::SETNAME_EXPECTED
0000s0sZOOM::CCL::Error::::TERM_EXPECTED ZOOM::CCL::Error::TERM_EXPECTED
0000s0sZOOM::CCL::Error::::TRUNC_NOT_BOTH ZOOM::CCL::Error::TRUNC_NOT_BOTH
0000s0sZOOM::CCL::Error::::TRUNC_NOT_LEFT ZOOM::CCL::Error::TRUNC_NOT_LEFT
0000s0sZOOM::CCL::Error::::TRUNC_NOT_RIGHT ZOOM::CCL::Error::TRUNC_NOT_RIGHT
0000s0sZOOM::CCL::Error::::UNKNOWN_QUAL ZOOM::CCL::Error::UNKNOWN_QUAL
0000s0sZOOM::Connection::::_check ZOOM::Connection::_check
0000s0sZOOM::Connection::::_conn ZOOM::Connection::_conn
0000s0sZOOM::Connection::::addinfo ZOOM::Connection::addinfo
0000s0sZOOM::Connection::::check ZOOM::Connection::check
0000s0sZOOM::Connection::::connect ZOOM::Connection::connect
0000s0sZOOM::Connection::::create ZOOM::Connection::create
0000s0sZOOM::Connection::::destroy ZOOM::Connection::destroy
0000s0sZOOM::Connection::::diagset ZOOM::Connection::diagset
0000s0sZOOM::Connection::::errcode ZOOM::Connection::errcode
0000s0sZOOM::Connection::::errmsg ZOOM::Connection::errmsg
0000s0sZOOM::Connection::::error_x ZOOM::Connection::error_x
0000s0sZOOM::Connection::::exception ZOOM::Connection::exception
0000s0sZOOM::Connection::::is_idle ZOOM::Connection::is_idle
0000s0sZOOM::Connection::::last_event ZOOM::Connection::last_event
0000s0sZOOM::Connection::::new ZOOM::Connection::new
0000s0sZOOM::Connection::::option ZOOM::Connection::option
0000s0sZOOM::Connection::::option_binary ZOOM::Connection::option_binary
0000s0sZOOM::Connection::::package ZOOM::Connection::package
0000s0sZOOM::Connection::::peek_event ZOOM::Connection::peek_event
0000s0sZOOM::Connection::::scan ZOOM::Connection::scan
0000s0sZOOM::Connection::::scan_pqf ZOOM::Connection::scan_pqf
0000s0sZOOM::Connection::::search ZOOM::Connection::search
0000s0sZOOM::Connection::::search_pqf ZOOM::Connection::search_pqf
0000s0sZOOM::Error::::CCL_CONFIG ZOOM::Error::CCL_CONFIG
0000s0sZOOM::Error::::CCL_PARSE ZOOM::Error::CCL_PARSE
0000s0sZOOM::Error::::CLONE ZOOM::Error::CLONE
0000s0sZOOM::Error::::CONNECT ZOOM::Error::CONNECT
0000s0sZOOM::Error::::CONNECTION_LOST ZOOM::Error::CONNECTION_LOST
0000s0sZOOM::Error::::CQL_PARSE ZOOM::Error::CQL_PARSE
0000s0sZOOM::Error::::CQL_TRANSFORM ZOOM::Error::CQL_TRANSFORM
0000s0sZOOM::Error::::CREATE_QUERY ZOOM::Error::CREATE_QUERY
0000s0sZOOM::Error::::DECODE ZOOM::Error::DECODE
0000s0sZOOM::Error::::ENCODE ZOOM::Error::ENCODE
0000s0sZOOM::Error::::INTERNAL ZOOM::Error::INTERNAL
0000s0sZOOM::Error::::INVALID_QUERY ZOOM::Error::INVALID_QUERY
0000s0sZOOM::Error::::LOGLEVEL ZOOM::Error::LOGLEVEL
0000s0sZOOM::Error::::MEMORY ZOOM::Error::MEMORY
0000s0sZOOM::Error::::NONE ZOOM::Error::NONE
0000s0sZOOM::Error::::PACKAGE ZOOM::Error::PACKAGE
0000s0sZOOM::Error::::QUERY_CQL ZOOM::Error::QUERY_CQL
0000s0sZOOM::Error::::QUERY_PQF ZOOM::Error::QUERY_PQF
0000s0sZOOM::Error::::SCANTERM ZOOM::Error::SCANTERM
0000s0sZOOM::Error::::SORTBY ZOOM::Error::SORTBY
0000s0sZOOM::Error::::TIMEOUT ZOOM::Error::TIMEOUT
0000s0sZOOM::Error::::UNSUPPORTED_PROTOCOL ZOOM::Error::UNSUPPORTED_PROTOCOL
0000s0sZOOM::Error::::UNSUPPORTED_QUERY ZOOM::Error::UNSUPPORTED_QUERY
0000s0sZOOM::Error::::ZINIT ZOOM::Error::ZINIT
0000s0sZOOM::Event::::CONNECT ZOOM::Event::CONNECT
0000s0sZOOM::Event::::NONE ZOOM::Event::NONE
0000s0sZOOM::Event::::RECV_APDU ZOOM::Event::RECV_APDU
0000s0sZOOM::Event::::RECV_DATA ZOOM::Event::RECV_DATA
0000s0sZOOM::Event::::RECV_RECORD ZOOM::Event::RECV_RECORD
0000s0sZOOM::Event::::RECV_SEARCH ZOOM::Event::RECV_SEARCH
0000s0sZOOM::Event::::SEND_APDU ZOOM::Event::SEND_APDU
0000s0sZOOM::Event::::SEND_DATA ZOOM::Event::SEND_DATA
0000s0sZOOM::Event::::TIMEOUT ZOOM::Event::TIMEOUT
0000s0sZOOM::Event::::UNKNOWN ZOOM::Event::UNKNOWN
0000s0sZOOM::Event::::ZEND ZOOM::Event::ZEND
0000s0sZOOM::Exception::::addinfo ZOOM::Exception::addinfo
0000s0sZOOM::Exception::::code ZOOM::Exception::code
0000s0sZOOM::Exception::::diagset ZOOM::Exception::diagset
0000s0sZOOM::Exception::::message ZOOM::Exception::message
0000s0sZOOM::Exception::::new ZOOM::Exception::new
0000s0sZOOM::Exception::::render ZOOM::Exception::render
0000s0sZOOM::Log::::init ZOOM::Log::init
0000s0sZOOM::Log::::init_file ZOOM::Log::init_file
0000s0sZOOM::Log::::init_level ZOOM::Log::init_level
0000s0sZOOM::Log::::init_max_size ZOOM::Log::init_max_size
0000s0sZOOM::Log::::init_prefix ZOOM::Log::init_prefix
0000s0sZOOM::Log::::log ZOOM::Log::log
0000s0sZOOM::Log::::module_level ZOOM::Log::module_level
0000s0sZOOM::Log::::time_format ZOOM::Log::time_format
0000s0sZOOM::Options::::_opts ZOOM::Options::_opts
0000s0sZOOM::Options::::bool ZOOM::Options::bool
0000s0sZOOM::Options::::destroy ZOOM::Options::destroy
0000s0sZOOM::Options::::int ZOOM::Options::int
0000s0sZOOM::Options::::new ZOOM::Options::new
0000s0sZOOM::Options::::option ZOOM::Options::option
0000s0sZOOM::Options::::option_binary ZOOM::Options::option_binary
0000s0sZOOM::Options::::set_callback ZOOM::Options::set_callback
0000s0sZOOM::Options::::set_int ZOOM::Options::set_int
0000s0sZOOM::Package::::_new ZOOM::Package::_new
0000s0sZOOM::Package::::_p ZOOM::Package::_p
0000s0sZOOM::Package::::destroy ZOOM::Package::destroy
0000s0sZOOM::Package::::new ZOOM::Package::new
0000s0sZOOM::Package::::option ZOOM::Package::option
0000s0sZOOM::Package::::send ZOOM::Package::send
0000s0sZOOM::Query::CCL2RPN::::newZOOM::Query::CCL2RPN::new
0000s0sZOOM::Query::CQL2RPN::::newZOOM::Query::CQL2RPN::new
0000s0sZOOM::Query::CQL::::new ZOOM::Query::CQL::new
0000s0sZOOM::Query::PQF::::new ZOOM::Query::PQF::new
0000s0sZOOM::Query::::_query ZOOM::Query::_query
0000s0sZOOM::Query::::destroy ZOOM::Query::destroy
0000s0sZOOM::Query::::new ZOOM::Query::new
0000s0sZOOM::Query::::sortby ZOOM::Query::sortby
0000s0sZOOM::Query::::sortby2 ZOOM::Query::sortby2
0000s0sZOOM::Record::::_new ZOOM::Record::_new
0000s0sZOOM::Record::::_rec ZOOM::Record::_rec
0000s0sZOOM::Record::::clone ZOOM::Record::clone
0000s0sZOOM::Record::::destroy ZOOM::Record::destroy
0000s0sZOOM::Record::::error ZOOM::Record::error
0000s0sZOOM::Record::::exception ZOOM::Record::exception
0000s0sZOOM::Record::::get ZOOM::Record::get
0000s0sZOOM::Record::::new ZOOM::Record::new
0000s0sZOOM::Record::::raw ZOOM::Record::raw
0000s0sZOOM::Record::::render ZOOM::Record::render
0000s0sZOOM::ResultSet::::_new ZOOM::ResultSet::_new
0000s0sZOOM::ResultSet::::_rs ZOOM::ResultSet::_rs
0000s0sZOOM::ResultSet::::cache_reset ZOOM::ResultSet::cache_reset
0000s0sZOOM::ResultSet::::destroy ZOOM::ResultSet::destroy
0000s0sZOOM::ResultSet::::new ZOOM::ResultSet::new
0000s0sZOOM::ResultSet::::option ZOOM::ResultSet::option
0000s0sZOOM::ResultSet::::record ZOOM::ResultSet::record
0000s0sZOOM::ResultSet::::record_immediate ZOOM::ResultSet::record_immediate
0000s0sZOOM::ResultSet::::records ZOOM::ResultSet::records
0000s0sZOOM::ResultSet::::size ZOOM::ResultSet::size
0000s0sZOOM::ResultSet::::sort ZOOM::ResultSet::sort
0000s0sZOOM::ScanSet::::_new ZOOM::ScanSet::_new
0000s0sZOOM::ScanSet::::_ss ZOOM::ScanSet::_ss
0000s0sZOOM::ScanSet::::destroy ZOOM::ScanSet::destroy
0000s0sZOOM::ScanSet::::display_term ZOOM::ScanSet::display_term
0000s0sZOOM::ScanSet::::new ZOOM::ScanSet::new
0000s0sZOOM::ScanSet::::option ZOOM::ScanSet::option
0000s0sZOOM::ScanSet::::size ZOOM::ScanSet::size
0000s0sZOOM::ScanSet::::term ZOOM::ScanSet::term
0000s0sZOOM::::_oops ZOOM::_oops
0000s0sZOOM::::diag_srw_str ZOOM::diag_srw_str
0000s0sZOOM::::diag_str ZOOM::diag_str
0000s0sZOOM::::event ZOOM::event
0000s0sZOOM::::event_str ZOOM::event_str
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1230µs243µs
# spent 28µs (13+15) within C4::Context::BEGIN@1 which was called: # once (13µs+15µs) by C4::Context::BEGIN@101 at line 1
use strict;
# spent 28µs making 1 call to C4::Context::BEGIN@1 # spent 15µs making 1 call to strict::import
2228µs228µs
# spent 20µs (12+8) within C4::Context::BEGIN@2 which was called: # once (12µs+8µs) by C4::Context::BEGIN@101 at line 2
use warnings;
# spent 20µs making 1 call to C4::Context::BEGIN@2 # spent 8µs making 1 call to warnings::import
3233µs2256µs
# spent 135µs (13+122) within C4::Context::BEGIN@3 which was called: # once (13µs+122µs) by C4::Context::BEGIN@101 at line 3
use IO::File;
# spent 135µs making 1 call to C4::Context::BEGIN@3 # spent 122µs making 1 call to Exporter::import
422.11ms15.59ms
# spent 5.59ms (1.90+3.69) within C4::Context::BEGIN@4 which was called: # once (1.90ms+3.69ms) by C4::Context::BEGIN@101 at line 4
use Net::Z3950::ZOOM;
# spent 5.59ms making 1 call to C4::Context::BEGIN@4
5
6
7package ZOOM;
8
9# Member naming convention: hash-element names which begin with an
10# underscore represent underlying ZOOM-C object descriptors; those
11# which lack them represent Perl's ZOOM objects. (The same convention
12# is used in naming local variables where appropriate.)
13#
14# So, for example, the ZOOM::Connection class has an {_conn} element,
15# which is a pointer to the ZOOM-C Connection object; but the
16# ZOOM::ResultSet class has a {conn} element, which is a reference to
17# the Perl-level Connection object by which it was created. (It may
18# be that we find we have no need for these references, but for now
19# they are retained.)
20#
21# To get at the underlying ZOOM-C connection object of a result-set
22# (if you ever needed to do such a thing, which you probably don't)
23# you'd use $rs->{conn}->_conn().
24
25# ----------------------------------------------------------------------------
26
27# The "Error" package contains constants returned as error-codes.
28package ZOOM::Error;
29sub NONE { Net::Z3950::ZOOM::ERROR_NONE }
30sub CONNECT { Net::Z3950::ZOOM::ERROR_CONNECT }
31sub MEMORY { Net::Z3950::ZOOM::ERROR_MEMORY }
32sub ENCODE { Net::Z3950::ZOOM::ERROR_ENCODE }
33sub DECODE { Net::Z3950::ZOOM::ERROR_DECODE }
34sub CONNECTION_LOST { Net::Z3950::ZOOM::ERROR_CONNECTION_LOST }
35sub ZINIT { Net::Z3950::ZOOM::ERROR_INIT }
36sub INTERNAL { Net::Z3950::ZOOM::ERROR_INTERNAL }
37sub TIMEOUT { Net::Z3950::ZOOM::ERROR_TIMEOUT }
38sub UNSUPPORTED_PROTOCOL { Net::Z3950::ZOOM::ERROR_UNSUPPORTED_PROTOCOL }
39sub UNSUPPORTED_QUERY { Net::Z3950::ZOOM::ERROR_UNSUPPORTED_QUERY }
40sub INVALID_QUERY { Net::Z3950::ZOOM::ERROR_INVALID_QUERY }
41sub CQL_PARSE { Net::Z3950::ZOOM::ERROR_CQL_PARSE }
42sub CQL_TRANSFORM { Net::Z3950::ZOOM::ERROR_CQL_TRANSFORM }
43sub CCL_CONFIG { Net::Z3950::ZOOM::ERROR_CCL_CONFIG }
44sub CCL_PARSE { Net::Z3950::ZOOM::ERROR_CCL_PARSE }
45# The following are added specifically for this OO interface
46sub CREATE_QUERY { 20001 }
47sub QUERY_CQL { 20002 }
48sub QUERY_PQF { 20003 }
49sub SORTBY { 20004 }
50sub CLONE { 20005 }
51sub PACKAGE { 20006 }
52sub SCANTERM { 20007 }
53sub LOGLEVEL { 20008 }
54
55# Separate space for CCL errors. Great.
56package ZOOM::CCL::Error;
57sub OK { Net::Z3950::ZOOM::CCL_ERR_OK }
58sub TERM_EXPECTED { Net::Z3950::ZOOM::CCL_ERR_TERM_EXPECTED }
59sub RP_EXPECTED { Net::Z3950::ZOOM::CCL_ERR_RP_EXPECTED }
60sub SETNAME_EXPECTED { Net::Z3950::ZOOM::CCL_ERR_SETNAME_EXPECTED }
61sub OP_EXPECTED { Net::Z3950::ZOOM::CCL_ERR_OP_EXPECTED }
62sub BAD_RP { Net::Z3950::ZOOM::CCL_ERR_BAD_RP }
63sub UNKNOWN_QUAL { Net::Z3950::ZOOM::CCL_ERR_UNKNOWN_QUAL }
64sub DOUBLE_QUAL { Net::Z3950::ZOOM::CCL_ERR_DOUBLE_QUAL }
65sub EQ_EXPECTED { Net::Z3950::ZOOM::CCL_ERR_EQ_EXPECTED }
66sub BAD_RELATION { Net::Z3950::ZOOM::CCL_ERR_BAD_RELATION }
67sub TRUNC_NOT_LEFT { Net::Z3950::ZOOM::CCL_ERR_TRUNC_NOT_LEFT }
68sub TRUNC_NOT_BOTH { Net::Z3950::ZOOM::CCL_ERR_TRUNC_NOT_BOTH }
69sub TRUNC_NOT_RIGHT { Net::Z3950::ZOOM::CCL_ERR_TRUNC_NOT_RIGHT }
70
71# The "Event" package contains constants returned by last_event()
72package ZOOM::Event;
73sub NONE { Net::Z3950::ZOOM::EVENT_NONE }
74sub CONNECT { Net::Z3950::ZOOM::EVENT_CONNECT }
75sub SEND_DATA { Net::Z3950::ZOOM::EVENT_SEND_DATA }
76sub RECV_DATA { Net::Z3950::ZOOM::EVENT_RECV_DATA }
77sub TIMEOUT { Net::Z3950::ZOOM::EVENT_TIMEOUT }
78sub UNKNOWN { Net::Z3950::ZOOM::EVENT_UNKNOWN }
79sub SEND_APDU { Net::Z3950::ZOOM::EVENT_SEND_APDU }
80sub RECV_APDU { Net::Z3950::ZOOM::EVENT_RECV_APDU }
81sub RECV_RECORD { Net::Z3950::ZOOM::EVENT_RECV_RECORD }
82sub RECV_SEARCH { Net::Z3950::ZOOM::EVENT_RECV_SEARCH }
83sub ZEND { Net::Z3950::ZOOM::EVENT_END }
84
85# ----------------------------------------------------------------------------
86
87package ZOOM;
88
89sub diag_str {
90 my($code) = @_;
91
92 # Special cases for error specific to the OO layer
93 if ($code == ZOOM::Error::CREATE_QUERY) {
94 return "can't create query object";
95 } elsif ($code == ZOOM::Error::QUERY_CQL) {
96 return "can't set CQL query";
97 } elsif ($code == ZOOM::Error::QUERY_PQF) {
98 return "can't set prefix query";
99 } elsif ($code == ZOOM::Error::SORTBY) {
100 return "can't set sort-specification";
101 } elsif ($code == ZOOM::Error::CLONE) {
102 return "can't clone record";
103 } elsif ($code == ZOOM::Error::PACKAGE) {
104 return "can't create package";
105 } elsif ($code == ZOOM::Error::SCANTERM) {
106 return "can't retrieve term from scan-set";
107 } elsif ($code == ZOOM::Error::LOGLEVEL) {
108 return "unregistered log-level";
109 }
110
111 return Net::Z3950::ZOOM::diag_str($code);
112}
113
114sub diag_srw_str {
115 my($code) = @_;
116
117 return Net::Z3950::ZOOM::diag_srw_str($code);
118}
119
120sub event_str {
121 return Net::Z3950::ZOOM::event_str(@_);
122}
123
124sub event {
125 my($connsref) = @_;
126
127 my @_connsref = map { $_->_conn() } @$connsref;
128 return Net::Z3950::ZOOM::event(\@_connsref);
129}
130
131sub _oops {
132 my($code, $addinfo, $diagset) = @_;
133
134 die new ZOOM::Exception($code, undef, $addinfo, $diagset);
135}
136
137# ----------------------------------------------------------------------------
138
139package ZOOM::Exception;
140
141sub new {
142 my $class = shift();
143 my($code, $message, $addinfo, $diagset) = @_;
144
145 $diagset ||= "ZOOM";
146 if (uc($diagset) eq "ZOOM" || uc($diagset) eq "BIB-1") {
147 $message ||= ZOOM::diag_str($code);
148 } elsif (lc($diagset) eq "info:srw/diagnostic/1") {
149 $message ||= ZOOM::diag_srw_str($code);
150 } else {
151 # Should fill in messages for any other known diagsets.
152 $message ||= "(unknown error)";
153 }
154
155 return bless {
156 code => $code,
157 message => $message,
158 addinfo => $addinfo,
159 diagset => $diagset,
160 }, $class;
161}
162
163sub code {
164 my $this = shift();
165 return $this->{code};
166}
167
168sub message {
169 my $this = shift();
170 return $this->{message};
171}
172
173sub addinfo {
174 my $this = shift();
175 return $this->{addinfo};
176}
177
178sub diagset {
179 my $this = shift();
180 return $this->{diagset};
181}
182
183sub render {
184 my $this = shift();
185
186 my $res = "ZOOM error " . $this->code();
187 $res .= ' "' . $this->message() . '"' if $this->message();
188 $res .= ' (addinfo: "' . $this->addinfo() . '")' if $this->addinfo();
189 $res .= " from diag-set '" . $this->diagset() . "'" if $this->diagset();
190 return $res;
191}
192
193# This means that untrapped exceptions render nicely.
19427.21ms24.58ms
# spent 4.55ms (2.60+1.95) within ZOOM::Exception::BEGIN@194 which was called: # once (2.60ms+1.95ms) by C4::Context::BEGIN@101 at line 194
use overload '""' => \&render;
# spent 4.55ms making 1 call to ZOOM::Exception::BEGIN@194 # spent 24µs making 1 call to overload::import
195
196# ----------------------------------------------------------------------------
197
198package ZOOM::Options;
199
200sub new {
201 my $class = shift();
202 my($p1, $p2) = @_;
203
204 my $opts;
205 if (@_ == 0) {
206 $opts = Net::Z3950::ZOOM::options_create();
207 } elsif (@_ == 1) {
208 $opts = Net::Z3950::ZOOM::options_create_with_parent($p1->_opts());
209 } elsif (@_ == 2) {
210 $opts = Net::Z3950::ZOOM::options_create_with_parent2($p1->_opts(),
211 $p2->_opts());
212 } else {
213 die "can't make $class object with more than 2 parents";
214 }
215
216 return bless {
217 _opts => $opts,
218 }, $class;
219}
220
221# PRIVATE to this class and ZOOM::Connection::create() and
222# ZOOM::Connection::package()
223#
224sub _opts {
225 my $this = shift();
226
227 my $_opts = $this->{_opts};
228 die "{_opts} undefined: has this Options block been destroy()ed?"
229 if !defined $_opts;
230
231 return $_opts;
232}
233
234sub option {
235 my $this = shift();
236 my($key, $value) = @_;
237
238 my $oldval = Net::Z3950::ZOOM::options_get($this->_opts(), $key);
239 Net::Z3950::ZOOM::options_set($this->_opts(), $key, $value)
240 if defined $value;
241
242 return $oldval;
243}
244
245sub option_binary {
246 my $this = shift();
247 my($key, $value) = @_;
248
249 my $dummylen = 0;
250 my $oldval = Net::Z3950::ZOOM::options_getl($this->_opts(),
251 $key, $dummylen);
252 Net::Z3950::ZOOM::options_setl($this->_opts(), $key,
253 $value, length($value))
254 if defined $value;
255
256 return $oldval;
257}
258
259# This is a bit stupid, since the scalar values that Perl returns from
260# option() can be used as a boolean; but it's just possible that some
261# applications will rely on ZOOM_options_get_bool()'s idiosyncratic
262# interpretation of what constitutes truth.
263#
264sub bool {
265 my $this = shift();
266 my($key, $default) = @_;
267
268 return Net::Z3950::ZOOM::options_get_bool($this->_opts(), $key, $default);
269}
270
271# .. and the next two are even more stupid
272sub int {
273 my $this = shift();
274 my($key, $default) = @_;
275
276 return Net::Z3950::ZOOM::options_get_int($this->_opts(), $key, $default);
277}
278
279sub set_int {
280 my $this = shift();
281 my($key, $value) = @_;
282
283 Net::Z3950::ZOOM::options_set_int($this->_opts(), $key, $value);
284}
285
286# ### Feel guilty. Feel very, very guilty. I've not been able to
287# get the callback memory-management right in "ZOOM.xs", with
288# the result that the values of $function and $udata passed into
289# this function, which are on the stack, have sometimes been
290# freed by the time they're used by __ZOOM_option_callback(),
291# with hilarious results. To avoid this, I copy the values into
292# module-scoped globals, and pass _those_ into the extension
293# function. To avoid overwriting those globals by subsequent
294# calls, I keep all the old ones, pushed onto the @_function and
295# @_udata arrays, which means that THIS FUNCTION LEAKS MEMORY
296# LIKE IT'S GOING OUT OF FASHION. Not nice. One day, I should
297# fix this, but for now there's more important fish to fry.
298#
2991200nsmy(@_function, @_udata);
300sub set_callback {
301 my $o1 = shift();
302 my($function, $udata) = @_;
303
304 push @_function, $function;
305 push @_udata, $udata;
306 Net::Z3950::ZOOM::options_set_callback($o1->_opts(),
307 $_function[-1], $_udata[-1]);
308}
309
310sub destroy {
311 my $this = shift();
312
313 Net::Z3950::ZOOM::options_destroy($this->_opts());
314 $this->{_opts} = undef;
315}
316
317
318# ----------------------------------------------------------------------------
319
320package ZOOM::Connection;
321
322sub new {
323 my $class = shift();
324 my($host, $port, @options) = @_;
325
326 my $conn = $class->create(@options);
327 $conn->{host} = $host;
328 $conn->{port} = $port;
329
330 Net::Z3950::ZOOM::connection_connect($conn->_conn(), $host, $port || 0);
331 $conn->_check();
332
333 return $conn;
334}
335
336# PRIVATE to this class, to ZOOM::event() and to ZOOM::Query::CQL2RPN::new()
337sub _conn {
338 my $this = shift();
339
340 my $_conn = $this->{_conn};
341 die "{_conn} undefined: has this Connection been destroy()ed?"
342 if !defined $_conn;
343
344 return $_conn;
345}
346
347sub _check {
348 my $this = shift();
349 my($always_die_on_error) = @_;
350
351 my($errcode, $errmsg, $addinfo, $diagset) = (undef, "x", "x", "x");
352 $errcode = Net::Z3950::ZOOM::connection_error_x($this->_conn(), $errmsg,
353 $addinfo, $diagset);
354 if ($errcode) {
355 my $exception = new ZOOM::Exception($errcode, $errmsg, $addinfo,
356 $diagset);
357 if (!$this->option("async") || $always_die_on_error) {
358 ZOOM::Log::log("zoom_check", "throwing error $exception");
359 die $exception;
360 } else {
361 ZOOM::Log::log("zoom_check", "not reporting error $exception");
362 }
363 }
364}
365
366# This wrapper for _check() is called only from outside the ZOOM
367# module, and therefore only in situations where an asynchronous
368# application is actively asking for an exception to be thrown if an
369# error has been detected. So it passed always_die_on_error=1 to the
370# underlying _check() method.
371#
372sub check {
373 my $this = shift();
374 return $this->_check(1);
375}
376
377sub create {
378 my $class = shift();
379 my(@options) = @_;
380
381 my $_opts;
382 if (@_ == 1) {
383 $_opts = $_[0]->_opts();
384 } else {
385 $_opts = Net::Z3950::ZOOM::options_create();
386 while (@options >= 2) {
387 my $key = shift(@options);
388 my $val = shift(@options);
389 Net::Z3950::ZOOM::options_set($_opts, $key, $val);
390 }
391
392 die "Odd number of options specified"
393 if @options;
394 }
395
396 my $_conn = Net::Z3950::ZOOM::connection_create($_opts);
397 my $conn = bless {
398 host => undef,
399 port => undef,
400 _conn => $_conn,
401 }, $class;
402 return $conn;
403}
404
405sub error_x {
406 my $this = shift();
407
408 my($errcode, $errmsg, $addinfo, $diagset) = (undef, "dummy", "dummy", "d");
409 $errcode = Net::Z3950::ZOOM::connection_error_x($this->_conn(), $errmsg,
410 $addinfo, $diagset);
411 return wantarray() ? ($errcode, $errmsg, $addinfo, $diagset) : $errcode;
412}
413
414sub exception {
415 my $this = shift();
416
417 my($errcode, $errmsg, $addinfo, $diagset) = $this->error_x();
418 return undef if $errcode == 0;
419 return new ZOOM::Exception($errcode, $errmsg, $addinfo, $diagset);
420}
421
422sub errcode {
423 my $this = shift();
424 return Net::Z3950::ZOOM::connection_errcode($this->_conn());
425}
426
427sub errmsg {
428 my $this = shift();
429 return Net::Z3950::ZOOM::connection_errmsg($this->_conn());
430}
431
432sub addinfo {
433 my $this = shift();
434 return Net::Z3950::ZOOM::connection_addinfo($this->_conn());
435}
436
437sub diagset {
438 my $this = shift();
439 return Net::Z3950::ZOOM::connection_diagset($this->_conn());
440}
441
442sub connect {
443 my $this = shift();
444 my($host, $port) = @_;
445
446 $port = 0 if !defined $port;
447 Net::Z3950::ZOOM::connection_connect($this->_conn(), $host, $port);
448 $this->_check();
449 # No return value
450}
451
452sub option {
453 my $this = shift();
454 my($key, $value) = @_;
455
456 my $oldval = Net::Z3950::ZOOM::connection_option_get($this->_conn(), $key);
457 Net::Z3950::ZOOM::connection_option_set($this->_conn(), $key, $value)
458 if defined $value;
459
460 return $oldval;
461}
462
463sub option_binary {
464 my $this = shift();
465 my($key, $value) = @_;
466
467 my $dummylen = 0;
468 my $oldval = Net::Z3950::ZOOM::connection_option_getl($this->_conn(),
469 $key, $dummylen);
470 Net::Z3950::ZOOM::connection_option_setl($this->_conn(), $key,
471 $value, length($value))
472 if defined $value;
473
474 return $oldval;
475}
476
477sub search {
478 my $this = shift();
479 my($query) = @_;
480
481 my $_rs = Net::Z3950::ZOOM::connection_search($this->_conn(),
482 $query->_query());
483 $this->_check();
484 return _new ZOOM::ResultSet($this, $query, $_rs);
485}
486
487sub search_pqf {
488 my $this = shift();
489 my($pqf) = @_;
490
491 my $_rs = Net::Z3950::ZOOM::connection_search_pqf($this->_conn(), $pqf);
492 $this->_check();
493 return _new ZOOM::ResultSet($this, $pqf, $_rs);
494}
495
496sub scan_pqf {
497 my $this = shift();
498 my($startterm) = @_;
499
500 my $_ss = Net::Z3950::ZOOM::connection_scan($this->_conn(), $startterm);
501 $this->_check();
502 return _new ZOOM::ScanSet($this, $startterm, $_ss);
503}
504
505sub scan {
506 my $this = shift();
507 my($query) = @_;
508
509 my $_ss = Net::Z3950::ZOOM::connection_scan1($this->_conn(),
510 $query->_query());
511 $this->_check();
512 return _new ZOOM::ScanSet($this, $query, $_ss);
513}
514
515sub package {
516 my $this = shift();
517 my($options) = @_;
518
519 my $_o = defined $options ? $options->_opts() :
520 Net::Z3950::ZOOM::options_create();
521 my $_p = Net::Z3950::ZOOM::connection_package($this->_conn(), $_o)
522 or ZOOM::_oops(ZOOM::Error::PACKAGE);
523
524 return _new ZOOM::Package($this, $options, $_p);
525}
526
527sub last_event {
528 my $this = shift();
529
530 return Net::Z3950::ZOOM::connection_last_event($this->_conn());
531}
532
533sub is_idle {
534 my $this = shift();
535
536 return Net::Z3950::ZOOM::connection_is_idle($this->_conn());
537}
538
539sub peek_event {
540 my $this = shift();
541
542 return Net::Z3950::ZOOM::connection_peek_event($this->_conn());
543}
544
545sub destroy {
546 my $this = shift();
547
548 Net::Z3950::ZOOM::connection_destroy($this->_conn());
549 $this->{_conn} = undef;
550}
551
552
553# ----------------------------------------------------------------------------
554
555package ZOOM::Query;
556
557sub new {
558 my $class = shift();
559 die "You can't create $class objects: it's a virtual base class";
560}
561
562# PRIVATE to this class and ZOOM::Connection::search()
563sub _query {
564 my $this = shift();
565
566 my $_query = $this->{_query};
567 die "{_query} undefined: has this Query been destroy()ed?"
568 if !defined $_query;
569
570 return $_query;
571}
572
573sub sortby {
574 my $this = shift();
575 my($sortby) = @_;
576
577 Net::Z3950::ZOOM::query_sortby($this->_query(), $sortby) == 0
578 or ZOOM::_oops(ZOOM::Error::SORTBY, $sortby);
579}
580
581sub sortby2 {
582 my $this = shift();
583 my($strategy, $sortby) = @_;
584
585 Net::Z3950::ZOOM::query_sortby2($this->_query(), $strategy, $sortby) == 0
586 or ZOOM::_oops(ZOOM::Error::SORTBY, $sortby);
587}
588
589sub destroy {
590 my $this = shift();
591
592 Net::Z3950::ZOOM::query_destroy($this->_query());
593 $this->{_query} = undef;
594}
595
596
597package ZOOM::Query::CQL;
59819µsour @ISA = qw(ZOOM::Query);
599
600sub new {
601 my $class = shift();
602 my($string) = @_;
603
604 my $q = Net::Z3950::ZOOM::query_create()
605 or ZOOM::_oops(ZOOM::Error::CREATE_QUERY);
606 Net::Z3950::ZOOM::query_cql($q, $string) == 0
607 or ZOOM::_oops(ZOOM::Error::QUERY_CQL, $string);
608
609 return bless {
610 _query => $q,
611 }, $class;
612}
613
614
615package ZOOM::Query::CQL2RPN;
61613µsour @ISA = qw(ZOOM::Query);
617
618sub new {
619 my $class = shift();
620 my($string, $conn) = @_;
621
622 my $q = Net::Z3950::ZOOM::query_create()
623 or ZOOM::_oops(ZOOM::Error::CREATE_QUERY);
624 # check() throws the exception we want; but we only want it on failure!
625 Net::Z3950::ZOOM::query_cql2rpn($q, $string, $conn->_conn()) == 0
626 or $conn->_check();
627
628 return bless {
629 _query => $q,
630 }, $class;
631}
632
633
634# We have to work around the retarded ZOOM_query_ccl2rpn() API
635package ZOOM::Query::CCL2RPN;
63612µsour @ISA = qw(ZOOM::Query);
637
638sub new {
639 my $class = shift();
640 my($string, $conn) = @_;
641
642 my $q = Net::Z3950::ZOOM::query_create()
643 or ZOOM::_oops(ZOOM::Error::CREATE_QUERY);
644
645 my $config = $conn->option("cclqual");
646 if (!defined $config) {
647 my $cclfile = $conn->option("cclfile")
648 or ZOOM::_oops(ZOOM::Error::CCL_CONFIG,
649 "no 'cclqual' or 'cclfile' specified");
650 my $fh = new IO::File("<$cclfile")
651 or ZOOM::_oops(ZOOM::Error::CCL_CONFIG,
652 "can't open cclfile '$cclfile': $!");
653 $config = join("", <$fh>);
654 $fh->close();
655 }
656
657 my($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0, "", 0);
658 if (Net::Z3950::ZOOM::query_ccl2rpn($q, $string, $config,
659 $ccl_errcode, $ccl_errstr,
660 $ccl_errpos) < 0) {
661 # We have no use for $ccl_errcode or $ccl_errpos
662 ZOOM::_oops(ZOOM::Error::CCL_PARSE, $ccl_errstr);
663 }
664
665 return bless {
666 _query => $q,
667 }, $class;
668}
669
670
671package ZOOM::Query::PQF;
67212µsour @ISA = qw(ZOOM::Query);
673
674sub new {
675 my $class = shift();
676 my($string) = @_;
677
678 my $q = Net::Z3950::ZOOM::query_create()
679 or ZOOM::_oops(ZOOM::Error::CREATE_QUERY);
680 Net::Z3950::ZOOM::query_prefix($q, $string) == 0
681 or ZOOM::_oops(ZOOM::Error::QUERY_PQF, $string);
682
683 return bless {
684 _query => $q,
685 }, $class;
686}
687
688
689# ----------------------------------------------------------------------------
690
691package ZOOM::ResultSet;
692
693sub new {
694 my $class = shift();
695 die "You can't create $class objects directly";
696}
697
698# PRIVATE to ZOOM::Connection::search() and ZOOM::Connection::search_pqf()
699sub _new {
700 my $class = shift();
701 my($conn, $query, $_rs) = @_;
702
703 return bless {
704 conn => $conn,
705 query => $query, # This is not currently used, which is
706 # just as well since it could be
707 # either a string (when the RS is
708 # created with search_pqf()) or a
709 # ZOOM::Query object (when it's
710 # created with search())
711 _rs => $_rs,
712 }, $class;
713}
714
715# PRIVATE to this class
716sub _rs {
717 my $this = shift();
718
719 my $_rs = $this->{_rs};
720 die "{_rs} undefined: has this ResultSet been destroy()ed?"
721 if !defined $_rs;
722
723 return $_rs;
724}
725
726sub option {
727 my $this = shift();
728 my($key, $value) = @_;
729
730 my $oldval = Net::Z3950::ZOOM::resultset_option_get($this->_rs(), $key);
731 Net::Z3950::ZOOM::resultset_option_set($this->_rs(), $key, $value)
732 if defined $value;
733
734 return $oldval;
735}
736
737sub size {
738 my $this = shift();
739
740 return Net::Z3950::ZOOM::resultset_size($this->_rs());
741}
742
743sub record {
744 my $this = shift();
745 my($which) = @_;
746
747 my $_rec = Net::Z3950::ZOOM::resultset_record($this->_rs(), $which);
748 $this->{conn}->_check();
749
750 # Even if no error has occurred, I think record() might
751 # legitimately return undef if we're running in asynchronous mode
752 # and the record just hasn't been retrieved yet. This goes double
753 # for record_immediate().
754 return undef if !defined $_rec;
755
756 # For some reason, I have to use the explicit "->" syntax in order
757 # to invoke the ZOOM::Record constructor here, even though I don't
758 # have to do the same for _new ZOOM::ResultSet above. Weird.
759 return ZOOM::Record->_new($this, $which, $_rec);
760}
761
762sub record_immediate {
763 my $this = shift();
764 my($which) = @_;
765
766 my $_rec = Net::Z3950::ZOOM::resultset_record_immediate($this->_rs(),
767 $which);
768 $this->{conn}->_check();
769 # The record might legitimately not be there yet
770 return undef if !defined $_rec;
771
772 return ZOOM::Record->_new($this, $which, $_rec);
773}
774
775sub cache_reset {
776 my $this = shift();
777
778 Net::Z3950::ZOOM::resultset_cache_reset($this->_rs());
779}
780
781sub records {
782 my $this = shift();
783 my($start, $count, $return_records) = @_;
784
785 # If the request is out of range, ZOOM-C will currently (as of YAZ
786 # 2.1.38) no-op: it understandably refuses to build and send a
787 # known-bad APDU, but it doesn't set a diagnostic as it ought. So
788 # for now, we do it here. It would be more polite to stash the
789 # error-code in the ZOOM-C connection object for subsequent
790 # discovery (which is what ZOOM-C will presumably do itself when
791 # it's fixed) but since there is no API that allows us to do that,
792 # we just have to throw the exception right now. That's probably
793 # OK for synchronous applications, but not really for
794 # multiplexers.
795 my $size = $this->size();
796 if ($start + $count-1 >= $size) {
797 # BIB-1 diagnostic 13 is "Present request out-of-range"
798 ZOOM::_oops(13, undef, "BIB-1");
799 }
800
801 my $raw = Net::Z3950::ZOOM::resultset_records($this->_rs(), $start, $count,
802 $return_records);
803 # By design, $raw may be undefined (if $return_records is true)
804 return undef if !defined $raw;
805
806 # We need to package up the returned records in ZOOM::Record objects
807 my @res = ();
808 for my $i (0 .. @$raw-1) {
809 my $_rec = $raw->[$i];
810 if (!defined $_rec) {
811 push @res, undef;
812 } else {
813 push @res, ZOOM::Record->_new($this, $start+$i, $_rec);
814 }
815 }
816
817 return \@res;
818}
819
820sub sort {
821 my $this = shift();
822 my($sort_type, $sort_spec) = @_;
823
824 return Net::Z3950::ZOOM::resultset_sort1($this->_rs(),
825 $sort_type, $sort_spec);
826}
827
828sub destroy {
829 my $this = shift();
830
831 Net::Z3950::ZOOM::resultset_destroy($this->_rs());
832 $this->{_rs} = undef;
833}
834
835
836# ----------------------------------------------------------------------------
837
838package ZOOM::Record;
839
840sub new {
841 my $class = shift();
842 die "You can't create $class objects directly";
843}
844
845# PRIVATE to ZOOM::ResultSet::record(),
846# ZOOM::ResultSet::record_immediate(), ZOOM::ResultSet::records() and
847# ZOOM::Record::clone()
848#
849sub _new {
850 my $class = shift();
851 my($rs, $which, $_rec) = @_;
852
853 return bless {
854 rs => $rs,
855 which => $which,
856 _rec => $_rec,
857 }, $class;
858}
859
860# PRIVATE to this class
861sub _rec {
862 my $this = shift();
863
864 my $_rec = $this->{_rec};
865 die "{_rec} undefined: has this Record been destroy()ed?"
866 if !defined $_rec;
867
868 return $_rec;
869}
870
871sub error {
872 my $this = shift();
873
874 my($errcode, $errmsg, $addinfo, $diagset) = (undef, "dummy", "dummy", "d");
875 $errcode = Net::Z3950::ZOOM::record_error($this->_rec(), $errmsg,
876 $addinfo, $diagset);
877
878 return wantarray() ? ($errcode, $errmsg, $addinfo, $diagset) : $errcode;
879}
880
881sub exception {
882 my $this = shift();
883
884 my($errcode, $errmsg, $addinfo, $diagset) = $this->error();
885 return undef if $errcode == 0;
886 return new ZOOM::Exception($errcode, $errmsg, $addinfo, $diagset);
887}
888
889
890sub render {
891 my $this = shift();
892
893 return $this->get("render", @_);
894}
895
896sub raw {
897 my $this = shift();
898
899 return $this->get("raw", @_);
900}
901
902sub get {
903 my $this = shift();
904 my($type, $args) = @_;
905
906 $type = "$type;$args" if defined $args;
907 return Net::Z3950::ZOOM::record_get($this->_rec(), $type);
908}
909
910sub clone {
911 my $this = shift();
912
913 my $raw = Net::Z3950::ZOOM::record_clone($this->_rec())
914 or ZOOM::_oops(ZOOM::Error::CLONE);
915
916 # Arg 1 (rs) is undefined as the new record doesn't belong to an RS
917 return _new ZOOM::Record(undef, undef, $raw);
918}
919
920sub destroy {
921 my $this = shift();
922
923 Net::Z3950::ZOOM::record_destroy($this->_rec());
924 $this->{_rec} = undef;
925}
926
927
928# ----------------------------------------------------------------------------
929
930package ZOOM::ScanSet;
931
932sub new {
933 my $class = shift();
934 die "You can't create $class objects directly";
935}
936
937# PRIVATE to ZOOM::Connection::scan(),
938sub _new {
939 my $class = shift();
940 my($conn, $startterm, $_ss) = @_;
941
942 return bless {
943 conn => $conn,
944 startterm => $startterm,# This is not currently used, which is
945 # just as well since it could be
946 # either a string (when the SS is
947 # created with scan()) or a
948 # ZOOM::Query object (when it's
949 # created with scan1())
950 _ss => $_ss,
951 }, $class;
952}
953
954# PRIVATE to this class
955sub _ss {
956 my $this = shift();
957
958 my $_ss = $this->{_ss};
959 die "{_ss} undefined: has this ScanSet been destroy()ed?"
960 if !defined $_ss;
961
962 return $_ss;
963}
964
965sub option {
966 my $this = shift();
967 my($key, $value) = @_;
968
969 my $oldval = Net::Z3950::ZOOM::scanset_option_get($this->_ss(), $key);
970 Net::Z3950::ZOOM::scanset_option_set($this->_ss(), $key, $value)
971 if defined $value;
972
973 return $oldval;
974}
975
976sub size {
977 my $this = shift();
978
979 return Net::Z3950::ZOOM::scanset_size($this->_ss());
980}
981
982sub term {
983 my $this = shift();
984 my($which) = @_;
985
986 my($occ, $len) = (0, 0);
987 my $term = Net::Z3950::ZOOM::scanset_term($this->_ss(), $which,
988 $occ, $len)
989 or ZOOM::_oops(ZOOM::Error::SCANTERM);
990
991 die "length of term '$term' differs from returned len=$len"
992 if length($term) != $len;
993
994 return ($term, $occ);
995}
996
997sub display_term {
998 my $this = shift();
999 my($which) = @_;
1000
1001 my($occ, $len) = (0, 0);
1002 my $term = Net::Z3950::ZOOM::scanset_display_term($this->_ss(), $which,
1003 $occ, $len)
1004 or ZOOM::_oops(ZOOM::Error::SCANTERM);
1005
1006 die "length of display term '$term' differs from returned len=$len"
1007 if length($term) != $len;
1008
1009 return ($term, $occ);
1010}
1011
1012sub destroy {
1013 my $this = shift();
1014
1015 Net::Z3950::ZOOM::scanset_destroy($this->_ss());
1016 $this->{_ss} = undef;
1017}
1018
1019
1020# ----------------------------------------------------------------------------
1021
1022package ZOOM::Package;
1023
1024sub new {
1025 my $class = shift();
1026 die "You can't create $class objects directly";
1027}
1028
1029# PRIVATE to ZOOM::Connection::package(),
1030sub _new {
1031 my $class = shift();
1032 my($conn, $options, $_p) = @_;
1033
1034 return bless {
1035 conn => $conn,
1036 options => $options,
1037 _p => $_p,
1038 }, $class;
1039}
1040
1041# PRIVATE to this class
1042sub _p {
1043 my $this = shift();
1044
1045 my $_p = $this->{_p};
1046 die "{_p} undefined: has this Package been destroy()ed?"
1047 if !defined $_p;
1048
1049 return $_p;
1050}
1051
1052sub option {
1053 my $this = shift();
1054 my($key, $value) = @_;
1055
1056 my $oldval = Net::Z3950::ZOOM::package_option_get($this->_p(), $key);
1057 Net::Z3950::ZOOM::package_option_set($this->_p(), $key, $value)
1058 if defined $value;
1059
1060 return $oldval;
1061}
1062
1063sub send {
1064 my $this = shift();
1065 my($type) = @_;
1066
1067 Net::Z3950::ZOOM::package_send($this->_p(), $type);
1068 $this->{conn}->_check();
1069}
1070
1071sub destroy {
1072 my $this = shift();
1073
1074 Net::Z3950::ZOOM::package_destroy($this->_p());
1075 $this->{_p} = undef;
1076}
1077
1078
1079# There follows trivial support for YAZ logging. This is wired out
1080# into the Net::Z3950::ZOOM package, and we here provide wrapper
1081# functions -- nothing more than aliases, really -- in the ZOOM::Log
1082# package. There really is no point in inventing an OO interface.
1083#
1084# Passing @_ directly to the underlying Net::Z3950::ZOOM::* functions
1085# doesn't work, for reasons that I can't begin to fathom, and that
1086# don't particularly interest me. Unpacking into scalars and passing
1087# those _does_ work, so that's what we do.
1088
1089package ZOOM::Log;
1090
1091235µs123µs
# spent 33µs (10+23) within ZOOM::Log::mask_str which was called: # once (10µs+23µs) by ZOOM::Log::BEGIN@1115 at line 1115
sub mask_str { my($a) = @_; Net::Z3950::ZOOM::yaz_log_mask_str($a); }
# spent 23µs making 1 call to Net::Z3950::ZOOM::yaz_log_mask_str
1092sub module_level { my($a) = @_; Net::Z3950::ZOOM::yaz_log_module_level($a); }
1093sub init { my($a, $b, $c) = @_;
1094 Net::Z3950::ZOOM::yaz_log_init($a, $b, $c) }
1095sub init_file { my($a) = @_; Net::Z3950::ZOOM::yaz_log_init_file($a) }
1096sub init_level { my($a) = @_; Net::Z3950::ZOOM::yaz_log_init_level($a) }
1097sub init_prefix { my($a) = @_; Net::Z3950::ZOOM::yaz_log_init_prefix($a) }
1098sub time_format { my($a) = @_; Net::Z3950::ZOOM::yaz_log_time_format($a) }
1099sub init_max_size { my($a) = @_; Net::Z3950::ZOOM::yaz_log_init_max_size($a) }
1100
1101sub log {
1102 my($level, @message) = @_;
1103
1104 if ($level !~ /^(0x)?\d+$/) {
1105 # Assuming its log-level name, we look it up.
1106 my $num = module_level($level);
1107 ZOOM::_oops(ZOOM::Error::LOGLEVEL, $level)
1108 if $num == 0;
1109 $level = $num;
1110 }
1111
1112 Net::Z3950::ZOOM::yaz_log($level, join("", @message));
1113}
1114
1115152µs274µs
# spent 41µs (8+33) within ZOOM::Log::BEGIN@1115 which was called: # once (8µs+33µs) by C4::Context::BEGIN@101 at line 1115
BEGIN { ZOOM::Log::mask_str("zoom_check"); }
# spent 41µs making 1 call to ZOOM::Log::BEGIN@1115 # spent 33µs making 1 call to ZOOM::Log::mask_str
1116
111715µs1;