]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/index.c
Add a default case with assert() just in case.
[openldap] / servers / slapd / back-ldbm / index.c
1 /* index.c - routines for dealing with attribute indexes */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16 #include "back-ldbm.h"
17
18 static slap_mask_t index_mask(
19         Backend *be,
20         AttributeDescription *desc,
21         char **dbname,
22         struct berval *atname )
23 {
24         AttributeType *at;
25         slap_mask_t mask = 0;
26
27         attr_mask( be->be_private, desc, &mask );
28
29         if( mask ) {
30                 *atname = desc->ad_cname;
31                 *dbname = desc->ad_cname.bv_val;
32                 return mask;
33         }
34
35         /* If there is a language tag, did we ever index the base
36          * type? If so, check for mask, otherwise it's not there.
37          */
38         if( slap_ad_is_lang( desc ) && desc != desc->ad_type->sat_ad ) {
39                 /* has language tag */
40                 attr_mask( be->be_private, desc->ad_type->sat_ad, &mask );
41
42                 if( mask && ( mask ^ SLAP_INDEX_NOLANG ) ) {
43                         *atname = desc->ad_type->sat_cname;
44                         *dbname = desc->ad_type->sat_cname.bv_val;
45                         return mask;
46                 }
47         }
48
49         /* see if supertype defined mask for its subtypes */
50         for( at = desc->ad_type->sat_sup; at != NULL ; at = at->sat_sup ) {
51                 /* If no AD, we've never indexed this type */
52                 if (!at->sat_ad)
53                         continue;
54                 
55                 attr_mask( be->be_private, at->sat_ad, &mask );
56
57                 if( mask && ( mask ^ SLAP_INDEX_NOSUBTYPES ) ) {
58                         *atname = desc->ad_type->sat_cname;
59                         *dbname = at->sat_cname.bv_val;
60                         return mask;
61                 }
62         }
63
64         return 0;
65 }
66
67 int index_is_indexed(
68         Backend *be,
69         AttributeDescription *desc )
70 {
71         int rc;
72         slap_mask_t mask;
73         char *dbname;
74         struct berval prefix;
75
76         mask = index_mask( be, desc, &dbname, &prefix );
77
78         if( mask == 0 ) {
79                 return LDAP_INAPPROPRIATE_MATCHING;
80         }
81
82         return LDAP_SUCCESS;
83 }
84
85 int index_param(
86         Backend *be,
87         AttributeDescription *desc,
88         int ftype,
89         char **dbnamep,
90         slap_mask_t *maskp,
91         struct berval *prefixp )
92 {
93         slap_mask_t mask;
94         char *dbname;
95
96         mask = index_mask( be, desc, &dbname, prefixp );
97
98         if( mask == 0 ) {
99                 return LDAP_INAPPROPRIATE_MATCHING;
100         }
101
102         switch( ftype ) {
103         case LDAP_FILTER_PRESENT:
104                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
105                         goto done;
106                 }
107                 break;
108
109         case LDAP_FILTER_APPROX:
110                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
111                         goto done;
112                 }
113                 /* fall thru */
114
115         case LDAP_FILTER_EQUALITY:
116                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
117                         goto done;
118                 }
119                 break;
120
121         case LDAP_FILTER_SUBSTRINGS:
122                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
123                         goto done;
124                 }
125                 break;
126
127         default:
128                 return LDAP_OTHER;
129         }
130
131         return LDAP_INAPPROPRIATE_MATCHING;
132
133 done:
134         *dbnamep = dbname;
135         *maskp = mask;
136         return LDAP_SUCCESS;
137 }
138
139 static int indexer(
140         Backend *be,
141         char *dbname,
142         struct berval *atname,
143         BerVarray vals,
144         ID id,
145         int op,
146         slap_mask_t mask )
147 {
148         int rc, i;
149         const char *text;
150     DBCache     *db;
151         AttributeDescription *ad = NULL;
152         struct berval *keys;
153
154         assert( mask );
155
156         rc = slap_bv2ad( atname, &ad, &text );
157
158         if( rc != LDAP_SUCCESS ) return rc;
159
160         db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_WRCREAT );
161         
162         if ( db == NULL ) {
163 #ifdef NEW_LOGGING
164                 LDAP_LOG(( "index", LDAP_LEVEL_ERR,
165                            "index_read: Could not open db %s%s\n",
166                            dbname, LDBM_SUFFIX ));
167 #else
168                 Debug( LDAP_DEBUG_ANY,
169                     "<= index_read NULL (could not open %s%s)\n",
170                         dbname, LDBM_SUFFIX, 0 );
171 #endif
172
173                 return LDAP_OTHER;
174         }
175
176         if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
177                 key_change( be, db, atname, id, op );
178         }
179
180         if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
181                 rc = ad->ad_type->sat_equality->smr_indexer(
182                         LDAP_FILTER_EQUALITY,
183                         mask,
184                         ad->ad_type->sat_syntax,
185                         ad->ad_type->sat_equality,
186                         atname, vals, &keys );
187
188                 if( rc == LDAP_SUCCESS && keys != NULL ) {
189                         for( i=0; keys[i].bv_val != NULL; i++ ) {
190                                 key_change( be, db, &keys[i], id, op );
191                         }
192                         ber_bvarray_free( keys );
193                 }
194         }
195
196         if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
197                 rc = ad->ad_type->sat_approx->smr_indexer(
198                         LDAP_FILTER_APPROX,
199                         mask,
200                         ad->ad_type->sat_syntax,
201                         ad->ad_type->sat_approx,
202                         atname, vals, &keys );
203
204                 if( rc == LDAP_SUCCESS && keys != NULL ) {
205                         for( i=0; keys[i].bv_val != NULL; i++ ) {
206                                 key_change( be, db, &keys[i], id, op );
207                         }
208                         ber_bvarray_free( keys );
209                 }
210         }
211
212         if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
213                 rc = ad->ad_type->sat_substr->smr_indexer(
214                         LDAP_FILTER_SUBSTRINGS,
215                         mask,
216                         ad->ad_type->sat_syntax,
217                         ad->ad_type->sat_substr,
218                         atname, vals, &keys );
219
220                 if( rc == LDAP_SUCCESS && keys != NULL ) {
221                         for( i=0; keys[i].bv_val != NULL; i++ ) {
222                                 key_change( be, db, &keys[i], id, op );
223                         }
224                         ber_bvarray_free( keys );
225                 }
226         }
227
228         ldbm_cache_close( be, db );
229         return LDAP_SUCCESS;
230 }
231
232 static int index_at_values(
233         Backend *be,
234         AttributeType *type,
235         struct berval *lang,
236         BerVarray vals,
237         ID id,
238         int op,
239         char ** dbnamep,
240         slap_mask_t *maskp )
241 {
242         slap_mask_t mask = 0;
243         slap_mask_t tmpmask = 0;
244
245         if( type->sat_sup ) {
246                 /* recurse */
247                 (void) index_at_values( be,
248                         type->sat_sup, lang,
249                         vals, id, op,
250                         dbnamep, &tmpmask );
251         }
252
253         /* If this type has no AD, we've never used it before */
254         if( type->sat_ad ) {
255                 attr_mask( be->be_private, type->sat_ad, &mask );
256         }
257
258         if( mask ) {
259                 *dbnamep = type->sat_cname.bv_val;
260         } else if ( tmpmask ^ SLAP_INDEX_NOSUBTYPES ) {
261                 mask = tmpmask;
262         }
263
264         if( mask ) {
265                 indexer( be, *dbnamep,
266                         &type->sat_cname,
267                         vals, id, op,
268                         mask );
269                 *maskp = mask;
270         }
271
272         if( lang->bv_len ) {
273                 char *dbname = NULL;
274                 struct berval lname;
275                 AttributeDescription *desc;
276
277                 tmpmask = 0;
278                 lname.bv_val = NULL;
279
280                 desc = ad_find_lang(type, lang);
281                 if( desc ) {
282                         attr_mask( be->be_private, desc, &tmpmask );
283                 }
284
285                 if( tmpmask ) {
286                         dbname = desc->ad_cname.bv_val;
287                         lname = desc->ad_cname;
288                         mask = tmpmask;
289                 }
290
291                 if( dbname != NULL ) {
292                         indexer( be, dbname, &lname,
293                                 vals, id, op,
294                                 mask );
295                         if( !tmpmask ) {
296                                 ch_free( lname.bv_val );
297                         }
298                 }
299         }
300
301         return LDAP_SUCCESS;
302 }
303
304 int index_values(
305         Backend *be,
306         AttributeDescription *desc,
307         BerVarray vals,
308         ID id,
309         int op )
310 {
311         char *dbname = NULL;
312         slap_mask_t mask;
313
314         (void) index_at_values( be,
315                 desc->ad_type, &desc->ad_lang,
316                 vals, id, op,
317                 &dbname, &mask );
318
319         return LDAP_SUCCESS;
320 }
321
322 int
323 index_entry(
324     Backend     *be,
325         int op,
326     Entry *e,
327         Attribute *ap )
328 {
329 #ifdef NEW_LOGGING
330         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
331                    "index_entry: %s (%s)%ld\n",
332                    op == SLAP_INDEX_ADD_OP ? "add" : "del",
333                    e->e_dn, e->e_id ));
334 #else
335         Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
336                 op == SLAP_INDEX_ADD_OP ? "add" : "del",
337                 e->e_id, e->e_dn );
338 #endif
339
340         /* add each attribute to the indexes */
341         for ( ; ap != NULL; ap = ap->a_next ) {
342                 index_values( be, ap->a_desc, ap->a_vals, e->e_id, op );
343         }
344
345 #ifdef NEW_LOGGING
346         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
347                    "index_entry: success\n" ));
348 #else
349         Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
350             op == SLAP_INDEX_ADD_OP ? "add" : "del",
351                 e->e_id, e->e_dn );
352 #endif
353
354         return LDAP_SUCCESS;
355 }
356