]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/index.c
Remove lint
[openldap] / servers / slapd / back-bdb / index.c
1 /* index.c - routines for dealing with attribute indexes */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 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-bdb.h"
17
18 static slap_mask_t index_mask(
19         Backend *be,
20         AttributeDescription *desc,
21         char **dbname,
22         char **atname )
23 {
24         AttributeType *at;
25         slap_mask_t mask = 0;
26
27         bdb_attr_mask( be->be_private, desc->ad_cname.bv_val, &mask );
28
29         if( mask ) {
30                 *atname = desc->ad_cname.bv_val;
31                 *dbname = desc->ad_cname.bv_val;
32                 return mask;
33         }
34
35         if( slap_ad_is_lang( desc ) ) {
36                 /* has language tag */
37                 bdb_attr_mask( be->be_private, desc->ad_type->sat_cname, &mask );
38
39                 if( mask & SLAP_INDEX_AUTO_LANG ) {
40                         *atname = desc->ad_cname.bv_val;
41                         *dbname = desc->ad_type->sat_cname;
42                         return mask;
43                 }
44                 if( mask & SLAP_INDEX_LANG ) {
45                         *atname = desc->ad_type->sat_cname;
46                         *dbname = desc->ad_type->sat_cname;
47                         return mask;
48                 }
49         }
50
51         /* see if supertype defined mask for its subtypes */
52         for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) {
53                 bdb_attr_mask( be->be_private, at->sat_cname, &mask );
54
55                 if( mask & SLAP_INDEX_AUTO_SUBTYPES ) {
56                         *atname = desc->ad_type->sat_cname;
57                         *dbname = at->sat_cname;
58                         return mask;
59                 }
60                 if( mask & SLAP_INDEX_SUBTYPES ) {
61                         *atname = at->sat_cname;
62                         *dbname = at->sat_cname;
63                         return mask;
64                 }
65
66                 if( mask ) break;
67         }
68
69         return 0;
70 }
71
72 int bdb_index_param(
73         Backend *be,
74         AttributeDescription *desc,
75         int ftype,
76         DB **dbp,
77         slap_mask_t *maskp,
78         struct berval **prefixp )
79 {
80         int rc;
81         slap_mask_t mask;
82         DB *db;
83         char *dbname;
84         char *atname;
85
86         mask = index_mask( be, desc, &dbname, &atname );
87
88         if( mask == 0 ) {
89                 return LDAP_INAPPROPRIATE_MATCHING;
90         }
91
92         rc = bdb_db_cache( be, dbname, &db );
93
94         if( rc != LDAP_SUCCESS ) {
95                 return rc;
96         }
97
98         switch(ftype) {
99         case LDAP_FILTER_PRESENT:
100                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
101                         goto done;
102                 }
103                 break;
104
105         case LDAP_FILTER_APPROX:
106                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
107                         goto done;
108                 }
109                 /* fall thru */
110
111         case LDAP_FILTER_EQUALITY:
112                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
113                         goto done;
114                 }
115                 break;
116
117         case LDAP_FILTER_SUBSTRINGS:
118                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
119                         goto done;
120                 }
121                 break;
122
123         default:
124                 return LDAP_OTHER;
125         }
126
127         return LDAP_INAPPROPRIATE_MATCHING;
128
129 done:
130         *dbp = db;
131         *prefixp = ber_bvstrdup( atname );
132         *maskp = mask;
133         return LDAP_SUCCESS;
134 }
135
136 static int indexer(
137         Backend *be,
138         DB_TXN *txn,
139         char *dbname,
140         char *atname,
141         struct berval **vals,
142         ID id,
143         int op,
144         slap_mask_t mask )
145 {
146         int rc, i;
147         const char *text;
148         DB *db;
149         AttributeDescription *ad = NULL;
150         struct berval **keys;
151         struct berval prefix;
152
153         assert( mask );
154
155         rc = bdb_db_cache( be, dbname, &db );
156         
157         if ( rc != LDAP_SUCCESS ) {
158 #ifdef NEW_LOGGING
159                 LDAP_LOG(( "index", LDAP_LEVEL_ERR,
160                         "bdb_index_read: Could not open DB %s\n", dbname));
161 #else
162                 Debug( LDAP_DEBUG_ANY,
163                         "<= bdb_index_read NULL (could not open %s)\n",
164                         dbname, 0, 0 );
165 #endif
166                 return LDAP_OTHER;
167         }
168
169         rc = slap_str2ad( atname, &ad, &text );
170         if( rc != LDAP_SUCCESS ) return rc;
171
172         prefix.bv_val = atname;
173         prefix.bv_len = strlen( atname );
174
175         if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
176                 rc = bdb_key_change( be, db, txn, &prefix, id, op );
177                 if( rc ) {
178                         goto done;
179                 }
180         }
181
182         if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
183                 rc = ad->ad_type->sat_equality->smr_indexer(
184                         LDAP_FILTER_EQUALITY,
185                         mask,
186                         ad->ad_type->sat_syntax,
187                         ad->ad_type->sat_equality,
188                         &prefix, vals, &keys );
189
190                 if( rc == LDAP_SUCCESS && keys != NULL ) {
191                         for( i=0; keys[i] != NULL; i++ ) {
192                                 rc = bdb_key_change( be, db, txn, keys[i], id, op );
193                                 if( rc ) {
194                                         ber_bvecfree( keys );
195                                         goto done;
196                                 }
197                         }
198                         ber_bvecfree( keys );
199                 }
200                 rc = LDAP_SUCCESS;
201         }
202
203         if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
204                 rc = ad->ad_type->sat_approx->smr_indexer(
205                         LDAP_FILTER_APPROX,
206                         mask,
207                         ad->ad_type->sat_syntax,
208                         ad->ad_type->sat_approx,
209                         &prefix, vals, &keys );
210
211                 if( rc == LDAP_SUCCESS && keys != NULL ) {
212                         for( i=0; keys[i] != NULL; i++ ) {
213                                 rc = bdb_key_change( be, db, txn, keys[i], id, op );
214                                 if( rc ) {
215                                         ber_bvecfree( keys );
216                                         goto done;
217                                 }
218                         }
219                         ber_bvecfree( keys );
220                 }
221
222                 rc = LDAP_SUCCESS;
223         }
224
225         if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
226                 rc = ad->ad_type->sat_substr->smr_indexer(
227                         LDAP_FILTER_SUBSTRINGS,
228                         mask,
229                         ad->ad_type->sat_syntax,
230                         ad->ad_type->sat_substr,
231                         &prefix, vals, &keys );
232
233                 if( rc == LDAP_SUCCESS && keys != NULL ) {
234                         for( i=0; keys[i] != NULL; i++ ) {
235                                 bdb_key_change( be, db, txn, keys[i], id, op );
236                                 if( rc ) {
237                                         ber_bvecfree( keys );
238                                         goto done;
239                                 }
240                         }
241                         ber_bvecfree( keys );
242                 }
243
244                 rc = LDAP_SUCCESS;
245         }
246
247 done:
248         return rc;
249 }
250
251 static int index_at_values(
252         Backend *be,
253         DB_TXN *txn,
254         AttributeType *type,
255         struct berval *lang,
256         struct berval **vals,
257         ID id,
258         int op,
259         char ** dbnamep,
260         slap_mask_t *maskp )
261 {
262         int rc;
263         slap_mask_t mask;
264         slap_mask_t tmpmask = 0;
265         int lindex = 0;
266
267         if( type->sat_sup ) {
268                 /* recurse */
269                 rc = index_at_values( be, txn,
270                         type->sat_sup, lang,
271                         vals, id, op,
272                         dbnamep, &tmpmask );
273
274                 if( rc ) return rc;
275         }
276
277         bdb_attr_mask( be->be_private, type->sat_cname, &mask );
278
279         if( mask ) {
280                 *dbnamep = type->sat_cname;
281         } else if ( tmpmask & SLAP_INDEX_AUTO_SUBTYPES ) {
282                 mask = tmpmask;
283         }
284
285         if( mask ) {
286                 rc = indexer( be, txn, *dbnamep,
287                         type->sat_cname,
288                         vals, id, op,
289                         mask );
290
291                 if( rc ) return rc;
292         }
293
294         if( lang->bv_len ) {
295                 char *dbname = NULL;
296                 size_t tlen = strlen( type->sat_cname );
297                 size_t llen = lang->bv_len;
298                 char *lname = ch_malloc( tlen + llen + sizeof(";") );
299
300                 sprintf( lname, "%s;%s", type->sat_cname, lang->bv_val );
301
302                 bdb_attr_mask( be->be_private, lname, &tmpmask );
303
304                 if( tmpmask ) {
305                         dbname = lname;
306                 } else if ( mask & SLAP_INDEX_AUTO_LANG ) {
307                         dbname = *dbnamep;
308                         tmpmask = mask;
309                 }
310
311                 if( dbname != NULL ) {
312                         rc = indexer( be, txn, dbname, lname,
313                                 vals, id, op,
314                                 tmpmask );
315
316                         if( rc ) {
317                                 ch_free( lname );
318                                 return rc;
319                         }
320                 }
321
322                 ch_free( lname );
323         }
324
325         return LDAP_SUCCESS;
326 }
327
328 int bdb_index_values(
329         Backend *be,
330         DB_TXN *txn,
331         AttributeDescription *desc,
332         struct berval **vals,
333         ID id,
334         int op )
335 {
336         int rc;
337         char *dbname = NULL;
338         slap_mask_t mask;
339
340         rc = index_at_values( be, txn,
341                 desc->ad_type, &desc->ad_lang,
342                 vals, id, op,
343                 &dbname, &mask );
344
345         return rc;
346 }
347
348 int
349 bdb_index_entry(
350         Backend *be,
351         DB_TXN *txn,
352         int op,
353         Entry   *e,
354         Attribute *ap )
355 {
356         int rc;
357
358 #ifdef NEW_LOGGING
359         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
360                 "index_entry: %s (%s) %ld\n",
361                 op == SLAP_INDEX_ADD_OP ? "add" : "del",
362                 e->e_dn, (long) e->e_id ));
363 #else
364         Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
365                 op == SLAP_INDEX_ADD_OP ? "add" : "del",
366                 (long) e->e_id, e->e_dn );
367 #endif
368
369         /* add each attribute to the indexes */
370         for ( ; ap != NULL; ap = ap->a_next ) {
371                 rc = bdb_index_values( be, txn,
372                         ap->a_desc, ap->a_vals, e->e_id, op );
373
374                 if( rc != LDAP_SUCCESS ) {
375 #ifdef NEW_LOGGING
376                         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
377                            "index_entry: success\n" ));
378 #else
379                         Debug( LDAP_DEBUG_TRACE,
380                                 "<= index_entry_%s( %ld, \"%s\" ) success\n",
381                                 op == SLAP_INDEX_ADD_OP ? "add" : "del",
382                                 (long) e->e_id, e->e_dn );
383 #endif
384                         return rc;
385                 }
386         }
387
388 #ifdef NEW_LOGGING
389         LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
390                 "index_entry: success\n" ));
391 #else
392         Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
393                 op == SLAP_INDEX_ADD_OP ? "add" : "del",
394                 (long) e->e_id, e->e_dn );
395 #endif
396
397         return LDAP_SUCCESS;
398 }