]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/index.c
Deleted autosubtypes support.
[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 = at->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 {
240         slap_mask_t mask = 0;
241
242         if( type->sat_sup ) {
243                 /* recurse */
244                 (void) index_at_values( be,
245                         type->sat_sup, lang,
246                         vals, id, op );
247         }
248
249         /* If this type has no AD, we've never used it before */
250         if( type->sat_ad ) {
251                 attr_mask( be->be_private, type->sat_ad, &mask );
252         }
253
254         if( mask ) {
255                 indexer( be, type->sat_cname.bv_val,
256                         &type->sat_cname,
257                         vals, id, op,
258                         mask );
259         }
260
261         if( lang->bv_len ) {
262                 AttributeDescription *desc;
263
264                 mask = 0;
265
266                 desc = ad_find_lang(type, lang);
267                 if( desc ) {
268                         attr_mask( be->be_private, desc, &mask );
269                 }
270
271                 if( mask ) {
272                         indexer( be, desc->ad_cname.bv_val, &desc->ad_cname,
273                                 vals, id, op,
274                                 mask );
275                 }
276         }
277
278         return LDAP_SUCCESS;
279 }
280
281 int index_values(
282         Backend *be,
283         AttributeDescription *desc,
284         BerVarray vals,
285         ID id,
286         int op )
287 {
288         (void) index_at_values( be,
289                 desc->ad_type, &desc->ad_lang,
290                 vals, id, op );
291
292         return LDAP_SUCCESS;
293 }
294
295 int
296 index_entry(
297     Backend     *be,
298         int op,
299     Entry *e,
300         Attribute *ap )
301 {
302 #ifdef NEW_LOGGING
303         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
304                    "index_entry: %s (%s)%ld\n",
305                    op == SLAP_INDEX_ADD_OP ? "add" : "del",
306                    e->e_dn, e->e_id ));
307 #else
308         Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
309                 op == SLAP_INDEX_ADD_OP ? "add" : "del",
310                 e->e_id, e->e_dn );
311 #endif
312
313         /* add each attribute to the indexes */
314         for ( ; ap != NULL; ap = ap->a_next ) {
315                 index_values( be, ap->a_desc, ap->a_vals, e->e_id, op );
316         }
317
318 #ifdef NEW_LOGGING
319         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
320                    "index_entry: success\n" ));
321 #else
322         Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
323             op == SLAP_INDEX_ADD_OP ? "add" : "del",
324                 e->e_id, e->e_dn );
325 #endif
326
327         return LDAP_SUCCESS;
328 }
329