Fix the way we delete the shadow files after a "succesful" commit
[idzebra-moved-to-github.git] / index / zebraapi.c
index d89c263..0c94394 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zebraapi.c,v 1.204 2006-03-23 09:15:25 adam Exp $
+/* $Id: zebraapi.c,v 1.211 2006-04-04 00:00:18 adam Exp $
    Copyright (C) 1995-2005
    Index Data ApS
 
@@ -84,7 +84,7 @@ static struct zebra_register *zebra_register_open(ZebraService zs,
                                                  int rw, int useshadow,
                                                  Res res,
                                                  const char *reg_path);
-static void zebra_register_close (ZebraService zs, struct zebra_register *reg);
+static void zebra_register_close(ZebraService zs, struct zebra_register *reg);
 
 ZebraHandle zebra_open(ZebraService zs, Res res)
 {
@@ -280,6 +280,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
     const char *recordCompression = 0;
     const char *profilePath;
     char cwd[1024];
+    ZEBRA_RES ret = ZEBRA_OK;
 
     ASSERTZS;
     
@@ -296,9 +297,10 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
     yaz_log (YLOG_DEBUG, "zebra_register_open rw=%d useshadow=%d p=%p n=%s rp=%s",
              rw, useshadow, reg, name, reg_path ? reg_path : "(none)");
     
-    reg->dh = data1_createx (DATA1_FLAG_XML);
+    reg->dh = data1_create();
     if (!reg->dh)
     {
+       xfree(reg->name);
        xfree(reg);
         return 0;
     }
@@ -306,6 +308,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
     if (!reg->bfs)
     {
         data1_destroy(reg->dh);
+       xfree(reg->name);
        xfree(reg);
         return 0;
     }
@@ -315,6 +318,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
        {
            bfs_destroy(reg->bfs);
            data1_destroy(reg->dh);
+           xfree(reg->name);
            xfree(reg);
            return 0;
        }
@@ -328,14 +332,17 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
     data1_set_tabroot (reg->dh, reg_path);
     reg->recTypes = recTypes_init (zs->record_classes, reg->dh);
 
-    if ((reg->zebra_maps = zebra_maps_open (res, reg_path)) == 0) {
-       /* ### Do we need to destroy reg->recTypes? */
+    reg->zebra_maps =
+       zebra_maps_open(res, reg_path, profilePath);
+    if (!reg->zebra_maps)
+    {
+       recTypes_destroy(reg->recTypes);
        bfs_destroy(reg->bfs);
        data1_destroy(reg->dh);
+       xfree(reg->name);
        xfree(reg);
        return 0;
     }
-
     reg->rank_classes = NULL;
 
     reg->key_buf = 0;
@@ -370,10 +377,20 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
     if (!strcmp (recordCompression, "bzip2"))
        record_compression = REC_COMPRESS_BZIP2;
 
+    if (1)
+    {
+       const char *index_fname = res_get_def(res, "index", "default.idx");
+       if (index_fname && *index_fname)
+       {
+           if (zebra_maps_read_file(reg->zebra_maps, index_fname) != ZEBRA_OK)
+               ret = ZEBRA_FAIL;
+       }
+    }
+
     if (!(reg->records = rec_open (reg->bfs, rw, record_compression)))
     {
        yaz_log (YLOG_WARN, "rec_open failed");
-       return 0;
+       ret = ZEBRA_FAIL;
     }
     if (rw)
     {
@@ -382,12 +399,12 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
     if (!(reg->dict = dict_open_res (reg->bfs, FNAME_DICT, 40, rw, 0, res)))
     {
        yaz_log (YLOG_WARN, "dict_open failed");
-       return 0;
+       ret = ZEBRA_FAIL;
     }
     if (!(reg->sortIdx = sortIdx_open (reg->bfs, rw)))
     {
        yaz_log (YLOG_WARN, "sortIdx_open failed");
-       return 0;
+       ret = ZEBRA_FAIL;
     }
     if (res_get_match (res, "isam", "s", ISAM_DEFAULT))
     {
@@ -396,7 +413,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
                                      key_isams_m(res, &isams_m))))
        {
            yaz_log (YLOG_WARN, "isams_open failed");
-           return 0;
+           ret = ZEBRA_FAIL;
        }
     }
     if (res_get_match (res, "isam", "c", ISAM_DEFAULT))
@@ -406,7 +423,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
                                    rw, key_isamc_m(res, &isamc_m))))
        {
            yaz_log (YLOG_WARN, "isamc_open failed");
-           return 0;
+           ret = ZEBRA_FAIL;
        }
     }
     if (res_get_match (res, "isam", "b", ISAM_DEFAULT))
@@ -417,7 +434,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
                                        rw, key_isamc_m(res, &isamc_m), 0)))
        {
            yaz_log (YLOG_WARN, "isamb_open failed");
-           return 0;
+           ret = ZEBRA_FAIL;
        }
     }
     if (res_get_match (res, "isam", "bc", ISAM_DEFAULT))
@@ -428,7 +445,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
                                        rw, key_isamc_m(res, &isamc_m), 1)))
        {
            yaz_log (YLOG_WARN, "isamb_open failed");
-           return 0;
+           ret = ZEBRA_FAIL;
        }
     }
     if (res_get_match (res, "isam", "null", ISAM_DEFAULT))
@@ -439,19 +456,26 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
                                        rw, key_isamc_m(res, &isamc_m), -1)))
        {
            yaz_log (YLOG_WARN, "isamb_open failed");
-           return 0;
+           ret = ZEBRA_FAIL;
        }
     }
-    reg->zei = zebraExplain_open (reg->records, reg->dh,
-                                  res, rw, reg,
-                                  explain_extract);
-    if (!reg->zei)
+    if (ret == ZEBRA_OK)
     {
-       yaz_log (YLOG_WARN, "Cannot obtain EXPLAIN information");
+       reg->zei = zebraExplain_open(reg->records, reg->dh,
+                                    res, rw, reg,
+                                    explain_extract);
+       if (!reg->zei)
+       {
+           yaz_log (YLOG_WARN, "Cannot obtain EXPLAIN information");
+           ret = ZEBRA_FAIL;
+       }
+    }
+    
+    if (ret != ZEBRA_OK)
+    {
+       zebra_register_close(zs, reg);
        return 0;
     }
-
-    reg->active = 2;
     yaz_log (YLOG_DEBUG, "zebra_register_open ok p=%p", reg);
     return reg;
 }
@@ -478,28 +502,26 @@ ZEBRA_RES zebra_admin_start (ZebraHandle zh)
     return ZEBRA_OK;
 }
 
-static void zebra_register_close (ZebraService zs, struct zebra_register *reg)
+static void zebra_register_close(ZebraService zs, struct zebra_register *reg)
 {
     ASSERTZS;
     assert(reg);
     yaz_log(YLOG_DEBUG, "zebra_register_close p=%p", reg);
     reg->stop_flag = 0;
     zebra_chdir (zs);
-    if (reg->records)
-    {
-        zebraExplain_close (reg->zei);
-        dict_close (reg->dict);
-        if (reg->matchDict)
-            dict_close (reg->matchDict);
-       sortIdx_close (reg->sortIdx);
-       if (reg->isams)
-           isams_close (reg->isams);
-        if (reg->isamc)
-            isamc_close (reg->isamc);
-        if (reg->isamb)
-            isamb_close (reg->isamb);
-        rec_close (&reg->records);
-    }
+    
+    zebraExplain_close (reg->zei);
+    dict_close (reg->dict);
+    if (reg->matchDict)
+       dict_close (reg->matchDict);
+    sortIdx_close (reg->sortIdx);
+    if (reg->isams)
+       isams_close (reg->isams);
+    if (reg->isamc)
+       isamc_close (reg->isamc);
+    if (reg->isamb)
+       isamb_close (reg->isamb);
+    rec_close (&reg->records);
 
     recTypes_destroy (reg->recTypes);
     zebra_maps_close (reg->zebra_maps);
@@ -559,7 +581,7 @@ ZEBRA_RES zebra_close (ZebraHandle zh)
     resultSetDestroy (zh, -1, 0, 0);
 
     if (zh->reg)
-        zebra_register_close (zh->service, zh->reg);
+        zebra_register_close(zh->service, zh->reg);
     zebra_close_res (zh);
     res_close(zh->session_res);
 
@@ -661,7 +683,7 @@ static void zebra_select_register (ZebraHandle zh, const char *new_reg)
         if (zh->reg)
         {
             resultSetInvalidate (zh);
-            zebra_register_close (zh->service, zh->reg);
+            zebra_register_close(zh->service, zh->reg);
             zh->reg = 0;
         }
         zebra_close_res(zh);
@@ -732,8 +754,6 @@ static void zebra_select_register (ZebraHandle zh, const char *new_reg)
     {
        if (res_get_int(zh->res, "staticrank", &zh->m_staticrank) == ZEBRA_OK)
            yaz_log(YLOG_LOG, "static rank set and is %d", zh->m_staticrank);
-       else
-           yaz_log(YLOG_LOG, "static rank unset");
     }
 }
 
@@ -1341,7 +1361,8 @@ ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh,
     {
         if (action == 1)  /* fail if insert */
         {
-           zebra_end_trans(zh);
+           if (zebra_end_trans(zh) != ZEBRA_OK)
+               yaz_log(YLOG_WARN, "zebra_end_trans failed");
            zebra_setError(zh, YAZ_BIB1_ES_IMMEDIATE_EXECUTION_FAILED,
                           "Cannot insert record: already exist");
            return ZEBRA_FAIL;
@@ -1353,7 +1374,8 @@ ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh,
     {
         if (action == 2 || action == 3) /* fail if delete or update */
         {
-           zebra_end_trans(zh);
+           if (zebra_end_trans(zh) != ZEBRA_OK)
+               yaz_log(YLOG_WARN, "zebra_end_trans failed");
            zebra_setError(zh, YAZ_BIB1_ES_IMMEDIATE_EXECUTION_FAILED,
                           "Cannot delete/update record: does not exist");
             return ZEBRA_FAIL;
@@ -1384,7 +1406,11 @@ ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh,
     {
         dict_delete_ord(zh->reg->matchDict, db_ord, recid_z);
     }
-    zebra_end_trans(zh);
+    if (zebra_end_trans(zh) != ZEBRA_OK)
+    {
+       yaz_log(YLOG_WARN, "zebra_end_trans failed");
+       res = ZEBRA_FAIL;
+    }
     return res;
 }
 
@@ -1444,7 +1470,11 @@ ZEBRA_RES zebra_drop_database(ZebraHandle zh, const char *db)
                       "drop database only supported for isam:b");
        ret = ZEBRA_FAIL;
     }
-    zebra_end_trans (zh);
+    if (zebra_end_trans (zh) != ZEBRA_OK)
+    {
+       yaz_log(YLOG_WARN, "zebra_end_trans failed");
+       ret = ZEBRA_FAIL;
+    }
     return ret;
 }
 
@@ -1463,7 +1493,10 @@ ZEBRA_RES zebra_create_database (ZebraHandle zh, const char *db)
     if (zebraExplain_newDatabase (zh->reg->zei, db, 0 
                                   /* explainDatabase */))
     {
-        zebra_end_trans (zh);
+        if (zebra_end_trans (zh) != ZEBRA_OK)
+       {
+           yaz_log(YLOG_WARN, "zebra_end_trans failed");
+       }
        zebra_setError(zh, YAZ_BIB1_ES_IMMEDIATE_EXECUTION_FAILED, db);
        return ZEBRA_FAIL;
     }
@@ -1623,7 +1656,7 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw)
         if (zh->reg)
        {
             resultSetInvalidate (zh);
-            zebra_register_close (zh->service, zh->reg);
+            zebra_register_close(zh->service, zh->reg);
        }
         zh->trans_w_no = zh->trans_no;
 
@@ -1670,7 +1703,7 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw)
                     yaz_log (YLOG_WARN, "previous transaction didn't reach commit");
                     bf_commitClean (bfs, rval);
                     bfs_destroy (bfs);
-            }
+               }
                 else
                 {
                     yaz_log (YLOG_WARN, "your previous transaction didn't finish");
@@ -1765,7 +1798,7 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw)
         if (zh->reg)
        {
             resultSetInvalidate (zh);
-            zebra_register_close (zh->service, zh->reg);
+            zebra_register_close(zh->service, zh->reg);
        }
         zh->reg = zebra_register_open(zh->service, zh->reg_name,
                                       0, val == 'c' ? 1 : 0,
@@ -1841,7 +1874,7 @@ ZEBRA_RES zebra_end_transaction (ZebraHandle zh, ZebraTransactionStatus *status)
         
         resultSetInvalidate (zh);
 
-        zebra_register_close (zh->service, zh->reg);
+        zebra_register_close(zh->service, zh->reg);
         zh->reg = 0;
         
         yaz_log (YLOG_LOG, "Records: "ZINT_FORMAT" i/u/d "
@@ -1953,19 +1986,24 @@ static ZEBRA_RES zebra_commit_ex(ZebraHandle zh, int clean_only)
             sync ();
 #endif
         }
-        yaz_log (YLOG_DEBUG, "commit clean");
-        bf_commitClean (bfs, rval);
         seqno++;
         zebra_set_state (zh, 'o', seqno);
+
+       zebra_unlock (zh->lock_shadow);
+       zebra_unlock (zh->lock_normal);
+
+       zebra_lock_w(zh->lock_shadow);
+        bf_commitClean (bfs, rval);
+       zebra_unlock (zh->lock_normal);
     }
     else
     {
+       zebra_unlock(zh->lock_shadow);
+       zebra_unlock(zh->lock_normal);
         yaz_log (log_level, "nothing to commit");
     }
     bfs_destroy (bfs);
 
-    zebra_unlock (zh->lock_shadow);
-    zebra_unlock (zh->lock_normal);
     return ZEBRA_OK;
 }
 
@@ -2175,7 +2213,11 @@ ZEBRA_RES zebra_insert_record (ZebraHandle zh,
                                 match, fname,
                                 0, 
                                 0); /* allow_update */
-    zebra_end_trans(zh); 
+    if (zebra_end_trans(zh) != ZEBRA_OK)
+    {
+       yaz_log(YLOG_WARN, "zebra_end_trans failed");
+       res = ZEBRA_FAIL;
+    }
     return res; 
 }
 
@@ -2206,7 +2248,11 @@ ZEBRA_RES zebra_update_record (ZebraHandle zh,
                                 match, fname,
                                 force_update, 
                                 1); /* allow_update */
-    zebra_end_trans(zh); 
+    if (zebra_end_trans(zh) != ZEBRA_OK)
+    {
+       yaz_log(YLOG_WARN, "zebra_end_trans failed");
+       res = ZEBRA_FAIL;
+    }
     return res; 
 }
 
@@ -2235,7 +2281,11 @@ ZEBRA_RES zebra_delete_record (ZebraHandle zh,
                                 match,fname,
                                 force_update,
                                 1); /* allow_update */
-    zebra_end_trans(zh);
+    if (zebra_end_trans(zh) != ZEBRA_OK)
+    {
+       yaz_log(YLOG_WARN, "zebra_end_trans failed");
+       res = ZEBRA_FAIL;
+    }
     return res;
 }