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