DWORD VmDirMDBSimpleDnToEntry( PSTR pszEntryDN, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_BERVALUE entryDn = VDIR_BERVALUE_INIT; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; assert(pEntry); dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); entryDn.lberbv.bv_val = pszEntryDN; entryDn.lberbv.bv_len = VmDirStringLenA(entryDn.lberbv.bv_val); dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = TRUE; dwError = VmDirMDBDNToEntry( &mdbBECtx, pSchemaCtx, &entryDn, pEntry, VDIR_BACKEND_ENTRY_LOCK_READ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } mdbBECtx.pBEPrivate = NULL; VmDirBackendCtxContentFree(&mdbBECtx); VmDirFreeBervalContent(&entryDn); return dwError; error: if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } goto cleanup; }
DWORD VmDirMDBSimpleEIdToEntry( PVDIR_BACKEND_INTERFACE pBE, ENTRYID eId, PVDIR_ENTRY pEntry) { DWORD dwError = 0; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; assert(pBE && pEntry); dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); mdbBECtx.pBE = pBE; dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ, &bHasTxn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirMDBEIdToEntry( &mdbBECtx, pSchemaCtx, eId, pEntry, VDIR_BACKEND_ENTRY_LOCK_READ); BAIL_ON_VMDIR_ERROR(dwError); if (bHasTxn) { dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); } cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } VmDirBackendCtxContentFree(&mdbBECtx); return dwError; error: if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } goto cleanup; }
// To get the current max ENTRYID // Entry database is separated from log databases. DWORD VmDirMDBMaxEntryId( PVDIR_BACKEND_INTERFACE pBE, ENTRYID* pEId ) { DWORD dwError = 0; VDIR_DB mdbDBi = 0; PVDIR_DB_DBC pCursor = NULL; MDB_val key = {0}; MDB_val value = {0}; ENTRYID eId = {0}; unsigned char EIDBytes[sizeof(ENTRYID)] = {0}; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; PVDIR_MDB_DB pDB = VmDirSafeDBFromBE(pBE); assert(pEId && pDB); mdbBECtx.pBE = pBE; dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ, &bHasTxn); BAIL_ON_VMDIR_ERROR(dwError); mdbDBi = pDB->mdbEntryDB.pMdbDataFiles[0].mdbDBi; dwError = mdb_cursor_open((PVDIR_DB_TXN)mdbBECtx.pBEPrivate, mdbDBi, &pCursor); BAIL_ON_VMDIR_ERROR(dwError); key.mv_data = &EIDBytes[0]; if (pBE == VmDirBackendSelect(ALIAS_MAIN)) { //Set cursor position equal or above LOG_ENTRY_EID_PREFIX // it would find the first entry id of raft log entry on legacy data // i.e. database creaded before we implemented a split log. eId = LOG_ENTRY_EID_PREFIX; MDBEntryIdToDBT(eId, &key); dwError = mdb_cursor_get(pCursor, &key, &value, MDB_SET_RANGE); if (dwError == MDB_NOTFOUND) { //mainDb was created after we implemented split log (no log entries in mainDb) // - simply find the last id which will be the last entry-id in normal entries. eId = 0; MDBEntryIdToDBT(eId, &key); dwError = mdb_cursor_get(pCursor, &key, &value, MDB_LAST); BAIL_ON_VMDIR_ERROR(dwError); MDBDBTToEntryId(&key, &eId); } else { BAIL_ON_VMDIR_ERROR(dwError); //Found an entry that is LOG_ENTRY_EID_PREFIX or above // - search backward, and the first one is the last normal entry do { dwError = mdb_cursor_get(pCursor, &key, &value, MDB_PREV); BAIL_ON_VMDIR_ERROR(dwError); MDBDBTToEntryId(&key, &eId); } while (eId >= LOG_ENTRY_EID_PREFIX); } } else { //For logDb, the last one is the log entry. eId = 0; MDBEntryIdToDBT(eId, &key); dwError = mdb_cursor_get(pCursor, &key, &value, MDB_LAST); BAIL_ON_VMDIR_ERROR(dwError); MDBDBTToEntryId(&key, &eId); } mdb_cursor_close(pCursor); pCursor = NULL; if (bHasTxn) { dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); } *pEId = eId; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirMDBMaxEntryId: failed with error (%d),(%s)", dwError, mdb_strerror(dwError) ); mdb_cursor_close(pCursor); if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } VMDIR_SET_BACKEND_ERROR(dwError); goto cleanup; }