Skip to content

Comments

feat(rust/driver_manager): implement connection profiles#3973

Open
zeroshade wants to merge 18 commits intoapache:mainfrom
zeroshade:rust-connection-profile
Open

feat(rust/driver_manager): implement connection profiles#3973
zeroshade wants to merge 18 commits intoapache:mainfrom
zeroshade:rust-connection-profile

Conversation

@zeroshade
Copy link
Member

Implementing connection profiles for the Rust driver manager including the default FilesystemProfileProvider and updating the objects and tests accordingly.

Copy link
Contributor

@felipecrv felipecrv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a full review yet. But it's a good start.

// an immutable struct of function pointers. Wrapping the driver in a `Mutex`
// would prevent any parallelism between driver calls, which is not desirable.

pub mod connection_profiles;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use singular connection_profile. Or even better, just profile.

///
/// URIs can specify either a direct driver connection or a profile to load.
#[derive(Debug)]
pub(crate) enum SearchResult<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a struct called SearchHit already with the actual loaded library object. Need a name for this enum that is not so close to SearchHit in meaning. Suggestion DriverLocator (as it wraps a universinal resource LOCATORS).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you can drop the Driver from the enum entry.

DriverLocator = Uri | ProfilePath

Comment on lines +561 to +567
drv = ManagedDriver::load_from_name(
driver,
entrypoint,
version,
load_flags,
additional_search_paths.clone(),
)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can become

DriverLibrary::search(name, load_flags, additional_search_paths)?

and you can make every branch return SearchHit. Then at the end you can:

        let entrypoint = search_hit.resolve_entrypoint(entrypoint).to_vec();
        Self::load_from_library(search_hit.library, entrypoint.as_ref(), version)

Then, at the end of all this, you can extract a function that returns SearchHit to search.rs and keep the load_from_library call here. This is what enables different users of search.rs (which I intend to make more public in the upstream too) to instantiate structs that are not ManagedDriver.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is not a trivial change, but you get the intention: move search logic to search.rs and keep only the final instantiation of ManagedDriver in this file.

let profile_opts: Vec<(OptionDatabase, OptionValue)> = profile
.get_options()?
.into_iter()
.map(|(k, v)| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.map(|(k, v)| {
.map(|(k, v)| -> Result<(OptionDatabase, OptionValue), Error> {

.map(|(k, v)| {
if let OptionValue::String(s) = v {
let result = process_profile_value(&s)?;
Ok::<(OptionDatabase, OptionValue), Error>((k, result))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Ok::<(OptionDatabase, OptionValue), Error>((k, result))
Ok((k, result))

// Convert the name to a PathBuf to ensure proper platform-specific path handling.
// This normalizes forward slashes to backslashes on Windows.
let profile_path = PathBuf::from_slash(name.as_ref());
let profile_path = profile_path.as_path();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're shadowing the profile_path: PathBuf but then you are allocating a new PathBuf from the Path to return it.

You should invert: use profile_path.as_path() where you need a Path and delete the .to_path_buf() and use just profile_path: PathBuf.

Comment on lines +864 to +867
Err(Error::with_message_and_status(
format!("Profile not found: {}", profile_path.display()),
Status::NotFound,
))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should let the caller try to open the absolute path and provide an error message (there) about the file failing to open instead of the profile path not being found. There is nothing to "find" because it's an absolute path.

}

// No .toml extension - add it
return Ok(profile_path.with_extension("toml"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specially considering that you don't stat the file here. Which is good.


// Handle absolute paths
if profile_path.is_absolute() {
let has_toml_ext = profile_path.extension().is_some_and(|ext| ext == "toml");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable can be defined right after profile_path is defined.

Comment on lines +887 to +900
if has_toml_ext {
// Name already has .toml extension, use it as-is
let full_path = path.join(profile_path);
if full_path.is_file() {
return Some(full_path);
}
}
// Try adding .toml extension
let mut full_path = path.join(profile_path);
full_path.set_extension("toml");
if full_path.is_file() {
return Some(full_path);
}
None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not just a style change. It avoid checking the same path twice when it has the .toml extension and doesn't exist.

Suggested change
if has_toml_ext {
// Name already has .toml extension, use it as-is
let full_path = path.join(profile_path);
if full_path.is_file() {
return Some(full_path);
}
}
// Try adding .toml extension
let mut full_path = path.join(profile_path);
full_path.set_extension("toml");
if full_path.is_file() {
return Some(full_path);
}
None
let mut full_path = path.join(profile_path);
if has_toml_ext {
// Name already has .toml extension, use it as-is
if full_path.is_file() {
Some(full_path)
} else {
None
}
} else {
// Try adding .toml extension
full_path.set_extension("toml");
if full_path.is_file() {
Some(full_path)
} else {
None
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants