Skip to content

Commit

Permalink
Merge pull request #1 from roeap/win-tests
Browse files Browse the repository at this point in the history
fix: windows tests
  • Loading branch information
rtyler authored Jan 3, 2024
2 parents c88175e + be43b8b commit 10db6c3
Showing 1 changed file with 50 additions and 32 deletions.
82 changes: 50 additions & 32 deletions crates/deltalake-core/src/table/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use url::Url;
use super::DeltaTable;
use crate::errors::{DeltaResult, DeltaTableError};
use crate::logstore::LogStoreRef;
use crate::storage::StorageOptions;
use crate::storage::{StorageOptions, factories};

#[allow(dead_code)]
#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -323,17 +323,35 @@ impl DeltaTableBuilder {
}
}

fn create_filetree_from_path(path: &PathBuf) -> DeltaResult<()> {
if !path.exists() {
std::fs::create_dir_all(path).map_err(|err| {
let msg = format!(
"Could not create local directory: {:?}\nError: {:?}",
path, err
);
DeltaTableError::InvalidTableLocation(msg)
})?;
enum UriType {
LocalPath(PathBuf),
Url(Url),
}

/// Utility function to figure out whether string representation of the path
/// is either local path or some kind or URL.
///
/// Will return an error if the path is not valid.
fn resolve_uri_type(table_uri: impl AsRef<str>) -> DeltaResult<UriType> {
let table_uri = table_uri.as_ref();
let known_schemes: Vec<_> = factories().iter().map(|v| v.key().scheme().to_owned()).collect();

if let Ok(url) = Url::parse(table_uri) {
let scheme = url.scheme().to_string();
if url.scheme() == "file" {
Ok(UriType::LocalPath(url.to_file_path().map_err(|err| {
let msg = format!("Invalid table location: {}\nError: {:?}", table_uri, err);
DeltaTableError::InvalidTableLocation(msg)
})?))
// NOTE this check is required to support absolute windows paths which may properly parse as url
} else if known_schemes.contains(&scheme) {
Ok(UriType::Url(url))
} else {
Ok(UriType::LocalPath(PathBuf::from(table_uri)))
}
} else {
Ok(UriType::LocalPath(PathBuf::from(table_uri)))
}
Ok(())
}

/// Attempt to create a Url from given table location.
Expand All @@ -350,35 +368,35 @@ fn create_filetree_from_path(path: &PathBuf) -> DeltaResult<()> {
pub fn ensure_table_uri(table_uri: impl AsRef<str>) -> DeltaResult<Url> {
let table_uri = table_uri.as_ref();

debug!("ensure_table_uri {table_uri}");
let mut url = match Url::parse(table_uri) {
Ok(url) => {
if url.scheme() == "file" {
create_filetree_from_path(
&url.to_file_path()
.expect("Failed to convert a file:// URL to a file path"),
)?;
let uri_type: UriType = resolve_uri_type(table_uri)?;

// If it is a local path, we need to create it if it does not exist.
let mut url = match uri_type {
UriType::LocalPath(path) => {
if !path.exists() {
std::fs::create_dir_all(&path).map_err(|err| {
let msg = format!(
"Could not create local directory: {}\nError: {:?}",
table_uri, err
);
DeltaTableError::InvalidTableLocation(msg)
})?;
}
Ok(url)
}
Err(_) => {
let path = PathBuf::from(table_uri);
create_filetree_from_path(&path)?;
let path = std::fs::canonicalize(path.clone()).map_err(|err| {
let msg = format!("Invalid table location: {:?}\nError: {:?}", path, err);
let path = std::fs::canonicalize(path).map_err(|err| {
let msg = format!("Invalid table location: {}\nError: {:?}", table_uri, err);
DeltaTableError::InvalidTableLocation(msg)
})?;

Url::from_directory_path(path.clone()).map_err(|_| {
Url::from_directory_path(path).map_err(|_| {
let msg = format!(
"Could not construct a URL from canonicalized path: {:?}.\n\
"Could not construct a URL from canonicalized path: {}.\n\
Something must be very wrong with the table path.",
path,
table_uri
);
DeltaTableError::InvalidTableLocation(msg)
})
})?
}
}?;
UriType::Url(url) => url,
};

let trimmed_path = url.path().trim_end_matches('/').to_owned();
url.set_path(&trimmed_path);
Expand Down

0 comments on commit 10db6c3

Please sign in to comment.