use super::TableInfo;
pub(crate) fn scaffold_strategy(info: &TableInfo) -> String {
match info.suggest_mode() {
"chunked" => match info.single_pk_column() {
Some(pk) => format!("keyset({pk})"),
None => format!("chunked({})", info.best_chunk_column().unwrap_or("id")),
},
"incremental" => format!(
"incremental({})",
info.best_cursor_column().unwrap_or("updated_at")
),
other => other.to_string(), }
}
#[cfg(test)]
mod tests {
use super::*;
const FIXTURE: &str = include_str!("fixtures/hostile_catalog.json");
#[derive(serde::Deserialize)]
struct FixtureRow {
expect: String,
#[allow(dead_code)]
note: String,
table: TableInfo,
}
#[test]
fn scaffold_strategy_matches_every_distilled_field_shape() {
let rows: Vec<FixtureRow> =
serde_json::from_str(FIXTURE).expect("hostile_catalog.json must parse");
assert!(rows.len() >= 6, "fixture must cover several shapes");
for row in &rows {
let got = scaffold_strategy(&row.table);
assert_eq!(
got, row.expect,
"table '{}' ({}): expected strategy {}, got {}",
row.table.table, row.note, row.expect, got
);
}
}
#[test]
fn wide_but_short_table_is_currently_full_a_known_row_width_gap() {
let info: TableInfo = serde_json::from_str(
r#"{
"schema": "s", "table": "wide_short_25k",
"row_estimate": 25000, "total_bytes": 21474836480,
"columns": [
{"name":"id","data_type":"bigint","is_primary_key":true,"is_nullable":false,"numeric_precision":null,"numeric_scale":null},
{"name":"wide_text_a","data_type":"longtext","is_primary_key":false,"is_nullable":true,"numeric_precision":null,"numeric_scale":null},
{"name":"wide_text_b","data_type":"longtext","is_primary_key":false,"is_nullable":true,"numeric_precision":null,"numeric_scale":null}
]
}"#,
)
.unwrap();
assert_eq!(
scaffold_strategy(&info),
"full",
"documents the row-width gap: this SHOULD be keyset(id) once init weighs total_bytes"
);
}
}