Skip to content

Commit

Permalink
feat: add optional DuckDB query source
Browse files Browse the repository at this point in the history
  • Loading branch information
program-- committed Dec 7, 2024
1 parent 4146a8c commit ff84517
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 2 deletions.
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ Imports:
sf,
methods
Suggests:
testthat
testthat,
duckdb
License: GPL (>= 3)
Encoding: UTF-8
LazyData: true
Expand All @@ -44,6 +45,7 @@ Collate:
'query.R'
'query_source.R'
'query_source_arrow.R'
'query_source_duckdb.R'
'query_source_sf.R'
'query_subset.R'
'sf_arrow.R'
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export(query_set_layers)
export(query_set_sink)
export(query_set_source)
export(query_source_arrow)
export(query_source_duckdb)
export(query_source_sf)
export(query_subset)
export(read_sf_dataset)
Expand Down
47 changes: 47 additions & 0 deletions R/query_source_duckdb.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#' Create a new DuckDB query source
#' @param srcname Path or URI to source
#' @param ... Passed to [DBI::dbConnect].
#' @param .attach If `TRUE`, then `ATTACH <srcname>` is executed on the DuckDB connection
#' @param .extensions Optional extensions to install and load on connection
#' @returns An `hfsubset_query_source_duckdb` object
#' @export
query_source_duckdb <- function(srcname, ..., .attach = FALSE, .extensions = c("spatial")) {
if (!requireNamespace("duckdb", quietly = TRUE)) {
stop("Package `duckdb` is required for query_source_duckdb()")
}

conn <- DBI::dbConnect(duckdb::duckdb(), ...)

for (ext in .extensions) {
DBI::dbExecute(conn, paste("INSTALL", ext))
DBI::dbExecute(conn, paste("LOAD", ext))
}

if (.attach) {
DBI::dbExecute(
conn,
paste0("ATTACH '", srcname, "' AS hydrofabric (TYPE SQLITE)")
)
}

structure(
list(src = srcname, conn = conn),
class = c("hfsubset_query_source_duckdb", "hfsubset_query_source")
)
}

#' @method query_source_layer hfsubset_query_source_duckdb
#' @keywords internal
query_source_layer.hfsubset_query_source_duckdb <- function(query_source, layer, ..., query = NULL) {
if (missing(layer) && !is.null(query)) {
dplyr::tbl(query_source$conn, dbplyr::sql(query), ...)
} else {
dplyr::tbl(query_source$conn, paste0("hydrofabric.", layer), ...)
}
}

#' @method query_source_layers hfsubset_query_source_duckdb
#' @keywords internal
query_source_layers.hfsubset_query_source_duckdb <- function(query_source, ...) {
DBI::dbListTables(query_source$conn)
}
3 changes: 2 additions & 1 deletion R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

query_source_classes <- c(
"hfsubset_query_source_arrow",
"hfsubset_query_source_sf"
"hfsubset_query_source_sf",
"hfsubset_query_source_duckdb"
)

for (query_source_class in query_source_classes) {
Expand Down
2 changes: 2 additions & 0 deletions man/hfsubsetR-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions man/query_source_duckdb.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ff84517

Please sign in to comment.