]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldbm/index.c
When recreating a database from an ldif file created by ldbmcat,
[openldap] / servers / slapd / back-ldbm / index.c
index 3a785fd2157a13b9dbea41de4b7d73bbee383c59..1a3a468fc20f606bf17ee4f04f688da72248cf8e 100644 (file)
 #include "slap.h"
 #include "back-ldbm.h"
 
-static int     add_value(Backend *be, struct dbcache *db, char *type, int indextype, char *val, ID id);
+static int     change_value(Backend *be,
+                         DBCache *db,
+                         char *type,
+                         int indextype,
+                         char *val,
+                         ID id,
+                         int
+                         (*idl_func)(Backend *, DBCache *, Datum, ID));
 static int     index2prefix(int indextype);
 
 int
@@ -20,7 +27,6 @@ index_add_entry(
 )
 {
        Attribute       *ap;
-       char            *dnval;
        struct berval   bv;
        struct berval   *bvals[2];
 
@@ -29,27 +35,32 @@ index_add_entry(
 
        /*
         * dn index entry - make it look like an attribute so it works
-        * with index_add_values() call
+        * with index_change_values() call
         */
 
-       bv.bv_val = ch_strdup( e->e_dn );
+       bv.bv_val = ch_strdup( e->e_ndn );
        bv.bv_len = strlen( bv.bv_val );
-       (void) dn_normalize_case( bv.bv_val );
        bvals[0] = &bv;
        bvals[1] = NULL;
 
        /* add the dn to the indexes */
-       index_add_values( be, "dn", bvals, e->e_id );
+       {
+               char *dn = ch_strdup("dn");
+               index_change_values( be, dn, bvals, e->e_id, __INDEX_ADD_OP );
+               free( dn );
+       }
 
        free( bv.bv_val );
 
        /* add each attribute to the indexes */
        for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
-               index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
+
+               index_change_values( be, ap->a_type, ap->a_vals, e->e_id,
+                                    __INDEX_ADD_OP );
        }
 
        Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
-           e->e_dn, 0 );
+           e->e_ndn, 0 );
        return( 0 );
 }
 
@@ -66,13 +77,25 @@ index_add_mods(
                LDAPMod *mod = &ml->ml_mod;
 
                switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
-               case LDAP_MOD_ADD:
                case LDAP_MOD_REPLACE:
-                       rc = index_add_values( be, mod->mod_type,
-                           mod->mod_bvalues, id );
+                       /* XXX: Delete old index data==>problem when this 
+                        * gets called we lost values already!
+                        */
+               case LDAP_MOD_ADD:
+                       rc = index_change_values( be,
+                                              mod->mod_type,
+                                              mod->mod_bvalues,
+                                              id,
+                                              __INDEX_ADD_OP);
                        break;
-
                case LDAP_MOD_DELETE:
+                       rc =  index_change_values( be,
+                                                  mod->mod_type,
+                                                  mod->mod_bvalues,
+                                                  id,
+                                                  __INDEX_DELETE_OP );
+                       break;
+               case LDAP_MOD_SOFTADD:  /* SOFTADD means index was there */
                        rc = 0;
                        break;
                }
@@ -93,7 +116,7 @@ index_read(
     char       *val
 )
 {
-       struct dbcache  *db;
+       DBCache *db;
        Datum           key;
        ID_BLOCK                *idl;
        int             indexmask, syntax;
@@ -101,6 +124,8 @@ index_read(
        char            *realval, *tmpval;
        char            buf[BUFSIZ];
 
+       char            *at_cn;
+
        ldbm_datum_init( key );
 
        prefix = index2prefix( indextype );
@@ -111,16 +136,18 @@ index_read(
        if ( ! (indextype & indexmask) ) {
                idl =  idl_allids( be );
                Debug( LDAP_DEBUG_TRACE,
-                   "<= index_read %lu candidates (allids - not indexed)\n",
+                   "<= index_read %ld candidates (allids - not indexed)\n",
                    idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
                return( idl );
        }
 
        attr_normalize( type );
-       if ( (db = ldbm_cache_open( be, type, LDBM_SUFFIX, LDBM_WRCREAT ))
+       at_cn = at_canonical_name( type );
+
+       if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
            == NULL ) {
                Debug( LDAP_DEBUG_ANY,
-                   "<= index_read NULL (could not open %s%s)\n", type,
+                   "<= index_read NULL (could not open %s%s)\n", at_cn,
                    LDBM_SUFFIX, 0 );
                return( NULL );
        }
@@ -145,30 +172,32 @@ index_read(
        key.dsize = strlen( realval ) + 1;
 
        idl = idl_fetch( be, db, key );
-      if ( tmpval != NULL ) {
+       if ( tmpval != NULL ) {
               free( tmpval );
-      }
+       }
 
        ldbm_cache_close( be, db );
 
-       Debug( LDAP_DEBUG_TRACE, "<= index_read %lu candidates\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n",
+              idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
        return( idl );
 }
 
+/* Add or remove stuff from index files */
+
 static int
-add_value(
+change_value(
     Backend            *be,
-    struct dbcache     *db,
+    DBCache    *db,
     char               *type,
     int                        indextype,
     char               *val,
-    ID                 id
+    ID                 id,
+    int                        (*idl_func)(Backend *, DBCache *, Datum, ID)
 )
 {
        int     rc;
        Datum   key;
-       ID_BLOCK        *idl = NULL;
        char    *tmpval = NULL;
        char    *realval = val;
        char    buf[BUFSIZ];
@@ -177,18 +206,20 @@ add_value(
 
        ldbm_datum_init( key );
 
-       Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
+       Debug( LDAP_DEBUG_TRACE,
+              "=> change_value( \"%c%s\", op=%s )\n",
+              prefix, val, (idl_func == idl_insert_key ? "ADD":"DELETE") );
 
        if ( prefix != UNKNOWN_PREFIX ) {
               unsigned int     len = strlen( val );
 
               if ( (len + 2) < sizeof(buf) ) {
                        realval = buf;
-               } else {
+             } else {
                        /* value + prefix + null */
                        tmpval = (char *) ch_malloc( len + 2 );
                        realval = tmpval;
-               }
+             }
               realval[0] = prefix;
               strcpy( &realval[1], val );
        }
@@ -196,28 +227,28 @@ add_value(
        key.dptr = realval;
        key.dsize = strlen( realval ) + 1;
 
-       rc = idl_insert_key( be, db, key, id );
+       rc = idl_func( be, db, key, id );
 
        if ( tmpval != NULL ) {
                free( tmpval );
        }
 
-       if( idl != NULL ) {
-               idl_free( idl );
-       }
-
        ldap_pvt_thread_yield();
 
-       /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
+       Debug( LDAP_DEBUG_TRACE, "<= change_value %d\n", rc, 0, 0 );
+
        return( rc );
-}
+
+}/* static int change_value() */
+
 
 int
-index_add_values(
+index_change_values(
     Backend            *be,
     char               *type,
     struct berval      **vals,
-    ID                 id
+    ID                 id,
+    unsigned int       op
 )
 {
        char            *val, *p, *code, *w;
@@ -226,21 +257,58 @@ index_add_values(
        char            buf[SUBLEN + 1];
        char            vbuf[BUFSIZ];
        char            *bigbuf;
-       struct dbcache  *db;
+       DBCache *db;
+
+       int             (*idl_funct)(Backend *,
+                                   DBCache *,
+                                   Datum, ID);
+       char            *at_cn; /* Attribute canonical name */
+       int             mode;
+
+       if( vals == NULL ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "=> index_change_values( %s, NULL, %ld, op=%s )\n", 
+                       type, id, ((op == __INDEX_ADD_OP) ? "ADD" : "DELETE" ) );
+               return 0;
+       }
+
+       Debug( LDAP_DEBUG_TRACE,
+              "=> index_change_values( \"%s\", %ld, op=%s )\n", 
+              type, id, ((op == __INDEX_ADD_OP) ? "ADD" : "DELETE" ) );
+
+       
+       if (op == __INDEX_ADD_OP) {
+
+           /* Add values */
+
+           idl_funct =  idl_insert_key;
+           mode = LDBM_WRCREAT;
+
+       } else {
 
-       Debug( LDAP_DEBUG_TRACE, "=> index_add_values( \"%s\", %ld )\n", type,
-           id, 0 );
+           /* Delete values */
 
+           idl_funct = idl_delete_key;
+           mode = LDBM_WRITER;
+
+       }
+
+       attr_normalize(type);
        attr_masks( be->be_private, type, &indexmask, &syntax );
+
        if ( indexmask == 0 ) {
                return( 0 );
        }
 
-       if ( (db = ldbm_cache_open( be, type, LDBM_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
+       at_cn = at_canonical_name( type );
+
+       if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, mode ))
+            == NULL ) {
                Debug( LDAP_DEBUG_ANY,
-                   "<= index_add_values -1 (could not open/create %s%s)\n",
-                   type, LDBM_SUFFIX, 0 );
+                      "<= index_change_values (couldn't open(%s%s),md=%s)\n",
+                      at_cn,
+                      LDBM_SUFFIX,
+                      ((mode==LDBM_WRCREAT)?"LDBM_WRCREAT":"LDBM_WRITER") );
                return( -1 );
        }
 
@@ -250,14 +318,21 @@ index_add_values(
                 * presence index entry
                 */
                if ( indexmask & INDEX_PRESENCE ) {
-                       add_value( be, db, type, INDEX_PRESENCE, "*", id );
+
+                       change_value( be, db, at_cn, INDEX_PRESENCE,
+                                     "*", id, idl_funct );
+
                }
 
-               Debug( LDAP_DEBUG_TRACE, "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
-                   syntax, SYNTAX_BIN, 0 );
+               Debug( LDAP_DEBUG_TRACE,
+                      "index_change_values syntax 0x%x syntax bin 0x%x\n",
+                      syntax, SYNTAX_BIN, 0 );
+
                if ( syntax & SYNTAX_BIN ) {
+
                        ldbm_cache_close( be, db );
                        return( 0 );
+
                }
 
                bigbuf = NULL;
@@ -275,11 +350,17 @@ index_add_values(
 
                value_normalize( val, syntax );
 
+               /* value_normalize could change the length of val */
+               len = strlen( val );
+
                /*
                 * equality index entry
                 */
                if ( indexmask & INDEX_EQUALITY ) {
-                       add_value( be, db, type, INDEX_EQUALITY, val, id );
+                   
+                       change_value( be, db, at_cn, INDEX_EQUALITY,
+                                     val, id, idl_funct);
+
                }
 
                /*
@@ -289,8 +370,13 @@ index_add_values(
                        for ( w = first_word( val ); w != NULL;
                            w = next_word( w ) ) {
                                if ( (code = phonetic( w )) != NULL ) {
-                                       add_value( be, db, type, INDEX_APPROX,
-                                           code, id );
+                                       change_value( be,
+                                                     db,
+                                                     at_cn,
+                                                     INDEX_APPROX,
+                                                     code,
+                                                     id,
+                                                     idl_funct );
                                        free( code );
                                }
                        }
@@ -308,7 +394,8 @@ index_add_values(
                                }
                                buf[SUBLEN] = '\0';
 
-                               add_value( be, db, type, INDEX_SUB, buf, id );
+                               change_value( be, db, at_cn, INDEX_SUB,
+                                             buf, id, idl_funct );
 
                                p = val + len - SUBLEN + 1;
                                for ( j = 0; j < SUBLEN - 1; j++ ) {
@@ -317,7 +404,8 @@ index_add_values(
                                buf[SUBLEN - 1] = '$';
                                buf[SUBLEN] = '\0';
 
-                               add_value( be, db, type, INDEX_SUB, buf, id );
+                               change_value( be, db, at_cn, INDEX_SUB,
+                                             buf, id, idl_funct );
                        }
 
                        /* any */
@@ -327,7 +415,8 @@ index_add_values(
                                }
                                buf[SUBLEN] = '\0';
 
-                               add_value( be, db, type, INDEX_SUB, buf, id );
+                               change_value( be, db, at_cn, INDEX_SUB,
+                                             buf, id, idl_funct );
                        }
                }
 
@@ -335,10 +424,12 @@ index_add_values(
                        free( bigbuf );
                }
        }
+
        ldbm_cache_close( be, db );
 
        return( 0 );
-}
+
+}/* int index_change_values() */
 
 static int
 index2prefix( int indextype )