add data validation
This commit is contained in:
+83
-51
@@ -4,9 +4,9 @@ use std::collections::HashMap;
|
||||
use tracing::{debug, info};
|
||||
|
||||
const DIM_MONTH: &str = "month";
|
||||
const DIM_SPECIES: &str = "Species (ASFIS2022)";
|
||||
const DIM_GEAR: &str = "Fishing Gear (ISSCFG2016)";
|
||||
const DIM_ZONE: &str = "Economic Zone (GEONOM2023)";
|
||||
pub const DIM_SPECIES: &str = "Species (ASFIS2022)";
|
||||
pub const DIM_GEAR: &str = "Fishing Gear (ISSCFG2016)";
|
||||
pub const DIM_ZONE: &str = "Economic Zone (GEONOM2023)";
|
||||
const DIM_PROCESSING: &str = "Processing (EUMOFAPresentation)";
|
||||
const DIM_PRESERVATION: &str = "Preservation (EUMOFAPreservation)";
|
||||
const DIM_SHIPSIZE: &str = "Shipsize";
|
||||
@@ -70,6 +70,20 @@ pub fn extract_available_months(meta: &MetadataResponse) -> Vec<String> {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn extract_non_total_values(meta: &MetadataResponse, dim_code: &str) -> Vec<String> {
|
||||
meta.variables
|
||||
.iter()
|
||||
.find(|v| v.code == dim_code)
|
||||
.map(|v| {
|
||||
v.values
|
||||
.iter()
|
||||
.filter(|val| **val != "TOTAL")
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn chunk_months(months: &[String], batch_size: usize) -> Vec<Vec<String>> {
|
||||
if months.is_empty() {
|
||||
return vec![];
|
||||
@@ -81,8 +95,13 @@ pub fn chunk_months(months: &[String], batch_size: usize) -> Vec<Vec<String>> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn build_query(all_months: &[String]) -> Result<Query> {
|
||||
if all_months.is_empty() {
|
||||
pub fn build_query(
|
||||
months: &[String],
|
||||
species_codes: &[String],
|
||||
gear_codes: &[String],
|
||||
zone_codes: &[String],
|
||||
) -> Result<Query> {
|
||||
if months.is_empty() {
|
||||
return Err(IngestError::InvalidValueCode(
|
||||
"build_query requires at least one month".to_string(),
|
||||
));
|
||||
@@ -94,28 +113,28 @@ pub fn build_query(all_months: &[String]) -> Result<Query> {
|
||||
code: DIM_MONTH.to_string(),
|
||||
selection: Selection {
|
||||
filter: "item".to_string(),
|
||||
values: all_months.to_vec(),
|
||||
values: months.to_vec(),
|
||||
},
|
||||
},
|
||||
QueryItem {
|
||||
code: DIM_SPECIES.to_string(),
|
||||
selection: Selection {
|
||||
filter: "all".to_string(),
|
||||
values: vec!["*".to_string()],
|
||||
filter: "item".to_string(),
|
||||
values: species_codes.to_vec(),
|
||||
},
|
||||
},
|
||||
QueryItem {
|
||||
code: DIM_GEAR.to_string(),
|
||||
selection: Selection {
|
||||
filter: "all".to_string(),
|
||||
values: vec!["*".to_string()],
|
||||
filter: "item".to_string(),
|
||||
values: gear_codes.to_vec(),
|
||||
},
|
||||
},
|
||||
QueryItem {
|
||||
code: DIM_ZONE.to_string(),
|
||||
selection: Selection {
|
||||
filter: "all".to_string(),
|
||||
values: vec!["*".to_string()],
|
||||
filter: "item".to_string(),
|
||||
values: zone_codes.to_vec(),
|
||||
},
|
||||
},
|
||||
QueryItem {
|
||||
@@ -463,53 +482,66 @@ mod tests {
|
||||
maps
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_query_uses_correct_dimension_codes() {
|
||||
let months = vec!["2015M01".to_string(), "2015M02".to_string()];
|
||||
let query = build_query(&months).unwrap();
|
||||
#[test]
|
||||
fn test_build_query_uses_correct_dimension_codes() {
|
||||
let months = vec!["2015M01".to_string(), "2015M02".to_string()];
|
||||
let species = vec!["COD".to_string(), "HER".to_string()];
|
||||
let gear = vec!["TR1".to_string(), "GN".to_string()];
|
||||
let zones = vec!["FO".to_string(), "INTL".to_string()];
|
||||
|
||||
assert_eq!(query.response.format, "json-stat2");
|
||||
assert_eq!(query.query.len(), 8);
|
||||
let query = build_query(&months, &species, &gear, &zones).unwrap();
|
||||
|
||||
assert_eq!(query.query[0].code, DIM_MONTH);
|
||||
assert_eq!(query.query[0].selection.filter, "item");
|
||||
assert_eq!(query.query[0].selection.values.len(), 2);
|
||||
assert_eq!(query.response.format, "json-stat2");
|
||||
assert_eq!(query.query.len(), 8);
|
||||
|
||||
assert_eq!(query.query[1].code, DIM_SPECIES);
|
||||
assert_eq!(query.query[1].selection.filter, "all");
|
||||
assert_eq!(query.query[0].code, DIM_MONTH);
|
||||
assert_eq!(query.query[0].selection.filter, "item");
|
||||
assert_eq!(query.query[0].selection.values.len(), 2);
|
||||
|
||||
assert_eq!(query.query[4].code, DIM_PROCESSING);
|
||||
assert_eq!(query.query[4].selection.filter, "item");
|
||||
assert_eq!(query.query[4].selection.values, vec!["TOTAL"]);
|
||||
assert_eq!(query.query[1].code, DIM_SPECIES);
|
||||
assert_eq!(query.query[1].selection.filter, "item");
|
||||
assert_eq!(query.query[1].selection.values, vec!["COD", "HER"]);
|
||||
|
||||
assert_eq!(query.query[5].code, DIM_PRESERVATION);
|
||||
assert_eq!(query.query[5].selection.filter, "item");
|
||||
assert_eq!(query.query[5].selection.values, vec!["TOTAL"]);
|
||||
assert_eq!(query.query[2].code, DIM_GEAR);
|
||||
assert_eq!(query.query[2].selection.filter, "item");
|
||||
assert_eq!(query.query[2].selection.values, vec!["TR1", "GN"]);
|
||||
|
||||
assert_eq!(query.query[6].code, DIM_SHIPSIZE);
|
||||
assert_eq!(query.query[6].selection.filter, "item");
|
||||
assert_eq!(query.query[6].selection.values, vec!["TOTAL"]);
|
||||
assert_eq!(query.query[3].code, DIM_ZONE);
|
||||
assert_eq!(query.query[3].selection.filter, "item");
|
||||
assert_eq!(query.query[3].selection.values, vec!["FO", "INTL"]);
|
||||
|
||||
assert_eq!(query.query[7].code, DIM_MEASURE);
|
||||
assert!(
|
||||
query.query[7]
|
||||
.selection
|
||||
.values
|
||||
.contains(&"MASS".to_string())
|
||||
);
|
||||
assert!(
|
||||
query.query[7]
|
||||
.selection
|
||||
.values
|
||||
.contains(&"VALUE".to_string())
|
||||
);
|
||||
}
|
||||
assert_eq!(query.query[4].code, DIM_PROCESSING);
|
||||
assert_eq!(query.query[4].selection.filter, "item");
|
||||
assert_eq!(query.query[4].selection.values, vec!["TOTAL"]);
|
||||
|
||||
#[test]
|
||||
fn test_build_query_returns_error_on_empty() {
|
||||
let result = build_query(&[]);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
assert_eq!(query.query[5].code, DIM_PRESERVATION);
|
||||
assert_eq!(query.query[5].selection.filter, "item");
|
||||
assert_eq!(query.query[5].selection.values, vec!["TOTAL"]);
|
||||
|
||||
assert_eq!(query.query[6].code, DIM_SHIPSIZE);
|
||||
assert_eq!(query.query[6].selection.filter, "item");
|
||||
assert_eq!(query.query[6].selection.values, vec!["TOTAL"]);
|
||||
|
||||
assert_eq!(query.query[7].code, DIM_MEASURE);
|
||||
assert!(
|
||||
query.query[7]
|
||||
.selection
|
||||
.values
|
||||
.contains(&"MASS".to_string())
|
||||
);
|
||||
assert!(
|
||||
query.query[7]
|
||||
.selection
|
||||
.values
|
||||
.contains(&"VALUE".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_query_returns_error_on_empty() {
|
||||
let result = build_query(&[], &[], &[], &[]);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_key_indices_basic() {
|
||||
|
||||
Reference in New Issue
Block a user