]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/dn2id.c
Add bdb_add() and supporting routines
[openldap] / servers / slapd / back-bdb / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
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 "back-bdb.h"
16
17 int
18 bdb_dn2id_add(
19     Backend     *be,
20         DB_TXN *txn,
21     const char  *dn,
22     ID          id
23 )
24 {
25         int             rc;
26         DBT             key, data;
27         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
28         DB *db = bdb->bi_dn2id->bdi_db;
29
30         Debug( LDAP_DEBUG_TRACE, "=> bdb_index_dn_add( \"%s\", %ld )\n", dn, id, 0 );
31         assert( id != NOID );
32
33         DBTzero( &key );
34         key.size = strlen( dn ) + 2;
35         key.data = ch_malloc( key.size );
36         ((char *)key.data)[0] = DN_BASE_PREFIX;
37         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
38
39         DBTzero( &data );
40         data.data = (char *) &id;
41         data.size = sizeof( id );
42
43         /* store it -- don't override */
44         rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
45         if( rc != 0 ) {
46                 goto done;
47         }
48
49         {
50                 char *pdn = dn_parent( NULL, dn );
51                 ((char *)(key.data))[0] = DN_ONE_PREFIX;
52
53                 if( pdn != NULL ) {
54                         key.size = strlen( pdn ) + 2;
55                         AC_MEMCPY( &((char*)key.data)[1],
56                                 pdn, key.size - 1 );
57
58                         rc = bdb_idl_insert_key( be, db, txn, &key, id );
59                         free( pdn );
60
61                         if( rc != 0 ) {
62                                 goto done;
63                         }
64                 }
65         }
66
67         if ( rc != -1 ) {
68                 char **subtree = dn_subtree( NULL, dn );
69
70                 if( subtree != NULL ) {
71                         int i;
72                         ((char *)key.data)[0] = DN_SUBTREE_PREFIX;
73                         for( i=0; subtree[i] != NULL; i++ ) {
74                                 key.size = strlen( subtree[i] ) + 2;
75                                 AC_MEMCPY( &((char *)key.data)[1],
76                                         subtree[i], key.size - 1 );
77
78                                 rc = bdb_idl_insert_key( be, db, txn, &key, id );
79
80                                 if( rc != 0 ) {
81                                         goto done;
82                                 }
83                         }
84
85                         charray_free( subtree );
86                 }
87         }
88
89 done:
90         ch_free( key.data );
91         Debug( LDAP_DEBUG_TRACE, "<= bdb_index_dn_add %d\n", rc, 0, 0 );
92         return( rc );
93 }
94
95 #if 0
96 ID
97 dn2id(
98     Backend     *be,
99     const char  *dn
100 )
101 {
102         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
103         DBCache *db;
104         ID              id;
105         Datum           key, data;
106
107         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
108
109         /* first check the cache */
110         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
111                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
112                         0, 0 );
113                 return( id );
114         }
115
116         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
117                 == NULL ) {
118                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
119                         LDBM_SUFFIX, 0, 0 );
120                 return( NOID );
121         }
122
123         ldbm_datum_init( key );
124
125         key.dsize = strlen( dn ) + 2;
126         key.dptr = ch_malloc( key.dsize );
127         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
128
129         data = ldbm_cache_fetch( db, key );
130
131         ldbm_cache_close( be, db );
132
133         free( key.dptr );
134
135         if ( data.dptr == NULL ) {
136                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
137                 return( NOID );
138         }
139
140         AC_MEMCPY( (char *) &id, data.dptr, sizeof(ID) );
141
142         assert( id != NOID );
143
144         ldbm_datum_free( db->dbc_db, data );
145
146         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
147         return( id );
148 }
149
150 ID_BLOCK *
151 dn2idl(
152     Backend     *be,
153     const char  *dn,
154         int             prefix
155 )
156 {
157         DBCache *db;
158         Datum           key;
159         ID_BLOCK        *idl;
160
161         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
162
163         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
164                 == NULL ) {
165                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
166                         LDBM_SUFFIX, 0, 0 );
167                 return NULL;
168         }
169
170         ldbm_datum_init( key );
171
172         key.dsize = strlen( dn ) + 2;
173         key.dptr = ch_malloc( key.dsize );
174         sprintf( key.dptr, "%c%s", prefix, dn );
175
176         idl = idl_fetch( be, db, key );
177
178         ldbm_cache_close( be, db );
179
180         free( key.dptr );
181
182         return( idl );
183 }
184
185
186 int
187 dn2id_delete(
188     Backend     *be,
189     const char  *dn,
190         ID id
191 )
192 {
193         DBCache *db;
194         Datum           key;
195         int             rc;
196
197         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
198
199         assert( id != NOID );
200
201         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
202             == NULL ) {
203                 Debug( LDAP_DEBUG_ANY,
204                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
205                     0, 0 );
206                 return( -1 );
207         }
208
209
210         {
211                 char *pdn = dn_parent( NULL, dn );
212
213                 if( pdn != NULL ) {
214                         ldbm_datum_init( key );
215                         key.dsize = strlen( pdn ) + 2;
216                         key.dptr = ch_malloc( key.dsize );
217                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
218
219                         (void) idl_delete_key( be, db, key, id );
220
221                         free( key.dptr );
222                         free( pdn );
223                 }
224         }
225
226         {
227                 char **subtree = dn_subtree( NULL, dn );
228
229                 if( subtree != NULL ) {
230                         int i;
231                         for( i=0; subtree[i] != NULL; i++ ) {
232                                 ldbm_datum_init( key );
233                                 key.dsize = strlen( subtree[i] ) + 2;
234                                 key.dptr = ch_malloc( key.dsize );
235                                 sprintf( key.dptr, "%c%s",
236                                         DN_SUBTREE_PREFIX, subtree[i] );
237
238                                 (void) idl_delete_key( be, db, key, id );
239
240                                 free( key.dptr );
241                         }
242
243                         charray_free( subtree );
244                 }
245         }
246
247         ldbm_datum_init( key );
248
249         key.dsize = strlen( dn ) + 2;
250         key.dptr = ch_malloc( key.dsize );
251         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
252
253         rc = ldbm_cache_delete( db, key );
254
255         free( key.dptr );
256
257         ldbm_cache_close( be, db );
258
259         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
260         return( rc );
261 }
262
263 /*
264  * dn2entry - look up dn in the cache/indexes and return the corresponding
265  * entry.
266  */
267
268 Entry *
269 dn2entry_rw(
270     Backend     *be,
271     const char  *dn,
272     Entry       **matched,
273     int         rw
274 )
275 {
276         ID              id;
277         Entry           *e = NULL;
278         char            *pdn;
279
280         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
281                 rw ? "w" : "r", dn, 0);
282
283         if( matched != NULL ) {
284                 /* caller cares about match */
285                 *matched = NULL;
286         }
287
288         if ( (id = dn2id( be, dn )) != NOID &&
289                 (e = id2entry_rw( be, id, rw )) != NULL )
290         {
291                 return( e );
292         }
293
294         if ( id != NOID ) {
295                 Debug(LDAP_DEBUG_ANY,
296                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
297                         rw ? "w" : "r", id, dn);
298                 /* must have been deleted from underneath us */
299                 /* treat as if NOID was found */
300         }
301
302         /* caller doesn't care about match */
303         if( matched == NULL ) return NULL;
304
305         /* entry does not exist - see how much of the dn does exist */
306         /* dn_parent checks returns NULL if dn is suffix */
307         if ( (pdn = dn_parent( be, dn )) != NULL ) {
308                 /* get entry with reader lock */
309                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
310                         *matched = e;
311                 }
312                 free( pdn );
313         }
314
315         return NULL;
316 }
317
318 #endif