1*549b59edSchristos /* $NetBSD: tools.c,v 1.2 2021/08/14 16:15:02 christos Exp $ */
2e670fd5cSchristos
3e670fd5cSchristos /* OpenLDAP WiredTiger backend */
4e670fd5cSchristos /* $OpenLDAP$ */
5e670fd5cSchristos /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6e670fd5cSchristos *
7e670fd5cSchristos * Copyright 2002-2021 The OpenLDAP Foundation.
8e670fd5cSchristos * All rights reserved.
9e670fd5cSchristos *
10e670fd5cSchristos * Redistribution and use in source and binary forms, with or without
11e670fd5cSchristos * modification, are permitted only as authorized by the OpenLDAP
12e670fd5cSchristos * Public License.
13e670fd5cSchristos *
14e670fd5cSchristos * A copy of this license is available in the file LICENSE in the
15e670fd5cSchristos * top-level directory of the distribution or, alternatively, at
16e670fd5cSchristos * <http://www.OpenLDAP.org/license.html>.
17e670fd5cSchristos */
18e670fd5cSchristos /* ACKNOWLEDGEMENTS:
19e670fd5cSchristos * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
20e670fd5cSchristos * based on back-bdb for inclusion in OpenLDAP Software.
21e670fd5cSchristos * WiredTiger is a product of MongoDB Inc.
22e670fd5cSchristos */
23e670fd5cSchristos
24e670fd5cSchristos #include <sys/cdefs.h>
25*549b59edSchristos __RCSID("$NetBSD: tools.c,v 1.2 2021/08/14 16:15:02 christos Exp $");
26e670fd5cSchristos
27e670fd5cSchristos #include "portable.h"
28e670fd5cSchristos
29e670fd5cSchristos #include <stdio.h>
30e670fd5cSchristos #include <ac/string.h>
31e670fd5cSchristos #include "back-wt.h"
32e670fd5cSchristos #include "slap-config.h"
33e670fd5cSchristos
34e670fd5cSchristos typedef struct dn_id {
35e670fd5cSchristos ID id;
36e670fd5cSchristos struct berval dn;
37e670fd5cSchristos } dn_id;
38e670fd5cSchristos
39e670fd5cSchristos #define HOLE_SIZE 4096
40e670fd5cSchristos static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
41e670fd5cSchristos static unsigned nhmax = HOLE_SIZE;
42e670fd5cSchristos static unsigned nholes;
43e670fd5cSchristos
44e670fd5cSchristos static int index_nattrs;
45e670fd5cSchristos
46e670fd5cSchristos static struct berval *tool_base;
47e670fd5cSchristos static int tool_scope;
48e670fd5cSchristos static Filter *tool_filter;
49e670fd5cSchristos static Entry *tool_next_entry;
50e670fd5cSchristos
51e670fd5cSchristos static wt_ctx *wc;
52e670fd5cSchristos static WT_CURSOR *reader;
53e670fd5cSchristos static WT_ITEM item;
54e670fd5cSchristos
55e670fd5cSchristos int
wt_tool_entry_open(BackendDB * be,int mode)56e670fd5cSchristos wt_tool_entry_open( BackendDB *be, int mode )
57e670fd5cSchristos {
58e670fd5cSchristos struct wt_info *wi = (struct wt_info *) be->be_private;
59e670fd5cSchristos WT_CONNECTION *conn = wi->wi_conn;
60e670fd5cSchristos int rc;
61e670fd5cSchristos
62e670fd5cSchristos wc = wt_ctx_init(wi);
63e670fd5cSchristos if( !wc ){
64e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
65e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_open)
66e670fd5cSchristos ": wt_ctx_get failed\n" );
67e670fd5cSchristos return -1;
68e670fd5cSchristos }
69e670fd5cSchristos
70e670fd5cSchristos rc = wc->session->open_cursor(wc->session, WT_TABLE_ID2ENTRY"(entry)"
71e670fd5cSchristos ,NULL, NULL, &reader);
72e670fd5cSchristos if ( rc ) {
73e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
74e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_open)
75e670fd5cSchristos ": cursor open failed: %s (%d)\n",
76e670fd5cSchristos wiredtiger_strerror(rc), rc );
77e670fd5cSchristos return -1;
78e670fd5cSchristos }
79e670fd5cSchristos
80e670fd5cSchristos return 0;
81e670fd5cSchristos }
82e670fd5cSchristos
83e670fd5cSchristos int
wt_tool_entry_close(BackendDB * be)84e670fd5cSchristos wt_tool_entry_close( BackendDB *be )
85e670fd5cSchristos {
86e670fd5cSchristos int rc;
87e670fd5cSchristos
88e670fd5cSchristos if( reader ) {
89e670fd5cSchristos reader->close(reader);
90e670fd5cSchristos reader = NULL;
91e670fd5cSchristos }
92e670fd5cSchristos
93e670fd5cSchristos wt_ctx_free(NULL, wc);
94e670fd5cSchristos
95e670fd5cSchristos if( nholes ) {
96e670fd5cSchristos unsigned i;
97e670fd5cSchristos fprintf( stderr, "Error, entries missing!\n");
98e670fd5cSchristos for (i=0; i<nholes; i++) {
99e670fd5cSchristos fprintf(stderr, " entry %ld: %s\n",
100e670fd5cSchristos holes[i].id, holes[i].dn.bv_val);
101e670fd5cSchristos }
102e670fd5cSchristos return -1;
103e670fd5cSchristos }
104e670fd5cSchristos
105e670fd5cSchristos return 0;
106e670fd5cSchristos }
107e670fd5cSchristos
108e670fd5cSchristos ID
wt_tool_entry_first_x(BackendDB * be,struct berval * base,int scope,Filter * f)109e670fd5cSchristos wt_tool_entry_first_x( BackendDB *be,
110e670fd5cSchristos struct berval *base,
111e670fd5cSchristos int scope,
112e670fd5cSchristos Filter *f )
113e670fd5cSchristos {
114e670fd5cSchristos tool_base = base;
115e670fd5cSchristos tool_scope = scope;
116e670fd5cSchristos tool_filter = f;
117e670fd5cSchristos
118e670fd5cSchristos return wt_tool_entry_next( be );
119e670fd5cSchristos }
120e670fd5cSchristos
121e670fd5cSchristos ID
wt_tool_entry_next(BackendDB * be)122e670fd5cSchristos wt_tool_entry_next( BackendDB *be )
123e670fd5cSchristos {
124e670fd5cSchristos int rc;
125e670fd5cSchristos ID id;
126e670fd5cSchristos
127e670fd5cSchristos rc = reader->next(reader);
128e670fd5cSchristos switch( rc ){
129e670fd5cSchristos case 0:
130e670fd5cSchristos break;
131e670fd5cSchristos case WT_NOTFOUND:
132e670fd5cSchristos return NOID;
133e670fd5cSchristos default:
134e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
135e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_next)
136e670fd5cSchristos ": next failed: %s (%d)\n",
137e670fd5cSchristos wiredtiger_strerror(rc), rc );
138e670fd5cSchristos return NOID;
139e670fd5cSchristos }
140e670fd5cSchristos
141e670fd5cSchristos rc = reader->get_key(reader, &id);
142e670fd5cSchristos if( rc ){
143e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
144e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_next)
145e670fd5cSchristos ": get_key failed: %s (%d)\n",
146e670fd5cSchristos wiredtiger_strerror(rc), rc );
147e670fd5cSchristos }
148e670fd5cSchristos
149e670fd5cSchristos rc = reader->get_value(reader, &item);
150e670fd5cSchristos if( rc ){
151e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
152e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_next)
153e670fd5cSchristos ": get_value failed: %s (%d)\n",
154e670fd5cSchristos wiredtiger_strerror(rc), rc );
155e670fd5cSchristos }
156e670fd5cSchristos return id;
157e670fd5cSchristos }
158e670fd5cSchristos
159e670fd5cSchristos static ber_len_t
entry_getlen(unsigned char ** buf)160e670fd5cSchristos entry_getlen(unsigned char **buf)
161e670fd5cSchristos {
162e670fd5cSchristos ber_len_t len;
163e670fd5cSchristos int i;
164e670fd5cSchristos
165e670fd5cSchristos len = *(*buf)++;
166e670fd5cSchristos if (len <= 0x7f)
167e670fd5cSchristos return len;
168e670fd5cSchristos i = len & 0x7f;
169e670fd5cSchristos len = 0;
170e670fd5cSchristos for (;i > 0; i--) {
171e670fd5cSchristos len <<= 8;
172e670fd5cSchristos len |= *(*buf)++;
173e670fd5cSchristos }
174e670fd5cSchristos return len;
175e670fd5cSchristos }
176e670fd5cSchristos
wt_entry_header(WT_ITEM * item,EntryHeader * eh)177e670fd5cSchristos int wt_entry_header(WT_ITEM *item, EntryHeader *eh){
178e670fd5cSchristos unsigned char *ptr = (unsigned char *)item->data;
179e670fd5cSchristos
180e670fd5cSchristos /* Some overlays can create empty entries
181e670fd5cSchristos * so don't check for zeros here.
182e670fd5cSchristos */
183e670fd5cSchristos eh->nattrs = entry_getlen(&ptr);
184e670fd5cSchristos eh->nvals = entry_getlen(&ptr);
185e670fd5cSchristos eh->data = (char *)ptr;
186e670fd5cSchristos return LDAP_SUCCESS;
187e670fd5cSchristos }
188e670fd5cSchristos
189e670fd5cSchristos Entry *
wt_tool_entry_get(BackendDB * be,ID id)190e670fd5cSchristos wt_tool_entry_get( BackendDB *be, ID id )
191e670fd5cSchristos {
192e670fd5cSchristos Entry *e = NULL;
193e670fd5cSchristos static EntryHeader eh;
194e670fd5cSchristos int rc, eoff;
195e670fd5cSchristos
196e670fd5cSchristos assert( be != NULL );
197e670fd5cSchristos assert( slapMode & SLAP_TOOL_MODE );
198e670fd5cSchristos
199e670fd5cSchristos rc = wt_entry_header( &item, &eh );
200e670fd5cSchristos assert( rc == 0 );
201e670fd5cSchristos eoff = eh.data - (char *)item.data;
202e670fd5cSchristos
203e670fd5cSchristos eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + item.size;
204e670fd5cSchristos eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len );
205e670fd5cSchristos memset(eh.bv.bv_val, 0xff, eh.bv.bv_len);
206e670fd5cSchristos eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
207e670fd5cSchristos memcpy(eh.data, item.data, item.size);
208e670fd5cSchristos eh.data += eoff;
209e670fd5cSchristos
210e670fd5cSchristos rc = entry_decode( &eh, &e );
211e670fd5cSchristos assert( rc == 0 );
212e670fd5cSchristos
213e670fd5cSchristos if( rc == LDAP_SUCCESS ) {
214e670fd5cSchristos e->e_id = id;
215e670fd5cSchristos }
216e670fd5cSchristos
217e670fd5cSchristos return e;
218e670fd5cSchristos }
219e670fd5cSchristos
wt_tool_next_id(Operation * op,Entry * e,struct berval * text,int hole)220e670fd5cSchristos static int wt_tool_next_id(
221e670fd5cSchristos Operation *op,
222e670fd5cSchristos Entry *e,
223e670fd5cSchristos struct berval *text,
224e670fd5cSchristos int hole )
225e670fd5cSchristos {
226e670fd5cSchristos struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
227e670fd5cSchristos struct berval dn = e->e_name;
228e670fd5cSchristos struct berval ndn = e->e_nname;
229e670fd5cSchristos struct berval pdn, npdn;
230e670fd5cSchristos int rc;
231e670fd5cSchristos ID id = 0;
232e670fd5cSchristos ID pid = 0;
233e670fd5cSchristos
234e670fd5cSchristos if(ndn.bv_len == 0){
235e670fd5cSchristos e->e_id = 0;
236e670fd5cSchristos return 0;
237e670fd5cSchristos }
238e670fd5cSchristos
239e670fd5cSchristos rc = wt_dn2id(op, wc->session, &ndn, &id);
240e670fd5cSchristos if(rc == 0){
241e670fd5cSchristos e->e_id = id;
242e670fd5cSchristos }else if( rc == WT_NOTFOUND ){
243e670fd5cSchristos if ( !be_issuffix( op->o_bd, &ndn ) ) {
244e670fd5cSchristos ID eid = e->e_id;
245e670fd5cSchristos dnParent( &dn, &pdn );
246e670fd5cSchristos dnParent( &ndn, &npdn );
247e670fd5cSchristos e->e_name = pdn;
248e670fd5cSchristos e->e_nname = npdn;
249e670fd5cSchristos rc = wt_tool_next_id( op, e, text, 1 );
250e670fd5cSchristos e->e_name = dn;
251e670fd5cSchristos e->e_nname = ndn;
252e670fd5cSchristos if ( rc ) {
253e670fd5cSchristos return rc;
254e670fd5cSchristos }
255e670fd5cSchristos /* If parent didn't exist, it was created just now
256e670fd5cSchristos * and its ID is now in e->e_id. Make sure the current
257e670fd5cSchristos * entry gets added under the new parent ID.
258e670fd5cSchristos */
259e670fd5cSchristos if ( eid != e->e_id ) {
260e670fd5cSchristos pid = e->e_id;
261e670fd5cSchristos }
262e670fd5cSchristos }else{
263e670fd5cSchristos pid = id;
264e670fd5cSchristos }
265e670fd5cSchristos wt_next_id( op->o_bd, &e->e_id );
266e670fd5cSchristos rc = wt_dn2id_add(op, wc->session, pid, e);
267e670fd5cSchristos if( rc ){
268e670fd5cSchristos snprintf( text->bv_val, text->bv_len,
269e670fd5cSchristos "wt_dn2id_add failed: %s (%d)",
270e670fd5cSchristos wiredtiger_strerror(rc), rc );
271e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
272e670fd5cSchristos "=> wt_tool_next_id: %s\n", text->bv_val );
273e670fd5cSchristos }
274e670fd5cSchristos
275e670fd5cSchristos }else if ( !hole ) {
276e670fd5cSchristos unsigned i, j;
277e670fd5cSchristos e->e_id = id;
278e670fd5cSchristos
279e670fd5cSchristos for ( i=0; i<nholes; i++) {
280e670fd5cSchristos if ( holes[i].id == e->e_id ) {
281e670fd5cSchristos free(holes[i].dn.bv_val);
282e670fd5cSchristos for (j=i;j<nholes;j++) holes[j] = holes[j+1];
283e670fd5cSchristos holes[j].id = 0;
284e670fd5cSchristos nholes--;
285e670fd5cSchristos break;
286e670fd5cSchristos } else if ( holes[i].id > e->e_id ) {
287e670fd5cSchristos break;
288e670fd5cSchristos }
289e670fd5cSchristos }
290e670fd5cSchristos }
291e670fd5cSchristos return rc;
292e670fd5cSchristos }
293e670fd5cSchristos
294e670fd5cSchristos static int
wt_tool_index_add(Operation * op,wt_ctx * wc,Entry * e)295e670fd5cSchristos wt_tool_index_add(
296e670fd5cSchristos Operation *op,
297e670fd5cSchristos wt_ctx *wc,
298e670fd5cSchristos Entry *e )
299e670fd5cSchristos {
300e670fd5cSchristos return wt_index_entry_add( op, wc, e );
301e670fd5cSchristos }
302e670fd5cSchristos
303e670fd5cSchristos ID
wt_tool_entry_put(BackendDB * be,Entry * e,struct berval * text)304e670fd5cSchristos wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
305e670fd5cSchristos {
306e670fd5cSchristos struct wt_info *wi = (struct wt_info *) be->be_private;
307e670fd5cSchristos int rc;
308e670fd5cSchristos
309e670fd5cSchristos Operation op = {0};
310e670fd5cSchristos Opheader ohdr = {0};
311e670fd5cSchristos
312e670fd5cSchristos assert( slapMode & SLAP_TOOL_MODE );
313e670fd5cSchristos assert( text != NULL );
314e670fd5cSchristos assert( text->bv_val != NULL );
315e670fd5cSchristos assert( text->bv_val[0] == '\0' ); /* overconservative? */
316e670fd5cSchristos
317e670fd5cSchristos Debug( LDAP_DEBUG_TRACE,
318e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_put)
319e670fd5cSchristos ": ( \"%s\" )\n", e->e_dn );
320e670fd5cSchristos
321e670fd5cSchristos rc = wc->session->begin_transaction(wc->session, NULL);
322e670fd5cSchristos if( rc ){
323e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
324e670fd5cSchristos LDAP_XSTRING(wt_dn2id_add)
325e670fd5cSchristos ": begin_transaction failed: %s (%d)\n",
326e670fd5cSchristos wiredtiger_strerror(rc), rc );
327e670fd5cSchristos return NOID;
328e670fd5cSchristos }
329e670fd5cSchristos
330e670fd5cSchristos op.o_hdr = &ohdr;
331e670fd5cSchristos op.o_bd = be;
332e670fd5cSchristos op.o_tmpmemctx = NULL;
333e670fd5cSchristos op.o_tmpmfuncs = &ch_mfuncs;
334e670fd5cSchristos
335e670fd5cSchristos rc = wt_tool_next_id( &op, e, text, 0 );
336e670fd5cSchristos if( rc != 0 ) {
337e670fd5cSchristos snprintf( text->bv_val, text->bv_len,
338e670fd5cSchristos "wt_tool_next_id failed: %s (%d)",
339e670fd5cSchristos wiredtiger_strerror(rc), rc );
340e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
341e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
342e670fd5cSchristos text->bv_val );
343e670fd5cSchristos goto done;
344e670fd5cSchristos }
345e670fd5cSchristos
346e670fd5cSchristos rc = wt_id2entry_add( &op, wc->session, e );
347e670fd5cSchristos if( rc != 0 ) {
348e670fd5cSchristos snprintf( text->bv_val, text->bv_len,
349e670fd5cSchristos "id2entry_add failed: %s (%d)",
350e670fd5cSchristos wiredtiger_strerror(rc), rc );
351e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
352e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
353e670fd5cSchristos text->bv_val );
354e670fd5cSchristos goto done;
355e670fd5cSchristos }
356e670fd5cSchristos
357e670fd5cSchristos rc = wt_tool_index_add( &op, wc, e );
358e670fd5cSchristos if( rc != 0 ) {
359e670fd5cSchristos snprintf( text->bv_val, text->bv_len,
360e670fd5cSchristos "index_entry_add failed: %s (%d)",
361e670fd5cSchristos rc == LDAP_OTHER ? "Internal error" :
362e670fd5cSchristos wiredtiger_strerror(rc), rc );
363e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
364e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
365e670fd5cSchristos text->bv_val );
366e670fd5cSchristos goto done;
367e670fd5cSchristos }
368e670fd5cSchristos
369e670fd5cSchristos done:
370e670fd5cSchristos if ( rc == 0 ){
371e670fd5cSchristos rc = wc->session->commit_transaction(wc->session, NULL);
372e670fd5cSchristos if( rc != 0 ) {
373e670fd5cSchristos snprintf( text->bv_val, text->bv_len,
374e670fd5cSchristos "txn_commit failed: %s (%d)",
375e670fd5cSchristos wiredtiger_strerror(rc), rc );
376e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
377e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
378e670fd5cSchristos text->bv_val );
379e670fd5cSchristos e->e_id = NOID;
380e670fd5cSchristos }
381e670fd5cSchristos }else{
382e670fd5cSchristos rc = wc->session->rollback_transaction(wc->session, NULL);
383e670fd5cSchristos snprintf( text->bv_val, text->bv_len,
384e670fd5cSchristos "txn_aborted! %s (%d)",
385e670fd5cSchristos rc == LDAP_OTHER ? "Internal error" :
386e670fd5cSchristos wiredtiger_strerror(rc), rc );
387e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
388e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
389e670fd5cSchristos text->bv_val );
390e670fd5cSchristos e->e_id = NOID;
391e670fd5cSchristos }
392e670fd5cSchristos
393e670fd5cSchristos return e->e_id;
394e670fd5cSchristos }
395e670fd5cSchristos
wt_tool_entry_reindex(BackendDB * be,ID id,AttributeDescription ** adv)396e670fd5cSchristos int wt_tool_entry_reindex(
397e670fd5cSchristos BackendDB *be,
398e670fd5cSchristos ID id,
399e670fd5cSchristos AttributeDescription **adv )
400e670fd5cSchristos {
401e670fd5cSchristos struct wt_info *wi = (struct wt_info *) be->be_private;
402e670fd5cSchristos int rc;
403e670fd5cSchristos Entry *e;
404e670fd5cSchristos Operation op = {0};
405e670fd5cSchristos Opheader ohdr = {0};
406e670fd5cSchristos
407e670fd5cSchristos Debug( LDAP_DEBUG_ARGS,
408e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld )\n",
409e670fd5cSchristos (long) id );
410e670fd5cSchristos assert( tool_base == NULL );
411e670fd5cSchristos assert( tool_filter == NULL );
412e670fd5cSchristos
413e670fd5cSchristos /* No indexes configured, nothing to do. Could return an
414e670fd5cSchristos * error here to shortcut things.
415e670fd5cSchristos */
416e670fd5cSchristos if (!wi->wi_attrs) {
417e670fd5cSchristos return 0;
418e670fd5cSchristos }
419e670fd5cSchristos
420e670fd5cSchristos /* Check for explicit list of attrs to index */
421e670fd5cSchristos if ( adv ) {
422e670fd5cSchristos int i, j, n;
423e670fd5cSchristos
424e670fd5cSchristos if ( wi->wi_attrs[0]->ai_desc != adv[0] ) {
425e670fd5cSchristos /* count */
426e670fd5cSchristos for ( n = 0; adv[n]; n++ ) ;
427e670fd5cSchristos
428e670fd5cSchristos /* insertion sort */
429e670fd5cSchristos for ( i = 0; i < n; i++ ) {
430e670fd5cSchristos AttributeDescription *ad = adv[i];
431e670fd5cSchristos for ( j = i-1; j>=0; j--) {
432e670fd5cSchristos if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break;
433e670fd5cSchristos adv[j+1] = adv[j];
434e670fd5cSchristos }
435e670fd5cSchristos adv[j+1] = ad;
436e670fd5cSchristos }
437e670fd5cSchristos }
438e670fd5cSchristos
439e670fd5cSchristos for ( i = 0; adv[i]; i++ ) {
440e670fd5cSchristos if ( wi->wi_attrs[i]->ai_desc != adv[i] ) {
441e670fd5cSchristos for ( j = i+1; j < wi->wi_nattrs; j++ ) {
442e670fd5cSchristos if ( wi->wi_attrs[j]->ai_desc == adv[i] ) {
443e670fd5cSchristos AttrInfo *ai = wi->wi_attrs[i];
444e670fd5cSchristos wi->wi_attrs[i] = wi->wi_attrs[j];
445e670fd5cSchristos wi->wi_attrs[j] = ai;
446e670fd5cSchristos break;
447e670fd5cSchristos }
448e670fd5cSchristos }
449e670fd5cSchristos if ( j == wi->wi_nattrs ) {
450e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
451e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_reindex)
452e670fd5cSchristos ": no index configured for %s\n",
453e670fd5cSchristos adv[i]->ad_cname.bv_val );
454e670fd5cSchristos return -1;
455e670fd5cSchristos }
456e670fd5cSchristos }
457e670fd5cSchristos }
458e670fd5cSchristos wi->wi_nattrs = i;
459e670fd5cSchristos }
460e670fd5cSchristos
461e670fd5cSchristos e = wt_tool_entry_get( be, id );
462e670fd5cSchristos
463e670fd5cSchristos if( e == NULL ) {
464e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
465e670fd5cSchristos LDAP_XSTRING(wt_tool_entry_reindex)
466e670fd5cSchristos ": could not locate id=%ld\n",
467e670fd5cSchristos (long) id );
468e670fd5cSchristos return -1;
469e670fd5cSchristos }
470e670fd5cSchristos
471e670fd5cSchristos op.o_hdr = &ohdr;
472e670fd5cSchristos op.o_bd = be;
473e670fd5cSchristos op.o_tmpmemctx = NULL;
474e670fd5cSchristos op.o_tmpmfuncs = &ch_mfuncs;
475e670fd5cSchristos
476e670fd5cSchristos rc = wc->session->begin_transaction(wc->session, NULL);
477e670fd5cSchristos if( rc ){
478e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
479e670fd5cSchristos LDAP_XSTRING(wt_dn2id_add)
480e670fd5cSchristos ": begin_transaction failed: %s (%d)\n",
481e670fd5cSchristos wiredtiger_strerror(rc), rc );
482e670fd5cSchristos goto done;
483e670fd5cSchristos }
484e670fd5cSchristos Debug( LDAP_DEBUG_TRACE,
485e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld, \"%s\" )\n",
486e670fd5cSchristos (long) id, e->e_dn );
487e670fd5cSchristos
488e670fd5cSchristos rc = wt_tool_index_add( &op, wc, e );
489e670fd5cSchristos
490e670fd5cSchristos done:
491e670fd5cSchristos if ( rc == 0 ){
492e670fd5cSchristos rc = wc->session->commit_transaction(wc->session, NULL);
493e670fd5cSchristos if( rc ) {
494e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
495e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_reindex)
496e670fd5cSchristos "commit_transaction failed: %s (%d)\n",
497e670fd5cSchristos wiredtiger_strerror(rc), rc );
498e670fd5cSchristos }
499e670fd5cSchristos }else{
500e670fd5cSchristos rc = wc->session->rollback_transaction(wc->session, NULL);
501e670fd5cSchristos Debug( LDAP_DEBUG_ANY,
502e670fd5cSchristos "=> " LDAP_XSTRING(wt_tool_entry_reindex)
503e670fd5cSchristos ": rollback transaction %s (%d)\n",
504e670fd5cSchristos wiredtiger_strerror(rc), rc );
505e670fd5cSchristos }
506e670fd5cSchristos
507e670fd5cSchristos wt_entry_release( &op, e, 0 );
508e670fd5cSchristos
509e670fd5cSchristos return rc;
510e670fd5cSchristos }
511e670fd5cSchristos
512e670fd5cSchristos /*
513e670fd5cSchristos * Local variables:
514e670fd5cSchristos * indent-tabs-mode: t
515e670fd5cSchristos * tab-width: 4
516e670fd5cSchristos * c-basic-offset: 4
517e670fd5cSchristos * End:
518e670fd5cSchristos */
519