]> git.sur5r.net Git - openldap/blob - servers/slapd/back-wt/dn2id.c
994d4bfe299ecf3188cf39c0b0478aee219531df
[openldap] / servers / slapd / back-wt / dn2id.c
1 /* OpenLDAP WiredTiger backend */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2002-2017 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
18  * based on back-bdb for inclusion in OpenLDAP Software.
19  * WiredTiger is a product of MongoDB Inc.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25 #include "back-wt.h"
26 #include "config.h"
27 #include "idl.h"
28
29 char *
30 mkrevdn(struct berval src){
31         char *dst, *p;
32         char *rdn;
33         size_t rdn_len;
34
35         p = dst = ch_malloc(src.bv_len + 2);
36         while(src.bv_len){
37                 rdn = ber_bvrchr( &src, ',' );
38                 if (rdn) {
39                         rdn_len = src.bv_len;
40                         src.bv_len = rdn - src.bv_val;
41                         rdn_len -= src.bv_len + 1;
42                         rdn++;
43                 }else{
44                         /* first rdn */
45                         rdn_len = src.bv_len;
46                         rdn = src.bv_val;
47                         src.bv_len = 0;
48                 }
49                 AC_MEMCPY( p, rdn, rdn_len );
50                 p += rdn_len;
51                 *p++ = ',';
52         }
53         *p = '\0';
54         return dst;
55 }
56
57 int
58 wt_dn2id_add(
59         Operation *op,
60         WT_SESSION *session,
61         ID pid,
62         Entry *e)
63 {
64         int rc;
65         WT_CURSOR *cursor = NULL;
66         char *revdn = NULL;
67
68         Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_add 0x%lx: \"%s\"\n",
69                    e->e_id, e->e_ndn, 0 );
70         assert( e->e_id != NOID );
71
72         /* make reverse dn */
73         revdn = mkrevdn(e->e_nname);
74
75         rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
76                                                           NULL, &cursor);
77         if(rc){
78                 Debug( LDAP_DEBUG_ANY,
79                            LDAP_XSTRING(wt_dn2id_add)
80                            ": open_cursor failed: %s (%d)\n",
81                            wiredtiger_strerror(rc), rc, 0 );
82                 goto done;
83     }
84         cursor->set_key(cursor, e->e_ndn);
85         cursor->set_value(cursor, e->e_id, pid, revdn);
86         rc = cursor->insert(cursor);
87         if(rc){
88                 Debug( LDAP_DEBUG_ANY,
89                            LDAP_XSTRING(wt_dn2id_add)
90                            ": insert failed: %s (%d)\n",
91                            wiredtiger_strerror(rc), rc, 0 );
92                 goto done;
93     }
94
95 done:
96         if(revdn){
97                 ch_free(revdn);
98         }
99         if(cursor){
100                 cursor->close(cursor);
101         }
102         Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 );
103         return rc;
104 }
105
106 int
107 wt_dn2id_delete(
108         Operation *op,
109         WT_SESSION *session,
110         struct berval *ndn)
111 {
112         int rc = 0;
113         WT_CURSOR *cursor = NULL;
114
115         Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_delete %s\n", ndn->bv_val, 0, 0 );
116
117         rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
118                                                           NULL, &cursor);
119         if ( rc ) {
120                 Debug( LDAP_DEBUG_ANY,
121                            LDAP_XSTRING(wt_dn2id_delete)
122                            ": open_cursor failed: %s (%d)\n",
123                            wiredtiger_strerror(rc), rc, 0 );
124                 goto done;
125         }
126
127         cursor->set_key(cursor, ndn->bv_val);
128         rc = cursor->remove(cursor);
129         if ( rc ) {
130                 Debug( LDAP_DEBUG_ANY,
131                            LDAP_XSTRING(wt_dn2id_delete)
132                            ": remove failed: %s (%d)\n",
133                            wiredtiger_strerror(rc), rc, 0 );
134                 goto done;
135         }
136
137         Debug( LDAP_DEBUG_TRACE,
138                    "<= wt_dn2id_delete %s: %d\n",
139                    ndn->bv_val, rc, 0 );
140 done:
141         if(cursor){
142                 cursor->close(cursor);
143         }
144         return rc;
145 }
146
147 int
148 wt_dn2id(
149         Operation *op,
150         WT_SESSION *session,
151     struct berval *ndn,
152     ID *id)
153 {
154         WT_CURSOR *cursor = NULL;
155         struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
156         int rc;
157         ID nid;
158
159         Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n",
160                    ndn->bv_val, 0, 0 );
161
162         if ( ndn->bv_len == 0 ) {
163                 *id = 0;
164                 goto done;
165         }
166
167         rc = session->open_cursor(session, WT_TABLE_DN2ID
168                                                           "(id)",
169                               NULL, NULL, &cursor);
170         if( rc ){
171                 Debug( LDAP_DEBUG_ANY,
172                            LDAP_XSTRING(wt_dn2id)
173                            ": cursor open failed: %s (%d)\n",
174                            wiredtiger_strerror(rc), rc, 0 );
175                 goto done;
176         }
177
178         cursor->set_key(cursor, ndn->bv_val);
179         rc = cursor->search(cursor);
180         switch( rc ){
181         case 0:
182                 break;
183         case WT_NOTFOUND:
184                 goto done;
185         default:
186                 Debug( LDAP_DEBUG_ANY,
187                            LDAP_XSTRING(wt_dn2id)
188                            ": search failed: %s (%d)\n",
189                            wiredtiger_strerror(rc), rc, 0 );
190                 goto done;
191         }
192         rc = cursor->get_value(cursor, id);
193         if( rc ){
194                 Debug( LDAP_DEBUG_ANY,
195                            LDAP_XSTRING(wt_dn2id)
196                            ": get_value failed: %s (%d)\n",
197                            wiredtiger_strerror(rc), rc, 0 );
198                 goto done;
199         }
200
201 done:
202         if(cursor){
203                 cursor->close(cursor);
204         }
205
206         if( rc ) {
207                 Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: get failed: %s (%d)\n",
208                            wiredtiger_strerror(rc), rc, 0 );
209         } else {
210                 Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: got id=0x%lx\n",
211                            *id, 0, 0 );
212         }
213
214         return rc;
215 }
216
217 int
218 wt_dn2id_has_children(
219         Operation *op,
220         WT_SESSION *session,
221         ID id )
222 {
223         struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
224         WT_CURSOR *cursor = NULL;
225         int rc;
226         uint64_t key = id;
227
228         rc = session->open_cursor(session, WT_INDEX_PID,
229                               NULL, NULL, &cursor);
230         if( rc ){
231                 Debug( LDAP_DEBUG_ANY,
232                            LDAP_XSTRING(wt_dn2id_has_children)
233                            ": cursor open failed: %s (%d)\n",
234                            wiredtiger_strerror(rc), rc, 0 );
235                 goto done;
236         }
237
238         cursor->set_key(cursor, key);
239         rc = cursor->search(cursor);
240
241 done:
242         if(cursor){
243                 cursor->close(cursor);
244         }
245
246         return rc;
247 }
248
249 int
250 wt_dn2idl(
251         Operation *op,
252         WT_SESSION *session,
253         struct berval *ndn,
254         Entry *e,
255         ID *ids,
256         ID *stack)
257 {
258         struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
259         WT_CURSOR *cursor = NULL;
260         int exact = 0;
261         int rc;
262         char *revdn = NULL;
263         size_t revdn_len;
264         char *key;
265         ID id, pid;
266
267         Debug( LDAP_DEBUG_TRACE,
268                    "=> wt_dn2idl(\"%s\")\n",
269                    ndn->bv_val, 0, 0 );
270
271         if(op->ors_scope != LDAP_SCOPE_ONELEVEL &&
272            be_issuffix( op->o_bd, &e->e_nname )){
273                 WT_IDL_ALL(wi, ids);
274                 return 0;
275         }
276
277         revdn = mkrevdn(*ndn);
278         revdn_len = strlen(revdn);
279         rc = session->open_cursor(session, WT_INDEX_REVDN"(id, pid)",
280                               NULL, NULL, &cursor);
281         if( rc ){
282                 Debug( LDAP_DEBUG_ANY,
283                            LDAP_XSTRING(wt_dn2idl)
284                            ": cursor open failed: %s (%d)\n",
285                            wiredtiger_strerror(rc), rc, 0 );
286                 goto done;
287         }
288         cursor->set_key(cursor, revdn);
289         rc = cursor->search_near(cursor, &exact);
290         if( rc ){
291                 Debug( LDAP_DEBUG_ANY,
292                            LDAP_XSTRING(wt_dn2idl)
293                            ": search failed: %s (%d)\n",
294                            wiredtiger_strerror(rc), rc, 0 );
295                 goto done;
296         }
297
298         do {
299                 rc = cursor->get_key(cursor, &key);
300                 if( rc ){
301                         Debug( LDAP_DEBUG_ANY,
302                                    LDAP_XSTRING(wt_dn2idl)
303                                    ": get_key failed: %s (%d)\n",
304                                    wiredtiger_strerror(rc), rc, 0 );
305                         goto done;
306                 }
307
308                 if( strncmp(revdn, key, revdn_len) ){
309                         if(exact < 0){
310                                 rc = cursor->next(cursor);
311                                 if (rc) {
312                                         break;
313                                 }else{
314                                         continue;
315                                 }
316                         }
317                         break;
318                 }
319                 exact = 0;
320                 rc = cursor->get_value(cursor, &id, &pid);
321                 if( rc ){
322                         Debug( LDAP_DEBUG_ANY,
323                                    LDAP_XSTRING(wt_dn2id)
324                                    ": get_value failed: %s (%d)\n",
325                                    wiredtiger_strerror(rc), rc, 0 );
326                         goto done;
327                 }
328                 if( op->ors_scope == LDAP_SCOPE_ONELEVEL &&
329                         e->e_id != pid){
330                         rc = cursor->next(cursor);
331                         if ( rc ) {
332                                 break;
333                         }
334                         continue;
335                 }else{
336                         wt_idl_append_one(ids, id);
337                 }
338                 rc = cursor->next(cursor);
339         }while(rc == 0);
340
341         if (rc == WT_NOTFOUND ) {
342                 rc = LDAP_SUCCESS;
343         }
344
345 done:
346         if(revdn){
347                 ch_free(revdn);
348         }
349         if(cursor){
350                 cursor->close(cursor);
351         }
352         return rc;
353 }
354
355 #if 0
356 int
357 wt_dn2id(
358         Operation *op,
359         WT_SESSION *session,
360     struct berval *dn,
361     ID *id)
362 {
363         struct wt_info *wi = (struct wy_info *) op->o_bd->be_private;
364         WT_CURSOR *cursor = NULL;
365         int rc;
366         Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n", dn->bv_val, 0, 0 );
367
368         rc = session->open_cursor(session, WT_INDEX_DN"(id)",
369                               NULL, NULL, &cursor);
370         if( rc ){
371                 Debug( LDAP_DEBUG_ANY,
372                            LDAP_XSTRING(wt_dn2id)
373                            ": cursor open failed: %s (%d)\n",
374                            wiredtiger_strerror(rc), rc, 0 );
375                 return rc;
376         }
377         cursor->set_key(cursor, dn->bv_val);
378         rc = cursor->search(cursor);
379         if( !rc ){
380                 cursor->get_key(cursor, &id);
381         }
382         cursor->close(cursor);
383         return rc;
384 }
385 #endif
386
387 /*
388  * Local variables:
389  * indent-tabs-mode: t
390  * tab-width: 4
391  * c-basic-offset: 4
392  * End:
393  */