1 /* index.c - routines for dealing with attribute indexes */
8 #include <sys/socket.h>
10 #include "back-ldbm.h"
12 extern char *first_word();
13 extern char *next_word();
14 extern char *phonetic();
15 extern IDList *idl_fetch();
16 extern IDList *idl_allids();
17 extern struct dbcache *ldbm_cache_open();
19 int index_add_values();
21 static int add_value();
22 static int index2prefix();
33 struct berval *bvals[2];
35 Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
39 * dn index entry - make it look like an attribute so it works
40 * with index_add_values() call
43 bv.bv_val = strdup( e->e_dn );
44 bv.bv_len = strlen( bv.bv_val );
45 (void) dn_normalize_case( bv.bv_val );
49 /* add the dn to the indexes */
50 index_add_values( be, "dn", bvals, e->e_id );
54 /* add each attribute to the indexes */
55 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
56 index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
59 Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
73 for ( ; mods != NULL; mods = mods->mod_next ) {
74 switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
76 case LDAP_MOD_REPLACE:
77 rc = index_add_values( be, mods->mod_type,
78 mods->mod_bvalues, id );
105 int indexmask, syntax;
107 char *realval, *tmpval;
111 memset( &key, 0, sizeof( key ) );
114 prefix = index2prefix( indextype );
115 Debug( LDAP_DEBUG_TRACE, "=> index_read( \"%s\" \"%c\" \"%s\" )\n",
118 attr_masks( be->be_private, type, &indexmask, &syntax );
119 if ( ! (indextype & indexmask) ) {
120 idl = idl_allids( be );
121 Debug( LDAP_DEBUG_TRACE,
122 "<= index_read %d candidates (allids - not indexed)\n",
123 idl ? idl->b_nids : 0, 0, 0 );
127 attr_normalize( type );
128 if ( (db = ldbm_cache_open( be, type, LDBM_SUFFIX, LDBM_WRCREAT ))
130 Debug( LDAP_DEBUG_ANY,
131 "<= index_read NULL (could not open %s%s)\n", type,
138 if ( prefix != '\0' ) {
139 int len = strlen( val );
141 if ( (len + 2) < sizeof(buf) ) {
144 /* value + prefix + null */
145 tmpval = (char *) ch_malloc( len + 2 );
149 strcpy( &realval[1], val );
153 key.dsize = strlen( realval ) + 1;
155 idl = idl_fetch( be, db, key );
156 if ( tmpval != NULL ) {
160 ldbm_cache_close( be, db );
162 Debug( LDAP_DEBUG_TRACE, "<= index_read %d candidates\n",
163 idl ? idl->b_nids : 0, 0, 0 );
181 char *realval, *tmpval, *s;
185 memset( &key, 0, sizeof( key ) );
188 prefix = index2prefix( indextype );
189 Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
194 if ( prefix != '\0' ) {
195 int len = strlen( val );
197 if ( (len + 2) < sizeof(buf) ) {
200 /* value + prefix + null */
201 tmpval = (char *) ch_malloc( len + 2 );
205 strcpy( &realval[1], val );
209 key.dsize = strlen( realval ) + 1;
211 rc = idl_insert_key( be, db, key, id );
213 if ( tmpval != NULL ) {
220 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
228 struct berval **vals,
232 char *val, *p, *code, *w;
234 int indexmask, syntax;
235 char buf[SUBLEN + 1];
240 Debug( LDAP_DEBUG_TRACE, "=> index_add_values( \"%s\", %ld )\n", type,
243 attr_masks( be->be_private, type, &indexmask, &syntax );
244 if ( indexmask == 0 ) {
248 if ( (db = ldbm_cache_open( be, type, LDBM_SUFFIX, LDBM_WRCREAT ))
250 Debug( LDAP_DEBUG_ANY,
251 "<= index_add_values -1 (could not open/create %s%s)\n",
252 type, LDBM_SUFFIX, 0 );
257 for ( i = 0; vals[i] != NULL; i++ ) {
259 * presence index entry
261 if ( indexmask & INDEX_PRESENCE ) {
262 add_value( be, db, type, INDEX_PRESENCE, "*", id );
265 Debug( LDAP_DEBUG_TRACE, "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
266 syntax, SYNTAX_BIN, 0 );
267 if ( syntax & SYNTAX_BIN ) {
268 ldbm_cache_close( be, db );
273 len = vals[i]->bv_len;
276 if ( len + 2 > sizeof(vbuf) ) {
277 bigbuf = (char *) ch_malloc( len + 1 );
282 (void) memcpy( val, vals[i]->bv_val, len );
285 value_normalize( val, syntax );
288 * equality index entry
290 if ( indexmask & INDEX_EQUALITY ) {
291 add_value( be, db, type, INDEX_EQUALITY, val, id );
295 * approximate index entry
297 if ( indexmask & INDEX_APPROX ) {
298 for ( w = first_word( val ); w != NULL;
299 w = next_word( w ) ) {
300 if ( (code = phonetic( w )) != NULL ) {
301 add_value( be, db, type, INDEX_APPROX,
309 * substrings index entry
311 if ( indexmask & INDEX_SUB ) {
312 /* leading and trailing */
313 if ( len > SUBLEN - 2 ) {
315 for ( j = 0; j < SUBLEN - 1; j++ ) {
320 add_value( be, db, type, INDEX_SUB, buf, id );
322 p = val + len - SUBLEN + 1;
323 for ( j = 0; j < SUBLEN - 1; j++ ) {
326 buf[SUBLEN - 1] = '$';
329 add_value( be, db, type, INDEX_SUB, buf, id );
333 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
334 for ( j = 0; j < SUBLEN; j++ ) {
339 add_value( be, db, type, INDEX_SUB, buf, id );
343 if ( bigbuf != NULL ) {
347 ldbm_cache_close( be, db );
353 index2prefix( int indextype )
357 switch ( indextype ) {
362 prefix = APPROX_PREFIX;