Cleaned test scripts to be (nearly?) atomic
[idzebra-moved-to-github.git] / perl / lib / IDZebra / Resultset.pm
1 # $Id: Resultset.pm,v 1.12 2004-09-15 14:11:06 heikki 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.12 $ =~ /\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 ######################
63 # this is disabled, while the term counts are broken by the work done to
64 # rsets. To be reinstantiated some day real soon now...
65 #sub terms {
66 #    use Data::Dumper;
67 #    my ($self) = @_;
68 #    my $count = 0; my $type = 0; my $len = 0;
69 #    my $tc = IDZebra::resultSetTerms($self->{session}{zh},$self->{name},
70 #                                    0, \$count, \$type, "\0", \$len);
71 #
72 #    logf (LOG_LOG,"Got $tc terms");
73 #    
74 #    
75 #    my @res = ();
76 #    for (my $i=0; $i<$tc; $i++) {
77 #       my $len = 1024;
78 #       my $t = {term => "\0" x $len, count => 0, type => 0};
79 #       my $stat = IDZebra::resultSetTerms($self->{session}{zh},$self->{name},
80 #                                          $i, \$t->{count}, \$t->{type}, 
81 #                                          $t->{term}, \$len);
82 #       $t->{term} = substr($t->{term}, 0, $len);
83 #       logf (LOG_LOG,
84 #             "term $i: type $t->{type}, '$t->{term}' ($t->{count})");
85 #       push (@res, $t);
86 #    }
87 #    return (@res);
88 #}
89
90 # =============================================================================
91 sub DESTROY {
92     my $self = shift;
93
94 #    print STDERR "Destroy RS\n";
95     # Deleteresultset?
96     
97     my $stats = 0;
98     if ($self->{session}{zh}) { 
99         my $r = IDZebra::deleteResultSet($self->{session}{zh},
100                                          0, #Z_DeleteRequest_list,
101                                          1,[$self->{name}],
102                                          $stats);
103     }
104
105     if ($self->{odr_stream}) {
106         IDZebra::odr_reset($self->{odr_stream});
107         IDZebra::odr_destroy($self->{odr_stream});
108         $self->{odr_stream} = undef;  
109     }
110
111     delete($self->{session});
112 }
113 # -----------------------------------------------------------------------------
114 sub records {
115     my ($self, %args) = @_;
116
117     unless ($self->{session}{zh}) { 
118         croak ("Session is closed or out of scope");
119     }
120     my $from = $args{from} ? $args{from} : 1;
121     my $to   = $args{to}   ? $args{to}   : $self->{recordCount};
122
123     if (($to-$from) >= 1000) {
124         if ($args{to}) {
125             croak ("Cannot fetch more than 1000 records at a time");
126         } else {
127             $to = $from + 999;
128         }
129     }
130
131     my $elementSet   = $args{elementSet}   ? $args{elementSet}    : 'R';
132     my $schema       = $args{schema}       ? $args{schema}        : '';
133     my $recordSyntax = $args{recordSyntax} ? $args{recordSyntax}  : '';
134     
135     my $class        = $args{class}        ? $args{class}         : '';
136     
137     # ADAM: Reset before we use it (not after)
138     IDZebra::odr_reset($self->{odr_stream});
139
140     my $ro = IDZebra::RetrievalObj->new();
141     IDZebra::records_retrieve($self->{session}{zh},
142                               $self->{odr_stream},
143                               $self->{name},
144                               $elementSet,
145                               $schema,
146                               $recordSyntax,
147                               $from,
148                               $to,
149                               $ro);
150
151     my @res = ();
152
153     for (my $i=$from; $i<=$to; $i++) {
154         my $rec = IDZebra::RetrievalRecord->new();
155         IDZebra::record_retrieve($ro, $self->{odr_stream}, $rec, $i-$from+1);
156         if ($class) {
157             
158         } else {
159             push (@res, $rec); 
160         }
161     }
162
163     return (@res);
164 }
165
166 # ============================================================================
167 sub sort {
168     my ($self, $sortspec, $setname) = @_;
169
170     unless ($self->{session}{zh}) { 
171         croak ("Session is closed or out of scope");
172     }
173
174     unless ($setname) {
175         return ($_[0] = $self->{session}->sortResultsets($sortspec, 
176                          $self->{session}->_new_setname, ($self)));
177         return ($_[0]);
178     } else {
179         return ($self->{session}->sortResultsets($sortspec, 
180                                                  $setname, ($self)));
181     }
182 }
183
184 # ============================================================================
185 __END__
186
187 =head1 NAME
188
189 IDZebra::Resultset - Representation of Zebra search results
190
191 =head1 SYNOPSIS
192
193   $count = $rs->count;
194
195   printf ("RS Status is %d (%s)\n", $rs->errCode, $rs->errString);
196
197   my @recs = $rs->records(from => 1,
198                           to   => 10);
199
200 =head1 DESCRIPTION
201
202 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.
203
204 =head1 PROPERTIES
205
206 The folowing properties are available, trough object methods and the object hash reference:
207
208 =over 4
209
210 =item B<errCode>
211
212 The error code returned from search, resulting the Resultset object.
213
214 =item B<errString>
215
216 The optional error string
217
218 =item B<recordCount>
219
220 The number of hits (records available) in the resultset
221
222 =item B<count>
223
224 Just the synonym for I<recordCount>
225
226 =back
227
228 =head1 RETRIEVING RECORDS
229
230 In order to retrieve records, use the I<records> method:
231
232   my @recs = $rs->records();
233
234 By default this is going to return an array of IDZebra::RetrievalRecord objects. The possible arguments are:
235
236 =over 4
237
238 =item B<from>
239
240 Retrieve records from the given position. The first record corresponds to position 1. If not specified, retrieval starts from the first record.
241
242 =item B<to>
243
244 The last record position to be fetched. If not specified, all records are going to be fetched, starting from position I<from>.
245
246 =item B<elementSet>
247
248 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).
249
250 =item B<schema>
251
252 The schema used for retrieval. The default is "".
253
254 =item B<recordSyntax>
255
256 The record syntax for retrieval. The default is SUTRS.
257
258 =back
259
260 =head1 SORTING
261
262 You can sort resultsets by calling:
263
264   $rs1->sort($sort_expr);
265
266 or create a new sorted resultset:
267
268   $rs2 = $rs1->sort($sort_expr);
269
270 The sort expression has the same format as described in the I<yaz_client> documentation. For example:
271
272   $rs1->sort('1=4 id');
273
274 will sort thr results by title, in a case insensitive way, in descending order, while
275
276   $rs1->sort('1=4 a');
277
278 will sort ascending by titles.
279
280 =head1 COPYRIGHT
281
282 Fill in
283
284 =head1 AUTHOR
285
286 Peter Popovics, pop@technomat.hu
287
288 =head1 SEE ALSO
289
290 Zebra documentation, IDZebra::ResultSet, IDZebra::RetrievalRecord manpages.
291
292 =cut