int
mdb_dn2id_add(
Operation *op,
- MDB_txn *txn,
+ MDB_cursor *mcp,
+ MDB_cursor *mcd,
ID pid,
Entry *e )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- MDB_dbi dbi = mdb->mi_dn2id;
MDB_val key, data;
- MDB_cursor *mc;
ID nid;
int rc, rlen, nrlen;
diskNode *d;
nid = pid;
- rc = mdb_cursor_open( txn, dbi, &mc );
- if ( rc )
- goto fail;
-
/* Need to make dummy root node once. Subsequent attempts
* will fail harmlessly.
*/
data.mv_data = &dummy;
data.mv_size = sizeof(diskNode);
- mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA );
+ mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );
}
data.mv_data = d;
data.mv_size = sizeof(diskNode) + rlen + nrlen;
- rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA );
+ rc = mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );
if (rc == 0) {
nid = e->e_id;
memcpy( ptr, &pid, sizeof( ID ));
d->nrdnlen[0] ^= 0x80;
- rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA|MDB_APPEND );
+ rc = mdb_cursor_put( mcd, &key, &data, MDB_NODUPDATA|MDB_APPEND );
}
- mdb_cursor_close( mc );
fail:
op->o_tmpfree( d, op->o_tmpmemctx );
return rc;
}
+/* mc must have been set by mdb_dn2id */
int
mdb_dn2id_delete(
Operation *op,
- MDB_txn *txn,
- ID pid,
- Entry *e )
+ MDB_cursor *mc,
+ ID id )
{
- struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- MDB_dbi dbi = mdb->mi_dn2id;
- MDB_val key, data;
- diskNode *d;
- int rc, nrlen;
- ID nid;
-
- Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx: \"%s\"\n",
- e->e_id, e->e_ndn, 0 );
-
- key.mv_size = sizeof(ID);
- key.mv_data = &nid;
- nid = pid;
-
- nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
- data.mv_size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
+ int rc;
- d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
- d->nrdnlen[1] = nrlen & 0xff;
- d->nrdnlen[0] = (nrlen >> 8) | 0x80;
- memcpy( d->nrdn, e->e_nname.bv_val, nrlen );
- d->nrdn[nrlen] = '\0';
- data.mv_data = d;
+ Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx\n",
+ id, 0, 0 );
/* Delete our ID from the parent's list */
- rc = mdb_del( txn, dbi, &key, &data );
+ rc = mdb_cursor_del( mc, 0 );
/* Delete our ID from the tree. With sorted duplicates, this
* will leave any child nodes still hanging around. This is OK
* for modrdn, which will add our info back in later.
*/
if ( rc == 0 ) {
- nid = e->e_id;
- d->nrdnlen[0] ^= 0x80;
- rc = mdb_del( txn, dbi, &key, &data );
+ MDB_val key;
+ key.mv_size = sizeof(ID);
+ key.mv_data = &id;
+ rc = mdb_cursor_get( mc, &key, NULL, MDB_SET );
+ if ( rc == 0 )
+ rc = mdb_cursor_del( mc, 0 );
}
- op->o_tmpfree( d, op->o_tmpmemctx );
-
- Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
+ Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", id, rc, 0 );
return rc;
}
-/* return last found ID in *id if no match */
+/* return last found ID in *id if no match
+ * If mc is provided, it will be left pointing to the RDN's
+ * record under the parent's ID.
+ */
int
mdb_dn2id(
Operation *op,
MDB_txn *txn,
+ MDB_cursor *mc,
struct berval *in,
ID *id,
struct berval *matched,
nid = 0;
key.mv_size = sizeof(ID);
- rc = mdb_cursor_open( txn, dbi, &cursor );
- if ( rc ) return rc;
+ if ( mc ) {
+ cursor = mc;
+ } else {
+ rc = mdb_cursor_open( txn, dbi, &cursor );
+ if ( rc ) return rc;
+ }
for (;;) {
key.mv_data = &pid;
}
}
*id = nid;
- mdb_cursor_close( cursor );
+ if ( !mc )
+ mdb_cursor_close( cursor );
done:
if ( matched ) {
if ( matched->bv_len ) {
static int mdb_entry_partsize(struct mdb_info *mdb, MDB_txn *txn, Entry *e,
Ecount *eh);
-static int mdb_entry_encode(Operation *op, MDB_txn *txn, Entry *e, MDB_val *data,
+static int mdb_entry_encode(Operation *op, Entry *e, MDB_val *data,
Ecount *ec);
static Entry *mdb_entry_alloc( Operation *op, int nattrs, int nvals );
static int mdb_id2entry_put(
Operation *op,
- MDB_txn *tid,
+ MDB_txn *txn,
+ MDB_cursor *mc,
Entry *e,
int flag )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- MDB_dbi dbi = mdb->mi_id2entry;
Ecount ec;
MDB_val key, data;
int rc;
key.mv_data = &e->e_id;
key.mv_size = sizeof(ID);
- rc = mdb_entry_partsize( mdb, tid, e, &ec );
+ rc = mdb_entry_partsize( mdb, txn, e, &ec );
if (rc)
return LDAP_OTHER;
again:
data.mv_size = ec.len;
- rc = mdb_put( tid, dbi, &key, &data, flag );
+ if ( mc )
+ rc = mdb_cursor_put( mc, &key, &data, flag );
+ else
+ rc = mdb_put( txn, mdb->mi_id2entry, &key, &data, flag );
if (rc == MDB_SUCCESS) {
- rc = mdb_entry_encode( op, tid, e, &data, &ec );
+ rc = mdb_entry_encode( op, e, &data, &ec );
if( rc != LDAP_SUCCESS )
return LDAP_OTHER;
}
"mdb_id2entry_put: mdb_put failed: %s(%d) \"%s\"\n",
mdb_strerror(rc), rc,
e->e_nname.bv_val );
- rc = LDAP_OTHER;
+ if ( rc != MDB_KEYEXIST )
+ rc = LDAP_OTHER;
}
return rc;
}
int mdb_id2entry_add(
Operation *op,
- MDB_txn *tid,
+ MDB_txn *txn,
+ MDB_cursor *mc,
Entry *e )
{
- return mdb_id2entry_put(op, tid, e, MDB_NOOVERWRITE|MDB_APPEND);
+ return mdb_id2entry_put(op, txn, mc, e, MDB_NOOVERWRITE|MDB_APPEND);
}
int mdb_id2entry_update(
Operation *op,
- MDB_txn *tid,
+ MDB_txn *txn,
+ MDB_cursor *mc,
Entry *e )
{
- return mdb_id2entry_put(op, tid, e, 0);
+ return mdb_id2entry_put(op, txn, mc, e, 0);
}
int mdb_id2entry(
txn = moi->moi_txn;
/* can we find entry */
- rc = mdb_dn2entry( op, txn, ndn, &e, 0 );
+ rc = mdb_dn2entry( op, txn, NULL, ndn, &e, 0 );
switch( rc ) {
case MDB_NOTFOUND:
case 0:
* The entire buffer size is precomputed so that a single malloc can be
* performed.
*/
-static int mdb_entry_encode(Operation *op, MDB_txn *txn, Entry *e, MDB_val *data, Ecount *eh)
+static int mdb_entry_encode(Operation *op, Entry *e, MDB_val *data, Ecount *eh)
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
ber_len_t len, i;