pub struct DuckdbSource { /* private fields */ }Expand description
A source that executes a SQL query against DuckDB and returns rows as JSON.
The connection is opened once in DuckdbSource::new and reused for every
fetch/stream, wrapped in Arc<Mutex<_>> so it can move into the blocking
task that runs each query.
Implementations§
Source§impl DuckdbSource
impl DuckdbSource
Sourcepub async fn new(config: DuckdbSourceConfig) -> Result<Self, FaucetError>
pub async fn new(config: DuckdbSourceConfig) -> Result<Self, FaucetError>
Create a new DuckDB source, opening (and reusing) one connection.
Trait Implementations§
Source§impl Source for DuckdbSource
impl Source for DuckdbSource
Source§fn stream_pages<'a>(
&'a self,
context: &'a HashMap<String, Value>,
_batch_size: usize,
) -> Pin<Box<dyn Stream<Item = Result<StreamPage, FaucetError>> + Send + 'a>>
fn stream_pages<'a>( &'a self, context: &'a HashMap<String, Value>, _batch_size: usize, ) -> Pin<Box<dyn Stream<Item = Result<StreamPage, FaucetError>> + Send + 'a>>
Stream rows in bounded-memory pages. A blocking task holds the connection and pushes each finished page over a small channel; the async side never holds more than a couple of pages at once.
The trait-level batch_size argument is ignored in favour of the config
field (the user-facing knob). batch_size = 0 drains the whole result
into a single page. This is a full-query source with no incremental
mode, so every page carries bookmark: None.
Source§fn fetch_with_context<'life0, 'life1, 'async_trait>(
&'life0 self,
context: &'life1 HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Value>, FaucetError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn fetch_with_context<'life0, 'life1, 'async_trait>(
&'life0 self,
context: &'life1 HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Value>, FaucetError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn config_schema(&self) -> Value
fn config_schema(&self) -> Value
Source§fn connector_name(&self) -> &'static str
fn connector_name(&self) -> &'static str
connector label on metrics and the
connector attribute on spans. Defaults to the final segment of
std::any::type_name::<Self>(), e.g. "RestSource". Built-in
connectors override with a short, friendly snake_case name (e.g.
"rest"). Must return a non-empty string; observability decorators
fall back to "unknown" in release builds if it is empty (and
debug_assert! in debug builds).Source§fn dataset_uri(&self) -> String
fn dataset_uri(&self) -> String
Source§fn fetch_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<Value>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn fetch_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<Value>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn fetch_with_context_incremental<'life0, 'life1, 'async_trait>(
&'life0 self,
context: &'life1 HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Value>, Option<Value>), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn fetch_with_context_incremental<'life0, 'life1, 'async_trait>(
&'life0 self,
context: &'life1 HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Value>, Option<Value>), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn fetch_all_incremental<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Value>, Option<Value>), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn fetch_all_incremental<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Value>, Option<Value>), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn state_key(&self) -> Option<String>
fn state_key(&self) -> Option<String>
StateStore. Read moreSource§fn apply_start_bookmark<'life0, 'async_trait>(
&'life0 self,
_bookmark: Value,
) -> Pin<Box<dyn Future<Output = Result<(), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn apply_start_bookmark<'life0, 'async_trait>(
&'life0 self,
_bookmark: Value,
) -> Pin<Box<dyn Future<Output = Result<(), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
StateStore
as this run’s starting point. Read moreSource§fn capture_resume_position<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<Value>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn capture_resume_position<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<Value>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn supports_exactly_once(&self) -> bool
fn supports_exactly_once(&self) -> bool
false. Read moreSource§fn replay_guarantee(&self) -> ReplayGuarantee
fn replay_guarantee(&self) -> ReplayGuarantee
ReplayGuarantee. Read moreSource§fn is_shardable(&self) -> bool
fn is_shardable(&self) -> bool
false (single whole-dataset
shard). Sources with a natural partition (object-store prefixes, table
primary-key ranges) override this to true and implement
enumerate_shards +
apply_shard.Source§fn enumerate_shards<'life0, 'async_trait>(
&'life0 self,
_target: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<ShardSpec>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn enumerate_shards<'life0, 'async_trait>(
&'life0 self,
_target: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<ShardSpec>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
target
of them (a hint — the source may return fewer, e.g. when the dataset is
small, or one per natural partition regardless of target). Read moreSource§fn apply_shard<'life0, 'life1, 'async_trait>(
&'life0 self,
_shard: &'life1 ShardSpec,
) -> Pin<Box<dyn Future<Output = Result<(), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn apply_shard<'life0, 'life1, 'async_trait>(
&'life0 self,
_shard: &'life1 ShardSpec,
) -> Pin<Box<dyn Future<Output = Result<(), FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn supports_discover(&self) -> bool
fn supports_discover(&self) -> bool
discover. Default: false. Sources backed by
an introspectable catalog (database information_schema, MongoDB
collections, Elasticsearch indices, object-store prefixes) override
this to true.Source§fn discover<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<DatasetDescriptor>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn discover<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<DatasetDescriptor>, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
DatasetDescriptor per table /
collection / index / prefix, each carrying a partial config override
that selects it (used by faucet discover to scaffold one matrix row
per dataset). Read moreSource§fn check<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 CheckContext,
) -> Pin<Box<dyn Future<Output = Result<CheckReport, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn check<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 CheckContext,
) -> Pin<Box<dyn Future<Output = Result<CheckReport, FaucetError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
faucet doctor). Read more