Fix memory leak
[idzebra-moved-to-github.git] / index / zinfo.c
index a29f76a..67060ef 100644 (file)
@@ -1,10 +1,24 @@
-/*
- * Copyright (C) 1994-2002, Index Data
- * All rights reserved.
- * Sebastian Hammer, Adam Dickmeiss
- *
- * $Id: zinfo.c,v 1.30 2002-05-13 14:13:43 adam Exp $
- */
+/* $Id: zinfo.c,v 1.37 2003-06-30 19:37:12 adam Exp $
+   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003
+   Index Data Aps
+
+This file is part of the Zebra server.
+
+Zebra is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Zebra; see the file LICENSE.zebra.  If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+*/
 
 #include <stdlib.h>
 #include <assert.h>
@@ -257,6 +271,52 @@ void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
     }
 }
 
+/* Explain structure
+    root record
+      of type targetInfo
+      and has sysno = 1
+
+    databaseList (list of databases)
+*/
+/*
+Example root:
+explain:
+  targetInfo: TargetInfo
+    name: Zebra
+    namedResultSets: 1
+    multipleDbSearch: 1
+    nicknames:
+      name: Zebra
+    commonInfo:
+      dateAdded: 20030630190601
+      dateChanged: 20030630190601
+      languageCode: EN
+    accessinfo:
+      unitSystems:
+        string: ISO
+      attributeSetIds:
+        oid: 1.2.840.10003.3.2
+        oid: 1.2.840.10003.3.5
+        oid: 1.2.840.10003.3.1
+      schemas:
+        oid: 1.2.840.10003.13.1000.81.2
+        oid: 1.2.840.10003.13.2
+    zebraInfo:
+      version: 1.3.12
+      databaseList:
+        database:
+          name: Default
+          id: 50
+          attributeDetailsId: 51
+        database:
+          name: IR-Explain-1
+          id: 52
+          attributeDetailsId: 53
+      ordinalSU: 38
+      runNumber: 1
+nextResultSetPosition = 2
+*/
+
 ZebraExplainInfo zebraExplain_open (
     Records records, data1_handle dh,
     Res res,
@@ -291,12 +351,17 @@ ZebraExplainInfo zebraExplain_open (
     zei->categoryList->dirty = 0;
     zei->categoryList->data1_categoryList = NULL;
 
-    time (&our_time);
-    tm = localtime (&our_time);
-    sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
-            tm->tm_year+1900, tm->tm_mon+1,  tm->tm_mday,
-            tm->tm_hour, tm->tm_min, tm->tm_sec);
-
+    if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
+    {
+        time (&our_time);
+        tm = localtime (&our_time);
+        sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
+                tm->tm_year+1900, tm->tm_mon+1,  tm->tm_mday,
+                tm->tm_hour, tm->tm_min, tm->tm_sec);
+    } else {
+        sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
+                0, 0, 0,  0, 0, 0);
+    }
     zdip = &zei->databaseInfo;
     trec = rec_get (records, 1);      /* get "root" record */
 
@@ -322,8 +387,8 @@ ZebraExplainInfo zebraExplain_open (
 #if ZINFO_DEBUG
        data1_pr_tree (zei->dh, zei->data1_target, stderr);
 #endif
-       node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
-                                        "targetInfo");
+       node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
+                                        "/targetInfo");
        zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
                                      &zei->accessInfo);
 
@@ -397,7 +462,7 @@ ZebraExplainInfo zebraExplain_open (
            np = np->child;
            assert (np && np->which == DATA1N_data);
            zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
-            yaz_log (LOG_LOG, "READ runnumber = %d", zei->runNumber);
+            yaz_log (LOG_DEBUG, "read runnumber = %d", zei->runNumber);
            *zdip = NULL;
        }
        rec_rm (&trec);
@@ -426,8 +491,8 @@ ZebraExplainInfo zebraExplain_open (
                nmem_destroy (zei->nmem);
                return 0;
            }
-           node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
-                                           "targetInfo");
+           node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
+                                             "/targetInfo");
            assert (node_tgtinfo);
 
            zebraExplain_initCommonInfo (zei, node_tgtinfo);
@@ -464,10 +529,8 @@ ZebraExplainInfo zebraExplain_open (
        
            if (zcl->data1_categoryList)
            {
-               assert (zcl->data1_categoryList->child);
-               node_cl = data1_search_tag (zei->dh,
-                                           zcl->data1_categoryList->child,
-                                           "categoryList");
+               node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
+                                           "/categoryList");
                assert (node_cl);
                zebraExplain_initCommonInfo (zei, node_cl);
            }
@@ -488,8 +551,8 @@ static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
 
     zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
 
-    node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
-                                   "attributeDetails");
+    node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
+                                   "/attributeDetails");
     node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
                                 "zebraInfo");
     node_list = data1_search_tag (zei->dh, node_zebra->child,
@@ -553,8 +616,9 @@ static void zebraExplain_readDatabase (ZebraExplainInfo zei,
 
     zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
     
-    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
-                                  "databaseInfo");
+    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
+                                    "/databaseInfo");
+    assert (node_dbinfo);
     zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
 
     node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
@@ -578,6 +642,45 @@ static void zebraExplain_readDatabase (ZebraExplainInfo zei,
     rec_rm (&rec);
 }
 
+int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
+{
+    struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
+
+    while (*zdip)
+    {
+       if (*zdip == zei->curDatabaseInfo)
+       {
+           struct zebDatabaseInfoB *zdi = *zdip;
+           Record rec;
+
+           zei->dirty = 1;
+           zei->updateHandle = update_handle;
+
+           if (zdi->attributeDetails)
+           {
+               /* remove attribute details keys and delete it */
+               zebAttributeDetails zad = zdi->attributeDetails;
+               
+               rec = rec_get(zei->records, zad->sysno);
+               (*zei->updateFunc)(zei->updateHandle, rec, 0);
+               rec_rm(&rec);
+           }
+           /* remove database record keys and delete it */
+           rec = rec_get (zei->records, zdi->sysno);
+           (*zei->updateFunc)(zei->updateHandle, rec, 0);
+           rec_rm(&rec);
+
+           /* remove from list */
+           *zdip = zdi->next;
+
+           /* current database is IR-Explain-1 */
+           return 0;
+       }
+       zdip = &(*zdip)->next;
+    }
+    return -1;
+}
+
 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
 {
     struct zebDatabaseInfoB *zdi;
@@ -590,11 +693,11 @@ int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
     
     assert (zei);
     if (zei->curDatabaseInfo &&
-        !strcmp (zei->curDatabaseInfo->databaseName, database))
+        !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
         return 0;
     for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
     {
-        if (!strcmp (zdi->databaseName, database_n))
+        if (!STRCASECMP (zdi->databaseName, database_n))
             break;
     }
     if (!zdi)
@@ -689,7 +792,7 @@ int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
     assert (zei);
     for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
     {
-        if (!strcmp (zdi->databaseName, database_n))
+        if (!STRCASECMP (zdi->databaseName, database_n))
             break;
     }
     if (zdi)
@@ -715,9 +818,9 @@ int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
                         "</></>\n");
     if (!zdi->data1_database)
        return -2;
-    
-    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
-                                  "databaseInfo");
+
+    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
+                                    "/databaseInfo");
     assert (node_dbinfo);
 
     zebraExplain_initCommonInfo (zei, node_dbinfo);
@@ -754,9 +857,8 @@ int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
                         "<explain><attributeDetails>AttributeDetails\n"
                         "</></>\n");
 
-    node_adinfo =
-       data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
-                         "attributeDetails");
+    node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
+                                    "/attributeDetails");
     assert (node_adinfo);
 
     zebraExplain_initCommonInfo (zei, node_adinfo);
@@ -818,9 +920,9 @@ static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
 #endif
 
     drec = createRecord (zei->records, &sysno);
-
-    node_ci = data1_search_tag (zei->dh, node_categoryList->child,
-                               "categoryList");
+    
+    node_ci = data1_search_tag (zei->dh, node_categoryList,
+                               "/categoryList");
     assert (node_ci);
     node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
                             node_ci);
@@ -873,8 +975,9 @@ static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
 
     drec = createRecord (zei->records, &zad->sysno);
     assert (zad->data1_tree);
-    node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
-                                  "attributeDetails");
+
+    node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
+                                  "/attributeDetails");
     zebraExplain_updateCommonInfo (zei, node_adinfo);
 
     data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
@@ -999,9 +1102,11 @@ static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
 #endif
     drec = createRecord (zei->records, &zdi->sysno);
     assert (zdi->data1_database);
-    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
-                                  "databaseInfo");
 
+    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
+                                    "/databaseInfo");
+
+    assert (node_dbinfo);
     zebraExplain_updateCommonInfo (zei, node_dbinfo);
     zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
 
@@ -1087,9 +1192,10 @@ static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
                         "<explain><attributeSetInfo>AttributeSetInfo\n"
                         "</></>\n" );
 
-    node_attinfo = data1_search_tag (zei->dh, node_root->child,
-                                  "attributeSetInfo");
+    node_attinfo = data1_search_tag (zei->dh, node_root,
+                                  "/attributeSetInfo");
 
+    assert (node_attinfo);
     zebraExplain_initCommonInfo (zei, node_attinfo);
     zebraExplain_updateCommonInfo (zei, node_attinfo);
 
@@ -1145,8 +1251,8 @@ static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
     trec = rec_get (zei->records, 1);
     xfree (trec->info[recInfo_storeData]);
 
-    node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
-                                  "targetInfo");
+    node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
+                                     "/targetInfo");
     assert (node_tgtinfo);
 
     zebraExplain_updateCommonInfo (zei, node_tgtinfo);
@@ -1204,6 +1310,19 @@ int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
     return -1;
 }
 
+int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
+                         int (*f)(void *handle, int ord))
+{
+    struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
+    if (zdb)
+    {
+       struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
+       for ( ;zsui; zsui = zsui->next)
+           (*f)(handle,  zsui->info.ordinal);
+    }
+    return 0;
+}
+                         
 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
                             const char **db, int *set, int *use)
 {
@@ -1316,7 +1435,6 @@ int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
     if (adjust_num)
     {
        zei->dirty = 1;
-        yaz_log (LOG_LOG, "zinfo run number=%d", zei->runNumber+adjust_num);
     }
     return zei->runNumber += adjust_num;
 }