zebra_begin_trans got extra "write" flag. zebra_begin_read
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 4 Mar 2003 23:30:20 +0000 (23:30 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 4 Mar 2003 23:30:20 +0000 (23:30 +0000)
implemented in temrs of zebra_begin_trans. zebra_end_read
is equivalent to zebra_end_trans.

doc/installation.xml
examples/gils/zebra.cfg
index/extract.c
index/index.h
index/main.c
index/zebraapi.c
index/zebraapi.h
index/zserver.c
test/api/t2.c

index fd1e873..021a610 100644 (file)
-<chapter id="installation">
- <!-- $Id: installation.xml,v 1.6 2002-12-01 23:26:26 mike Exp $ -->
- <title>Installation</title>
- <para>
-  An ANSI C compiler is required to compile the Zebra
-  server system &mdash; <literal>gcc</literal> works fine if your
-  own system doesn't provide an adequate compiler.
- </para>
- <para>
-  Unpack the distribution archive. The <literal>configure</literal>
-  shell script attempts to guess correct values for various
-  system-dependent variables used during compilation.
-  It uses those values to create a <literal>Makefile</literal> in each
-  directory of Zebra.
- </para>
- <para>
-  To run the configure script type:
+<!-- $Id: installation.xml,v 1.7 2003-03-04 23:30:20 adam Exp $ -->
+ <chapter id="installation">
+  <title>Installation</title>
+  <para>
+   Zebra is very portable. An ANSI C compiler is required. We
+   primarily use GNU C on UNIX and Microsoft Visual C++ on Windows.
+  </para>
 
-  <screen>
-  ./configure
-  </screen>
+  <para>
+   Zebra uses following components. Most of these are optional.
+   <variablelist>
+    <varlistentry>
+     <term><ulink url="http://www.indexdata.dk/yaz/">yaz</ulink> (required)</term>
+     <listitem>
+      <para>
+       Zebra uses lots of utilities provided by YAZ. Most notably
+       Z39.50 support.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><ulink url="http://www.gnu.org/software/libiconv/">iconv</ulink>
+      (optional)</term>
+     <listitem>
+      <para>
+       Character set conversion. This is required if you're
+       going to use any other character set than UTF-8 and ISO-8859-1
+       for records. Note that some Unixes has iconv built-in.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><ulink url="http://expat.sourceforge.net/">Expat</ulink>
+      (optional)</term>
+     <listitem>
+      <para>
+       XML parser. If you're going to index real XML you should
+       install this (filter grs.xml). On most system, you should be able
+       to find binary Expat packages.
+      </para>
+     </listitem>
+    </varlistentry>
 
- </para>
- <para>
-  The configure script attempts to use C compiler specified by
-  the <literal>CC</literal> environment variable.
-  If this is not set, <literal>cc</literal> or GNU C will be used.
-  The <literal>CFLAGS</literal> environment variable holds
-  options to be passed to the C compiler. If you're using a
-  Bourne-shell compatible shell you may pass something like this:
-  
-  <screen>
-  CC=/opt/ccs/bin/cc CFLAGS=-O ./configure
-  </screen>
- </para>
- <para>
-  The configure script support various options: you can see what they
-  are with
-  <screen>
-  ./configure --help
-  </screen>
- </para>
- <para>
-  Once the build environment is configured, build the software by
-  typing:
-  <screen>
-  make
-  </screen>
- </para>
- <para>
-  If the build is successful, two executables are created in the
-  sub-directory <literal>index</literal>:
-  <variablelist>
+    <varlistentry>
+     <term><ulink url="http://www.perl.com/">Perl</ulink> (optional)</term>
+     <listitem>
+      <para>
+       Perl is required if you're going to use the Zebra perl
+       filter facility or the Zebra perl API. Perl is preinstalled
+       on many Unixes. We've not tried the Perl extension on 
+       Windows ourselves.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term><ulink url="http://www.tcl.tk/">Tcl</ulink> (optional)</term>
+     <listitem>
+      <para>
+       Tcl is required if you  need to use the Tcl record filter
+       for Zebra. You can find binary packages for Tcl for many
+       Unices and Windows.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term>
+      <ulink url="http://www.gnu.org/software/autoconf/">Autoconf</ulink>,
+      <ulink url="
+      
+ (optional)</term>
+     <listitem>
+      <para>
+       GNU Automake and Autoconf are only required if you're
+       using the CVS version of Zebra. You do not need these
+       if you have fetched a Zebra tar.
+      </para>
+     </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+     <term>Docbook and friends (optional)</term>
+     <listitem>
+      <para>
+       These tools are only required if you're writing
+       Documentation for Zebra. You need the following
+       Debian packages: jadetex, docbook, docbook-dsssl,
+       docbook-xml, docbook-utils.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </para>
+
+  <sect1 id="installation.unix"><title>UNIX</title>
+   <para>
+    On Unix, <literal>gcc</literal> works fine, but any native
+    C compiler should be possible to use as long as it is 
+    ANSI C compliant.
+   </para>
+   
+   <para>
+    Unpack the distribution archive. The <literal>configure</literal>
+    shell script attempts to guess correct values for various
+    system-dependent variables used during compilation.
+    It uses those values to create a <literal>Makefile</literal> in each
+    directory of Zebra.
+   </para>
+   
+   <para>
+    To run the configure script type:
+    
+    <screen>
+     ./configure
+    </screen>
+    
+   </para>
+   
+   <para>
+    The configure script attempts to use C compiler specified by
+    the <literal>CC</literal> environment variable.
+    If this is not set, <literal>cc</literal> or GNU C will be used.
+    The <literal>CFLAGS</literal> environment variable holds
+    options to be passed to the C compiler. If you're using a
+    Bourne-shell compatible shell you may pass something like this:
+    
+    <screen>
+     CC=/opt/ccs/bin/cc CFLAGS=-O ./configure
+    </screen>
+   </para>
+   <para>
+    The configure script support various options: you can see what they
+    are with
+    <screen>
+     ./configure --help
+    </screen>
+   </para>
+   
+   <para>
+    Once the build environment is configured, build the software by
+    typing:
+    <screen>
+     make
+    </screen>
+   </para>
+   
+   <para>
+    If the build is successful, two executables are created in the
+    sub-directory <literal>index</literal>:
+    <variablelist>
+     
+     <varlistentry>
+      <term><literal>zebrasrv</literal></term>
+      <listitem>
+       <para>
+        The Z39.50 server and search engine.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+     <term><literal>zebraidx</literal></term>
+      <listitem>
+       <para>
+        The administrative indexing tool.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
    
-   <varlistentry>
-    <term><literal>zebrasrv</literal></term>
-    <listitem>
-     <para>
-      The Z39.50 server and search engine.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term><literal>zebraidx</literal></term>
-    <listitem>
-     <para>
-      The administrative indexing tool.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
- </para>
- <para>
-  You can now use Zebra. If you wish to install it system-wide, then
-  as root type
-  <screen>
-    make install
-  </screen>
-  By default this will install the Zebra executables in 
-  <filename>/usr/local/bin</filename>,
-  and the standard configuration files in 
-  <filename>/usr/local/share/idzebra</filename>
-  You can override this with the <literal>--prefix</literal> option
-  to configure.
- </para>
-</chapter>
+   <para>
+    You can now use Zebra. If you wish to install it system-wide, then
+    as root type
+    <screen>
+     make install
+    </screen>
+    By default this will install the Zebra executables in 
+    <filename>/usr/local/bin</filename>,
+    and the standard configuration files in 
+    <filename>/usr/local/share/idzebra</filename>
+    You can override this with the <literal>--prefix</literal> option
+    to configure.
+   </para>
+  </sect1>
+  <sect1><title>WIN32</title>
+   <para>
+    
+   </para>
+  </sect1>
+ </chapter>
  <!-- Keep this comment at the end of the file
  Local variables:
  mode: sgml
index 44972ed..52d0bd9 100644 (file)
@@ -1,5 +1,5 @@
 # Simple Zebra configuration file
-# $Id: zebra.cfg,v 1.1 2002-10-30 14:35:09 adam Exp $
+# $Id: zebra.cfg,v 1.2 2003-03-04 23:30:20 adam Exp $
 #
 # Where the schema files, attribute files, etc are located.
 profilePath: ../../tab
@@ -10,4 +10,4 @@ attset: gils.att
 attset: explain.att
 
 recordtype: grs.sgml
-isam: c
+isam: b
index 4fb41d9..0dc5773 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: extract.c,v 1.139 2003-02-27 23:08:10 pop Exp $
+/* $Id: extract.c,v 1.140 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -973,33 +973,33 @@ int bufferExtractRecord (ZebraHandle zh,
         logf (LOG_WARN, "Invalid record group, no database name given");
        return 0;
     }
-
+    
     if (zebraExplain_curDatabase (zh->reg->zei, rGroup->databaseName))
     {
-      if (zebraExplain_newDatabase (zh->reg->zei, rGroup->databaseName, 0))
-       return 0;
+        if (zebraExplain_newDatabase (zh->reg->zei, rGroup->databaseName, 0))
+            return 0;
     }
-
+    
     if (*recordType) {
-      logf (LOG_DEBUG, "Record type explicitly specified: %s", recordType);
-      recType = recType_byName (zh->reg->recTypes, recordType, subType,
-                               &clientData);
+        logf (LOG_DEBUG, "Record type explicitly specified: %s", recordType);
+        recType = recType_byName (zh->reg->recTypes, recordType, subType,
+                                  &clientData);
     } else {
-      if (!(rGroup->recordType)) {
-        logf (LOG_WARN, "No such record type defined");
-        return 0;
-      }
-      logf (LOG_DEBUG, "Get record type from rgroup: %s",rGroup->recordType);
-      recType = recType_byName (zh->reg->recTypes, rGroup->recordType, subType,
-                               &clientData);
-      recordType = rGroup->recordType;
+        if (!(rGroup->recordType)) {
+            logf (LOG_WARN, "No such record type defined");
+            return 0;
+        }
+        logf (LOG_DEBUG, "Get record type from rgroup: %s",rGroup->recordType);
+        recType = recType_byName (zh->reg->recTypes, rGroup->recordType, subType,
+                                  &clientData);
+        recordType = rGroup->recordType;
     }
-
+    
     if (!recType) {
-      logf (LOG_WARN, "No such record type: %s", rGroup->recordType);
-      return 0;
+        logf (LOG_WARN, "No such record type: %s", rGroup->recordType);
+        return 0;
     }
-
+    
     extractCtrl.subType = subType;
     extractCtrl.init = extract_init;
     extractCtrl.tokenAdd = extract_token_add;
@@ -1045,25 +1045,24 @@ int bufferExtractRecord (ZebraHandle zh,
     /* match criteria */
     matchStr = NULL;
 
-    if (! *sysno) {
-      char *rinfo;
-      if (strlen(match_criteria) > 0) {
-       matchStr = (char *)match_criteria;
-      } else {
-       if (rGroup->recordId && *rGroup->recordId) {
-         matchStr = fileMatchStr (zh, &zh->reg->keys, rGroup, fname, 
-                                  rGroup->recordId);
-       }
-      }
-      if (matchStr) {
-       rinfo = dict_lookup (zh->reg->matchDict, matchStr);
-       if (rinfo)
-         memcpy (sysno, rinfo+1, sizeof(*sysno));
-      } else {
-       logf (LOG_WARN, "Bad match criteria (recordID)");
-       return 0;
-      }
-
+    if (! *sysno && match_criteria) {
+        char *rinfo;
+        if (*match_criteria) {
+            matchStr = (char *)match_criteria;
+        } else {
+            if (rGroup->recordId && *rGroup->recordId) {
+                matchStr = fileMatchStr (zh, &zh->reg->keys, rGroup, fname, 
+                                         rGroup->recordId);
+            }
+        }
+        if (matchStr) {
+            rinfo = dict_lookup (zh->reg->matchDict, matchStr);
+            if (rinfo)
+                memcpy (sysno, rinfo+1, sizeof(*sysno));
+        } else {
+            logf (LOG_WARN, "Bad match criteria (recordID)");
+            return 0;
+        }
     }
 
     if (! *sysno)
index 119d5ee..8b21f91 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: index.h,v 1.93 2003-02-27 17:12:11 adam Exp $
+/* $Id: index.h,v 1.94 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -296,6 +296,8 @@ struct zebra_session {
     ZebraLockHandle lock_shadow;
 
     int trans_no;
+    int trans_w_no;
+
     int destroyed;
     ZebraSet sets;
     Res res;
index 6881e54..8a23e03 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.101 2003-02-27 22:55:40 adam Exp $
+/* $Id: main.c,v 1.102 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -205,7 +205,7 @@ int main (int argc, char **argv)
                if (!trans_started)
                {
                    trans_started=1;
-                    zebra_begin_trans (zh);
+                    zebra_begin_trans (zh, 1);
                }
 
                 switch (cmd)
index e3b7f8e..0ff0880 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zebraapi.c,v 1.87 2003-03-04 23:05:30 pop Exp $
+/* $Id: zebraapi.c,v 1.88 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -33,6 +33,8 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #endif
 
 #include <yaz/diagbib1.h>
+#include <yaz/pquery.h>
+#include <yaz/sortspec.h>
 #include "index.h"
 #include <charmap.h>
 #include "zebraapi.h"
@@ -104,6 +106,7 @@ ZebraHandle zebra_open (ZebraService zs)
     zh->basenames = 0;
 
     zh->trans_no = 0;
+    zh->trans_w_no = 0;
 
     zh->lock_normal = 0;
     zh->lock_shadow = 0;
@@ -931,7 +934,7 @@ void zebra_admin_import_begin (ZebraHandle zh, const char *database,
     zh->errCode=0;
     if (zebra_select_database(zh, database))
         return;
-    zebra_begin_trans (zh);
+    zebra_begin_trans (zh, 1);
     xfree (zh->admin_databaseName);
     zh->admin_databaseName = xstrdup(database);
 }
@@ -1033,7 +1036,7 @@ void zebra_admin_create (ZebraHandle zh, const char *database)
 
     if (zebra_select_database (zh, database))
         return;
-    zebra_begin_trans (zh);
+    zebra_begin_trans (zh, 1);
 
     zs = zh->service;
     /* announce database */
@@ -1111,181 +1114,168 @@ void zebra_get_state (ZebraHandle zh, char *val, int *seqno)
 
 int zebra_begin_read (ZebraHandle zh)
 {
-    int dirty = 0;
-    char val;
-    int seqno;
-    ASSERTZH;
-
-    assert (zh->res);
-
-    (zh->trans_no)++;
-
-    if (zh->trans_no != 1)
-    {
-        zebra_flush_reg (zh);
-        return 0;
-    }
-    zh->errCode=0;
-#if HAVE_SYS_TIMES_H
-    times (&zh->tms1);
-#endif
-    if (!zh->res)
-    {
-        (zh->trans_no)--;
-        zh->errCode = 109;
-        return -1;
-    }
-    if (!zh->lock_normal || !zh->lock_shadow)
-    {
-        (zh->trans_no)--;
-        zh->errCode = 2;
-       return -1;
-    }
-    zebra_get_state (zh, &val, &seqno);
-    if (val == 'd')
-        val = 'o';
-
-    if (!zh->reg)
-        dirty = 1;
-    else if (seqno != zh->reg->seqno)
-    {
-        yaz_log (LOG_LOG, "reopen seqno cur/old %d/%d",
-                 seqno, zh->reg->seqno);
-        dirty = 1;
-    }
-    else if (zh->reg->last_val != val)
-    {
-        yaz_log (LOG_LOG, "reopen last cur/old %d/%d",
-                 val, zh->reg->last_val);
-        dirty = 1;
-    }
-    if (!dirty)
-        return 0;
-
-    if (val == 'c')
-        zebra_lock_r (zh->lock_shadow);
-    else
-        zebra_lock_r (zh->lock_normal);
-    
-    if (zh->reg)
-        zebra_register_close (zh->service, zh->reg);
-    zh->reg = zebra_register_open (zh->service, zh->reg_name,
-                                   0, val == 'c' ? 1 : 0,
-                                   zh->res, zh->path_reg);
-    if (!zh->reg)
-    {
-        zh->errCode = 109;
-        return -1;
-    }
-    zh->reg->last_val = val;
-    zh->reg->seqno = seqno;
-
-    return 0;
+    return zebra_begin_trans(zh, 0);
 }
 
 void zebra_end_read (ZebraHandle zh)
 {
-    ASSERTZH;
-    (zh->trans_no)--;
-
-    if (zh->trans_no != 0)
-        return;
-#if HAVE_SYS_TIMES_H
-    times (&zh->tms2);
-    logf (LOG_LOG, "user/system: %ld/%ld",
-                    (long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
-                    (long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
-
-#endif
-
-    zebra_unlock (zh->lock_normal);
-    zebra_unlock (zh->lock_shadow);
+    zebra_end_trans(zh);
 }
 
-void zebra_begin_trans (ZebraHandle zh)
+int zebra_begin_trans (ZebraHandle zh, int rw)
 {
-    int pass;
-    int seqno = 0;
-    char val = '?';
-    const char *rval = 0;
     ASSERTZHRES;
-
     assert (zh->res);
-
-    (zh->trans_no++);
-    if (zh->trans_no != 1)
+    if (rw)
     {
-        return;
-    }
-    zh->errCode=0;
-    
-    yaz_log (LOG_LOG, "zebra_begin_trans");
-
-    zh->records_inserted = 0;
-    zh->records_updated = 0;
-    zh->records_deleted = 0;
-    zh->records_processed = 0;
-
+        int pass;
+        int seqno = 0;
+        char val = '?';
+        const char *rval = 0;
+        
+        (zh->trans_no++);
+        if (zh->trans_w_no)
+            return 0;
+        zh->trans_w_no = zh->trans_no;
+        
+        zh->errCode=0;
+        
+        yaz_log (LOG_LOG, "zebra_begin_trans");
+        
+        zh->records_inserted = 0;
+        zh->records_updated = 0;
+        zh->records_deleted = 0;
+        zh->records_processed = 0;
+        
 #if HAVE_SYS_TIMES_H
-    times (&zh->tms1);
+        times (&zh->tms1);
 #endif
-    
-    /* lock */
-    if (zh->shadow_enable)
-        rval = res_get (zh->res, "shadow");
-
-    for (pass = 0; pass < 2; pass++)
-    {
-        if (rval)
-        {
-            zebra_lock_r (zh->lock_normal);
-            zebra_lock_w (zh->lock_shadow);
-        }
-        else
-        {
-            zebra_lock_w (zh->lock_normal);
-            zebra_lock_w (zh->lock_shadow);
-        }
+        /* lock */
+        if (zh->shadow_enable)
+            rval = res_get (zh->res, "shadow");
         
-        zebra_get_state (zh, &val, &seqno);
-        if (val == 'c')
-        {
-            yaz_log (LOG_LOG, "previous transaction didn't finish commit");
-            zebra_unlock (zh->lock_shadow);
-            zebra_unlock (zh->lock_normal);
-            zebra_commit (zh);
-            continue;
-        }
-        else if (val == 'd')
+        for (pass = 0; pass < 2; pass++)
         {
             if (rval)
             {
-                BFiles bfs = bfs_create (res_get (zh->res, "shadow"),
-                                         zh->path_reg);
-                yaz_log (LOG_LOG, "previous transaction didn't reach commit");
-                bf_commitClean (bfs, rval);
-                bfs_destroy (bfs);
+                zebra_lock_r (zh->lock_normal);
+                zebra_lock_w (zh->lock_shadow);
             }
             else
             {
-                yaz_log (LOG_WARN, "your previous transaction didn't finish");
+                zebra_lock_w (zh->lock_normal);
+                zebra_lock_w (zh->lock_shadow);
+            }
+            
+            zebra_get_state (zh, &val, &seqno);
+            if (val == 'c')
+            {
+                yaz_log (LOG_LOG, "previous transaction didn't finish commit");
+                zebra_unlock (zh->lock_shadow);
+                zebra_unlock (zh->lock_normal);
+                zebra_commit (zh);
+                continue;
+            }
+            else if (val == 'd')
+            {
+                if (rval)
+                {
+                    BFiles bfs = bfs_create (res_get (zh->res, "shadow"),
+                                             zh->path_reg);
+                    yaz_log (LOG_LOG, "previous transaction didn't reach commit");
+                    bf_commitClean (bfs, rval);
+                    bfs_destroy (bfs);
+            }
+                else
+                {
+                    yaz_log (LOG_WARN, "your previous transaction didn't finish");
+                }
             }
+            break;
         }
-        break;
+        if (pass == 2)
+        {
+            yaz_log (LOG_FATAL, "zebra_begin_trans couldn't finish commit");
+            abort();
+            return -1;
+        }
+        zebra_set_state (zh, 'd', seqno);
+        
+        zh->reg = zebra_register_open (zh->service, zh->reg_name,
+                                       1, rval ? 1 : 0, zh->res,
+                                       zh->path_reg);
+        
+        zh->reg->seqno = seqno;
     }
-    if (pass == 2)
+    else
     {
-        yaz_log (LOG_FATAL, "zebra_begin_trans couldn't finish commit");
-        abort();
-        return;
+        int dirty = 0;
+        char val;
+        int seqno;
+        
+        (zh->trans_no)++;
+        
+        if (zh->trans_no != 1)
+        {
+            zebra_flush_reg (zh);
+            return 0;
+        }
+        zh->errCode=0;
+#if HAVE_SYS_TIMES_H
+        times (&zh->tms1);
+#endif
+        if (!zh->res)
+        {
+            (zh->trans_no)--;
+            zh->errCode = 109;
+            return -1;
+        }
+        if (!zh->lock_normal || !zh->lock_shadow)
+        {
+            (zh->trans_no)--;
+            zh->errCode = 2;
+            return -1;
+        }
+        zebra_get_state (zh, &val, &seqno);
+        if (val == 'd')
+            val = 'o';
+        
+        if (!zh->reg)
+            dirty = 1;
+        else if (seqno != zh->reg->seqno)
+        {
+            yaz_log (LOG_LOG, "reopen seqno cur/old %d/%d",
+                     seqno, zh->reg->seqno);
+            dirty = 1;
+        }
+        else if (zh->reg->last_val != val)
+        {
+            yaz_log (LOG_LOG, "reopen last cur/old %d/%d",
+                     val, zh->reg->last_val);
+            dirty = 1;
+        }
+        if (!dirty)
+            return 0;
+        
+        if (val == 'c')
+            zebra_lock_r (zh->lock_shadow);
+        else
+            zebra_lock_r (zh->lock_normal);
+        
+        if (zh->reg)
+            zebra_register_close (zh->service, zh->reg);
+        zh->reg = zebra_register_open (zh->service, zh->reg_name,
+                                       0, val == 'c' ? 1 : 0,
+                                       zh->res, zh->path_reg);
+        if (!zh->reg)
+        {
+            zh->errCode = 109;
+            return -1;
+        }
+        zh->reg->last_val = val;
+        zh->reg->seqno = seqno;
     }
-    zebra_set_state (zh, 'd', seqno);
-
-    zh->reg = zebra_register_open (zh->service, zh->reg_name,
-                                   1, rval ? 1 : 0, zh->res,
-                                   zh->path_reg);
-
-    zh->reg->seqno = seqno;
+    return 0;
 }
 
 void zebra_end_trans (ZebraHandle zh) {
@@ -1308,54 +1298,66 @@ void zebra_end_transaction (ZebraHandle zh, ZebraTransactionStatus *status)
     status->utime     = 0;
     status->stime     = 0;
 
-    zh->trans_no--;
-    if (zh->trans_no != 0)
-        return;
-    yaz_log (LOG_LOG, "zebra_end_trans");
-    rval = res_get (zh->res, "shadow");
-
-    zebraExplain_runNumberIncrement (zh->reg->zei, 1);
-
-    zebra_flush_reg (zh);
-
-    zebra_register_close (zh->service, zh->reg);
-    zh->reg = 0;
-
-    yaz_log (LOG_LOG, "Records: %7d i/u/d %d/%d/%d", 
-             zh->records_processed, zh->records_inserted,
-             zh->records_updated, zh->records_deleted);
-
-    status->processed = zh->records_processed;
-    status->inserted = zh->records_inserted;
-    status->updated = zh->records_updated;
-    status->deleted = zh->records_deleted;
-
-    zebra_get_state (zh, &val, &seqno);
-    if (val != 'd')
+    if (zh->trans_no != zh->trans_w_no)
     {
-        BFiles bfs = bfs_create (rval, zh->path_reg);
-        yaz_log (LOG_LOG, "deleting shadow stuff val=%c", val);
-        bf_commitClean (bfs, rval);
-        bfs_destroy (bfs);
-    }
-    if (!rval)
-        seqno++;
-    zebra_set_state (zh, 'o', seqno);
+        zh->trans_no--;
+        if (zh->trans_no != 0)
+            return;
 
-    zebra_unlock (zh->lock_shadow);
-    zebra_unlock (zh->lock_normal);
+        /* release read lock */
 
+        zebra_unlock (zh->lock_normal);
+        zebra_unlock (zh->lock_shadow);
+    }
+    else
+    {   /* release write lock */
+        zh->trans_no--;
+        zh->trans_w_no = 0;
+        
+        yaz_log (LOG_LOG, "zebra_end_trans");
+        rval = res_get (zh->res, "shadow");
+        
+        zebraExplain_runNumberIncrement (zh->reg->zei, 1);
+        
+        zebra_flush_reg (zh);
+        
+        zebra_register_close (zh->service, zh->reg);
+        zh->reg = 0;
+        
+        yaz_log (LOG_LOG, "Records: %7d i/u/d %d/%d/%d", 
+                 zh->records_processed, zh->records_inserted,
+                 zh->records_updated, zh->records_deleted);
+        
+        status->processed = zh->records_processed;
+        status->inserted = zh->records_inserted;
+        status->updated = zh->records_updated;
+        status->deleted = zh->records_deleted;
+        
+        zebra_get_state (zh, &val, &seqno);
+        if (val != 'd')
+        {
+            BFiles bfs = bfs_create (rval, zh->path_reg);
+            yaz_log (LOG_LOG, "deleting shadow stuff val=%c", val);
+            bf_commitClean (bfs, rval);
+            bfs_destroy (bfs);
+        }
+        if (!rval)
+            seqno++;
+        zebra_set_state (zh, 'o', seqno);
+        
+        zebra_unlock (zh->lock_shadow);
+        zebra_unlock (zh->lock_normal);
+        
+    }
 #if HAVE_SYS_TIMES_H
     times (&zh->tms2);
     logf (LOG_LOG, "user/system: %ld/%ld",
-                    (long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
-                    (long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
-
+          (long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
+          (long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
+    
     status->utime = (long) (zh->tms2.tms_utime - zh->tms1.tms_utime);
     status->stime = (long) (zh->tms2.tms_stime - zh->tms1.tms_stime);
 #endif
-
-    return;
 }
 
 void zebra_repository_update (ZebraHandle zh)
@@ -1484,7 +1486,7 @@ int zebra_record_insert (ZebraHandle zh, const char *buf, int len)
     int olderr;
     ASSERTZH;
     zh->errCode=0;
-    zebra_begin_trans (zh);
+    zebra_begin_trans (zh, 1);
     if (zh->errCode)
       return 0; /* bad sysno */
     extract_rec_in_mem (zh, "grs.sgml",
@@ -1779,7 +1781,7 @@ int zebra_update_record (ZebraHandle zh,
 
     if (buf_size < 1) buf_size = strlen(buf);
 
-    zebra_begin_trans(zh);
+    zebra_begin_trans(zh, 1);
     res=bufferExtractRecord (zh, buf, buf_size, rGroup, 
                             0, // delete_flag 
                             0, // test_mode,
@@ -1800,7 +1802,7 @@ int zebra_delete_record (ZebraHandle zh,
 
     if (buf_size < 1) buf_size = strlen(buf);
 
-    zebra_begin_trans(zh);
+    zebra_begin_trans(zh, 1);
     res=bufferExtractRecord (zh, buf, buf_size, rGroup, 
                             1, // delete_flag
                             0, // test_mode, 
@@ -1838,23 +1840,23 @@ int zebra_search_PQF (ZebraHandle zh,
                      ODR odr_input, ODR odr_output, 
                      const char *pqf_query,
                      const char *setname)
-
+    
 {
-  int hits;
-  Z_RPNQuery *query;
-  query = p_query_rpn (odr_input, PROTO_Z3950, pqf_query);
-
-  if (!query) {
-    logf (LOG_WARN, "bad query %s\n", pqf_query);
+    int hits;
+    Z_RPNQuery *query;
+    query = p_query_rpn (odr_input, PROTO_Z3950, pqf_query);
+    
+    if (!query) {
+        logf (LOG_WARN, "bad query %s\n", pqf_query);
+        odr_reset (odr_input);
+        return(0);
+    }
+    zebra_search_RPN (zh, odr_input, odr_output, query, setname, &hits);
+    
     odr_reset (odr_input);
-    return(0);
-  }
-  zebra_search_RPN (zh, odr_input, odr_output, query, setname, &hits);
-
-  odr_reset (odr_input);
-  odr_reset (odr_output);
-  
-  return(hits);
+    odr_reset (odr_output);
+    
+    return(hits);
 }
 
 /* ---------------------------------------------------------------------------
@@ -1865,27 +1867,27 @@ int sort (ZebraHandle zh,
          const char *sort_spec,
          const char *output_setname,
          const char **input_setnames
-         ) 
+    ) 
 {
-  int num_input_setnames = 0;
-  int sort_status = 0;
-  Z_SortKeySpecList *sort_sequence = yaz_sort_spec (stream, sort_spec);
-  if (!sort_sequence) {
-    logf(LOG_WARN,"invalid sort specs '%s'", sort_spec);
-    zh->errCode = 207;
+    int num_input_setnames = 0;
+    int sort_status = 0;
+    Z_SortKeySpecList *sort_sequence = yaz_sort_spec (stream, sort_spec);
+    if (!sort_sequence) {
+        logf(LOG_WARN,"invalid sort specs '%s'", sort_spec);
+        zh->errCode = 207;
     return (-1);
-  }
-  
-  /* we can do this, since the perl typemap code for char** will 
-     put a NULL at the end of list */
-  while (input_setnames[num_input_setnames]) num_input_setnames++;
+    }
+    
+    /* we can do this, since the perl typemap code for char** will 
+       put a NULL at the end of list */
+    while (input_setnames[num_input_setnames]) num_input_setnames++;
 
-  if (zebra_begin_read (zh))
-    return;
-  
-  resultSetSort (zh, stream->mem, num_input_setnames, input_setnames,
-                output_setname, sort_sequence, &sort_status);
-  
-  zebra_end_read(zh);
-  return (sort_status);
+    if (zebra_begin_read (zh))
+        return -1;
+    
+    resultSetSort (zh, stream->mem, num_input_setnames, input_setnames,
+                   output_setname, sort_sequence, &sort_status);
+    
+    zebra_end_read(zh);
+    return (sort_status);
 }
index ca18834..d83695e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zebraapi.h,v 1.27 2003-02-28 20:12:18 pop Exp $
+/* $Id: zebraapi.h,v 1.28 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -197,7 +197,7 @@ int zebra_admin_exchange_record (ZebraHandle zh,
                                  const char *recid_buf, size_t recid_len,
                                  int action);
 
-void zebra_begin_trans (ZebraHandle zh);
+int zebra_begin_trans (ZebraHandle zh, int rw);
 void zebra_end_trans (ZebraHandle zh);
 void zebra_end_transaction (ZebraHandle zh, ZebraTransactionStatus *stat);
 
index ecb2569..24b7648 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zserver.c,v 1.103 2003-02-25 21:51:05 adam Exp $
+/* $Id: zserver.c,v 1.104 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -519,7 +519,7 @@ int bend_esrequest (void *handle, bend_esrequest_rr *rr)
            if (notToKeep)
            {
                int i;
-                zebra_begin_trans (zh);
+                zebra_begin_trans (zh, 1);
                for (i = 0; i < notToKeep->num; i++)
                {
                    Z_External *rec = notToKeep->elements[i]->record;
index e9c3efb..2db3bd3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t2.c,v 1.3 2002-08-02 19:26:57 adam Exp $
+/* $Id: t2.c,v 1.4 2003-03-04 23:30:20 adam Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -41,8 +41,8 @@ int main(int argc, char **argv)
     
     zs = zebra_start("t2.cfg");
     zh = zebra_open (zs);
-    
-    zebra_begin_trans (zh);
+    zebra_select_database(zh, "Default");
+    zebra_begin_trans (zh, 1);
     zebra_record_insert (zh, myrec, strlen(myrec));
     zebra_end_trans (zh);
     zebra_commit (zh);