diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index 0260f788b..c2e43be30 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -34,3 +34,4 @@ crate-type = ["cdylib"] iceberg = { path = "../../crates/iceberg" } pyo3 = { version = "0.21.1", features = ["extension-module"] } arrow = { version = "52.2.0", features = ["pyarrow"] } +iceberg-catalog-sql = { path = "../../crates/catalog/sql" } diff --git a/bindings/python/src/catalog.rs b/bindings/python/src/catalog.rs new file mode 100644 index 000000000..3c95c70a5 --- /dev/null +++ b/bindings/python/src/catalog.rs @@ -0,0 +1,55 @@ +use pyo3::prelude::*; +use pyo3::wrap_pyfunction; + + +use std::collections::HashMap; + +use iceberg_catalog_sql::{SqlCatalog, SqlCatalogConfig, SqlBindStyle}; +use iceberg::catalog::NamespaceIdent; +use iceberg::io::FileIO; + + + +#[pyclass] +pub struct PySqlCatalog { + inner: SqlCatalog, +} + +#[pymethods] +impl PySqlCatalog { + #[new] + fn new(uri: String, name: String, warehouse_location: String, sql_bind_style: String) -> PyResult { + let sql_bind_style = match sql_bind_style.as_str() { + "DollarNumeric" => SqlBindStyle::DollarNumeric, + "QMark" => SqlBindStyle::QMark, + _ => return Err(PyErr::new::("Invalid SqlBindStyle")), + }; + + let config = SqlCatalogConfig { + uri, + name, + warehouse_location, + file_io: FileIO::from_path(&warehouse_location).unwrap().build().unwrap(), + sql_bind_style, + props: HashMap::new(), + }; + + let inner = SqlCatalog::new(config).unwrap(); + + Ok(PySqlCatalog { inner }) + } + + fn list_namespaces(&self, parent: Option) -> PyResult> { + let parent_ident = parent.map(|p| NamespaceIdent::new(p)); + let namespaces = self.inner.list_namespaces(parent_ident.as_ref()).unwrap(); + Ok(namespaces.into_iter().map(|ns| ns.to_string()).collect()) + } + + fn create_namespace(&self, namespace: String, properties: HashMap) -> PyResult<()> { + let namespace_ident = NamespaceIdent::new(namespace); + self.inner.create_namespace(&namespace_ident, properties).unwrap(); + Ok(()) + } + + // Add other methods similarly... +} diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs index 5c3f77ff7..fef0f20a6 100644 --- a/bindings/python/src/lib.rs +++ b/bindings/python/src/lib.rs @@ -20,6 +20,7 @@ use pyo3::prelude::*; use pyo3::wrap_pyfunction; mod transform; +mod catalog; #[pyfunction] fn hello_world() -> PyResult { @@ -33,5 +34,6 @@ fn pyiceberg_core_rust(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(hello_world, m)?)?; m.add_class::()?; + m.add_class::()?; Ok(()) } diff --git a/crates/iceberg/src/lib.rs b/crates/iceberg/src/lib.rs index d6c5010d3..46271e1c7 100644 --- a/crates/iceberg/src/lib.rs +++ b/crates/iceberg/src/lib.rs @@ -59,7 +59,7 @@ extern crate derive_builder; mod error; pub use error::{Error, ErrorKind, Result}; -mod catalog; +pub mod catalog; pub use catalog::{ Catalog, Namespace, NamespaceIdent, TableCommit, TableCreation, TableIdent, TableRequirement,