From 52551bf774d771a0422a401946fd0c5ee3788f34 Mon Sep 17 00:00:00 2001 From: pop Date: Thu, 13 Mar 2003 04:25:17 +0000 Subject: [PATCH] added zebra_insert_record call, function in perl api, documentation and tests --- index/extract.c | 16 +++++++++--- index/index.h | 5 ++-- index/zebraapi.c | 36 ++++++++++++++++++++++++--- perl/IDZebra.i | 11 ++++++++ perl/IDZebra_wrap.c | 58 ++++++++++++++++++++++++++++++++++++++++++- perl/lib/IDZebra.pm | 1 + perl/lib/IDZebra/Session.pm | 39 ++++++++++++++++++++++++----- perl/t/03_record_update.t | 22 +++++++++++----- 8 files changed, 166 insertions(+), 22 deletions(-) diff --git a/index/extract.c b/index/extract.c index e431453..edf6e37 100644 --- a/index/extract.c +++ b/index/extract.c @@ -1,4 +1,4 @@ -/* $Id: extract.c,v 1.142 2003-03-12 17:11:23 pop Exp $ +/* $Id: extract.c,v 1.143 2003-03-13 04:25:17 pop Exp $ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 Index Data Aps @@ -918,7 +918,7 @@ int extract_rec_in_mem (ZebraHandle zh, const char *recordType, sysno, match_criteria, "", - 0)); + 0,1)); } /* If sysno is provided, then it's used to identify the reocord. @@ -935,7 +935,8 @@ int bufferExtractRecord (ZebraHandle zh, int *sysno, const char *match_criteria, const char *fname, - int force_update) + int force_update, + int allow_update) { RecordAttr *recordAttr; @@ -1094,13 +1095,20 @@ int bufferExtractRecord (ZebraHandle zh, extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys); zh->records_inserted++; - } + } else { /* record already exists */ struct recKeys delkeys; struct sortKeys sortKeys; + if (!allow_update) { + logf (LOG_LOG, "skipped %s %s %ld", + recordType, fname, (long) recordOffset); + logRecord(zh); + return -1; + } + rec = rec_get (zh->reg->records, *sysno); assert (rec); diff --git a/index/index.h b/index/index.h index 56e7292..1f0ac62 100644 --- a/index/index.h +++ b/index/index.h @@ -1,4 +1,4 @@ -/* $Id: index.h,v 1.96 2003-03-12 17:11:23 pop Exp $ +/* $Id: index.h,v 1.97 2003-03-13 04:25:17 pop Exp $ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 Index Data Aps @@ -421,7 +421,8 @@ int bufferExtractRecord (ZebraHandle zh, int *sysno, const char *match_criteria, const char *fname, - int force_update); + int force_update, + int allow_update); int extract_rec_in_mem (ZebraHandle zh, const char *recordType, const char *buf, size_t buf_size, diff --git a/index/zebraapi.c b/index/zebraapi.c index 7ce50b9..01c6433 100644 --- a/index/zebraapi.c +++ b/index/zebraapi.c @@ -1,4 +1,4 @@ -/* $Id: zebraapi.c,v 1.92 2003-03-12 17:11:23 pop Exp $ +/* $Id: zebraapi.c,v 1.93 2003-03-13 04:25:17 pop Exp $ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 Index Data Aps @@ -1776,6 +1776,32 @@ void api_records_retrieve (ZebraHandle zh, ODR stream, If not, and a record is provided, then sysno is got from there */ +int zebra_insert_record (ZebraHandle zh, + struct recordGroup *rGroup, + const char *recordType, + int sysno, const char *match, const char *fname, + const char *buf, int buf_size, + int force_update) // This one is ignored + +{ + int res; + + if (buf_size < 1) buf_size = strlen(buf); + + zebra_begin_trans(zh, 1); + res=bufferExtractRecord (zh, buf, buf_size, rGroup, + 0, // delete_flag + 0, // test_mode, + recordType, + &sysno, + match, fname, + force_update, + 0); // allow_update + zebra_end_trans(zh); + if (res < 0) return (res); + return sysno; +} + int zebra_update_record (ZebraHandle zh, struct recordGroup *rGroup, const char *recordType, @@ -1795,11 +1821,14 @@ int zebra_update_record (ZebraHandle zh, recordType, &sysno, match, fname, - force_update); + force_update, + 1); // allow_update zebra_end_trans(zh); return sysno; } + + int zebra_delete_record (ZebraHandle zh, struct recordGroup *rGroup, const char *recordType, @@ -1818,7 +1847,8 @@ int zebra_delete_record (ZebraHandle zh, recordType, &sysno, match,fname, - force_update); + force_update, + 1); // allow_update zebra_end_trans(zh); return sysno; } diff --git a/perl/IDZebra.i b/perl/IDZebra.i index 27af217..6a9c75d 100644 --- a/perl/IDZebra.i +++ b/perl/IDZebra.i @@ -278,6 +278,17 @@ void zebra_repository_show (ZebraHandle zh); If not, and match_criteria is provided, then sysno is guessed If not, and a record is provided, then sysno is got from there */ +%name(insert_record) +int zebra_insert_record (ZebraHandle zh, + recordGroup *rGroup, + const char *recordType, + int sysno, + const char *match, + const char *fname, + const char *buf, + int buf_size, + int force_update); + %name(update_record) int zebra_update_record (ZebraHandle zh, recordGroup *rGroup, diff --git a/perl/IDZebra_wrap.c b/perl/IDZebra_wrap.c index 73c64e9..e147810 100644 --- a/perl/IDZebra_wrap.c +++ b/perl/IDZebra_wrap.c @@ -212,7 +212,7 @@ SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { * perl5.swg * * Perl5 runtime library - * $Header: /home/cvsroot/idis/perl/Attic/IDZebra_wrap.c,v 1.15 2003-03-12 17:08:53 pop Exp $ + * $Header: /home/cvsroot/idis/perl/Attic/IDZebra_wrap.c,v 1.16 2003-03-13 04:25:17 pop Exp $ * ----------------------------------------------------------------------------- */ #define SWIGPERL @@ -3976,6 +3976,61 @@ XS(_wrap_repository_show) { } +XS(_wrap_insert_record) { + char _swigmsg[SWIG_MAX_ERRMSG] = ""; + const char *_swigerr = _swigmsg; + { + ZebraHandle arg1 ; + recordGroup *arg2 ; + char *arg3 ; + int arg4 ; + char *arg5 ; + char *arg6 ; + char *arg7 ; + int arg8 ; + int arg9 ; + int result; + int argvi = 0; + dXSARGS; + + if ((items < 9) || (items > 9)) { + SWIG_croak("Usage: insert_record(zh,rGroup,recordType,sysno,match,fname,buf,buf_size,force_update);"); + } + { + ZebraHandle * argp; + if (SWIG_ConvertPtr(ST(0),(void **) &argp, SWIGTYPE_p_ZebraHandle,0) < 0) { + SWIG_croak("Type error in argument 1 of insert_record. Expected _p_ZebraHandle"); + } + arg1 = *argp; + } + { + if (SWIG_ConvertPtr(ST(1), (void **) &arg2, SWIGTYPE_p_recordGroup,0) < 0) { + SWIG_croak("Type error in argument 2 of insert_record. Expected _p_recordGroup"); + } + } + if (!SvOK((SV*) ST(2))) arg3 = 0; + else arg3 = (char *) SvPV(ST(2), PL_na); + arg4 = (int) SvIV(ST(3)); + if (!SvOK((SV*) ST(4))) arg5 = 0; + else arg5 = (char *) SvPV(ST(4), PL_na); + if (!SvOK((SV*) ST(5))) arg6 = 0; + else arg6 = (char *) SvPV(ST(5), PL_na); + if (!SvOK((SV*) ST(6))) arg7 = 0; + else arg7 = (char *) SvPV(ST(6), PL_na); + arg8 = (int) SvIV(ST(7)); + arg9 = (int) SvIV(ST(8)); + result = (int)zebra_insert_record(arg1,arg2,(char const *)arg3,arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,arg8,arg9); + + ST(argvi) = sv_newmortal(); + sv_setiv(ST(argvi++), (IV) result); + XSRETURN(argvi); + fail: + (void) _swigerr; + } + croak(_swigerr); +} + + XS(_wrap_update_record) { char _swigmsg[SWIG_MAX_ERRMSG] = ""; const char *_swigerr = _swigmsg; @@ -8464,6 +8519,7 @@ static swig_command_info swig_commands[] = { {"IDZebrac::repository_update", _wrap_repository_update}, {"IDZebrac::repository_delete", _wrap_repository_delete}, {"IDZebrac::repository_show", _wrap_repository_show}, +{"IDZebrac::insert_record", _wrap_insert_record}, {"IDZebrac::update_record", _wrap_update_record}, {"IDZebrac::delete_record", _wrap_delete_record}, {"IDZebrac::search_PQF", _wrap_search_PQF}, diff --git a/perl/lib/IDZebra.pm b/perl/lib/IDZebra.pm index 8540a01..927e004 100644 --- a/perl/lib/IDZebra.pm +++ b/perl/lib/IDZebra.pm @@ -64,6 +64,7 @@ package IDZebra; *repository_update = *IDZebrac::repository_update; *repository_delete = *IDZebrac::repository_delete; *repository_show = *IDZebrac::repository_show; +*insert_record = *IDZebrac::insert_record; *update_record = *IDZebrac::update_record; *delete_record = *IDZebrac::delete_record; *search_PQF = *IDZebrac::search_PQF; diff --git a/perl/lib/IDZebra/Session.pm b/perl/lib/IDZebra/Session.pm index 258ffc5..a98a232 100644 --- a/perl/lib/IDZebra/Session.pm +++ b/perl/lib/IDZebra/Session.pm @@ -1,4 +1,4 @@ -# $Id: Session.pm,v 1.14 2003-03-12 17:08:53 pop Exp $ +# $Id: Session.pm,v 1.15 2003-03-13 04:25:18 pop Exp $ # # Zebra perl API header # ============================================================================= @@ -15,7 +15,7 @@ BEGIN { use IDZebra::ScanList; use IDZebra::RetrievalRecord; require Exporter; - our $VERSION = do { my @r = (q$Revision: 1.14 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; + our $VERSION = do { my @r = (q$Revision: 1.15 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; our @ISA = qw(IDZebra::Logger Exporter); our @EXPORT = qw (TRANS_RW TRANS_RO); } @@ -451,6 +451,12 @@ sub _update_args { # ----------------------------------------------------------------------------- # Per record update # ----------------------------------------------------------------------------- +sub insert_record { + my ($self, %args) = @_; + $self->checkzh; + return(IDZebra::insert_record($self->{zh}, + $self->_record_update_args(%args))); +} sub update_record { my ($self, %args) = @_; @@ -540,7 +546,7 @@ sub cql2pqf { my $res = "\0" x 2048; my $r = IDZebra::cql2pqf($self->{cql_ct}, $cqlquery, $res, 2048); if ($r) { - carp ("Error transforming CQL query: '$cqlquery', status:$r"); +# carp ("Error transforming CQL query: '$cqlquery', status:$r"); } $res=~s/\0.+$//g; return ($res,$r); @@ -950,15 +956,36 @@ where sysno in itself is sufficient to identify the record This case the record is extracted, and if already exists, located in the database, then deleted... - $sysno = $sess->delete_record(data => $rec1, + $sysno = $sess->update_record(data => $rec1, match => $myid, recordType => 'grs.perl.pod', groupName => "demo1"); -Don't try this at home! This case, the record identifier string (which is normally generated according to the rules set in recordId directive of zebra.cfg) is provided directly.... +Don't try this at home! This case, the record identifier string (which is normally generated according to the rules set in I member of the record group, or in the I parameter) is provided directly.... Looks much better this way: + + $sysno = $sess->update_record(data => $rec1, + databaseName => 'books', + recordId => '(bib1,ISBN)', + recordType => 'grs.perl.pod', + flagStoreData => 1, + flagStoreKeys => 1); + +You can notice, that it's not necessary to define a record group in zebra.cfg: you can do it "on the fly" in your code. +B Note, that one record can be updated only once within a transaction - all subsequent updates are skipped. If you'd like to override this feature, use the I1> flag: + + $sysno = $sess->update_record(data => $rec1, + recordType => 'grs.perl.pod', + groupName => "demo1", + force => 1); + +If you don't like to update the record, if it alerady exists, use the I method: + + $sysno = $sess->insert_record(data => $rec1, + recordType => 'grs.perl.pod', + groupName => "demo1"); -B Note, that one record can be updated only once within a transaction - all subsequent updates are skipped. +In this case, sysno will be -1, if the record could not be added, because there was already one in the database, with the same record identifier (generated according to the I setting). =head1 DATABASE SELECTION diff --git a/perl/t/03_record_update.t b/perl/t/03_record_update.t index ae5f865..ab15e07 100644 --- a/perl/t/03_record_update.t +++ b/perl/t/03_record_update.t @@ -1,6 +1,6 @@ #!perl # ============================================================================= -# $Id: 03_record_update.t,v 1.2 2003-03-05 13:55:22 pop Exp $ +# $Id: 03_record_update.t,v 1.3 2003-03-13 04:25:18 pop Exp $ # # Perl API header # ============================================================================= @@ -14,7 +14,7 @@ BEGIN { use strict; use warnings; -use Test::More tests => 7; +use Test::More tests => 11; # ---------------------------------------------------------------------------- # Session opening and closing @@ -57,13 +57,23 @@ $stat = $sess->end_trans; ok(($stat->{deleted} == 1), "Deleted 1 records"); $sess->begin_trans; -$sysno = $sess->update_record(data => $rec2, - recordType => 'grs.perl.pod', - groupName => "demo1", - ); +$sysno = $sess->insert_record(data => $rec2, + recordType => 'grs.perl.pod', + groupName => "demo1", + ); $stat = $sess->end_trans; ok(($stat->{inserted} == 1), "Inserted 1 records"); +ok(($sysno > 0),"Inserted record got valid sysno"); +$sess->begin_trans; +$sysno = $sess->insert_record(data => $rec2, + recordType => 'grs.perl.pod', + groupName => "demo1", + ); +$stat = $sess->end_trans; +ok(($stat->{inserted} == 0), "Inserted 0 records"); +ok(($stat->{updated} == 0), "Updated 0 records"); +ok(($sysno < 0),"Inserted record got invalid sysno"); -- 1.7.10.4