]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Utils/ZClient.pm
multi-target Z39.50 searches -- just supply an array for all of username, password...
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / ZClient.pm
1 package OpenILS::Utils::ZClient;
2 use UNIVERSAL::require;
3
4 use overload 'bool' => sub { return $_[0]->{connection} ? 1 : 0 };
5
6 sub EVENT_NONE { 0 }
7 sub EVENT_CONNECT { 1 }
8 sub EVENT_SEND_DATA { 2 }
9 sub EVENT_RECV_DATA { 3 }
10 sub EVENT_TIMEOUT { 4 }
11 sub EVENT_UNKNOWN { 5 }
12 sub EVENT_SEND_APDU { 6 }
13 sub EVENT_RECV_APDU { 7 }
14 sub EVENT_RECV_RECORD { 8 }
15 sub EVENT_RECV_SEARCH { 9 }
16 sub EVENT_END { 10 }
17
18 our $conn_class = 'ZOOM::Connection';
19 our $imp_class = 'ZOOM';
20 our $AUTOLOAD;
21
22 # Detect the installed z client, prefering ZOOM.
23 if (!$imp_class->use()) {
24
25         $imp_class = 'Net::Z3950';  # Try Net::Z3950
26         if ($imp_class->use()) {
27
28                 # Tell 'new' how to build the connection
29                 $conn_class = 'Net::Z3950::Connection';
30                 
31         } else {
32                 die "Cannot load a z39.50 client implementation!  Please install either ZOOM or Net::Z3950.\n";
33         }
34 }
35
36 # 'new' is called thusly:
37 #  my $conn = OpenILS::Utils::ZClient->new( $host, $port, databaseName => $db, user => $username )
38
39 sub new {
40         my $class = shift();
41         my @args = @_;
42
43         if ($class ne __PACKAGE__) { # NOT called OO-ishly
44                 # put the first param back if called like OpenILS::Utils::ZClient::new()
45                 unshift @args, $class;
46         }
47
48         return bless { connection => $conn_class->new(@_) } => __PACKAGE__;
49 }
50
51 sub search {
52         my $self = shift;
53         my $r =  $imp_class eq 'Net::Z3950' ?
54                 $self->{connection}->search( @_ ) :
55                 $self->{connection}->search_pqf( @_ );
56
57         return OpenILS::Utils::ZClient::ResultSet->new( $r );
58 }
59
60 sub event {
61         my $list = shift;
62         if ($imp_class eq 'Net::Z3950') {
63                 if (defined $$list[0]{_async_index}) {  
64                         return 0 if ($$list[0]{_async_index} == @$list);
65                         return ++$$list[0]{_async_index};
66                 } else {
67                         return $$list[0]{_async_index} = 1;
68                 }
69         }
70
71         return ZOOM::event([map { ($_->{connection}) } @$list]);
72 }
73
74 *{__PACKAGE__ . '::search_pqf'} = \&search; 
75
76 sub AUTOLOAD {
77         my $self = shift;
78
79         my $method = $AUTOLOAD;
80         $method =~ s/.*://;   # strip fully-qualified portion
81
82         return $self->{connection}->$method( @_ );
83 }
84
85 #-------------------------------------------------------------------------------
86 package OpenILS::Utils::ZClient::ResultSet;
87
88 our $AUTOLOAD;
89
90 sub new {
91         my $class = shift;
92         my @args = @_;
93
94         if ($class ne __PACKAGE__) { # NOT called OO-ishly
95                 # put the first param back if called like OpenILS::Utils::ZClient::ResultSet::new()
96                 unshift @args, $class;
97         }
98
99
100         return bless { result => $args[0] } => __PACKAGE__;
101 }
102
103 sub record {
104         my $self = shift;
105         my $offset = shift;
106         my $r = $imp_class eq 'Net::Z3950' ?
107                 $self->{result}->record( ++$offset ) :
108                 $self->{result}->record( $offset );
109
110         return  OpenILS::Utils::ZClient::Record->new( $r );
111 }
112
113 sub last_event {
114         my $self = shift;
115         return OpenILS::Utils::ZClient::EVENT_END() if ($imp_class eq 'Net::Z3950');
116         $self->{result}->last_event();
117 }
118
119 sub AUTOLOAD {
120         my $self = shift;
121
122         my $method = $AUTOLOAD;
123         $method =~ s/.*://;   # strip fully-qualified portion
124
125         return $self->{result}->$method( @_ );
126 }
127
128 #-------------------------------------------------------------------------------
129 package OpenILS::Utils::ZClient::Record;
130
131 our $AUTOLOAD;
132
133 sub new {
134         my $class = shift;
135         my @args = @_;
136
137         if ($class ne __PACKAGE__) { # NOT called OO-ishly
138                 # put the first param back if called like OpenILS::Utils::ZClient::ResultSet::new()
139                 unshift @args, $class;
140         }
141
142
143         return bless { record => shift() } => __PACKAGE__;
144 }
145
146 sub rawdata {
147         my $self = shift;
148         return $OpenILS::Utils::ZClient::imp_class eq 'Net::Z3950' ?
149                 $self->{record}->rawdata( @_ ) :
150                 $self->{record}->raw( @_ );
151 }
152
153 *{__PACKAGE__ . '::raw'} = \&rawdata; 
154
155 sub AUTOLOAD {
156         my $self = shift;
157
158         my $method = $AUTOLOAD;
159         $method =~ s/.*://;   # strip fully-qualified portion
160
161         return $self->{record}->$method( @_ );
162 }
163
164 1;
165