Skip to content

Commit

Permalink
Restore Windows compatibility (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
vorot93 authored May 8, 2024
1 parent 0f3823b commit 1ee87b4
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 29 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ jobs:
ci:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: KyleMayes/install-llvm-action@v2
if: matrix.os == 'windows-latest'
with:
version: "18.1"
directory: ${{ runner.temp }}/llvm
- name: Set LIBCLANG_PATH
run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
if: matrix.os == 'windows-latest'
- uses: actions/checkout@main
- uses: dtolnay/rust-toolchain@master
with:
Expand Down
5 changes: 5 additions & 0 deletions mdbx-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,10 @@ fn main() {
cc_builder.define("MDBX_HAVE_BUILTIN_CPU_SUPPORTS", "0");
}

if cfg!(windows) {
println!(r"cargo:rustc-link-lib=dylib=ntdll");
println!(r"cargo:rustc-link-lib=dylib=user32");
}

cc_builder.file(mdbx.join("mdbx.c")).compile("libmdbx.a");
}
10 changes: 5 additions & 5 deletions src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use ffi::{
MDBX_NEXT_MULTIPLE, MDBX_NEXT_NODUP, MDBX_PREV, MDBX_PREV_DUP, MDBX_PREV_MULTIPLE,
MDBX_PREV_NODUP, MDBX_SET, MDBX_SET_KEY, MDBX_SET_LOWERBOUND, MDBX_SET_RANGE,
};
use libc::{c_uint, c_void};
use libc::c_void;
use parking_lot::Mutex;
use std::{borrow::Cow, fmt, marker::PhantomData, mem, ptr, result, sync::Arc};

Expand Down Expand Up @@ -498,7 +498,7 @@ impl<'txn> Cursor<'txn, RW> {
};
mdbx_result(unsafe {
txn_execute(&self.txn, |_| {
ffi::mdbx_cursor_put(self.cursor.0, &key_val, &mut data_val, flags.bits())
ffi::mdbx_cursor_put(self.cursor.0, &key_val, &mut data_val, c_enum(flags.bits()))
})
})?;

Expand All @@ -514,7 +514,7 @@ impl<'txn> Cursor<'txn, RW> {
pub fn del(&mut self, flags: WriteFlags) -> Result<()> {
mdbx_result(unsafe {
txn_execute(&self.txn, |_| {
ffi::mdbx_cursor_del(self.cursor.0, flags.bits())
ffi::mdbx_cursor_del(self.cursor.0, c_enum(flags.bits()))
})
})?;

Expand Down Expand Up @@ -810,7 +810,7 @@ where
cursor: &'cur mut Cursor<'txn, K>,

/// The first operation to perform when the consumer calls Iter.next().
op: c_uint,
op: ffi::MDBX_cursor_op,

_marker: PhantomData<fn(&'txn (Key, Value))>,
},
Expand All @@ -823,7 +823,7 @@ where
Value: Decodable<'txn>,
{
/// Creates a new iterator backed by the given cursor.
fn new(cursor: &'cur mut Cursor<'txn, K>, op: c_uint) -> Self {
fn new(cursor: &'cur mut Cursor<'txn, K>, op: ffi::MDBX_cursor_op) -> Self {
IterDup::Ok {
cursor,
op,
Expand Down
17 changes: 16 additions & 1 deletion src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,36 @@ use crate::{
use libc::c_uint;
use mem::size_of;
use sealed::sealed;
#[cfg(windows)]
use std::ffi::OsStr;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
use std::{
ffi::CString,
fmt,
fmt::Debug,
marker::PhantomData,
mem,
ops::Deref,
os::unix::ffi::OsStrExt,
path::Path,
ptr, result,
sync::mpsc::{sync_channel, SyncSender},
thread::sleep,
time::Duration,
};

#[cfg(windows)]
/// Adding a 'missing' trait from windows OsStrExt
trait OsStrExtLmdb {
fn as_bytes(&self) -> &[u8];
}
#[cfg(windows)]
impl OsStrExtLmdb for OsStr {
fn as_bytes(&self) -> &[u8] {
self.to_str().unwrap().as_bytes()
}
}

#[sealed]
pub trait DatabaseKind: Debug + 'static {
const EXTRA_FLAGS: ffi::MDBX_env_flags_t;
Expand Down
1 change: 1 addition & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ mod test {

#[test]
fn test_description() {
#[cfg(not(windows))]
assert_eq!("Permission denied", Error::from_err_code(13).to_string());

assert_eq!(
Expand Down
52 changes: 35 additions & 17 deletions src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,47 @@ bitflags! {
#[doc="Table options."]
#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct TableFlags: c_uint {
const REVERSE_KEY = MDBX_REVERSEKEY;
const DUP_SORT = MDBX_DUPSORT;
const INTEGER_KEY = MDBX_INTEGERKEY;
const DUP_FIXED = MDBX_DUPFIXED;
const INTEGER_DUP = MDBX_INTEGERDUP;
const REVERSE_DUP = MDBX_REVERSEDUP;
const CREATE = MDBX_CREATE;
const ACCEDE = MDBX_DB_ACCEDE;
const REVERSE_KEY = MDBX_REVERSEKEY as u32;
const DUP_SORT = MDBX_DUPSORT as u32;
const INTEGER_KEY = MDBX_INTEGERKEY as u32;
const DUP_FIXED = MDBX_DUPFIXED as u32;
const INTEGER_DUP = MDBX_INTEGERDUP as u32;
const REVERSE_DUP = MDBX_REVERSEDUP as u32;
const CREATE = MDBX_CREATE as u32;
const ACCEDE = MDBX_DB_ACCEDE as u32;
}
}

bitflags! {
#[doc="Write options."]
#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct WriteFlags: c_uint {
const UPSERT = MDBX_UPSERT;
const NO_OVERWRITE = MDBX_NOOVERWRITE;
const NO_DUP_DATA = MDBX_NODUPDATA;
const CURRENT = MDBX_CURRENT;
const ALLDUPS = MDBX_ALLDUPS;
const RESERVE = MDBX_RESERVE;
const APPEND = MDBX_APPEND;
const APPEND_DUP = MDBX_APPENDDUP;
const MULTIPLE = MDBX_MULTIPLE;
const UPSERT = MDBX_UPSERT as u32;
const NO_OVERWRITE = MDBX_NOOVERWRITE as u32;
const NO_DUP_DATA = MDBX_NODUPDATA as u32;
const CURRENT = MDBX_CURRENT as u32;
const ALLDUPS = MDBX_ALLDUPS as u32;
const RESERVE = MDBX_RESERVE as u32;
const APPEND = MDBX_APPEND as u32;
const APPEND_DUP = MDBX_APPENDDUP as u32;
const MULTIPLE = MDBX_MULTIPLE as u32;
}
}

/// Compatibility shim to convert between `i32` and `u32` enums on Windows and UNIX.
///
/// Windows treats C enums as `i32`, while Unix uses `u32`. We use `u32` enums internally
/// and then cast back to `i32` only where Windows requires it.
///
/// See https://github.com/rust-lang/rust-bindgen/issues/1907
#[cfg(windows)]
#[inline(always)]
pub const fn c_enum(rust_value: u32) -> i32 {
rust_value as i32
}

#[cfg(not(windows))]
#[inline(always)]
pub const fn c_enum(rust_value: u32) -> u32 {
rust_value
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![allow(clippy::type_complexity)]
#![allow(clippy::type_complexity, clippy::unnecessary_cast)]
#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]

Expand Down
3 changes: 2 additions & 1 deletion src/table.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
database::DatabaseKind,
error::{mdbx_result, Result},
flags::c_enum,
transaction::{txn_execute, TransactionKind},
Transaction,
};
Expand Down Expand Up @@ -30,7 +31,7 @@ impl<'txn> Table<'txn> {
};
let mut dbi: ffi::MDBX_dbi = 0;
mdbx_result(txn_execute(&txn.txn_mutex(), |txn| unsafe {
ffi::mdbx_dbi_open(txn, name_ptr, flags, &mut dbi)
ffi::mdbx_dbi_open(txn, name_ptr, c_enum(flags), &mut dbi)
}))?;
Ok(Self::new_from_ptr(dbi))
}
Expand Down
12 changes: 9 additions & 3 deletions src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
database::{Database, DatabaseKind, NoWriteMap, TxnManagerMessage, TxnPtr},
error::{mdbx_result, Result},
flags::{TableFlags, WriteFlags},
flags::{c_enum, TableFlags, WriteFlags},
table::Table,
Cursor, Decodable, Error, Stat,
};
Expand Down Expand Up @@ -287,7 +287,13 @@ where
iov_base: data.as_ptr() as *mut c_void,
};
mdbx_result(txn_execute(&self.txn, |txn| unsafe {
ffi::mdbx_put(txn, table.dbi(), &key_val, &mut data_val, flags.bits())
ffi::mdbx_put(
txn,
table.dbi(),
&key_val,
&mut data_val,
c_enum(flags.bits()),
)
}))?;

Ok(())
Expand Down Expand Up @@ -319,7 +325,7 @@ where
table.dbi(),
&key_val,
&mut data_val,
flags.bits() | ffi::MDBX_RESERVE,
c_enum(flags.bits() | ffi::MDBX_RESERVE as u32),
)
}))?;
Ok(slice::from_raw_parts_mut(
Expand Down

0 comments on commit 1ee87b4

Please sign in to comment.