#![allow(dead_code)]
use sqlx::SqlitePool;
#[derive(
Debug, Clone, PartialEq, sqlx::FromRow, serde::Serialize, serde::Deserialize, umbral::orm::Model,
)]
#[umbral(table = "csv_widget")]
pub struct Widget {
pub id: i64,
pub name: String,
pub qty: i64,
pub active: bool,
pub note: Option<String>,
}
async fn boot() -> SqlitePool {
let settings = umbral::Settings::from_env().expect("settings");
let pool = umbral::db::connect_sqlite("sqlite::memory:")
.await
.expect("sqlite");
umbral::App::builder()
.settings(settings)
.database("default", pool.clone())
.model::<Widget>()
.build()
.expect("App::build");
sqlx::query(
"CREATE TABLE csv_widget (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
qty BIGINT NOT NULL,
active BOOLEAN NOT NULL,
note TEXT
)",
)
.execute(&pool)
.await
.expect("create table");
pool
}
fn s(v: &str) -> String {
v.to_string()
}
#[tokio::test]
async fn imports_csv_rows_with_per_column_coercion() {
let pool = boot().await;
let meta = umbral::migrate::registered_models()
.into_iter()
.find(|m| m.table == "csv_widget")
.expect("model registered");
let headers = vec![s("name"), s("qty"), s("active"), s("note")];
let rows = vec![
vec![s("alpha"), s("5"), s("true"), s("hi")],
vec![s("beta"), s("0"), s("0"), s("")],
vec![s("gamma"), s("not-a-number"), s("true"), s("x")],
];
let report = umbral::orm::import_table_rows(&meta, &headers, &rows).await;
assert_eq!(report.inserted, 2, "two good rows imported: {report:?}");
assert_eq!(report.errors.len(), 1, "the bad row is reported");
assert_eq!(report.errors[0].0, 4);
let mut widgets = Widget::objects()
.on(&pool)
.fetch()
.await
.expect("read back");
widgets.sort_by(|a, b| a.name.cmp(&b.name));
assert_eq!(widgets.len(), 2);
let alpha = &widgets[0];
assert_eq!(alpha.name, "alpha");
assert_eq!(alpha.qty, 5); assert!(alpha.active); assert_eq!(alpha.note.as_deref(), Some("hi"));
let beta = &widgets[1];
assert_eq!(beta.name, "beta");
assert_eq!(beta.qty, 0);
assert!(!beta.active); assert_eq!(beta.note, None); }