]> arthur.barton.de Git - netatalk.git/blobdiff - etc/cnid_dbd/dbif.c
It works
[netatalk.git] / etc / cnid_dbd / dbif.c
index c40c8e8c29a007356684b86baf06e6b3a02dee81..8ddebc1fe18f66f5de6772c9e030812099dc0564 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: dbif.c,v 1.20 2010-01-19 14:57:11 franklahm Exp $
- *
  * Copyright (C) Joerg Lenneis 2003
  * Copyright (C) Frank Lahm 2009
  * All Rights Reserved.  See COPYING.
@@ -240,14 +238,19 @@ DBD *dbif_init(const char *envhome, const char *filename)
     dbd->db_table[DBIF_CNID].name        = "cnid2.db";
     dbd->db_table[DBIF_IDX_DEVINO].name  = "devino.db";
     dbd->db_table[DBIF_IDX_DIDNAME].name = "didname.db";
+    dbd->db_table[DBIF_IDX_NAME].name    = "name.db";
 
     dbd->db_table[DBIF_CNID].type        = DB_BTREE;
     dbd->db_table[DBIF_IDX_DEVINO].type  = DB_BTREE;
     dbd->db_table[DBIF_IDX_DIDNAME].type = DB_BTREE;
+    dbd->db_table[DBIF_IDX_NAME].type    = DB_BTREE;
 
     dbd->db_table[DBIF_CNID].openflags        = DB_CREATE;
     dbd->db_table[DBIF_IDX_DEVINO].openflags  = DB_CREATE;
     dbd->db_table[DBIF_IDX_DIDNAME].openflags = DB_CREATE;
+    dbd->db_table[DBIF_IDX_NAME].openflags    = DB_CREATE;
+
+    dbd->db_table[DBIF_IDX_NAME].flags = DB_DUPSORT;
 
     return dbd;
 }
@@ -497,6 +500,20 @@ int dbif_open(DBD *dbd, struct db_param *dbp, int reindex)
     }
     if (reindex)
         LOG(log_info, logtype_cnid, "... done.");
+
+    if (reindex)
+        LOG(log_info, logtype_cnid, "Reindexing name index...");
+    if ((ret = dbd->db_table[0].db->associate(dbd->db_table[0].db, 
+                                              dbd->db_txn,
+                                              dbd->db_table[DBIF_IDX_NAME].db, 
+                                              idxname,
+                                              DB_CREATE))
+        != 0) {
+        LOG(log_error, logtype_cnid, "Failed to associate name index: %s",db_strerror(ret));
+        return -1;
+    }
+    if (reindex)
+        LOG(log_info, logtype_cnid, "... done.");
     
     return 0;
 }
@@ -727,6 +744,59 @@ int dbif_del(DBD *dbd, const int dbi, DBT *key, u_int32_t flags)
         return 1;
 }
 
+/*!
+ * Search the database by name
+ *
+ * @param resbuf    (w) buffer for search results CNIDs, maxsize is assumed to be
+ *                      DBD_MAX_SRCH_RSLTS * sizefof(cnid_t)
+ *
+ * @returns -1 on error, 0 when nothing found, else the number of matches
+ */
+int dbif_search(DBD *dbd, DBT *key, char *resbuf)
+{
+    int ret = 0;
+    int count = 0;
+    DBC *cursorp = NULL;
+    DBT pkey, data;
+    char *cnids = resbuf;
+    cnid_t cnid;
+    char *namebkp = key->data;
+    int namelenbkp = key->size;
+
+    memset(&pkey, 0, sizeof(DBT));
+    memset(&data, 0, sizeof(DBT));
+
+    /* Get a cursor */
+    ret = dbd->db_table[DBIF_IDX_NAME].db->cursor(dbd->db_table[DBIF_IDX_NAME].db,
+                                                  NULL,
+                                                  &cursorp,
+                                                  0);
+    if (ret != 0) {
+        LOG(log_error, logtype_cnid, "Couldn't create cursor: %s", db_strerror(ret));
+        ret = -1;
+        goto exit;
+    }
+
+    ret = cursorp->pget(cursorp, key, &pkey, &data, DB_SET_RANGE);
+    while (count < DBD_MAX_SRCH_RSLTS && ret != DB_NOTFOUND) {
+        if (namelenbkp <= key->size && strncmp(namebkp, key->data, namelenbkp) == 0) {
+            count++;
+            memcpy(cnids, pkey.data, sizeof(cnid_t));
+            memcpy(&cnid, pkey.data, sizeof(cnid_t));
+            cnids += sizeof(cnid_t);
+            LOG(log_error, logtype_cnid, "match: CNID %" PRIu32, ntohl(cnid));
+        }
+        ret = cursorp->pget(cursorp, key, &pkey, &data, DB_NEXT_DUP);
+    }
+
+    ret = count;
+
+exit:
+    if (cursorp != NULL)
+        cursorp->close(cursorp);
+    return ret;
+}
+
 int dbif_txn_begin(DBD *dbd)
 {
     int ret;
@@ -1049,9 +1119,11 @@ int dbif_idwalk(DBD *dbd, cnid_t *cnid, int close)
     static DBT key = { 0 }, data = { 0 };
     DB *db = dbd->db_table[DBIF_CNID].db;
 
-    if (close && dbd->db_cur) {
-        dbd->db_cur->close(dbd->db_cur);
-        dbd->db_cur = NULL;
+    if (close) {
+        if (dbd->db_cur) {
+            dbd->db_cur->close(dbd->db_cur);
+            dbd->db_cur = NULL;
+        }
         return 0;
     }