use byteorder::ByteOrder;
use foundationdb::api::FdbApiBuilder;
use foundationdb::options::NetworkOption;
use foundationdb::tuple::Subspace;
use foundationdb::{Database, FdbBindingError, options};
const NETWORK_OPTION_EXTERNAL_CLIENT_DIRECTORY: &str =
"FDB_NETWORK_OPTION_EXTERNAL_CLIENT_DIRECTORY";
#[tokio::main]
async fn main() {
let mut network_builder = FdbApiBuilder::default()
.build()
.expect("Failed to build API");
if std::env::var(NETWORK_OPTION_EXTERNAL_CLIENT_DIRECTORY).is_err() {
network_builder = network_builder
.set_option(NetworkOption::ExternalClientDirectory(
"/usr/lib/foundationdb/".to_string(),
))
.expect("Failed to add external library directory");
}
let _guard = unsafe { network_builder.boot() };
let db = Database::new_compat(None)
.await
.expect("failed to get database");
db.set_option(options::DatabaseOption::TransactionTimeout(5000))
.expect("failed to set transaction timeout");
db.set_option(options::DatabaseOption::TransactionRetryLimit(3))
.expect("failed to set transaction retry limit");
let _ = db
.run(|trx, _| async move {
trx.set_option(options::TransactionOption::Timeout(3000))?;
let maybe_version = trx.get_read_version().await;
match maybe_version {
Ok(_) => Ok(()),
Err(err) if err.code() == 1039 => Err(FdbBindingError::from(err)),
Err(err) => Err(FdbBindingError::NonRetryableFdbError(err)),
}
})
.await;
let key = Subspace::all()
.subspace(&"examples")
.pack(&"multi_version_incr");
db.run(|trx, _| {
let key = key.clone();
async move {
let mut buf = [0u8; 8];
byteorder::LE::write_i64(&mut buf, 1);
trx.atomic_op(&key, &buf, options::MutationType::Add);
Ok(())
}
})
.await
.expect("could not commit");
let raw_counter = db
.run(|trx, _| {
let key = key.clone();
async move {
let result = trx.get(&key, true).await?;
Ok(result)
}
})
.await
.expect("could not read key")
.expect("no value found");
let counter = byteorder::LE::read_i64(raw_counter.as_ref());
dbg!(counter);
assert!(counter > 0);
}