Construct a reader whose behavior is defined entirely by R functions you supply. This makes it possible to plug in data sources that aren't provided natively by ggsql (e.g. an in-memory store, a custom HTTP API, a DBI connection, etc.) without touching the Rust side.
Arguments
- execute_sql
A function
function(sql)that executessqland returns either a data frame or a raw vector containing Arrow IPC stream bytes (as produced bynanoarrow::as_nanoarrow_array_stream()/ arrow IPC writers).- register
Optional
function(name, df, replace)that registersdfas a table namedname.replaceisTRUEif the caller expects an existing table with the same name to be replaced.- unregister
Optional
function(name)that removes a previously registered table.
Details
Only execute_sql is required. If register or unregister are
omitted, calling ggsql_register() / ggsql_unregister() on the
returned reader raises an error.
See also
Other readers:
duckdb_reader(),
odbc_reader(),
snowflake_reader()
Examples
# A trivial reader backed by a list of data frames in an environment,
# delegating the actual SQL engine to an in-memory DuckDB.
store <- new.env(parent = emptyenv())
backend <- duckdb_reader()
reader <- custom_reader(
execute_sql = function(sql) ggsql_execute_sql(backend, sql),
register = function(name, df, replace) {
store[[name]] <- df
ggsql_register(backend, df, name, replace = replace)
},
unregister = function(name) {
rm(list = name, envir = store)
ggsql_unregister(backend, name)
}
)
ggsql_register(reader, mtcars, "cars")
ggsql_execute_sql(reader, "SELECT mpg, disp FROM cars LIMIT 3")
#> mpg disp
#> 1 21.0 160
#> 2 21.0 160
#> 3 22.8 108
