added zebra_insert_record call, function in perl api, documentation and tests
authorpop <pop>
Thu, 13 Mar 2003 04:25:17 +0000 (04:25 +0000)
committerpop <pop>
Thu, 13 Mar 2003 04:25:17 +0000 (04:25 +0000)
index/extract.c
index/index.h
index/zebraapi.c
perl/IDZebra.i
perl/IDZebra_wrap.c
perl/lib/IDZebra.pm
perl/lib/IDZebra/Session.pm
perl/t/03_record_update.t

index e431453..edf6e37 100644 (file)
@@ -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
 
    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,
                                 "<no file>",
                                 sysno,
                                 match_criteria,
                                 "<no file>",
-                                0));
+                                0,1));
 }
 /*
   If sysno is provided, then it's used to identify the reocord.
 }
 /*
   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 *sysno,
                         const char *match_criteria,
                         const char *fname,
-                        int force_update)
+                        int force_update,
+                        int allow_update)
 
 {
     RecordAttr *recordAttr;
 
 {
     RecordAttr *recordAttr;
@@ -1094,13 +1095,20 @@ int bufferExtractRecord (ZebraHandle zh,
         extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys);
 
         zh->records_inserted++;
         extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys);
 
         zh->records_inserted++;
-    }
+    } 
     else
     {
         /* record already exists */
         struct recKeys delkeys;
         struct sortKeys sortKeys;
 
     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);
        
         rec = rec_get (zh->reg->records, *sysno);
         assert (rec);
        
index 56e7292..1f0ac62 100644 (file)
@@ -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
 
    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 *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,
 
 int extract_rec_in_mem (ZebraHandle zh, const char *recordType,
                         const char *buf, size_t buf_size,
index 7ce50b9..01c6433 100644 (file)
@@ -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
 
    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
 */
 
   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,
 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,
                             recordType,
                             &sysno,   
                             match, fname,
-                            force_update);     
+                            force_update, 
+                            1); // allow_update    
     zebra_end_trans(zh); 
     return sysno; 
 }
 
     zebra_end_trans(zh); 
     return sysno; 
 }
 
+
+
 int zebra_delete_record (ZebraHandle zh, 
                         struct recordGroup *rGroup, 
                         const char *recordType,
 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,
                             recordType,
                             &sysno,
                             match,fname,
-                            force_update);    
+                            force_update,
+                            1); // allow_update    
     zebra_end_trans(zh);
     return sysno;   
 }
     zebra_end_trans(zh);
     return sysno;   
 }
index 27af217..6a9c75d 100644 (file)
@@ -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 */
 
    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, 
 %name(update_record)       
 int zebra_update_record (ZebraHandle zh, 
                         recordGroup *rGroup, 
index 73c64e9..e147810 100644 (file)
@@ -212,7 +212,7 @@ SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
  * perl5.swg
  *
  * Perl5 runtime library
  * 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
  * ----------------------------------------------------------------------------- */
 
 #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;
 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::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},
 {"IDZebrac::update_record", _wrap_update_record},
 {"IDZebrac::delete_record", _wrap_delete_record},
 {"IDZebrac::search_PQF", _wrap_search_PQF},
index 8540a01..927e004 100644 (file)
@@ -64,6 +64,7 @@ package IDZebra;
 *repository_update = *IDZebrac::repository_update;
 *repository_delete = *IDZebrac::repository_delete;
 *repository_show = *IDZebrac::repository_show;
 *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;
 *update_record = *IDZebrac::update_record;
 *delete_record = *IDZebrac::delete_record;
 *search_PQF = *IDZebrac::search_PQF;
index 258ffc5..a98a232 100644 (file)
@@ -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
 # =============================================================================
 # 
 # Zebra perl API header
 # =============================================================================
@@ -15,7 +15,7 @@ BEGIN {
     use IDZebra::ScanList;
     use IDZebra::RetrievalRecord;
     require Exporter;
     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);
 }
     our @ISA = qw(IDZebra::Logger Exporter);
     our @EXPORT = qw (TRANS_RW TRANS_RO);
 }
@@ -451,6 +451,12 @@ sub _update_args {
 # -----------------------------------------------------------------------------
 # Per record update
 # -----------------------------------------------------------------------------
 # -----------------------------------------------------------------------------
 # 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) = @_;
 
 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) {
     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); 
     }
     $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... 
 
 
 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");
 
                                 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<recordId> member of the record group, or in the I<recordId> 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<Important:> 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 I<force=E<gt>1> 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<insert_record> method:
+
+  $sysno = $sess->insert_record(data       => $rec1,
+                               recordType => 'grs.perl.pod',
+                               groupName  => "demo1");
 
 
-B<Important:> 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<recordId> setting).
 
 =head1 DATABASE SELECTION
 
 
 =head1 DATABASE SELECTION
 
index ae5f865..ab15e07 100644 (file)
@@ -1,6 +1,6 @@
 #!perl
 # =============================================================================
 #!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
 # =============================================================================
 #
 # Perl API header
 # =============================================================================
@@ -14,7 +14,7 @@ BEGIN {
 use strict;
 use warnings;
 
 use strict;
 use warnings;
 
-use Test::More tests => 7;
+use Test::More tests => 11;
 
 # ----------------------------------------------------------------------------
 # Session opening and closing
 
 # ----------------------------------------------------------------------------
 # Session opening and closing
@@ -57,13 +57,23 @@ $stat = $sess->end_trans;
 ok(($stat->{deleted} == 1), "Deleted 1 records");
 
 $sess->begin_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");
 $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");