Perl API os growing
authorpop <pop>
Thu, 27 Feb 2003 23:12:18 +0000 (23:12 +0000)
committerpop <pop>
Thu, 27 Feb 2003 23:12:18 +0000 (23:12 +0000)
14 files changed:
perl/IDZebra.i
perl/IDZebra_wrap.c
perl/demo/index.sh
perl/demo/pod.abs
perl/demo/zebra.cfg
perl/lib/IDZebra.pm
perl/lib/IDZebra/Data1.pm
perl/lib/IDZebra/Filter.pm
perl/lib/IDZebra/Repository.pm
perl/lib/IDZebra/Session.pm
perl/test.pl
perl/zebra_api_ext.c
perl/zebra_perl.c
perl/zebra_perl.h

index 88e6a7b..e289a54 100644 (file)
@@ -7,6 +7,7 @@
 #include "zebra_perl.h"
 #include "data1.h"
 #include "yaz/odr.h"
+#include "yaz/cql.h"
 %}
 
 /* == Typemaps ============================================================= */
 
 %include "zebra_perl.h"
 
+typedef struct {
+  int processed;
+  int inserted;
+  int updated;
+  int deleted;
+  long utime;
+  long stime;
+} ZebraTransactionStatus;
+
+
 /* == Module initialization and cleanup (zebra_perl.c) ===================== */
 
 void init (void);
 void DESTROY (void);
 
-
 /* == Logging facilities (yaz/log.h) ======================================= */
 
 void logLevel (int level);
@@ -164,12 +174,16 @@ void zebra_begin_trans (ZebraHandle zh);
 
 /* end transaction (remove write lock) (zebraapi.c) */
 %name(end_trans)           
-void zebra_end_trans (ZebraHandle zh); 
+void zebra_end_transaction (ZebraHandle zh, ZebraTransactionStatus *stat); 
+
+%name(trans_no)
+int zebra_trans_no (ZebraHandle zh);
 
-/* begin retrieval (add read lock) (zebraapi.c) */
 %name(begin_read)          
 int zebra_begin_read (ZebraHandle zh);
 
+void zts_test (ZebraTransactionStatus *stat);
+
 /* end retrieval (remove read lock) (zebraapi.c) */
 %name(end_read)            
 void zebra_end_read (ZebraHandle zh);
@@ -214,6 +228,7 @@ void zebra_repository_show (ZebraHandle zh);
 %name(update_record)       
 int zebra_update_record (ZebraHandle zh, 
                         recordGroup *rGroup, 
+                        const char *recordType,
                         int sysno, 
                         const char *match, 
                         const char *fname,
@@ -223,6 +238,7 @@ int zebra_update_record (ZebraHandle zh,
 %name(delete_record)       
 int zebra_delete_record (ZebraHandle zh, 
                         recordGroup *rGroup, 
+                        const char *recordType,
                         int sysno, 
                         const char *match, 
                         const char *fname,
@@ -238,8 +254,16 @@ int zebra_search_PQF (ZebraHandle zh,
                      const char *setname);
 
 
-/* TODO: search_CCL */
+/* == YAZ - query tools ==================================================== */
+
+
+cql_transform_t cql_transform_open_fname(const char *fname);
+void cql_transform_close(cql_transform_t ct);
+int cql_transform_error(cql_transform_t ct, const char **addinfo);
 
+%name(cql2pqf) 
+int zebra_cql2pqf (cql_transform_t ct, 
+                  const char *query, char *res, int len);
 
 /* == Retrieval (zebra_api_ext.c) ========================================== */
 
@@ -272,19 +296,6 @@ int sort (ZebraHandle zh,
          ); 
 
 /* == Scan ================================================================= */
-/*
-%apply int *INOUT {int *position};
-%apply int *INOUT {int *num_entries};
-%apply int *INOUT {int *is_partial};
-
-%name(scan_PQF) 
-void zebra_scan_PQF (ZebraHandle zh,
-                    ODR stream,
-                    const char *pqf_query,
-                    int *position,
-                    int *num_entries,
-                    int *is_partial);
-*/
 %name(scan_PQF) 
 void zebra_scan_PQF (ZebraHandle zh,
                     ScanObj *so,
index 26298c1..fc20149 100644 (file)
@@ -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.4 2002-12-02 10:23:30 pop Exp $
+ * $Header: /home/cvsroot/idis/perl/Attic/IDZebra_wrap.c,v 1.5 2003-02-27 23:12:18 pop Exp $
  * ----------------------------------------------------------------------------- */
 
 #define SWIGPERL
@@ -499,49 +499,51 @@ static void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (C
 /* -------- TYPES TABLE (BEGIN) -------- */
 
 #define  SWIGTYPE_p_ZebraService swig_types[0] 
-#define  SWIGTYPE_p_data1_esetname swig_types[1] 
-#define  SWIGTYPE_p_data1_maptab swig_types[2] 
-#define  SWIGTYPE_p_ODR swig_types[3] 
-#define  SWIGTYPE_p_f_p_void__int swig_types[4] 
-#define  SWIGTYPE_p_p_char swig_types[5] 
-#define  SWIGTYPE_p_oid_value swig_types[6] 
-#define  SWIGTYPE_p_data1_absyn swig_types[7] 
-#define  SWIGTYPE_p_ZebraHandle swig_types[8] 
-#define  SWIGTYPE_p_void swig_types[9] 
-#define  SWIGTYPE_p_data1_attset swig_types[10] 
-#define  SWIGTYPE_p_size_t swig_types[11] 
-#define  SWIGTYPE_p_WRBUF swig_types[12] 
-#define  SWIGTYPE_p_f_data1_handle_p_void_p_data1_absyn__void swig_types[13] 
-#define  SWIGTYPE_p_Z_Espec1 swig_types[14] 
-#define  SWIGTYPE_p_off_t swig_types[15] 
-#define  SWIGTYPE_p_Odr_oid swig_types[16] 
-#define  SWIGTYPE_p_data1_varset swig_types[17] 
-#define  SWIGTYPE_p_RetrievalRecordBuf swig_types[18] 
-#define  SWIGTYPE_p_perl_context swig_types[19] 
-#define  SWIGTYPE_p_data1_node swig_types[20] 
-#define  SWIGTYPE_p_ScanObj swig_types[21] 
-#define  SWIGTYPE_p_RetrievalObj swig_types[22] 
-#define  SWIGTYPE_p_data1_tagset swig_types[23] 
-#define  SWIGTYPE_p_data1_tag swig_types[24] 
-#define  SWIGTYPE_p_ZebraRetrievalRecord swig_types[25] 
-#define  SWIGTYPE_p_RetrievalRecord swig_types[26] 
-#define  SWIGTYPE_p_NMEM swig_types[27] 
-#define  SWIGTYPE_p_Z_ExplainRecord swig_types[28] 
-#define  SWIGTYPE_p_data1_marctab swig_types[29] 
-#define  SWIGTYPE_p_Z_BriefBib swig_types[30] 
-#define  SWIGTYPE_p_ScanEntry swig_types[31] 
-#define  SWIGTYPE_p_f_p_void_p_char_size_t__int swig_types[32] 
-#define  SWIGTYPE_p_FILE swig_types[33] 
-#define  SWIGTYPE_p_data1_element swig_types[34] 
-#define  SWIGTYPE_p_recordGroup swig_types[35] 
-#define  SWIGTYPE_p_int swig_types[36] 
-#define  SWIGTYPE_p_data1_handle swig_types[37] 
-#define  SWIGTYPE_p_p_int swig_types[38] 
-#define  SWIGTYPE_p_data1_absyn_cache swig_types[39] 
-#define  SWIGTYPE_p_data1_attset_cache swig_types[40] 
-#define  SWIGTYPE_p_Z_GenericRecord swig_types[41] 
-#define  SWIGTYPE_p_data1_vartype swig_types[42] 
-static swig_type_info *swig_types[44];
+#define  SWIGTYPE_p_cql_transform_t swig_types[1] 
+#define  SWIGTYPE_p_data1_esetname swig_types[2] 
+#define  SWIGTYPE_p_data1_maptab swig_types[3] 
+#define  SWIGTYPE_p_ODR swig_types[4] 
+#define  SWIGTYPE_p_f_p_void__int swig_types[5] 
+#define  SWIGTYPE_p_p_char swig_types[6] 
+#define  SWIGTYPE_p_oid_value swig_types[7] 
+#define  SWIGTYPE_p_data1_absyn swig_types[8] 
+#define  SWIGTYPE_p_ZebraHandle swig_types[9] 
+#define  SWIGTYPE_p_void swig_types[10] 
+#define  SWIGTYPE_p_data1_attset swig_types[11] 
+#define  SWIGTYPE_p_size_t swig_types[12] 
+#define  SWIGTYPE_p_WRBUF swig_types[13] 
+#define  SWIGTYPE_p_f_data1_handle_p_void_p_data1_absyn__void swig_types[14] 
+#define  SWIGTYPE_p_Z_Espec1 swig_types[15] 
+#define  SWIGTYPE_p_off_t swig_types[16] 
+#define  SWIGTYPE_p_Odr_oid swig_types[17] 
+#define  SWIGTYPE_p_data1_varset swig_types[18] 
+#define  SWIGTYPE_p_RetrievalRecordBuf swig_types[19] 
+#define  SWIGTYPE_p_perl_context swig_types[20] 
+#define  SWIGTYPE_p_data1_node swig_types[21] 
+#define  SWIGTYPE_p_ScanObj swig_types[22] 
+#define  SWIGTYPE_p_RetrievalObj swig_types[23] 
+#define  SWIGTYPE_p_data1_tagset swig_types[24] 
+#define  SWIGTYPE_p_data1_tag swig_types[25] 
+#define  SWIGTYPE_p_ZebraRetrievalRecord swig_types[26] 
+#define  SWIGTYPE_p_RetrievalRecord swig_types[27] 
+#define  SWIGTYPE_p_NMEM swig_types[28] 
+#define  SWIGTYPE_p_Z_ExplainRecord swig_types[29] 
+#define  SWIGTYPE_p_data1_marctab swig_types[30] 
+#define  SWIGTYPE_p_ZebraTransactionStatus swig_types[31] 
+#define  SWIGTYPE_p_Z_BriefBib swig_types[32] 
+#define  SWIGTYPE_p_ScanEntry swig_types[33] 
+#define  SWIGTYPE_p_f_p_void_p_char_size_t__int swig_types[34] 
+#define  SWIGTYPE_p_FILE swig_types[35] 
+#define  SWIGTYPE_p_data1_element swig_types[36] 
+#define  SWIGTYPE_p_recordGroup swig_types[37] 
+#define  SWIGTYPE_p_int swig_types[38] 
+#define  SWIGTYPE_p_data1_handle swig_types[39] 
+#define  SWIGTYPE_p_p_int swig_types[40] 
+#define  SWIGTYPE_p_data1_absyn_cache swig_types[41] 
+#define  SWIGTYPE_p_data1_attset_cache swig_types[42] 
+#define  SWIGTYPE_p_Z_GenericRecord swig_types[43] 
+#define  SWIGTYPE_p_data1_vartype swig_types[44] 
+static swig_type_info *swig_types[46];
 
 /* -------- TYPES TABLE (END) -------- */
 
@@ -569,6 +571,7 @@ SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *);
 #include "zebra_perl.h"
 #include "data1.h"
 #include "yaz/odr.h"
+#include "yaz/cql.h"
 
 #ifdef PERL_OBJECT
 #define MAGIC_CLASS _wrap_IDZebra_var::
@@ -2439,6 +2442,404 @@ XS(_wrap_delete_ScanObj) {
 }
 
 
+XS(_wrap_ZebraTransactionStatus_processed_set) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int arg2 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_processed_set(self,processed);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_processed_set. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        arg2 = (int) SvIV(ST(1));
+        if (arg1) (arg1)->processed = arg2;
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_processed_get) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_processed_get(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_processed_get. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        result = (int) ((arg1)->processed);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_inserted_set) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int arg2 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_inserted_set(self,inserted);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_inserted_set. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        arg2 = (int) SvIV(ST(1));
+        if (arg1) (arg1)->inserted = arg2;
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_inserted_get) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_inserted_get(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_inserted_get. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        result = (int) ((arg1)->inserted);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_updated_set) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int arg2 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_updated_set(self,updated);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_updated_set. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        arg2 = (int) SvIV(ST(1));
+        if (arg1) (arg1)->updated = arg2;
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_updated_get) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_updated_get(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_updated_get. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        result = (int) ((arg1)->updated);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_deleted_set) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int arg2 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_deleted_set(self,deleted);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_deleted_set. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        arg2 = (int) SvIV(ST(1));
+        if (arg1) (arg1)->deleted = arg2;
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_deleted_get) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_deleted_get(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_deleted_get. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        result = (int) ((arg1)->deleted);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_utime_set) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        long arg2 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_utime_set(self,utime);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_utime_set. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        arg2 = (long) SvIV(ST(1));
+        if (arg1) (arg1)->utime = arg2;
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_utime_get) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        long result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_utime_get(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_utime_get. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        result = (long) ((arg1)->utime);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_stime_set) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        long arg2 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_stime_set(self,stime);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_stime_set. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        arg2 = (long) SvIV(ST(1));
+        if (arg1) (arg1)->stime = arg2;
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_ZebraTransactionStatus_stime_get) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        long result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: ZebraTransactionStatus_stime_get(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of ZebraTransactionStatus_stime_get. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        result = (long) ((arg1)->stime);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_new_ZebraTransactionStatus) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 0) || (items > 0)) {
+            SWIG_croak("Usage: new_ZebraTransactionStatus();");
+        }
+        result = (ZebraTransactionStatus *)(ZebraTransactionStatus *) calloc(1, sizeof(ZebraTransactionStatus));
+        
+        ST(argvi) = sv_newmortal();
+        SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE_p_ZebraTransactionStatus,0);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_delete_ZebraTransactionStatus) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: delete_ZebraTransactionStatus(self);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of delete_ZebraTransactionStatus. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        free((char *) arg1);
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
 XS(_wrap_init__SWIG_0) {
     char _swigmsg[SWIG_MAX_ERRMSG] = "";
     const char *_swigerr = _swigmsg;
@@ -3125,11 +3526,12 @@ XS(_wrap_end_trans) {
     const char *_swigerr = _swigmsg;
     {
         ZebraHandle arg1 ;
+        ZebraTransactionStatus *arg2 ;
         int argvi = 0;
         dXSARGS;
         
-        if ((items < 1) || (items > 1)) {
-            SWIG_croak("Usage: end_trans(zh);");
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: end_trans(zh,stat);");
         }
         {
             ZebraHandle * argp;
@@ -3138,9 +3540,45 @@ XS(_wrap_end_trans) {
             }
             arg1 = *argp;
         }
-        zebra_end_trans(arg1);
+        {
+            if (SWIG_ConvertPtr(ST(1), (void **) &arg2, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 2 of end_trans. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        zebra_end_transaction(arg1,arg2);
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_trans_no) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraHandle arg1 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
         
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: trans_no(zh);");
+        }
+        {
+            ZebraHandle * argp;
+            if (SWIG_ConvertPtr(ST(0),(void **) &argp, SWIGTYPE_p_ZebraHandle,0) < 0) {
+                SWIG_croak("Type error in argument 1 of trans_no. Expected _p_ZebraHandle");
+            }
+            arg1 = *argp;
+        }
+        result = (int)zebra_trans_no(arg1);
         
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
         XSRETURN(argvi);
         fail:
         (void) _swigerr;
@@ -3180,6 +3618,33 @@ XS(_wrap_begin_read) {
 }
 
 
+XS(_wrap_zts_test) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        ZebraTransactionStatus *arg1 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: zts_test(stat);");
+        }
+        {
+            if (SWIG_ConvertPtr(ST(0), (void **) &arg1, SWIGTYPE_p_ZebraTransactionStatus,0) < 0) {
+                SWIG_croak("Type error in argument 1 of zts_test. Expected _p_ZebraTransactionStatus");
+            }
+        }
+        zts_test(arg1);
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
 XS(_wrap_end_read) {
     char _swigmsg[SWIG_MAX_ERRMSG] = "";
     const char *_swigerr = _swigmsg;
@@ -3484,17 +3949,18 @@ XS(_wrap_update_record) {
     {
         ZebraHandle arg1 ;
         recordGroup *arg2 ;
-        int arg3 ;
-        char *arg4 ;
+        char *arg3 ;
+        int arg4 ;
         char *arg5 ;
         char *arg6 ;
-        int arg7 ;
+        char *arg7 ;
+        int arg8 ;
         int result;
         int argvi = 0;
         dXSARGS;
         
-        if ((items < 7) || (items > 7)) {
-            SWIG_croak("Usage: update_record(zh,rGroup,sysno,match,fname,buf,buf_size);");
+        if ((items < 8) || (items > 8)) {
+            SWIG_croak("Usage: update_record(zh,rGroup,recordType,sysno,match,fname,buf,buf_size);");
         }
         {
             ZebraHandle * argp;
@@ -3508,15 +3974,17 @@ XS(_wrap_update_record) {
                 SWIG_croak("Type error in argument 2 of update_record. Expected _p_recordGroup");
             }
         }
-        arg3 = (int) SvIV(ST(2));
-        if (!SvOK((SV*) ST(3))) arg4 = 0;
-        else arg4 = (char *) SvPV(ST(3), PL_na);
+        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);
-        arg7 = (int) SvIV(ST(6));
-        result = (int)zebra_update_record(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,arg7);
+        if (!SvOK((SV*) ST(6))) arg7 = 0;
+        else arg7 = (char *) SvPV(ST(6), PL_na);
+        arg8 = (int) SvIV(ST(7));
+        result = (int)zebra_update_record(arg1,arg2,(char const *)arg3,arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,arg8);
         
         ST(argvi) = sv_newmortal();
         sv_setiv(ST(argvi++), (IV) result);
@@ -3534,17 +4002,18 @@ XS(_wrap_delete_record) {
     {
         ZebraHandle arg1 ;
         recordGroup *arg2 ;
-        int arg3 ;
-        char *arg4 ;
+        char *arg3 ;
+        int arg4 ;
         char *arg5 ;
         char *arg6 ;
-        int arg7 ;
+        char *arg7 ;
+        int arg8 ;
         int result;
         int argvi = 0;
         dXSARGS;
         
-        if ((items < 7) || (items > 7)) {
-            SWIG_croak("Usage: delete_record(zh,rGroup,sysno,match,fname,buf,buf_size);");
+        if ((items < 8) || (items > 8)) {
+            SWIG_croak("Usage: delete_record(zh,rGroup,recordType,sysno,match,fname,buf,buf_size);");
         }
         {
             ZebraHandle * argp;
@@ -3558,15 +4027,17 @@ XS(_wrap_delete_record) {
                 SWIG_croak("Type error in argument 2 of delete_record. Expected _p_recordGroup");
             }
         }
-        arg3 = (int) SvIV(ST(2));
-        if (!SvOK((SV*) ST(3))) arg4 = 0;
-        else arg4 = (char *) SvPV(ST(3), PL_na);
+        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);
-        arg7 = (int) SvIV(ST(6));
-        result = (int)zebra_delete_record(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,arg7);
+        if (!SvOK((SV*) ST(6))) arg7 = 0;
+        else arg7 = (char *) SvPV(ST(6), PL_na);
+        arg8 = (int) SvIV(ST(7));
+        result = (int)zebra_delete_record(arg1,arg2,(char const *)arg3,arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,arg8);
         
         ST(argvi) = sv_newmortal();
         sv_setiv(ST(argvi++), (IV) result);
@@ -3631,6 +4102,161 @@ XS(_wrap_search_PQF) {
 }
 
 
+XS(_wrap_cql_transform_open_fname) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        char *arg1 ;
+        cql_transform_t result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: cql_transform_open_fname(fname);");
+        }
+        if (!SvOK((SV*) ST(0))) arg1 = 0;
+        else arg1 = (char *) SvPV(ST(0), PL_na);
+        result = cql_transform_open_fname((char const *)arg1);
+        
+        {
+            cql_transform_t * resultobj = (cql_transform_t *) malloc(sizeof(cql_transform_t));
+            memmove(resultobj, &result, sizeof(cql_transform_t));
+            ST(argvi) = sv_newmortal();
+            SWIG_MakePtr(ST(argvi++), (void *) resultobj, SWIGTYPE_p_cql_transform_t,0);
+        }
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_cql_transform_close) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        cql_transform_t arg1 ;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 1) || (items > 1)) {
+            SWIG_croak("Usage: cql_transform_close(ct);");
+        }
+        {
+            cql_transform_t * argp;
+            if (SWIG_ConvertPtr(ST(0),(void **) &argp, SWIGTYPE_p_cql_transform_t,0) < 0) {
+                SWIG_croak("Type error in argument 1 of cql_transform_close. Expected _p_cql_transform_t");
+            }
+            arg1 = *argp;
+        }
+        cql_transform_close(arg1);
+        
+        
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_cql_transform_error) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        cql_transform_t arg1 ;
+        char **arg2 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 2) || (items > 2)) {
+            SWIG_croak("Usage: cql_transform_error(ct,addinfo);");
+        }
+        {
+            cql_transform_t * argp;
+            if (SWIG_ConvertPtr(ST(0),(void **) &argp, SWIGTYPE_p_cql_transform_t,0) < 0) {
+                SWIG_croak("Type error in argument 1 of cql_transform_error. Expected _p_cql_transform_t");
+            }
+            arg1 = *argp;
+        }
+        {
+            AV *tempav;
+            I32 len;
+            int i;
+            SV  **tv;
+            STRLEN na;
+            if (!SvROK(ST(1)))
+            croak("Argument 2 is not a reference.");
+            if (SvTYPE(SvRV(ST(1))) != SVt_PVAV)
+            croak("Argument 2 is not an array.");
+            tempav = (AV*)SvRV(ST(1));
+            len = av_len(tempav);
+            arg2 = (char **) malloc((len+2)*sizeof(char *));
+            for (i = 0; i <= len; i++) {
+                tv = av_fetch(tempav, i, 0);   
+                arg2[i] = (char *) SvPV(*tv,na);
+            }
+            arg2[i] = NULL;
+        }
+        result = (int)cql_transform_error(arg1,(char const **)arg2);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        {
+            free(arg2);
+        }
+        XSRETURN(argvi);
+        fail:
+        {
+            free(arg2);
+        }
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
+XS(_wrap_cql2pqf) {
+    char _swigmsg[SWIG_MAX_ERRMSG] = "";
+    const char *_swigerr = _swigmsg;
+    {
+        cql_transform_t arg1 ;
+        char *arg2 ;
+        char *arg3 ;
+        int arg4 ;
+        int result;
+        int argvi = 0;
+        dXSARGS;
+        
+        if ((items < 4) || (items > 4)) {
+            SWIG_croak("Usage: cql2pqf(ct,query,res,len);");
+        }
+        {
+            cql_transform_t * argp;
+            if (SWIG_ConvertPtr(ST(0),(void **) &argp, SWIGTYPE_p_cql_transform_t,0) < 0) {
+                SWIG_croak("Type error in argument 1 of cql2pqf. Expected _p_cql_transform_t");
+            }
+            arg1 = *argp;
+        }
+        if (!SvOK((SV*) ST(1))) arg2 = 0;
+        else arg2 = (char *) SvPV(ST(1), PL_na);
+        if (!SvOK((SV*) ST(2))) arg3 = 0;
+        else arg3 = (char *) SvPV(ST(2), PL_na);
+        arg4 = (int) SvIV(ST(3));
+        result = (int)zebra_cql2pqf(arg1,(char const *)arg2,arg3,arg4);
+        
+        ST(argvi) = sv_newmortal();
+        sv_setiv(ST(argvi++), (IV) result);
+        XSRETURN(argvi);
+        fail:
+        (void) _swigerr;
+    }
+    croak(_swigerr);
+}
+
+
 XS(_wrap_records_retrieve) {
     char _swigmsg[SWIG_MAX_ERRMSG] = "";
     const char *_swigerr = _swigmsg;
@@ -7409,6 +8035,7 @@ XS(_wrap_grs_perl_set_res) {
 /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
 
 static swig_type_info _swigt__p_ZebraService[] = {{"_p_ZebraService", 0, "ZebraService *", 0},{"_p_ZebraService"},{0}};
+static swig_type_info _swigt__p_cql_transform_t[] = {{"_p_cql_transform_t", 0, "cql_transform_t *", 0},{"_p_cql_transform_t"},{0}};
 static swig_type_info _swigt__p_data1_esetname[] = {{"_p_data1_esetname", 0, "data1_esetname *", 0},{"_p_data1_esetname"},{0}};
 static swig_type_info _swigt__p_data1_maptab[] = {{"_p_data1_maptab", 0, "data1_maptab *", 0},{"_p_data1_maptab"},{0}};
 static swig_type_info _swigt__p_ODR[] = {{"_p_ODR", 0, "ODR *", 0},{"_p_ODR"},{0}};
@@ -7438,6 +8065,7 @@ static swig_type_info _swigt__p_RetrievalRecord[] = {{"IDZebra::RetrievalRecord"
 static swig_type_info _swigt__p_NMEM[] = {{"_p_NMEM", 0, "NMEM *", 0},{"_p_NMEM"},{0}};
 static swig_type_info _swigt__p_Z_ExplainRecord[] = {{"_p_Z_ExplainRecord", 0, "Z_ExplainRecord *", 0},{"_p_Z_ExplainRecord"},{0}};
 static swig_type_info _swigt__p_data1_marctab[] = {{"_p_data1_marctab", 0, "data1_marctab *", 0},{"_p_data1_marctab"},{0}};
+static swig_type_info _swigt__p_ZebraTransactionStatus[] = {{"IDZebra::ZebraTransactionStatus", 0, "ZebraTransactionStatus *", 0},{"IDZebra::ZebraTransactionStatus"},{0}};
 static swig_type_info _swigt__p_Z_BriefBib[] = {{"_p_Z_BriefBib", 0, "Z_BriefBib *", 0},{"_p_Z_BriefBib"},{0}};
 static swig_type_info _swigt__p_ScanEntry[] = {{"IDZebra::ScanEntry", 0, "ScanEntry *", 0},{"IDZebra::ScanEntry"},{0}};
 static swig_type_info _swigt__p_f_p_void_p_char_size_t__int[] = {{"_p_f_p_void_p_char_size_t__int", 0, "int (*)(void *,char *,size_t)", 0},{"_p_f_p_void_p_char_size_t__int"},{0}};
@@ -7454,6 +8082,7 @@ static swig_type_info _swigt__p_data1_vartype[] = {{"_p_data1_vartype", 0, "data
 
 static swig_type_info *swig_types_initial[] = {
 _swigt__p_ZebraService, 
+_swigt__p_cql_transform_t, 
 _swigt__p_data1_esetname, 
 _swigt__p_data1_maptab, 
 _swigt__p_ODR, 
@@ -7483,6 +8112,7 @@ _swigt__p_RetrievalRecord,
 _swigt__p_NMEM, 
 _swigt__p_Z_ExplainRecord, 
 _swigt__p_data1_marctab, 
+_swigt__p_ZebraTransactionStatus, 
 _swigt__p_Z_BriefBib, 
 _swigt__p_ScanEntry, 
 _swigt__p_f_p_void_p_char_size_t__int, 
@@ -7613,6 +8243,20 @@ static swig_command_info swig_commands[] = {
 {"IDZebrac::ScanObj_entries_get", _wrap_ScanObj_entries_get},
 {"IDZebrac::new_ScanObj", _wrap_new_ScanObj},
 {"IDZebrac::delete_ScanObj", _wrap_delete_ScanObj},
+{"IDZebrac::ZebraTransactionStatus_processed_set", _wrap_ZebraTransactionStatus_processed_set},
+{"IDZebrac::ZebraTransactionStatus_processed_get", _wrap_ZebraTransactionStatus_processed_get},
+{"IDZebrac::ZebraTransactionStatus_inserted_set", _wrap_ZebraTransactionStatus_inserted_set},
+{"IDZebrac::ZebraTransactionStatus_inserted_get", _wrap_ZebraTransactionStatus_inserted_get},
+{"IDZebrac::ZebraTransactionStatus_updated_set", _wrap_ZebraTransactionStatus_updated_set},
+{"IDZebrac::ZebraTransactionStatus_updated_get", _wrap_ZebraTransactionStatus_updated_get},
+{"IDZebrac::ZebraTransactionStatus_deleted_set", _wrap_ZebraTransactionStatus_deleted_set},
+{"IDZebrac::ZebraTransactionStatus_deleted_get", _wrap_ZebraTransactionStatus_deleted_get},
+{"IDZebrac::ZebraTransactionStatus_utime_set", _wrap_ZebraTransactionStatus_utime_set},
+{"IDZebrac::ZebraTransactionStatus_utime_get", _wrap_ZebraTransactionStatus_utime_get},
+{"IDZebrac::ZebraTransactionStatus_stime_set", _wrap_ZebraTransactionStatus_stime_set},
+{"IDZebrac::ZebraTransactionStatus_stime_get", _wrap_ZebraTransactionStatus_stime_get},
+{"IDZebrac::new_ZebraTransactionStatus", _wrap_new_ZebraTransactionStatus},
+{"IDZebrac::delete_ZebraTransactionStatus", _wrap_delete_ZebraTransactionStatus},
 {"IDZebrac::DESTROY", _wrap_DESTROY},
 {"IDZebrac::logLevel", _wrap_logLevel},
 {"IDZebrac::logFile", _wrap_logFile},
@@ -7635,7 +8279,9 @@ static swig_command_info swig_commands[] = {
 {"IDZebrac::select_databases", _wrap_select_databases},
 {"IDZebrac::begin_trans", _wrap_begin_trans},
 {"IDZebrac::end_trans", _wrap_end_trans},
+{"IDZebrac::trans_no", _wrap_trans_no},
 {"IDZebrac::begin_read", _wrap_begin_read},
+{"IDZebrac::zts_test", _wrap_zts_test},
 {"IDZebrac::end_read", _wrap_end_read},
 {"IDZebrac::commit", _wrap_commit},
 {"IDZebrac::get_shadow_enable", _wrap_get_shadow_enable},
@@ -7648,6 +8294,10 @@ static swig_command_info swig_commands[] = {
 {"IDZebrac::update_record", _wrap_update_record},
 {"IDZebrac::delete_record", _wrap_delete_record},
 {"IDZebrac::search_PQF", _wrap_search_PQF},
+{"IDZebrac::cql_transform_open_fname", _wrap_cql_transform_open_fname},
+{"IDZebrac::cql_transform_close", _wrap_cql_transform_close},
+{"IDZebrac::cql_transform_error", _wrap_cql_transform_error},
+{"IDZebrac::cql2pqf", _wrap_cql2pqf},
 {"IDZebrac::records_retrieve", _wrap_records_retrieve},
 {"IDZebrac::record_retrieve", _wrap_record_retrieve},
 {"IDZebrac::sort", _wrap_sort},
@@ -7802,6 +8452,7 @@ XS(SWIG_init) {
     SWIG_TypeClientData(SWIGTYPE_p_RetrievalRecord, (void*) "IDZebra::RetrievalRecord");
     SWIG_TypeClientData(SWIGTYPE_p_ScanEntry, (void*) "IDZebra::ScanEntry");
     SWIG_TypeClientData(SWIGTYPE_p_ScanObj, (void*) "IDZebra::ScanObj");
+    SWIG_TypeClientData(SWIGTYPE_p_ZebraTransactionStatus, (void*) "IDZebra::ZebraTransactionStatus");
     ST(0) = &PL_sv_yes;
     XSRETURN(1);
 }
index 5b739a7..40bd86d 100755 (executable)
@@ -1,4 +1,4 @@
 #!/bin/sh
 
-rm register/* lock/*
-../../index/zebraidx update /usr/lib/perl5
+rm demo/register/* demo/lock/*
+../index/zebraidx -c demo/zebra.cfg -g demo1 -v 255 update lib
index 7bc9a5a..8fff2cb 100644 (file)
@@ -13,5 +13,5 @@ maptab meta-usmarc.map
 # These tags are required by Zebra for GRS-1 generation
 elm (1,10)             rank                    -
 elm (1,14)             localControlNumber      Local-number
-elm name               NAME                    Title,Title:s,Any 
+elm name               NAME                    Title,Any,Title:s
 elm description        description             Any 
index bc6b2bd..92d856f 100644 (file)
@@ -1,28 +1,27 @@
 # Simple zebra configuration file to demonstate the usage of the perl filters
 
-profilePath: ../blib/lib:../blib/arch:../blib/lib:.:../../tab:../../../yaz/tab
+profilePath: blib/lib:blib/arch:blib/lib:demo/:../tab:../../yaz/tab
 
 # Files that describe the attribute sets supported.
 attset: bib1.att
 attset: explain.att
 
-register: register:1000M
+register: demo/register:1000M
+lockDir: demo/lock
+setTmpDir: demo/tmp
+keyTmpDir: demo/tmp
+memMax: 1
 
-# Specify record type
-recordType.pm: grs.perl.pod
-recordId: $filename (bib1,Title)
 
-# Lock File Area
-lockDir: lock
+demo1.recordType.pm: grs.perl.pod
+demo1.recordId: (bib1,Title)
+demo1.database: demo1
 
-# Temp File area for result sets
-setTmpDir: tmp
-
-# Temp File area for index program
-keyTmpDir: tmp
+demo2.recordType.pm: grs.perl.pod
+demo2.recordId: (bib1,Title)
+demo2.database: demo2
 
 # Approx. Memory usage during indexing
-memMax: 4
 
 storeKeys: 1
 storeData: 1
index c10d7fa..1a5a363 100644 (file)
@@ -55,7 +55,9 @@ package IDZebra;
 *select_databases = *IDZebrac::select_databases;
 *begin_trans = *IDZebrac::begin_trans;
 *end_trans = *IDZebrac::end_trans;
+*trans_no = *IDZebrac::trans_no;
 *begin_read = *IDZebrac::begin_read;
+*zts_test = *IDZebrac::zts_test;
 *end_read = *IDZebrac::end_read;
 *commit = *IDZebrac::commit;
 *get_shadow_enable = *IDZebrac::get_shadow_enable;
@@ -68,6 +70,10 @@ package IDZebra;
 *update_record = *IDZebrac::update_record;
 *delete_record = *IDZebrac::delete_record;
 *search_PQF = *IDZebrac::search_PQF;
+*cql_transform_open_fname = *IDZebrac::cql_transform_open_fname;
+*cql_transform_close = *IDZebrac::cql_transform_close;
+*cql_transform_error = *IDZebrac::cql_transform_error;
+*cql2pqf = *IDZebrac::cql2pqf;
 *records_retrieve = *IDZebrac::records_retrieve;
 *record_retrieve = *IDZebrac::record_retrieve;
 *sort = *IDZebrac::sort;
@@ -552,6 +558,85 @@ sub STORE {
 }
 
 
+############# Class : IDZebra::ZebraTransactionStatus ##############
+
+package IDZebra::ZebraTransactionStatus;
+@ISA = qw( IDZebra );
+%OWNER = ();
+%BLESSEDMEMBERS = (
+);
+
+%ITERATORS = ();
+*swig_processed_get = *IDZebrac::ZebraTransactionStatus_processed_get;
+*swig_processed_set = *IDZebrac::ZebraTransactionStatus_processed_set;
+*swig_inserted_get = *IDZebrac::ZebraTransactionStatus_inserted_get;
+*swig_inserted_set = *IDZebrac::ZebraTransactionStatus_inserted_set;
+*swig_updated_get = *IDZebrac::ZebraTransactionStatus_updated_get;
+*swig_updated_set = *IDZebrac::ZebraTransactionStatus_updated_set;
+*swig_deleted_get = *IDZebrac::ZebraTransactionStatus_deleted_get;
+*swig_deleted_set = *IDZebrac::ZebraTransactionStatus_deleted_set;
+*swig_utime_get = *IDZebrac::ZebraTransactionStatus_utime_get;
+*swig_utime_set = *IDZebrac::ZebraTransactionStatus_utime_set;
+*swig_stime_get = *IDZebrac::ZebraTransactionStatus_stime_get;
+*swig_stime_set = *IDZebrac::ZebraTransactionStatus_stime_set;
+sub new {
+    my $pkg = shift;
+    my @args = @_;
+    my $self = IDZebrac::new_ZebraTransactionStatus(@args);
+    return undef if (!defined($self));
+    $OWNER{$self} = 1;
+    my %retval;
+    tie %retval, "IDZebra::ZebraTransactionStatus", $self;
+    return bless \%retval, $pkg;
+}
+
+sub DESTROY {
+    return unless $_[0]->isa('HASH');
+    my $self = tied(%{$_[0]});
+    return unless defined $self;
+    delete $ITERATORS{$self};
+    if (exists $OWNER{$self}) {
+        IDZebrac::delete_ZebraTransactionStatus($self);
+        delete $OWNER{$self};
+    }
+}
+
+sub DISOWN {
+    my $self = shift;
+    my $ptr = tied(%$self);
+    delete $OWNER{$ptr};
+    };
+
+sub ACQUIRE {
+    my $self = shift;
+    my $ptr = tied(%$self);
+    $OWNER{$ptr} = 1;
+    };
+
+sub FETCH {
+    my ($self,$field) = @_;
+    my $member_func = "swig_${field}_get";
+    my $val = $self->$member_func();
+    if (exists $BLESSEDMEMBERS{$field}) {
+        return undef if (!defined($val));
+        my %retval;
+        tie %retval,$BLESSEDMEMBERS{$field},$val;
+        return bless \%retval, $BLESSEDMEMBERS{$field};
+    }
+    return $val;
+}
+
+sub STORE {
+    my ($self,$field,$newval) = @_;
+    my $member_func = "swig_${field}_set";
+    if (exists $BLESSEDMEMBERS{$field}) {
+        $self->$member_func(tied(%{$newval}));
+    } else {
+        $self->$member_func($newval);
+    }
+}
+
+
 # ------- VARIABLE STUBS --------
 
 package IDZebra;
index b617269..9aa54ff 100644 (file)
@@ -103,6 +103,7 @@ sub tag_add_attr {
 
 sub mk_text {
     my ($self, $parent, $text) = @_;
+    $text = "" unless ($text);
     return (IDZebra::data1_mk_text($self->{dh}, $self->{mem},
                                   $text, $parent)); 
 }
index 51adcc0..29e7635 100644 (file)
@@ -8,6 +8,10 @@ use Carp;
 package IDZebra::Filter;
 use IDZebra;
 use IDZebra::Data1;
+use IDZebra::Logger qw(:flags :calls);
+use Devel::Leak;
+
+our $SAFE_MODE = 1;
 
 BEGIN {
     IDZebra::init(); # ??? Do we need that at all (this is jus nmem init...)
@@ -31,13 +35,28 @@ sub new {
 # -----------------------------------------------------------------------------
 sub _process {
     my ($self) = @_;
+
+#    if ($self->{dl}) {
+#      print STDERR "LEAK",Devel::Leak::CheckSV($self->{dl}),"\n";
+#    }
+
+#    print STDERR "LEAK",Devel::Leak::NoteSV($self->{dl}),"\n";
+
     # This is ugly... could be passed as parameters... but didn't work.
     # I don't know why...
     my $dh  = IDZebra::grs_perl_get_dh($self->{context});
     my $mem = IDZebra::grs_perl_get_mem($self->{context});
     my $d1  = IDZebra::Data1->get($dh,$mem);
 
-    my $rootnode = $self->process($d1);
+    my $rootnode;
+    if ($SAFE_MODE) {
+       eval {$rootnode = $self->process($d1)};
+       if ($@) {
+           logf(LOG_WARN,"Error processing perl filter:%s\n",$@);
+       }
+    } else {
+       $rootnode = $self->process($d1);
+    }
     IDZebra::grs_perl_set_res($self->{context},$rootnode);
     return (0);
 }
index 0c6e442..ff1a4a4 100644 (file)
@@ -33,20 +33,28 @@ sub new {
 
 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) { $self->{rg}{groupName} = $groupName;  }
+    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();
-    print "recordType:",$self->{rg}{recordType},"\n";
 }
 
 sub _set_options {
-    my ($self, %args) = @_;
+    my ($self, %args) = @_; 
     my $i = 0;
     foreach my $key (keys(%args)) {
        $self->{rg}{$key} = $args{$key};
@@ -72,10 +80,31 @@ sub _prepare {
             "Could not select database %s errCode=%d",
             $self->{rg}{databaseName},
             $self->{session}->errCode());
-       croak("Fatal error selecting database");
+       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);
@@ -95,34 +124,52 @@ sub show {
 }
 
 sub update_record {
-    my ($self, $buf, $sysno, $match, $fname) = @_;
-
-    $sysno = 0 unless ($sysno > 0);
-    $match = "" unless ($match);
-    $fname = "<no file>" unless ($fname);
-
+    my ($self, %args) = @_;
     return(IDZebra::update_record($self->{session}{zh},
-                                $self->{rg},
-                                $sysno,$match,$fname,
-                                $buf, -1)); 
+                                 $self->{rg},
+                                 $self->update_args(%args)));
 }
 
 sub delete_record {
-    my ($self, $buf, $sysno, $match, $fname) = @_;
-    
-    $sysno = 0 unless ($sysno > 0);
-    $match = "" unless ($match);
-    $fname = "<no file>" unless ($fname);
-
+    my ($self, %args) = @_;
     return(IDZebra::delete_record($self->{session}{zh},
-                                $self->{rg},
-                                $sysno,$match,$fname,
-                                $buf, -1)); 
+                                 $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) = @_;
-    print STDERR "Destroy repository\n";
 }
 
 __END__
index f876555..c3bf82e 100644 (file)
@@ -3,15 +3,15 @@
 # Zebra perl API header
 # =============================================================================
 use strict;
-use Carp;
 # ============================================================================
 package IDZebra::Session;
 use IDZebra;
 use IDZebra::Logger qw(:flags :calls);
-use IDZebra::Repository;
+#use IDZebra::Repository;
 use IDZebra::Resultset;
 use Scalar::Util;
-
+use Carp;
+use strict;
 our @ISA = qw(IDZebra::Logger);
 
 1;
@@ -19,26 +19,67 @@ our @ISA = qw(IDZebra::Logger);
 # Class constructors, destructor
 # -----------------------------------------------------------------------------
 sub new {
-    my ($proto,$service) = @_;
+    my ($proto, %args) = @_;
     my $class = ref($proto) || $proto;
     my $self = {};
-    $self->{service} = $service;
-    $self->{sessionID} = $service->{sessc};
+    $self->{args} = \%args;
+    
     bless ($self, $class);
+    $self->{cql_ct} = undef;
     return ($self);
 }
 
+sub start_service {
+    my ($self, %args) = @_;
+
+    my $zs;
+    unless (defined($self->{zs})) {
+       if (defined($args{'configFile'})) {
+           $self->{zs} = IDZebra::start($args{'configFile'});
+       } else {
+           $self->{zs} = IDZebra::start("zebra.cfg");
+       }
+    }
+}
+
+sub stop_service {
+    my ($self) = @_;
+    if (defined($self->{zs})) {
+        IDZebra::stop($self->{zs}) if ($self->{zs});    
+       $self->{zs} = undef;
+    }
+}
+
+
 sub open {
-    my ($proto,$service) = @_;
+    my ($proto,%args) = @_;
     my $self = {};
+
     if (ref($proto)) { $self = $proto; } else { 
-       $self = $proto->new($service);
+       $self = $proto->new(%args);
+    }
+
+    unless (%args) {
+       %args = %{$self->{args}};
     }
+
+    $self->start_service(%args);
+
+    unless (defined($self->{zs})) {
+       croak ("Falied to open zebra service");
+    }    
+
     unless (defined($self->{zh})) {
-       $self->{zh}=IDZebra::open($self->{service}{zs}) if ($self->{service}); 
+       $self->{zh}=IDZebra::open($self->{zs}) #if ($self->{zs}); 
     }   
-    $self->Repository(); # Make a dummy record group
+  
 
+    # This is needed in order to somehow initialize the service
+    $self->select_databases("Default");
+
+    # Load the default configuration
+    $self->group(%args);
+    
     $self->{odr_input} = IDZebra::odr_createmem($IDZebra::ODR_DECODE);
     $self->{odr_output} = IDZebra::odr_createmem($IDZebra::ODR_ENCODE);
 
@@ -49,6 +90,11 @@ sub close {
     my ($self) = @_;
 
     if ($self->{zh}) {
+       while (IDZebra::trans_no($self->{zh}) > 0) {
+           logf (LOG_WARN,"Explicitly closing transaction with session");
+           $self->end_trans;
+       }
+
         IDZebra::close($self->{zh});
        $self->{zh} = undef;
     }
@@ -65,15 +111,142 @@ sub close {
        $self->{odr_output} = undef;  
     }
 
-    delete($self->{service}{sessions}{$self->{sessionID}});
-    delete($self->{service});
+    $self->stop_service;
 }
 
 sub DESTROY {
     my ($self) = @_;
-    print STDERR "Destroy_session\n";
+    logf (LOG_LOG,"DESTROY $self");
     $self->close; 
+
+    if (defined ($self->{cql_ct})) {
+      IDZebra::cql_transform_close($self->{cql_ct});
+    }
+}
+# -----------------------------------------------------------------------------
+# Record group selection
+# -----------------------------------------------------------------------------
+sub group {
+    my ($self,%args) = @_;
+#    print STDERR "A\n";
+    if ($#_ > 0) {
+       $self->{rg} = $self->_makeRecordGroup(%args);
+       $self->_selectRecordGroup($self->{rg});
+    }
+#    print STDERR "B\n";
+    return($self->{rg});
+}
+
+sub selectRecordGroup {
+    my ($self, $groupName) = @_;
+    $self->{rg} = $self->_getRecordGroup($groupName);
+    $self->_selectRecordGroup($self->{rg});
+}
+
+sub _displayRecordGroup {
+    my ($self, $rg) = @_;
+    print STDERR "-----\n";
+    foreach my $key qw (groupName 
+                       databaseName 
+                       path recordId 
+                       recordType 
+                       flagStoreData 
+                       flagStoreKeys 
+                       flagRw 
+                       fileVerboseLimit 
+                       databaseNamePath 
+                       explainDatabase 
+                       followLinks) {
+       print STDERR "$key:",$rg->{$key},"\n";
+    }
+}
+
+sub _cloneRecordGroup {
+    my ($self, $orig) = @_;
+    my $rg = IDZebra::recordGroup->new();
+    my $r = IDZebra::init_recordGroup($rg);
+    foreach my $key qw (groupName 
+                       databaseName 
+                       path 
+                       recordId 
+                       recordType 
+                       flagStoreData 
+                       flagStoreKeys 
+                       flagRw 
+                       fileVerboseLimit 
+                       databaseNamePath 
+                       explainDatabase 
+                       followLinks) {
+       $rg->{$key} = $orig->{$key} if ($orig->{$key});
+    }
+    return ($rg);
+}
+
+sub _getRecordGroup {
+    my ($self, $groupName, $ext) = @_;
+    my $rg = IDZebra::recordGroup->new();
+    my $r = IDZebra::init_recordGroup($rg);
+    $rg->{groupName} = $groupName if ($groupName ne "");  
+    $ext = "" unless ($ext);
+    my $r = IDZebra::res_get_recordGroup($self->{zh}, $rg, $ext);
+    return ($rg);
+}
+
+sub _makeRecordGroup {
+    my ($self, %args) = @_;
+    my $rg;
+
+    my @keys = keys(%args);
+    unless ($#keys >= 0) {
+       return ($self->{rg});
+    }
+
+    if ($args{groupName}) {
+       $rg = $self->_getRecordGroup($args{groupName});
+    } else {
+       $rg = $self->_cloneRecordGroup($self->{rg});
+    }
+    $self->_setRecordGroupOptions($rg, %args);
+    return ($rg);
+}
+
+sub _setRecordGroupOptions {
+    my ($self, $rg, %args) = @_;
+
+    foreach my $key qw (databaseName 
+                       path 
+                       recordId 
+                       recordType 
+                       flagStoreData 
+                       flagStoreKeys 
+                       flagRw 
+                       fileVerboseLimit 
+                       databaseNamePath 
+                       explainDatabase 
+                       followLinks) {
+       if (defined ($args{$key})) {
+           $rg->{$key} = $args{$key};
+       }
+    }
 }
+sub _selectRecordGroup {
+    my ($self, $rg) = @_;
+    my $r = IDZebra::set_group($self->{zh}, $rg);
+    my $dbName;
+    unless ($dbName = $rg->{databaseName}) {
+       $dbName = 'Default';
+    }
+    if (IDZebra::select_database($self->{zh}, $dbName)) {
+       logf(LOG_FATAL, 
+            "Could not select database %s errCode=%d",
+            $dbName,
+            $self->errCode());
+       croak("Fatal error selecting record group");
+    } else {
+       logf(LOG_LOG,"Database %s selected",$dbName);
+    }
+}
+
 # -----------------------------------------------------------------------------
 # Error handling
 # -----------------------------------------------------------------------------
@@ -97,18 +270,17 @@ sub errAdd {
 # -----------------------------------------------------------------------------
 sub begin_trans {
     my ($self) = @_;
-    unless ($self->{trans_started}) {
-        $self->{trans_started} = 1;
-        IDZebra::begin_trans($self->{zh});
-    }
+    IDZebra::begin_trans($self->{zh});
 }
 
+
+
+
 sub end_trans {
     my ($self) = @_;
-    if ($self->{trans_started}) {
-        $self->{trans_started} = 0;
-        IDZebra::end_trans($self->{zh});
-    }
+    my $stat = IDZebra::ZebraTransactionStatus->new();
+    IDZebra::end_trans($self->{zh}, $stat);
+    return ($stat);
 }
 
 sub begin_read {
@@ -158,18 +330,99 @@ sub compact {
     return(IDZebra::compact($self->{zh}));
 }
 
+sub update {
+    my ($self, %args) = @_;
+    my $rg = $self->update_args(%args);
+    $self->begin_trans;
+    IDZebra::repository_update($self->{zh});
+    $self->_selectRecordGroup($self->{rg});
+    $self->end_trans;
+}
+
+sub delete {
+    my ($self, %args) = @_;
+    my $rg = $self->update_args(%args);
+    $self->begin_trans;
+    IDZebra::repository_delete($self->{zh});
+    $self->_selectRecordGroup($self->{rg});
+    $self->end_trans;
+}
+
+sub show {
+    my ($self, %args) = @_;
+    my $rg = $self->update_args(%args);
+    $self->begin_trans;
+    IDZebra::repository_show($self->{zh});
+    $self->_selectRecordGroup($self->{rg});
+    $self->end_trans;
+}
+
+sub update_args {
+    my ($self, %args) = @_;
+    my $rg = $self->_makeRecordGroup(%args);
+    $self->_selectRecordGroup($rg);
+    return ($rg);
+}
+
 # -----------------------------------------------------------------------------
-# Repository stuff
+# Per record update
 # -----------------------------------------------------------------------------
-sub Repository {
+
+sub update_record {
     my ($self, %args) = @_;
-    if (!$self->{rep}) {
-       $self->{rep} = IDZebra::Repository->new($self, %args);
-    } else {
-       $self->{rep}->modify(%args);
+    return(IDZebra::update_record($self->{zh},
+                                 $self->record_update_args(%args)));
+}
+
+sub delete_record {
+    my ($self, %args) = @_;
+    return(IDZebra::delete_record($self->{zh},
+                                 $self->record_update_args(%args)));
+}
+sub record_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);
+
+    delete ($args{sysno});
+    delete ($args{match});
+    delete ($args{recordType});
+    delete ($args{file});
+    delete ($args{data});
+
+    my $rg = $self->_makeRecordGroup(%args);
+
+    # If no record type is given, then try to find it out from the
+    # file extension;
+    unless ($rectype) {
+       if (my ($ext) = $fname =~ /\.(\w+)$/) {
+           my $rg2 = $self->_getRecordGroup($rg->{groupName},$ext);
+           $rectype = $rg2->{recordType};
+       } 
     }
 
-    return ($self->{rep});
+    $rg->{databaseName} = "Default" unless ($rg->{databaseName});
+
+#    print STDERR "$rectype,$sysno,$match,$fname,$len\n";
+    unless ($rectype) {
+       $rectype="";
+    }
+    return ($rg, $rectype, $sysno, $match, $fname, $buff, $len);
 }
 
 # -----------------------------------------------------------------------------
@@ -198,6 +451,41 @@ sub search_pqf {
     return($rs);
 }
 
+sub cqlmap {
+    my ($self,$mapfile) = @_;
+    if ($#_ > 0) {
+       unless (-f $mapfile) {
+           croak("Cannot find $mapfile");
+       }
+       if (defined ($self->{cql_ct})) {
+         IDZebra::cql_transform_close($self->{cql_ct});
+       }
+       $self->{cql_ct} = IDZebra::cql_transform_open_fname($mapfile);
+       $self->{cql_mapfile} = $mapfile;
+    }
+    return ($self->{cql_mapfile});
+}
+
+sub cql2pqf {
+    my ($self, $cqlquery) = @_;
+    unless (defined($self->{cql_ct})) {
+       croak("CQL map file is not specified yet.");
+    }
+    my $res = "\0" x 2048;
+    my $r = IDZebra::cql2pqf($self->{cql_ct}, $cqlquery, $res, 2048);
+    $res=~s/\0.+$//g;
+    return ($res); 
+}
+
+sub search_cql {
+    my ($self, $query, $transfile) = @_;
+}
+
+
+sub search_ccl {
+    my ($self, $query, $transfile) = @_;
+}
+
 # -----------------------------------------------------------------------------
 # Sort
 #
@@ -240,12 +528,199 @@ __END__
 
 =head1 NAME
 
-IDZebra::Session - 
+IDZebra::Session - A Zebra database server session for update and retrieval
 
 =head1 SYNOPSIS
 
+  $sess = IDZebra::Session->new(configFile => 'demo/zebra.cfg');
+  $sess->open();
+
+  $sess = IDZebra::Session->open(configFile => 'demo/zebra.cfg');
+
+  $sess->close;
+
 =head1 DESCRIPTION
 
+Zebra is a high-performance, general-purpose structured text indexing and retrieval engine. It reads structured records in a variety of input formats (eg. email, XML, MARC) and allows access to them through exact boolean search expressions and relevance-ranked free-text queries. 
+
+Zebra supports large databases (more than ten gigabytes of data, tens of millions of records). It supports incremental, safe database updates on live systems. You can access data stored in Zebra using a variety of Index Data tools (eg. YAZ and PHP/YAZ) as well as commercial and freeware Z39.50 clients and toolkits. 
+
+=head1 OPENING AND CLOSING A ZEBRA SESSIONS
+
+For the time beeing only local database services are supported, the same way as calling zebraidx or zebrasrv from the command shell. In order to open a local Zebra database, with a specific configuration file, use
+
+  $sess = IDZebra::Session->new(configFile => 'demo/zebra.cfg');
+  $sess->open();
+
+or
+
+  $sess = IDZebra::Session->open(configFile => 'demo/zebra.cfg');
+
+where $sess is going to be the object representing a Zebra Session. Whenever this variable gets out of scope, the session is closed, together with all active transactions, etc... Anyway, if you'd like to close the session, just say:
+
+  $sess->close();
+
+This will
+  - close all transactions
+  - destroy all result sets
+  - close the session
+
+In the future different database access methods are going to be available, 
+like:
+
+  $sess = IDZebra::Session->open(server => 'ostrich.technomat.hu:9999');
+
+You can also use the B<record group> arguments described below directly when calling the constructor, or the open method:
+
+  $sess = IDZebra::Session->open(configFile => 'demo/zebra.cfg',
+                                 groupName  => 'demo');
+
+
+=head1 RECORD GROUPS 
+
+If you manage different sets of records that share common characteristics, you can organize the configuration settings for each type into "groups". See the Zebra manual on the configuration file (zebra.cfg). 
+
+For each open session a default record group is assigned. You can configure it in the constructor, or by the B<set_group> method:
+
+  $sess->group(groupName => ..., ...)
+
+The following options are available:
+
+=over 4
+
+=item B<groupName>
+
+This will select the named record group, and load the corresponding settings from the configuration file. All subsequent values will overwrite those...
+
+=item B<databaseName>
+
+The name of the (logical) database the updated records will belong to.
+
+=item B<path>
+
+This path is used for directory updates (B<update>, B<delete> methods);
+=item B<recordId>
+
+This option determines how to identify your records. See I<Zebra manual: Locating Records>
+
+=item B<recordType>
+
+The record type used for indexing. 
+
+=item B<flagStoreData> 
+
+Specifies whether the records should be stored internally in the Zebra system files. If you want to maintain the raw records yourself, this option should be false (0). If you want Zebra to take care of the records for you, it should be true(1). 
+
+=item B<flagStoreKeys>
+
+Specifies whether key information should be saved for a given group of records. If you plan to update/delete this type of records later this should be specified as 1; otherwise it should be 0 (default), to save register space. 
+
+=item B<flagRw>
+
+?
+
+=item B<fileVerboseLimit>
+
+Skip log messages, when doing a directory update, and the specified number of files are processed...
+
+=item B<databaseNamePath>
+
+?
+
+=item B<explainDatabase>
+
+The name of the explain database to be used
+
+=item B<followLinks>              
+
+Follow links when doing directory update.
+
+=back
+
+You can use the same parameters calling all update methods.
+
+=head1 TRANSACTIONS (WRITE LOCKS)
+
+A transaction is a block of record update (insert / modify / delete) procedures. So, all call to such function will implicitly start a transaction, unless one is started by
+
+  $sess->begin_trans;
+
+For multiple per record updates it's efficient to start transactions explicitly: otherwise registers (system files, vocabularies, etc..) are updated one by one. After finishing all requested updates, use
+
+  $stat = $sess->end_trans;
+
+The return value is a ZebraTransactionStatus object, containing the following members as a hash reference:
+
+  $stat->{processed} # Number of records processed
+  $stat->{updated}   # Number of records processed
+  $stat->{deleted}   # Number of records processed
+  $stat->{inserted}  # Number of records processed
+  $stat->{stime}     # System time used
+  $stat->{utime}     # User time used
+
+=head1 UPDATING DATA
+
+There are two ways to update data in a Zebra database using the perl API. You can update an entire directory structure just the way it's done by zebraidx:
+
+  $sess->update(path      =>  'lib');
+
+This will update the database with the files in directory "lib", according to the current record group settings.
+
+  $sess->update();
+
+This will update the database with the files, specified by the default record group setting. I<path> has to be specified there...
+
+  $sess->update(groupName => 'demo1',
+               path      =>  'lib');
+
+Update the database with files in "lib" according to the settings of group "demo1"
+
+  $sess->delete(groupName => 'demo1',
+               path      =>  'lib');
+
+Delete the records derived from the files in directory "lib", according to the "demo1" group settings. Sounds complex? Read zebra documentation about identifying records.
+
+You can also update records one by one, even directly from the memory:
+
+  $sysno = $sess->update_record(data       => $rec1,
+                               recordType => 'grs.perl.pod',
+                               groupName  => "demo1");
+
+This will update the database with the given record buffer. Note, that in this case recordType is explicitly specified, as there is no filename given, and for the demo1 group, no default record type is specified. The return value is the system assigned id of the record.
+
+You can also index a single file:
+
+  $sysno = $sess->update_record(file => "lib/IDZebra/Data1.pm");
+
+Or, provide a buffer, and a filename (where filename will only be used to identify the record, if configured that way, and possibly to find out it's record type):
+
+  $sysno = $sess->update_record(data => $rec1,
+                                file => "lib/IDZebra/Data1.pm");
+
+And some crazy stuff:
+
+  $sysno = $sess->delete_record(sysno => $sysno);
+
+where sysno in itself is sufficient to identify the record
+
+  $sysno = $sess->delete_record(data => $rec1,
+                               recordType => 'grs.perl.pod',
+                               groupName  => "demo1");
+
+This case the record is extracted, and if already exists, located in the database, then deleted... 
+
+  $sysno = $sess->delete_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....
+
+
+B<Important:> Note, that one record can be updated only once within a transaction - all subsequent updates are skipped. 
+
+
 =head1 COPYRIGHT
 
 Fill in
index 99bbfbc..3eb490f 100755 (executable)
 BEGIN {
     push (@INC,'demo','blib/lib','blib/arch');
 }
-use Test::More tests => 3;
-use Data::Dumper;
-use IDZebra::Logger qw(:flags :calls);
-use IDZebra::Repository;
+
 use pod;
 
+use Test::More tests => 15;
+
 BEGIN { 
-  use_ok('IDZebra'); 
-  use_ok('IDZebra::Service'); 
-  use_ok('IDZebra::Data1'); 
+  use_ok('IDZebra::Session'); 
 }
 
-mkdir ("demo/tmp");
-mkdir ("demo/register");
-mkdir ("demo/lock");
+IDZebra::logFile("test.log");
 
-#Zebra::API::LogFile("a.log");
+#IDZebra::logLevel(15);
 
+#IDZebra::init();
 
-#my $arr = IDZebra::give_me_array("strucc",6);
+# ----------------------------------------------------------------------------
+# Session opening and closing
+my $sess = IDZebra::Session->new(configFile => 'demo/zebra.cfg');
+isa_ok($sess,"IDZebra::Session");
 
-#print "$arr\n";
+$sess->open();
+ok(defined($sess->{zh}), "Zebra handle opened");
+$sess->close();
+ok(!defined($sess->{zh}), "Zebra handle closed");
 
-#for (@arr) {print "$_\n";}
 
-#exit;
+my $sess = IDZebra::Session->open(configFile => 'demo/zebra.cfg',
+                                 groupName  => 'demo1');
+isa_ok($sess,"IDZebra::Session");
+ok(defined($sess->{zh}), "Zebra handle opened");
 
-IDZebra::init();
+# ----------------------------------------------------------------------------
+# Record group tests
 
-chdir('demo');
+ok(($sess->group->{databaseName} eq "demo1"),"Record group is selected");
 
-my $service = IDZebra::Service->start('zebra.cfg');
-my $sess = $service->openSession;
-#my $sess = $service->createSession;
-#$sess->open;
-#my $session = IDZebra::open($service);
-#IDZebra::close($session);
-#IDZebra::stop($service);
-#$sess->close;
+$sess->group(groupName => 'demo2');
 
-my $rec1=`cat ../lib/IDZebra/Data1.pm`;
-my $rec2=`cat ../lib/IDZebra/Filter.pm`;
+ok(($sess->group->{databaseName} eq "demo2"),"Record group is selected");
 
-#$sess->Repository->readConfig;
-$sess->Repository->readConfig("","pm");
+# ----------------------------------------------------------------------------
+# init repository
+$sess->init();
 
+# ----------------------------------------------------------------------------
+# repository upadte
 $sess->begin_trans;
+$sess->update(path      =>  'lib');
+my $stat = $sess->end_trans;
 
-#$sess->Repository->update(databaseName => 'Default',
-#                        path  => '/usr/local/work/cvs/zebra/perl/lib');
-my $s1 = $sess->Repository->update_record($rec1,0,"","Data1.pm");
-my $s2 = $sess->Repository->update_record($rec2,0,"","Filter.pm");
-print STDERR "s1:$s1, s2:$s2\n";
-
-$sess->end_trans;
-#$sess->begin_trans;
-#$sess->Repository->delete_record($rec1,0,"","Data1.pm");
-#$sess->end_trans;
+ok(($stat->{inserted} == 6), "Inserted 6 records");
 
-$sess->select_databases('Default');
-
-goto scan;
+$sess->begin_trans;
+$sess->update(groupName => 'demo1',
+             path      =>  'lib');
 
-$sess->begin_read;
-#print STDERR "Hits:", $sess->search_pqf('@or @attr 1=4 Filter @attr 1=4 Data1','test_1'), "\n";
-#print STDERR "Hits:", $sess->search_pqf('@or @attr 1=4 Filter @attr 1=4 Data1','test_1'), "\n";
+my $stat = $sess->end_trans;
+ok(($stat->{updated} == 6), "Updated 6 records");
 
-my $rs1 = $sess->search_pqf('@or @attr 1=4 Filter @attr 1=4 Data1','test_1');
-print STDERR "Rs1 '$rs1->{name}' has $rs1->{recordCount} hits\n";
+$sess->begin_trans;
+$sess->delete(groupName => 'demo1',
+             path      =>  'lib');
+my $stat = $sess->end_trans;
+ok(($stat->{deleted} == 6), "Deleted 6 records");
 
-my $rs2 = $sess->search_pqf('@or @attr 1=4 Filter @attr 1=4 Data1','test_2');
-#print STDERR "Rs2 '$rs2->{name}' has $rs2->{recordCount} hits\n";
+$sess->begin_trans;
+$sess->update(groupName => 'demo1',
+             path      =>  'lib');
 
-my $rs3 = $sess->sortResultsets ('1=4 id','test_3',($rs1));
-#print STDERR "Rs3 '$rs3->{name}' has $rs3->{recordCount} hits\n";
-#print STDERR "Rs3 '$rs3->{name}' error $rs3->{errCode}: $rs3->{errString}\n";
+my $stat = $sess->end_trans;
+ok(($stat->{inserted} == 6), "Inserted 6 records");
 
-$rs1->sort('1=4 id');
+ok(($sess->group->{databaseName} eq "demo2"),"Original group is selected");
 
-#for ($i=1; $i<100000; $i++) {
-my @recs1 = $rs1->records(from=>1,to=>2);
-#}
-#my $res=$sess->retrieve_records('test_1',1,1);
+# ----------------------------------------------------------------------------
+# per record update
+my $rec1=`cat lib/IDZebra/Data1.pm`;
+my $rec2=`cat lib/IDZebra/Filter.pm`;
 
-$sess->end_read;
+$sess->begin_trans;
+my $s1=$sess->update_record(data       => $rec1,
+                           recordType => 'grs.perl.pod',
+                           groupName  => "demo1",
+                           );
 
+#my $s2=$sess->update_record(data       => $rec2);
+#                                      recordType => "grs.perl.pod");
 
-#IDZebra::describe_recordGroup($rep->{rg});
-#$rep->update;
-#    print "HOW did we got back???\n";
 
-scan:
+#my $s3=$sess->update_record(file       => "lib/IDZebra/Data1.pm");
 
-my $so = IDZebra::ScanObj->new;
-$so->{position} = 1;
-$so->{num_entries} = 20;
-$so->{is_partial} = 0;
-#print STDERR "Pos:$so->{position}\nNum:$so->{num_entries}\nPartial:$so->{is_partial}\n";
 
-IDZebra::scan_PQF($sess->{zh}, $so,
-                 $sess->{odr_output}, 
-                 "\@attr 1=4 a");
 
-#print STDERR "Pos:$so->{position}\nNum:$so->{num_entries}\nPartial:$so->{is_partial}\n";
+my $stat = $sess->end_trans;
+ok(($stat->{updated} == 1), "Updated 1 records");
 
-for ($i=1; $i<=$so->{num_entries}; $i++) {
-    my $se = IDZebra::getScanEntry($so, $i);
-    print STDERR "$se->{term} ($se->{occurrences})\n";
-}
+#$sess->cqlmap("cql.map");
+#print STDERR $sess->cql2pqf("job.id <= 5");
+#print STDERR $sess->cql2pqf("job.id=5 and dc.title=computer");
+#print STDERR "RES:$res\n";
 
 $sess->close;
-$service->stop;
-                         
-foreach my $rec (@recs1) {
-    foreach my $line (split (/\n/, $rec->{buf})) {
-       if ($line =~ /^package/) { print STDERR "$line\n";}
-    }
-}
-
-#$rep->{groupName} = "Strucc";
-#$rep->describe();
-
-sub test_data1 {
-    $m = IDZebra::nmem_create();
-    my $d1=IDZebra::Data1->new($m,$IDZebra::DATA1_FLAG_XML);
-    my $root=$d1->mk_root('strucc');
-    my $tag1 = $d1->mk_tag($root,'emu',('asd' => 1,
-                                       'bsd' => 2));
-    my $tag2 = $d1->mk_tag($root,'emu');
-    $d1->pr_tree($root);
-    IDZebra::nmem_destroy($m);
-    $d1->DESTROY();
-}
+ok(!defined($sess->{zh}), "Zebra handle closed");
 
-IDZebra::DESTROY;
index 10f0692..b217441 100644 (file)
@@ -16,6 +16,7 @@
 #include "zebra_api_ext.h"
 #include "yaz/log.h"
 #include <yaz/pquery.h>
+#include <yaz/cql.h>
 #include <yaz/sortspec.h>
 
 void data1_print_tree(data1_handle dh, data1_node *n, FILE *out) {
@@ -37,13 +38,13 @@ void init_recordGroup (recordGroup *rg) {
     rg->recordId = NULL;
     rg->recordType = NULL;
     rg->flagStoreData = -1;
-    rg->flagStoreKeys = -1;
+    rg->flagStoreKeys = -1; 
     rg->flagRw = 1;
     rg->databaseNamePath = 0;
-    rg->explainDatabase = 0;
-    rg->fileVerboseLimit = 100000;
+    rg->explainDatabase = 0; 
+    rg->fileVerboseLimit = 100000; 
     rg->followLinks = -1;
-}
+} 
 
 
 /* This is from extract.c... it seems useful, when extract_rec_in mem is 
@@ -52,11 +53,11 @@ void res_get_recordGroup (ZebraHandle zh,
                          recordGroup *rGroup,
                          const char *ext) {
   char gprefix[128];
-  char ext_res[128];
+  char ext_res[128]; 
     
   if (!rGroup->groupName || !*rGroup->groupName)
     *gprefix = '\0';
-  else
+  else 
     sprintf (gprefix, "%s.", rGroup->groupName);
   
   /* determine file type - depending on extension */
@@ -68,18 +69,18 @@ void res_get_recordGroup (ZebraHandle zh,
     }
   }
   /* determine match criteria */
-  if (!rGroup->recordId) {
+  if (!rGroup->recordId) { 
     sprintf (ext_res, "%srecordId.%s", gprefix, ext);
     if (!(rGroup->recordId = res_get (zh->res, ext_res))) {
       sprintf (ext_res, "%srecordId", gprefix);
       rGroup->recordId = res_get (zh->res, ext_res);
     }
-  }
+  } 
   
   /* determine database name */
   if (!rGroup->databaseName) {
     sprintf (ext_res, "%sdatabase.%s", gprefix, ext);
-    if (!(rGroup->databaseName = res_get (zh->res, ext_res))) {
+    if (!(rGroup->databaseName = res_get (zh->res, ext_res))) { 
       sprintf (ext_res, "%sdatabase", gprefix);
       rGroup->databaseName = res_get (zh->res, ext_res);
     }
@@ -120,6 +121,10 @@ void res_get_recordGroup (ZebraHandle zh,
   }
   if (rGroup->flagStoreKeys == -1) rGroup->flagStoreKeys = 0;
   
+} 
+
+int zebra_trans_processed(ZebraTransactionStatus s) {
+  return (s.processed);
 }
 
 /* ---------------------------------------------------------------------------
@@ -128,11 +133,11 @@ void res_get_recordGroup (ZebraHandle zh,
   If sysno is provided, then it's used to identify the reocord.
   If not, and match_criteria is provided, then sysno is guessed
   If not, and a record is provided, then sysno is got from there
-
 */
 
 int zebra_update_record (ZebraHandle zh, 
-                        struct recordGroup *rGroup, 
+                        struct recordGroup *rGroup,
+                        const char *recordType,
                         int sysno, const char *match, const char *fname,
                         const char *buf, int buf_size)
 
@@ -141,17 +146,20 @@ int zebra_update_record (ZebraHandle zh,
 
     if (buf_size < 1) buf_size = strlen(buf);
 
+    zebra_begin_trans(zh);
     res=bufferExtractRecord (zh, buf, buf_size, rGroup, 
-                            0, // delete_flag
-                            0, // test_mode, 
-                            &sysno,
-                            match, fname);    
-  
-    return sysno;
+                            0, // delete_flag 
+                            0, // test_mode,
+                            recordType,
+                            &sysno,   
+                            match, fname);     
+    zebra_end_trans(zh); 
+    return sysno; 
 }
 
 int zebra_delete_record (ZebraHandle zh, 
                         struct recordGroup *rGroup, 
+                        const char *recordType,
                         int sysno, const char *match, const char *fname,
                         const char *buf, int buf_size)
 {
@@ -159,12 +167,15 @@ int zebra_delete_record (ZebraHandle zh,
 
     if (buf_size < 1) buf_size = strlen(buf);
 
+    zebra_begin_trans(zh);
     res=bufferExtractRecord (zh, buf, buf_size, rGroup, 
                             1, // delete_flag
                             0, // test_mode, 
+                            recordType,
                             &sysno,
                             match,fname);    
-    return sysno;
+    zebra_end_trans(zh);
+    return sysno;   
 }
 
 /* ---------------------------------------------------------------------------
@@ -185,7 +196,7 @@ void zebra_search_RPN (ZebraHandle zh, ODR decode, ODR stream,
     resultSetAddRPN (zh, decode, stream, query, 
                      zh->num_basenames, zh->basenames, setname);
 
-        zebra_end_read (zh);
+    zebra_end_read (zh);
 
     *hits = zh->hits;
 }
@@ -213,6 +224,31 @@ int zebra_search_PQF (ZebraHandle zh,
   return(hits);
 }
 
+int zebra_cql2pqf (cql_transform_t ct, 
+                  const char *query, char *res, int len) {
+  
+  int status;
+  const char *addinfo;
+  CQL_parser cp = cql_parser_create();
+
+  if (status = cql_transform_error(ct, &addinfo)) {
+    logf (LOG_WARN,"Transform error %d %s\n", status, addinfo ? addinfo : "");
+    return (status);
+  }
+
+  if (status = cql_parser_string(cp, query))
+    return (status);
+
+  if (status = cql_transform_buf(ct, cql_parser_result(cp), res, len)) {
+    logf (LOG_WARN,"Transform error %d %s\n", status, addinfo ? addinfo : "");
+    return (status);
+  }
+
+  logf (LOG_LOG,"PQF:%s",res);
+
+  return (0);
+}
+
 void zebra_scan_PQF (ZebraHandle zh,
                     ScanObj *so,
                     ODR stream,
@@ -350,39 +386,40 @@ void records_retrieve(ZebraHandle zh,
   if (schema != VAL_NONE) {
     oident prefschema;
 
-    prefschema.proto  = PROTO_Z3950;
+    prefschema.proto = PROTO_Z3950;
     prefschema.oclass = CLASS_SCHEMA;
-    prefschema.value  = schema;
-
+    prefschema.value = schema;
+    
     compo.which = Z_RecordComp_complex;
     compo.u.complex = (Z_CompSpec *)
       odr_malloc(stream, sizeof(*compo.u.complex));
     compo.u.complex->selectAlternativeSyntax = (bool_t *) 
       odr_malloc(stream, sizeof(bool_t));
     *compo.u.complex->selectAlternativeSyntax = 0;
-
+    
     compo.u.complex->generic = (Z_Specification *)
       odr_malloc(stream, sizeof(*compo.u.complex->generic));
-    compo.u.complex->generic->schema = (Odr_oid *)
+    compo.u.complex->generic->which = Z_Schema_oid;
+    compo.u.complex->generic->schema.oid = (Odr_oid *)
       odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
-
-    if (!compo.u.complex->generic->schema) {
-      /* OID wasn't a schema! Try record syntax instead. */
-      prefschema.oclass = CLASS_RECSYN;
-      compo.u.complex->generic->schema = (Odr_oid *)
-       odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
-    }
-
-    if (!elementSetNames) {
+    if (!compo.u.complex->generic->schema.oid)
+      {
+       /* OID wasn't a schema! Try record syntax instead. */
+       prefschema.oclass = CLASS_RECSYN;
+       compo.u.complex->generic->schema.oid = (Odr_oid *)
+         odr_oiddup(stream, oid_ent_to_oid(&prefschema, oid));
+      }
+    if (!elementSetNames)
       compo.u.complex->generic->elementSpec = 0;
-    } else {
-      compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
-       odr_malloc(stream, sizeof(Z_ElementSpec));
-      compo.u.complex->generic->elementSpec->which =
-       Z_ElementSpec_elementSetName;
-      compo.u.complex->generic->elementSpec->u.elementSetName =
-       elementSetNames->u.generic;
-    }
+    else
+      {
+       compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
+         odr_malloc(stream, sizeof(Z_ElementSpec));
+       compo.u.complex->generic->elementSpec->which =
+         Z_ElementSpec_elementSetName;
+       compo.u.complex->generic->elementSpec->u.elementSetName =
+         elementSetNames->u.generic;
+      }
     compo.u.complex->num_dbSpecific = 0;
     compo.u.complex->dbSpecific = 0;
     compo.u.complex->num_recordSyntax = 0;
@@ -400,12 +437,16 @@ void records_retrieve(ZebraHandle zh,
                            res->noOfRecords, res->records);
   } else {
     api_records_retrieve (zh, stream, setname, 
-                           &compo, 
+                           &compo,
                            recordsyntax,
                            res->noOfRecords, res->records);
   }
 
 }
+int zebra_trans_no (ZebraHandle zh) {
+  return (zh->trans_no);
+}
 
 /* almost the same as zebra_records_retrieve ... but how did it work? 
    I mean for multiple records ??? CHECK ??? */
@@ -424,7 +465,7 @@ void api_records_retrieve (ZebraHandle zh, ODR stream,
         return;
     }
     
-    zh->errCode = 0;
+    zh->errCode = 0; 
 
     if (zebra_begin_read (zh))
        return;
index 7631593..0649bca 100644 (file)
@@ -20,7 +20,7 @@ void init (void) {
 void DESTROY (void) {
   nmem_exit ();
   yaz_log (LOG_LOG, "Zebra API destroyed");
-}
+}   
 
 /* Logging facilities from yaz */
 void logLevel (int level) {
@@ -35,5 +35,6 @@ void logMsg (int level, const char *message) {
   logf(level, "%s", message);
 }
 
-
-
+void zts_test (ZebraTransactionStatus *stat) {
+  stat->processed++;
+}
index 5abd5cc..9b49303 100644 (file)
@@ -47,3 +47,5 @@ typedef struct {
 } ScanObj;
 
 #endif
+
+