faucet_source_duckdb/
config.rs1use faucet_core::DEFAULT_BATCH_SIZE;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
9pub struct DuckdbSourceConfig {
10 pub database: String,
14 pub query: String,
16 #[serde(default)]
22 pub read_only: bool,
23 #[serde(default = "default_batch_size")]
30 pub batch_size: usize,
31}
32
33fn default_batch_size() -> usize {
34 DEFAULT_BATCH_SIZE
35}
36
37impl DuckdbSourceConfig {
38 pub fn new(database: impl Into<String>, query: impl Into<String>) -> Self {
40 Self {
41 database: database.into(),
42 query: query.into(),
43 read_only: false,
44 batch_size: DEFAULT_BATCH_SIZE,
45 }
46 }
47
48 pub fn with_batch_size(mut self, batch_size: usize) -> Self {
54 self.batch_size = batch_size;
55 self
56 }
57
58 pub fn read_only(mut self, read_only: bool) -> Self {
60 self.read_only = read_only;
61 self
62 }
63
64 pub(crate) fn resolved_path(&self) -> &str {
66 self.database
67 .trim_start_matches("duckdb://")
68 .trim_start_matches("duckdb:")
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn default_config() {
78 let config = DuckdbSourceConfig::new("data.duckdb", "SELECT * FROM events");
79 assert_eq!(config.database, "data.duckdb");
80 assert_eq!(config.query, "SELECT * FROM events");
81 assert_eq!(config.batch_size, DEFAULT_BATCH_SIZE);
82 assert!(!config.read_only);
83 }
84
85 #[test]
86 fn resolved_path_strips_scheme() {
87 assert_eq!(
88 DuckdbSourceConfig::new("duckdb:///tmp/a.duckdb", "SELECT 1").resolved_path(),
89 "/tmp/a.duckdb"
90 );
91 assert_eq!(
92 DuckdbSourceConfig::new("duckdb::memory:", "SELECT 1").resolved_path(),
93 ":memory:"
94 );
95 assert_eq!(
96 DuckdbSourceConfig::new(":memory:", "SELECT 1").resolved_path(),
97 ":memory:"
98 );
99 }
100
101 #[test]
102 fn with_batch_size_overrides_default() {
103 let config = DuckdbSourceConfig::new(":memory:", "SELECT 1").with_batch_size(500);
104 assert_eq!(config.batch_size, 500);
105 }
106
107 #[test]
108 fn batch_size_zero_is_accepted_as_no_batching_sentinel() {
109 let config = DuckdbSourceConfig::new(":memory:", "SELECT 1").with_batch_size(0);
110 assert_eq!(config.batch_size, 0);
111 assert!(faucet_core::validate_batch_size(config.batch_size).is_ok());
112 }
113
114 #[test]
115 fn batch_size_deserializes_from_json() {
116 let json = r#"{
117 "database": ":memory:",
118 "query": "SELECT 1",
119 "batch_size": 250
120 }"#;
121 let config: DuckdbSourceConfig = serde_json::from_str(json).unwrap();
122 assert_eq!(config.batch_size, 250);
123 assert!(!config.read_only);
124 }
125}