]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/attr.c
Add some initial BDB_INDEX code... needs much work.
[openldap] / servers / slapd / back-bdb / attr.c
1 /* attr.c - backend routines for dealing with attributes */
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/socket.h>
13 #include <ac/string.h>
14
15 #include "slap.h"
16 #include "back-bdb.h"
17
18 #if BDB_CONFIG_INDICES
19
20 /* for the cache of attribute information (which are indexed, etc.) */
21 typedef struct bdb_attrinfo {
22 #ifdef SLAPD_USE_AD
23         AttributeDescription *ai_desc; /* attribute description cn;lang-en      */
24 #else
25         char *ai_desc;
26 #endif
27         slap_mask_t ai_indexmask;       /* how the attr is indexed      */
28 } AttrInfo;
29
30 static int
31 ainfo_type_cmp(
32 #ifdef SLAPD_USE_AD
33         AttributeDescription *desc,
34 #else
35     char                *desc,
36 #endif
37     AttrInfo    *a
38 )
39 {
40 #ifdef SLAPD_USE_AD
41         return ad_cmp( desc, a->ai_desc );
42 #else
43         return( strcasecmp( desc, a->ai_desc ) );
44 #endif
45 }
46
47 static int
48 ainfo_cmp(
49     AttrInfo    *a,
50     AttrInfo    *b
51 )
52 {
53 #ifdef SLAPD_USE_AD
54         return ad_cmp( a->ai_desc, b->ai_desc );
55 #else
56         return( strcasecmp( a->ai_desc, b->ai_desc ) );
57 #endif
58 }
59
60 void
61 bdb_attr_mask(
62     struct bdb_info     *bdb,
63 #ifdef SLAPD_USE_AD
64         AttributeDescription *desc,
65 #else
66     const char *desc,
67 #endif
68     slap_mask_t *indexmask )
69 {
70         AttrInfo        *a;
71
72         a = (AttrInfo *) avl_find( bdb->bi_attrs, desc,
73             (AVL_CMP) ainfo_type_cmp );
74         
75         *indexmask = a != NULL ? a->ai_indexmask : 0;
76 }
77
78 int
79 bdb_attr_index_config(
80     struct bdb_info     *bdb,
81     const char          *fname,
82     int                 lineno,
83     int                 argc,
84     char                **argv )
85 {
86         int rc;
87         int     i;
88         slap_mask_t mask;
89         char **attrs;
90         char **indexes = NULL;
91
92         attrs = str2charray( argv[0], "," );
93
94         if( attrs == NULL ) {
95                 fprintf( stderr, "%s: line %d: "
96                         "no attributes specified: %s\n",
97                         fname, lineno, argv[0] );
98                 return LDAP_PARAM_ERROR;
99         }
100
101         if ( argc > 1 ) {
102                 indexes = str2charray( argv[1], "," );
103
104                 if( indexes == NULL ) {
105                         fprintf( stderr, "%s: line %d: "
106                                 "no indexes specified: %s\n",
107                                 fname, lineno, argv[1] );
108                         return LDAP_PARAM_ERROR;
109                 }
110         }
111
112         if( indexes == NULL ) {
113                 mask = bdb->bi_defaultmask;
114
115         } else {
116                 mask = 0;
117
118                 for ( i = 0; indexes[i] != NULL; i++ ) {
119                         slap_mask_t index;
120                         rc = slap_str2index( indexes[i], &index );
121
122                         if( rc != LDAP_SUCCESS ) {
123                                 fprintf( stderr, "%s: line %d: "
124                                         "index type \"%s\" undefined\n",
125                                         fname, lineno, indexes[i] );
126                                 return LDAP_PARAM_ERROR;
127                         }
128
129                         mask |= index;
130                 }
131         }
132
133     if( !mask ) {
134                 fprintf( stderr, "%s: line %d: "
135                         "no indexes selected\n",
136                         fname, lineno );
137                 return LDAP_PARAM_ERROR;
138         }
139
140         for ( i = 0; attrs[i] != NULL; i++ ) {
141                 AttrInfo        *a;
142                 AttributeDescription *ad;
143                 const char *text;
144
145                 if( strcasecmp( attrs[i], "default" ) == 0 ) {
146                         bdb->bi_defaultmask = mask;
147                         continue;
148                 }
149
150                 a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
151
152                 ad = NULL;
153                 rc = slap_str2ad( attrs[i], &ad, &text );
154
155                 if( rc != LDAP_SUCCESS ) {
156                         fprintf( stderr, "%s: line %d: "
157                                 "index attribute \"%s\" undefined\n",
158                                 fname, lineno, attrs[i] );
159                         return rc;
160                 }
161
162                 if( slap_ad_is_binary( ad ) ) {
163                         fprintf( stderr, "%s: line %d: "
164                                 "index of attribute \"%s\" disallowed\n",
165                                 fname, lineno, attrs[i] );
166                         return LDAP_UNWILLING_TO_PERFORM;
167                 }
168
169                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
170                         ( ad->ad_type->sat_approx
171                                 && ad->ad_type->sat_approx->smr_indexer
172                                 && ad->ad_type->sat_approx->smr_filter )
173                         && ( ad->ad_type->sat_equality
174                                 && ad->ad_type->sat_equality->smr_indexer
175                                 && ad->ad_type->sat_equality->smr_filter ) ) )
176                 {
177                         fprintf( stderr, "%s: line %d: "
178                                 "approx index of attribute \"%s\" disallowed\n",
179                                 fname, lineno, attrs[i] );
180                         return LDAP_INAPPROPRIATE_MATCHING;
181                 }
182
183                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
184                         ad->ad_type->sat_equality
185                                 && ad->ad_type->sat_equality->smr_indexer
186                                 && ad->ad_type->sat_equality->smr_filter ) )
187                 {
188                         fprintf( stderr, "%s: line %d: "
189                                 "equality index of attribute \"%s\" disallowed\n",
190                                 fname, lineno, attrs[i] );
191                         return LDAP_INAPPROPRIATE_MATCHING;
192                 }
193
194                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
195                         ad->ad_type->sat_substr
196                                 && ad->ad_type->sat_substr->smr_indexer
197                                 && ad->ad_type->sat_substr->smr_filter ) )
198                 {
199                         fprintf( stderr, "%s: line %d: "
200                                 "substr index of attribute \"%s\" disallowed\n",
201                                 fname, lineno, attrs[i] );
202                         return LDAP_INAPPROPRIATE_MATCHING;
203                 }
204
205 #ifdef NEW_LOGGING
206                 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
207                            "attr_index_config: index %s 0x%04x\n",
208                            ad->ad_cname->bv_val, mask ));
209 #else
210                 Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04x\n",
211                         ad->ad_cname->bv_val, mask, 0 ); 
212 #endif
213
214
215 #ifdef SLAPD_USE_AD
216                 a->ai_desc = ad;
217 #else
218                 a->ai_desc = ch_strdup( ad->ad_cname->bv_val );
219                 ad_free( ad, 1 );
220 #endif
221
222                 a->ai_indexmask = mask;
223
224                 rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
225                         (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
226
227                 if( rc ) {
228                         fprintf( stderr, "%s: line %d: duplicate index definition "
229                                 "for attr \"%s\" (ignored)\n",
230                             fname, lineno, attrs[i] );
231
232                         return LDAP_PARAM_ERROR;
233                 }
234         }
235
236         charray_free( attrs );
237         if ( indexes != NULL ) charray_free( indexes );
238
239         return LDAP_SUCCESS;
240 }
241
242
243 static void
244 ainfo_free( void *attr )
245 {
246         AttrInfo *ai = attr;
247 #ifdef SLAPD_USE_AD
248         ad_free( ai->ai_desc, 1 );
249 #else
250         free( ai->ai_desc );
251 #endif
252         free( ai );
253 }
254
255 void
256 bdb_attr_index_destroy( Avlnode *tree )
257 {
258         avl_free( tree, ainfo_free );
259 }
260
261 #endif