1/*	$NetBSD: id2entry.c,v 1.2 2021/08/14 16:15:02 christos Exp $	*/
2
3/* OpenLDAP WiredTiger backend */
4/* $OpenLDAP$ */
5/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2002-2021 The OpenLDAP Foundation.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
12 * Public License.
13 *
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
17 */
18/* ACKNOWLEDGEMENTS:
19 * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
20 * based on back-bdb for inclusion in OpenLDAP Software.
21 * WiredTiger is a product of MongoDB Inc.
22 */
23
24#include "back-wt.h"
25#include "slap-config.h"
26
27static int wt_id2entry_put(
28	Operation *op,
29	WT_SESSION *session,
30	Entry *e,
31	const char *config )
32{
33	struct berval bv;
34	WT_CURSOR *cursor = NULL;
35	WT_ITEM item;
36	int rc;
37
38	rc = entry_encode( e, &bv );
39	if(rc != LDAP_SUCCESS){
40		return -1;
41	}
42	item.size = bv.bv_len;
43	item.data = bv.bv_val;
44
45	rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
46							  config, &cursor);
47	if ( rc ) {
48		Debug( LDAP_DEBUG_ANY,
49			   LDAP_XSTRING(wt_id2entry_put)
50			   ": open_cursor failed: %s (%d)\n",
51			   wiredtiger_strerror(rc), rc );
52		goto done;
53	}
54	cursor->set_key(cursor, e->e_id);
55	cursor->set_value(cursor, e->e_ndn, &item);
56	rc = cursor->insert(cursor);
57	if ( rc ) {
58		Debug( LDAP_DEBUG_ANY,
59			   LDAP_XSTRING(wt_id2entry_put)
60			   ": insert failed: %s (%d)\n",
61			   wiredtiger_strerror(rc), rc );
62		goto done;
63	}
64
65done:
66	ch_free( bv.bv_val );
67	if(cursor){
68		cursor->close(cursor);
69	}
70	return rc;
71}
72
73int wt_id2entry_add(
74	Operation *op,
75	WT_SESSION *session,
76	Entry *e )
77{
78	return wt_id2entry_put(op, session, e, "overwrite=false");
79}
80
81int wt_id2entry_update(
82	Operation *op,
83	WT_SESSION *session,
84	Entry *e )
85{
86	return wt_id2entry_put(op, session, e, "overwrite=true");
87}
88
89int wt_id2entry_delete(
90	Operation *op,
91	WT_SESSION *session,
92	Entry *e )
93{
94	int rc;
95	WT_CURSOR *cursor = NULL;
96	rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
97							  NULL, &cursor);
98	if ( rc ) {
99		Debug( LDAP_DEBUG_ANY,
100			   LDAP_XSTRING(wt_id2entry_delete)
101			   ": open_cursor failed: %s (%d)\n",
102			   wiredtiger_strerror(rc), rc );
103		goto done;
104	}
105	cursor->set_key(cursor, e->e_id);
106	rc = cursor->remove(cursor);
107	if ( rc ) {
108		Debug( LDAP_DEBUG_ANY,
109			   LDAP_XSTRING(wt_id2entry_delete)
110			   ": remove failed: %s (%d)\n",
111			   wiredtiger_strerror(rc), rc );
112		goto done;
113	}
114
115done:
116	if(cursor){
117		cursor->close(cursor);
118	}
119	return rc;
120}
121
122int wt_id2entry( BackendDB *be,
123				 WT_SESSION *session,
124				 ID id,
125				 Entry **ep ){
126	int rc;
127	WT_CURSOR *cursor = NULL;
128	WT_ITEM item;
129	EntryHeader eh;
130	int eoff;
131	Entry *e = NULL;
132
133	rc = session->open_cursor(session, WT_TABLE_ID2ENTRY"(entry)", NULL,
134							  NULL, &cursor);
135	if ( rc ) {
136		Debug( LDAP_DEBUG_ANY,
137			   LDAP_XSTRING(wt_id2entry)
138			   ": open_cursor failed: %s (%d)\n",
139			   wiredtiger_strerror(rc), rc );
140		goto done;
141	}
142
143	cursor->set_key(cursor, id);
144	rc = cursor->search(cursor);
145	if ( rc ) {
146		goto done;
147	}
148
149	cursor->get_value(cursor, &item);
150	rc = wt_entry_header( &item,  &eh );
151	eoff = eh.data - (char *)item.data;
152	eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + item.size;
153	eh.bv.bv_val = ch_malloc( eh.bv.bv_len );
154	memset(eh.bv.bv_val, 0xff, eh.bv.bv_len);
155	eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
156	memcpy(eh.data, item.data, item.size);
157	eh.data += eoff;
158	rc = entry_decode( &eh, &e );
159	if ( rc ) {
160		Debug( LDAP_DEBUG_ANY,
161			   LDAP_XSTRING(wt_id2entry)
162			   ": entry decode error: %d\n",
163			   rc );
164		goto done;
165	}
166	e->e_id = id;
167	*ep = e;
168
169done:
170	if(cursor){
171		cursor->close(cursor);
172	}
173	return rc;
174}
175
176int wt_entry_return(
177	Entry *e
178	)
179{
180	if ( !e ) {
181		return 0;
182	}
183
184    /* Our entries are allocated in two blocks; the data comes from
185	 * the db itself and the Entry structure and associated pointers
186	 * are allocated in entry_decode. The db data pointer is saved
187	 * in e_bv.
188	 */
189	if ( e->e_bv.bv_val ) {
190#if 0
191		/* See if the DNs were changed by modrdn */
192		if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
193			e->e_bv.bv_val + e->e_bv.bv_len ) {
194			ch_free(e->e_name.bv_val);
195			ch_free(e->e_nname.bv_val);
196		}
197#endif
198		e->e_name.bv_val = NULL;
199		e->e_nname.bv_val = NULL;
200		/* In tool mode the e_bv buffer is realloc'd, leave it alone */
201		if( !(slapMode & SLAP_TOOL_MODE) ) {
202			free( e->e_bv.bv_val );
203		}
204		BER_BVZERO( &e->e_bv );
205	}
206
207	entry_free( e );
208}
209
210int wt_entry_release(
211	Operation *op,
212	Entry *e,
213	int rw )
214{
215	struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
216	return wt_entry_return( e );
217}
218
219/*
220 * return LDAP_SUCCESS IFF we can retrieve the specified entry.
221 */
222int wt_entry_get(
223	Operation *op,
224	struct berval *ndn,
225	ObjectClass *oc,
226	AttributeDescription *at,
227	int rw,
228	Entry **ent )
229{
230	return 0;
231}
232
233/*
234 * Local variables:
235 * indent-tabs-mode: t
236 * tab-width: 4
237 * c-basic-offset: 4
238 * End:
239 */
240