% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/reader.R
\name{custom_reader}
\alias{custom_reader}
\title{Create a reader backed by R callbacks}
\usage{
custom_reader(execute_sql, register = NULL, unregister = NULL)
}
\arguments{
\item{execute_sql}{A function \verb{function(sql)} that executes \code{sql} and
returns either a data frame or a raw vector containing Arrow IPC
stream bytes (as produced by \code{nanoarrow::as_nanoarrow_array_stream()}
/ arrow IPC writers).}

\item{register}{Optional \verb{function(name, df, replace)} that registers
\code{df} as a table named \code{name}. \code{replace} is \code{TRUE} if the caller
expects an existing table with the same name to be replaced.}

\item{unregister}{Optional \verb{function(name)} that removes a previously
registered table.}
}
\value{
A \code{Reader} object, usable anywhere the other \verb{*_reader()}
constructors are accepted.
}
\description{
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.
}
\details{
Only \code{execute_sql} is required. If \code{register} or \code{unregister} are
omitted, calling \code{\link[=ggsql_register]{ggsql_register()}} / \code{\link[=ggsql_unregister]{ggsql_unregister()}} on the
returned reader raises an error.
}
\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")

}
\seealso{
Other readers: 
\code{\link{duckdb_reader}()},
\code{\link{odbc_reader}()},
\code{\link{snowflake_reader}()}
}
\concept{readers}
