use faucet_core::{Sink, WriteMode, WriteSpec};
use faucet_sink_sqlite::{SqliteColumnMapping, SqliteSink, SqliteSinkConfig};
use sqlx::Row;
use sqlx::sqlite::SqlitePoolOptions;
use tempfile::TempDir;
async fn fresh_sink() -> (TempDir, String, SqliteSink) {
let dir = TempDir::new().expect("tempdir");
let url = format!("sqlite://{}?mode=rwc", dir.path().join("t.db").display());
let pool = SqlitePoolOptions::new()
.max_connections(1)
.connect(&url)
.await
.expect("connect");
sqlx::query("CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT)")
.execute(&pool)
.await
.expect("create table");
pool.close().await;
let cfg = SqliteSinkConfig {
database_url: url.clone(),
table_name: "t".to_string(),
column_mapping: SqliteColumnMapping::AutoMap,
batch_size: 1000,
max_connections: 1,
write: WriteSpec {
write_mode: WriteMode::Upsert,
key: vec!["id".to_string()],
delete_marker: None,
},
};
let sink = SqliteSink::new(cfg).await.expect("sink");
(dir, url, sink)
}
async fn count_rows(url: &str) -> usize {
let pool = SqlitePoolOptions::new()
.max_connections(1)
.connect(url)
.await
.expect("connect");
let row = sqlx::query("SELECT COUNT(*) AS n FROM t")
.fetch_one(&pool)
.await
.expect("count");
let n: i64 = row.get("n");
pool.close().await;
n as usize
}
#[tokio::test]
async fn conformance_config_schema_valid() {
let (_dir, _url, sink) = fresh_sink().await;
faucet_conformance::assert_config_schema_valid_value(
&sink.config_schema(),
sink.connector_name(),
);
}
#[tokio::test]
async fn conformance_idempotent_replay() {
let (_dir, url, sink) = fresh_sink().await;
faucet_conformance::assert_idempotent_replay(&sink, || {
let url = url.clone();
async move { count_rows(&url).await }
})
.await;
}
#[tokio::test]
async fn conformance_capabilities_truthful() {
let (_dir, url, sink) = fresh_sink().await;
faucet_conformance::assert_capabilities_truthful(&sink, || {
let url = url.clone();
async move { count_rows(&url).await }
})
.await;
}