253bba1b96e83cc24296d250dcc6ad74f721ffb4
[idzebra-moved-to-github.git] / perl / lib / IDZebra / Resultset.pm
1 # $Id: Resultset.pm,v 1.11 2004-07-28 08:15:46 adam Exp $
2
3 # Zebra perl API header
4 # =============================================================================
5 package IDZebra::Resultset;
6
7 use strict;
8 use warnings;
9
10 BEGIN {
11     use IDZebra;
12     use IDZebra::Logger qw(:flags :calls);
13     use Scalar::Util qw(weaken);
14     use Carp;
15     our $VERSION = do { my @r = (q$Revision: 1.11 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; 
16     our @ISA = qw(IDZebra::Logger);
17 }
18
19 1;
20 # -----------------------------------------------------------------------------
21 # Class constructors, destructor
22 # -----------------------------------------------------------------------------
23 sub new {
24     my ($proto,$session, %args) = @_;
25     my $class = ref($proto) || $proto;
26     my $self = {};
27     bless ($self, $class);
28
29     $self->{session} = $session;
30     weaken ($self->{session});
31
32     $self->{odr_stream} = IDZebra::odr_createmem($IDZebra::ODR_DECODE);
33
34     $self->{name}        = $args{name};
35     $self->{query}       = $args{query};
36     $self->{recordCount} = $args{recordCount};
37     $self->{errCode}     = $args{errCode};
38     $self->{errString}   = $args{errString};
39
40     return ($self);
41 }
42
43 sub recordCount {
44     my ($self) = @_;
45     return ($self->{recordCount});
46 }
47 sub count {
48     my ($self) = @_;
49     return ($self->{recordCount});
50 }
51
52 sub errCode {
53     my ($self) = @_;
54     return ($self->{errCode});
55 }
56
57 sub errString {
58     my ($self) = @_;
59     return ($self->{errCode});
60 }
61
62 sub terms {
63     use Data::Dumper;
64     my ($self) = @_;
65     my $count = 0; my $type = 0; my $len = 0;
66     my $tc = IDZebra::resultSetTerms($self->{session}{zh},$self->{name},
67                                      0, \$count, \$type, "\0", \$len);
68
69     logf (LOG_LOG,"Got $tc terms");
70     
71     
72     my @res = ();
73     for (my $i=0; $i<$tc; $i++) {
74         my $len = 1024;
75         my $t = {term => "\0" x $len, count => 0, type => 0};
76         my $stat = IDZebra::resultSetTerms($self->{session}{zh},$self->{name},
77                                            $i, \$t->{count}, \$t->{type}, 
78                                            $t->{term}, \$len);
79         $t->{term} = substr($t->{term}, 0, $len);
80         logf (LOG_LOG,
81               "term $i: type $t->{type}, '$t->{term}' ($t->{count})");
82         push (@res, $t);
83     }
84     return (@res);
85 }
86
87 # =============================================================================
88 sub DESTROY {
89     my $self = shift;
90
91 #    print STDERR "Destroy RS\n";
92     # Deleteresultset?
93     
94     my $stats = 0;
95     if ($self->{session}{zh}) { 
96         my $r = IDZebra::deleteResultSet($self->{session}{zh},
97                                          0, #Z_DeleteRequest_list,
98                                          1,[$self->{name}],
99                                          $stats);
100     }
101
102     if ($self->{odr_stream}) {
103         IDZebra::odr_reset($self->{odr_stream});
104         IDZebra::odr_destroy($self->{odr_stream});
105         $self->{odr_stream} = undef;  
106     }
107
108     delete($self->{session});
109 }
110 # -----------------------------------------------------------------------------
111 sub records {
112     my ($self, %args) = @_;
113
114     unless ($self->{session}{zh}) { 
115         croak ("Session is closed or out of scope");
116     }
117     my $from = $args{from} ? $args{from} : 1;
118     my $to   = $args{to}   ? $args{to}   : $self->{recordCount};
119
120     if (($to-$from) >= 1000) {
121         if ($args{to}) {
122             croak ("Cannot fetch more than 1000 records at a time");
123         } else {
124             $to = $from + 999;
125         }
126     }
127
128     my $elementSet   = $args{elementSet}   ? $args{elementSet}    : 'R';
129     my $schema       = $args{schema}       ? $args{schema}        : '';
130     my $recordSyntax = $args{recordSyntax} ? $args{recordSyntax}  : '';
131     
132     my $class        = $args{class}        ? $args{class}         : '';
133     
134     # ADAM: Reset before we use it (not after)
135     IDZebra::odr_reset($self->{odr_stream});
136
137     my $ro = IDZebra::RetrievalObj->new();
138     IDZebra::records_retrieve($self->{session}{zh},
139                               $self->{odr_stream},
140                               $self->{name},
141                               $elementSet,
142                               $schema,
143                               $recordSyntax,
144                               $from,
145                               $to,
146                               $ro);
147
148     my @res = ();
149
150     for (my $i=$from; $i<=$to; $i++) {
151         my $rec = IDZebra::RetrievalRecord->new();
152         IDZebra::record_retrieve($ro, $self->{odr_stream}, $rec, $i-$from+1);
153         if ($class) {
154             
155         } else {
156             push (@res, $rec); 
157         }
158     }
159
160     return (@res);
161 }
162
163 # ============================================================================
164 sub sort {
165     my ($self, $sortspec, $setname) = @_;
166
167     unless ($self->{session}{zh}) { 
168         croak ("Session is closed or out of scope");
169     }
170
171     unless ($setname) {
172         return ($_[0] = $self->{session}->sortResultsets($sortspec, 
173                                                  $self->{session}->_new_setname, ($self)));
174         return ($_[0]);
175     } else {
176         return ($self->{session}->sortResultsets($sortspec, 
177                                                  $setname, ($self)));
178     }
179 }
180
181 # ============================================================================
182 __END__
183
184 =head1 NAME
185
186 IDZebra::Resultset - Representation of Zebra search results
187
188 =head1 SYNOPSIS
189
190   $count = $rs->count;
191
192   printf ("RS Status is %d (%s)\n", $rs->errCode, $rs->errString);
193
194   my @recs = $rs->records(from => 1,
195                           to   => 10);
196
197 =head1 DESCRIPTION
198
199 The I<Resultset> object represents results of a Zebra search. Contains number of hits, search status, and can be used to sort and retrieve the records.
200
201 =head1 PROPERTIES
202
203 The folowing properties are available, trough object methods and the object hash reference:
204
205 =over 4
206
207 =item B<errCode>
208
209 The error code returned from search, resulting the Resultset object.
210
211 =item B<errString>
212
213 The optional error string
214
215 =item B<recordCount>
216
217 The number of hits (records available) in the resultset
218
219 =item B<count>
220
221 Just the synonym for I<recordCount>
222
223 =back
224
225 =head1 RETRIEVING RECORDS
226
227 In order to retrieve records, use the I<records> method:
228
229   my @recs = $rs->records();
230
231 By default this is going to return an array of IDZebra::RetrievalRecord objects. The possible arguments are:
232
233 =over 4
234
235 =item B<from>
236
237 Retrieve records from the given position. The first record corresponds to position 1. If not specified, retrieval starts from the first record.
238
239 =item B<to>
240
241 The last record position to be fetched. If not specified, all records are going to be fetched, starting from position I<from>.
242
243 =item B<elementSet>
244
245 The element set used for retrieval. If not specified 'I<R>' is used, which will return the "record" in the original format (ie.: without extraction, just as the original file, or data buffer in the update call).
246
247 =item B<schema>
248
249 The schema used for retrieval. The default is "".
250
251 =item B<recordSyntax>
252
253 The record syntax for retrieval. The default is SUTRS.
254
255 =back
256
257 =head1 SORTING
258
259 You can sort resultsets by calling:
260
261   $rs1->sort($sort_expr);
262
263 or create a new sorted resultset:
264
265   $rs2 = $rs1->sort($sort_expr);
266
267 The sort expression has the same format as described in the I<yaz_client> documentation. For example:
268
269   $rs1->sort('1=4 id');
270
271 will sort thr results by title, in a case insensitive way, in descending order, while
272
273   $rs1->sort('1=4 a');
274
275 will sort ascending by titles.
276
277 =head1 COPYRIGHT
278
279 Fill in
280
281 =head1 AUTHOR
282
283 Peter Popovics, pop@technomat.hu
284
285 =head1 SEE ALSO
286
287 Zebra documentation, IDZebra::ResultSet, IDZebra::RetrievalRecord manpages.
288
289 =cut