* perl5.swg
*
* Perl5 runtime library
- * $Header: /home/cvsroot/idis/perl/Attic/IDZebra_wrap.c,v 1.6 2003-02-28 16:17:42 pop Exp $
+ * $Header: /home/cvsroot/idis/perl/Attic/IDZebra_wrap.c,v 1.7 2003-02-28 18:38:28 pop Exp $
* ----------------------------------------------------------------------------- */
#define SWIGPERL
+++ /dev/null
-#!/usr/bin/perl
-# ============================================================================
-# Zebra perl API header
-# =============================================================================
-use strict;
-# ============================================================================
-package IDZebra::Repository;
-use IDZebra;
-use IDZebra::Logger qw(:flags :calls);
-use Carp;
-use Scalar::Util qw(weaken);
-1;
-
-
-# -----------------------------------------------------------------------------
-# Repository stuff
-# -----------------------------------------------------------------------------
-
-sub new {
- my ($proto,$session,%args) = @_;
- my $class = ref($proto) || $proto;
- my $self = {};
- $self->{session} = $session;
- weaken ($self->{session});
- $self->{rg} = IDZebra::recordGroup->new();
- IDZebra::init_recordGroup($self->{rg});
- bless ($self, $class);
- unless ($self->_set_options(%args)) {
- $self->_prepare;
- }
- return ($self);
-}
-
-sub modify {
- my ($self,%args) = @_;
- if ($args{name}) {
- if ($args{name} ne $self->{rg}{groupName}) {
- $self->readConfig($args{name},"");
- }
- delete($args{name});
- }
- $self->_set_options(%args);
-}
-
-sub readConfig {
- my ($self, $groupName, $ext) = @_;
- if ($#_ > 0) {
- IDZebra::init_recordGroup($self->{rg});
- $self->{rg}{groupName} = $groupName;
- }
- $ext = "" unless ($ext);
- IDZebra::res_get_recordGroup($self->{session}{zh}, $self->{rg}, $ext);
- $self->_prepare();
-}
-
-sub _set_options {
- my ($self, %args) = @_;
- my $i = 0;
- foreach my $key (keys(%args)) {
- $self->{rg}{$key} = $args{$key};
- $i++;
- }
- if ($i > 0) {
- $self->_prepare();
- }
- return ($i);
-}
-
-sub _prepare {
- my ($self) = @_;
-
- IDZebra::set_group($self->{session}{zh}, $self->{rg});
-
- my $dbName;
- unless ($dbName = $self->{rg}{databaseName}) {
- $dbName = 'Default';
- }
- if (my $res = IDZebra::select_database($self->{session}{zh}, $dbName)) {
- logf(LOG_FATAL,
- "Could not select database %s errCode=%d",
- $self->{rg}{databaseName},
- $self->{session}->errCode());
- croak("Fatal error opening/selecting database (record group)");
- } else {
- logf(LOG_LOG,"Database %s selected",$dbName);
- }
-}
-
-sub DEBUG {
- my ($self) = @_;
- foreach my $key qw (groupName databaseName path recordId recordType flagStoreData flagStoreKeys flagRw fileVerboseLimit databaseNamePath explainDatabase followLinks) {
- print STDERR "RG:$key:",$self->{rg}{$key},"\n";
- }
-}
-
-sub init {
- my ($self, %args) = @_;
- $self->_set_options(%args);
- IDZebra::init($self->{session}{zh});
-}
-
-sub compact {
- my ($self, %args) = @_;
- $self->_set_options(%args);
- IDZebra::compact($self->{session}{zh});
-}
-
-sub update {
- my ($self, %args) = @_;
- $self->_set_options(%args);
- IDZebra::repository_update($self->{session}{zh});
-}
-
-sub delete {
- my ($self, %args) = @_;
- $self->_set_options(%args);
- IDZebra::repository_delete($self->{session}{zh});
-}
-
-sub show {
- my ($self, %args) = @_;
- $self->_set_options(%args);
- IDZebra::repository_show($self->{session}{zh});
-}
-
-sub update_record {
- my ($self, %args) = @_;
- return(IDZebra::update_record($self->{session}{zh},
- $self->{rg},
- $self->update_args(%args)));
-}
-
-sub delete_record {
- my ($self, %args) = @_;
- return(IDZebra::delete_record($self->{session}{zh},
- $self->{rg},
- $self->update_args(%args)));
-}
-
-sub update_args {
- my ($self, %args) = @_;
-
- my $sysno = $args{sysno} ? $args{sysno} : 0;
- my $match = $args{match} ? $args{match} : "";
- my $rectype = $args{recordType} ? $args{recordType} : "";
- my $fname = $args{file} ? $args{file} : "<no file>";
-
- my $buff;
-
- if ($args{data}) {
- $buff = $args{data};
- }
- elsif ($args{file}) {
- open (F, $args{file}) || warn ("Cannot open $args{file}");
- $buff = join('',(<F>));
- close (F);
- }
- my $len = length($buff);
-
- # If no record type is given, then try to find it out from the
- # file extension;
-
- unless ($rectype) {
- my ($ext) = $fname =~ /\.(\w+)$/;
- $self->readConfig( $self->{rg}{groupName},$ext);
- }
-
- return ($rectype, $sysno, $match, $fname, $buff, $len);
-}
-
-sub DESTROY {
- my ($self) = @_;
-}
-
-__END__
-
-=head1 NAME
-
-IDZebra::Repository -
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-=head1 COPYRIGHT
-
-Fill in
-
-=head1 AUTHOR
-
-Peter Popovics, pop@technomat.hu
-
-=head1 SEE ALSO
-
-IDZebra, IDZebra::Data1, Zebra documentation
-
-=cut
return ($self);
}
+sub count {
+ my ($self) = @_;
+ return ($self->{recordCount});
+}
+
+sub errCode {
+ my ($self) = @_;
+ return ($self->{errCode});
+}
+
+sub errString {
+ my ($self) = @_;
+ return ($self->{errCode});
+}
+
sub DESTROY {
my ($self) = @_;
}
}
+# ============================================================================
__END__
=head1 NAME
-IDZebra::Session -
+IDZebra::Resultset - Representation of Zebra search results
=head1 SYNOPSIS
=head1 DESCRIPTION
+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.
+
+=head1 PROPERTIES
+
+ $count = $rs->count;
+
+ printf ("RS Status is %d (%s)\n", $rs->errCode, $rs->errString);
+
+I<$rs-E<gt>errCode> is 0, if there were no errors during search.
+
+=head1 RETRIEVING RECORDS
+
+
=head1 COPYRIGHT
Fill in
+++ /dev/null
-#!/usr/bin/perl
-# ============================================================================
-# Zebra perl API header
-# =============================================================================
-use strict;
-use Carp;
-# ============================================================================
-package IDZebra::Service;
-use IDZebra;
-use IDZebra::Session;
-use IDZebra::Logger qw(:flags :calls);
-use Scalar::Util qw(weaken);
-
-our @ISA = qw(IDZebra::Logger);
-
-1;
-# -----------------------------------------------------------------------------
-# Class constructors, destructor
-# -----------------------------------------------------------------------------
-sub new {
- my ($proto,$configName) = @_;
- my $class = ref($proto) || $proto;
- my $self = {};
- $self->{configName} = $configName;
- $self->{sessions} = {};
- $self->{sessc} = 0;
- bless ($self, $class);
- return ($self);
-}
-
-sub start {
- my ($proto,$configName) = @_;
- my $self = {};
- if (ref($proto)) { $self = $proto; } else {
- $self = $proto->new($configName);
- }
- unless (defined($self->{zs})) {
- $self->{zs} = IDZebra::start($self->{configName});
- }
- return ($self);
-}
-
-sub stop {
- my ($self) = @_;
- foreach my $sess (values(%{$self->{sessions}})) {
- $sess->close;
- }
- IDZebra::stop($self->{zs}) if ($self->{zs});
- $self->{zs} = undef;
-}
-
-sub DESTROY {
- my ($self) = @_;
- $self->stop;
-}
-# -----------------------------------------------------------------------------
-# Session management
-# -----------------------------------------------------------------------------
-sub createSession {
- my ($self) = @_;
- my $session = IDZebra::Session->new($self);
- $self->{sessions}{$self->{sessc}} = $session;
- weaken ($self->{sessions}{$self->{sessc}});
- $self->{sessc}++;
- return($session);
-}
-
-sub openSession {
- my ($self) = @_;
- my $session = IDZebra::Session->open($self);
- $self->{sessions}{$self->{sessc}} = $session;
- weaken ($self->{sessions}{$self->{sessc}});
- $self->{sessc}++;
- return($session);
-}
-
-__END__
-
-=head1 NAME
-
-IDZebra::Service -
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-=head1 COPYRIGHT
-
-Fill in
-
-=head1 AUTHOR
-
-Peter Popovics, pop@technomat.hu
-
-=head1 SEE ALSO
-
-IDZebra, IDZebra::Data1, Zebra documentation
-
-=cut
-#!/usr/bin/perl
-# ============================================================================
+# $Id: Session.pm,v 1.5 2003-02-28 18:38:29 pop Exp $
+#
# Zebra perl API header
# =============================================================================
use strict;
-# ============================================================================
package IDZebra::Session;
use IDZebra;
use IDZebra::Logger qw(:flags :calls);
-#use IDZebra::Repository;
use IDZebra::Resultset;
use Scalar::Util;
use Carp;
$self->{rscount} = 0;
# This is needed in order to somehow initialize the service
- $self->select_databases("Default");
+ $self->databases("Default");
# Load the default configuration
$self->group(%args);
unless ($dbName = $rg->{databaseName}) {
$dbName = 'Default';
}
- if ($self->select_databases($dbName)) {
+ unless ($self->databases($dbName)) {
croak("Fatal error selecting database $dbName");
}
}
# -----------------------------------------------------------------------------
# Selecting databases for search (and also for updating - internally)
# -----------------------------------------------------------------------------
-sub select_databases {
+sub databases {
my ($self, @databases) = @_;
+ unless ($#_ >0) {
+ return (keys(%{$self->{databases}}));
+ }
+
+ my %tmp;
+
my $changed = 0;
foreach my $db (@databases) {
next if ($self->{databases}{$db});
+ $tmp{$db}++;
$changed++;
}
+ foreach my $db (keys (%{$self->{databases}})) {
+ $changed++ unless ($tmp{$db});
+ }
+
if ($changed) {
delete ($self->{databases});
$self->{databases}{$db}++;
}
- if (my $res = IDZebra::select_databases($self->{zh},
+ if (IDZebra::select_databases($self->{zh},
($#databases + 1),
\@databases)) {
logf(LOG_FATAL,
"Could not select database(s) %s errCode=%d",
join(",",@databases),
$self->errCode());
- return ($res);
+ return (0);
} else {
logf(LOG_LOG,"Database(s) selected: %s",join(",",@databases));
}
}
- return (0);
+ return (keys(%{$self->{databases}}));
}
# -----------------------------------------------------------------------------
croak ("No query given to search");
}
+ my @origdbs;
+
+ if ($args{databases}) {
+ @origdbs = $self->databases;
+ $self->databases(@{$args{databases}});
+ }
+
my $rsname = $args{rsname} ? $args{rsname} : $self->_new_setname;
- return ($self->_search_pqf($query, $rsname));
+ my $rs = $self->_search_pqf($query, $rsname);
+
+ if ($args{databases}) {
+ $self->databases(@origdbs);
+ }
+
+ return ($rs);
}
sub _new_setname {
return($rs);
}
-sub search_cql {
- my ($self, $query, $transfile) = @_;
-}
-
-
-sub search_ccl {
- my ($self, $query, $transfile) = @_;
-}
-
# -----------------------------------------------------------------------------
# Sort
#
return ($rs);
}
+# ============================================================================
+
__END__
$sess = IDZebra::Session->new(configFile => 'demo/zebra.cfg');
$sess->open();
- $sess = IDZebra::Session->open(configFile => 'demo/zebra.cfg');
+ $sess = IDZebra::Session->open(configFile => 'demo/zebra.cfg',
+ groupName => 'demo1');
+
+ $sess->group(groupName => 'demo2');
+
+ $sess->init();
+ $sess->begin_trans;
+
+ $sess->update(path => 'lib');
+
+ my $s1=$sess->update_record(data => $rec1,
+ recordType => 'grs.perl.pod',
+ groupName => "demo1",
+ );
+
+ my $stat = $sess->end_trans;
+
+ $sess->databases('demo1','demo2');
+
+ my $rs1 = $sess->search(cqlmap => 'demo/cql.map',
+ cql => 'dc.title=IDZebra',
+ databases => [qw(demo1 demo2)]);
$sess->close;
=head1 DESCRIPTION
=item B<databaseName>
-The name of the (logical) database the updated records will belong to.
+The name of the (logical) database the updated records will belong to.
=item B<path>
B<Important:> Note, that one record can be updated only once within a transaction - all subsequent updates are skipped.
+=head1 DATABASE SELECTION
+
+Within a zebra repository you can define logical databases. You can either do this by record groups, or by providing the databaseName argument for update methods. For each record the database name it belongs to is stored.
+
+For searching, you can select databases by calling:
+
+ $sess->databases('db1','db2');
+
+This will not do anything if the given and only the given databases are already selected. You can get the list of the actually selected databases, by calling:
+
+ @dblist = $sess->databases();
+
=head1 SEARCHING
+It's nice to be able to store data in your repository... But it's useful to reach it as well. So this is how to do searching:
+
+ $rs = $sess->search(databases => [qw(demo1,demo2)], # optional
+ pqf => '@attr 1=4 computer');
+
+This is going to execute a search in databases demo1 and demo2, for title 'com,puter'. This is a PQF (Prefix Query Format) search, see YAZ documentation for details. The database selection is optional: if it's provided, the given list of databases is selected for this particular search, then the original selection is restored.
+
+=head2 CCL searching
+
+Not all users enjoy typing in prefix query structures and numerical attribute values, even in a minimalistic test client. In the library world, the more intuitive Common Command Language (or ISO 8777) has enjoyed some popularity - especially before the widespread availability of graphical interfaces. It is still useful in applications where you for some reason or other need to provide a symbolic language for expressing boolean query structures.
+
+The CCL searching is not currently supported by this API.
+
+=head2 CQL searching
+
+CQL - Common Query Language - was defined for the SRW protocol. In many ways CQL has a similar syntax to CCL. The objective of CQL is different. Where CCL aims to be an end-user language, CQL is the protocol query language for SRW.
+
+In order to map CQL queries to Zebra internal search structures, you have to define a mapping, the way it is described in YAZ documentation: I<Specification of CQL to RPN mapping>. The mapping is interpreted by the method:
+
+ $sess->cqlmap($mapfile);
+
+Or, you can directly provide the I<mapfile> parameter for the search:
+
+ my $rs1 = $sess->search(cqlmap => 'demo/cql.map',
+ cql => 'dc.title=IDZebra');
+
+As you see, CQL searching is so simple: just give the query in the I<cql> parameter.
+
+=head1 RESULTSETS
+
+As you have seen, the result of the search request is a I<Resultset> object.
+It contains number of hits, and search status, and can be used to sort and retrieve the resulting records.
+
+ $count = $rs->count;
+
+ printf ("RS Status is %d (%s)\n", $rs->errCode, $rs->errString);
+
+I<$rs-E<gt>errCode> is 0, if there were no errors during search. Read the I<IDZebra::Resultset> manpage for more details.
+
+=head1 MISC FUNCTIONS
=head1 COPYRIGHT
#!/usr/bin/perl
-
+# =============================================================================
+# $Id: test.pl,v 1.7 2003-02-28 18:38:28 pop Exp $
+#
+# Perl API header
+# =============================================================================
BEGIN {
+ use Test::More tests => 15;
push (@INC,'demo','blib/lib','blib/arch');
+ use_ok('IDZebra::Session');
}
-
use pod;
-use Test::More tests => 15;
-
-BEGIN {
- use_ok('IDZebra::Session');
-}
IDZebra::logFile("test.log");
groupName => 'demo1');
isa_ok($sess,"IDZebra::Session");
ok(defined($sess->{zh}), "Zebra handle opened");
+#use IDZebra::Repository;
# ----------------------------------------------------------------------------
# Record group tests
# ----------------------------------------------------------------------------
# repository upadte
-our $filecount = 6;
+our $filecount = 5;
$sess->begin_trans;
$sess->update(path => 'lib');
my $stat = $sess->end_trans;
ok(($stat->{inserted} == $filecount),
- "Inserted $stat->{updated}/$filecount records");
+ "Inserted $stat->{inserted}/$filecount records");
$sess->begin_trans;
$sess->delete(groupName => 'demo1',
my $stat = $sess->end_trans;
ok(($stat->{updated} == 1), "Updated 1 records");
-#exit;
# ----------------------------------------------------------------------------
# search
-$sess->select_databases('demo2');
-$sess->begin_read;
-my $rs1 = $sess->search(cqlmap => 'demo/cql.map',
- cql => 'IDZebra');
+$sess->databases('demo2');
+#$sess->begin_read;
+my $rs1 = $sess->search(cqlmap => 'demo/cql.map',
+ cql => 'IDZebra',
+ databases => [qw(demo1 demo2)]);
print STDERR "$rs1->{recordCount} hits.\n";
res->buf = buf;
res->buf->len = ro->records[i].len;
res->buf->buf = ro->records[i].buf;
+ res->score = ro->records[i].score;
+ res->sysno = ro->records[i].sysno;
}
recs[i].len = strlen(poset[i].term);
recs[i].buf = poset[i].term;
recs[i].base = poset[i].db;
+ recs[i].sysno = 0;
}
else if (poset[i].sysno)
recs[i].buf = (char *) odr_malloc(stream,recs[i].len);
memcpy(recs[i].buf, b, recs[i].len);
recs[i].errString = NULL;
+ recs[i].sysno = poset[i].sysno;
+ recs[i].score = poset[i].score;
}
else
{
char *errString; /* error string */
int position; /* position of record in result set (1,2,..) */
char *base;
+ int sysno;
+ int score;
oid_value format; /* record syntax */
RetrievalRecordBuf *buf;
} RetrievalRecord;