Skip to content

Commit

Permalink
feat(wip): stac-duckdb
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski committed May 31, 2024
1 parent 35f67f0 commit ec95a95
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"stac-arrow",
"stac-async",
"stac-cli",
"stac-duckdb",
"stac-server",
"stac-validate",
]
Expand All @@ -16,6 +17,7 @@ default-members = [
"stac-arrow",
"stac-async",
"stac-cli",
"stac-duckdb",
"stac-server",
"stac-validate",
]
11 changes: 11 additions & 0 deletions stac-duckdb/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "stac-duckdb"
version = "0.1.0"
edition = "2021"

[dependencies]
duckdb = { version = "0.10", features = ["parquet"] }
stac = { version = "0.7", path = "../stac" }
stac-api = { version = "0.4", path = "../stac-api" }
stac-arrow = { version = "0.1", path = "../stac-arrow" }
thiserror = "1"
Binary file added stac-duckdb/data/naip.parquet
Binary file not shown.
79 changes: 79 additions & 0 deletions stac-duckdb/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Use [STAC](https://stacspec.org/) with [DuckDB](https://duckdb.org).
use duckdb::Connection;
use stac::Item;
use stac_api::Search;
use thiserror::Error;

/// Crate-specific error enum.
#[derive(Debug, Error)]
pub enum Error {
/// [duckdb::Error]
#[error(transparent)]
DuckDb(#[from] duckdb::Error),

/// [stac_arrow::Error]
#[error(transparent)]
StacArrow(#[from] stac_arrow::Error),
}

pub type Result<T> = std::result::Result<T, Error>;

/// A STAC-DuckDB client.
pub struct Client {
connection: Connection,
path: String,
}

impl Client {
/// Creates a new client for the given path.
///
/// # Examples
///
/// ```
/// use stac_duckdb::Client;
///
/// let client = Client::from_path("data/naip.parquet").unwrap();
/// ```
pub fn from_path(path: impl ToString) -> Result<Client> {
Ok(Client {
connection: Connection::open_in_memory()?,
path: path.to_string(),
})
}

/// Searches this client's data store for items.
///
/// TODO actually support search.
///
/// # Examples
///
/// ```
/// use stac_duckdb::Client;
///
/// let client = Client::from_path("data/naip.parquet").unwrap();
/// let items = client.search(Default::default()).unwrap();
/// ```
pub fn search(&self, _: Search) -> Result<Vec<Item>> {
let mut statement = self
.connection
.prepare(&format!("SELECT * from '{}'", self.path))?;
let mut items = Vec::new();
for record_batch in statement.query_arrow([])? {
items.extend(stac_arrow::record_batch_to_items(record_batch)?);
}
Ok(items)
}
}

#[cfg(test)]
mod tests {
use super::Client;

#[test]
fn select_all() {
let client = Client::from_path("data/naip.parquet").unwrap();
let items = client.search(Default::default()).unwrap();
assert_eq!(items.len(), 5);
}
}

0 comments on commit ec95a95

Please sign in to comment.