Skip to content

Commit 9259d9c

Browse files
committed
Terminate persisted SQL definitions
1 parent 2188ba0 commit 9259d9c

1 file changed

Lines changed: 72 additions & 6 deletions

File tree

sidemantic-rs/src/ffi.rs

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -715,30 +715,42 @@ fn should_remove_item_statement(
715715
fn insert_definition_at_block_end(block: &str, definition: &str) -> String {
716716
let trimmed_len = block.trim_end().len();
717717
let (body, trailing) = block.split_at(trimmed_len);
718-
let trimmed_definition = definition.trim();
718+
let terminated_definition = terminate_definition(definition);
719+
if terminated_definition.is_empty() {
720+
return block.to_string();
721+
}
719722

720723
if body.is_empty() {
721-
return format!("{trimmed_definition}{trailing}");
724+
return format!("{terminated_definition}{trailing}");
722725
}
723726

724-
format!("{body}\n\n{trimmed_definition}{trailing}")
727+
format!("{body}\n\n{terminated_definition}{trailing}")
725728
}
726729

727730
fn append_definition_to_content(content: &str, definition: &str) -> String {
728-
let trimmed_definition = definition.trim();
729-
if trimmed_definition.is_empty() {
731+
let terminated_definition = terminate_definition(definition);
732+
if terminated_definition.is_empty() {
730733
return content.trim_end().to_string();
731734
}
732735

733736
let mut result = content.trim_end().to_string();
734737
if !result.is_empty() {
735738
result.push_str("\n\n");
736739
}
737-
result.push_str(trimmed_definition);
740+
result.push_str(&terminated_definition);
738741
result.push('\n');
739742
result
740743
}
741744

745+
fn terminate_definition(definition: &str) -> String {
746+
let trimmed_definition = definition.trim();
747+
if trimmed_definition.is_empty() || trimmed_definition.ends_with(';') {
748+
trimmed_definition.to_string()
749+
} else {
750+
format!("{trimmed_definition};")
751+
}
752+
}
753+
742754
fn read_definitions_file(path: &Path) -> io::Result<String> {
743755
match fs::read_to_string(path) {
744756
Ok(content) => Ok(content),
@@ -2008,6 +2020,60 @@ models:
20082020
remove_definitions_file(&db_path);
20092021
}
20102022

2023+
#[test]
2024+
fn test_semicolonless_simple_as_definition_is_terminated_before_append() {
2025+
let _guard = test_lock();
2026+
sidemantic_clear();
2027+
2028+
let db_path = unique_db_path("semicolonless_simple_as_append");
2029+
let db_path = CString::new(db_path.to_string_lossy().to_string()).unwrap();
2030+
remove_definitions_file(&db_path);
2031+
let definitions_path = get_definitions_path(db_path.as_ptr()).unwrap();
2032+
2033+
let orders =
2034+
CString::new("MODEL (name orders, table orders, primary_key order_id)").unwrap();
2035+
assert_success(sidemantic_define(orders.as_ptr(), db_path.as_ptr(), false));
2036+
2037+
let metric = CString::new("METRIC revenue AS SUM(amount)").unwrap();
2038+
assert_success(sidemantic_add_definition(
2039+
metric.as_ptr(),
2040+
db_path.as_ptr(),
2041+
false,
2042+
));
2043+
2044+
let customers =
2045+
CString::new("MODEL (name customers, table customers, primary_key customer_id)")
2046+
.unwrap();
2047+
assert_success(sidemantic_define(
2048+
customers.as_ptr(),
2049+
db_path.as_ptr(),
2050+
false,
2051+
));
2052+
2053+
let content = fs::read_to_string(&definitions_path).unwrap();
2054+
assert!(
2055+
content.contains("METRIC revenue AS SUM(amount);\n\nMODEL (name customers"),
2056+
"{content}"
2057+
);
2058+
2059+
sidemantic_clear();
2060+
assert_success(sidemantic_autoload(db_path.as_ptr()));
2061+
2062+
let customers_name = CString::new("customers").unwrap();
2063+
assert!(sidemantic_is_model(customers_name.as_ptr()));
2064+
2065+
let rewritten = take_rewrite_sql(sidemantic_rewrite(
2066+
CString::new("SELECT orders.revenue FROM orders")
2067+
.unwrap()
2068+
.as_ptr(),
2069+
));
2070+
assert!(rewritten.contains("SUM"), "{rewritten}");
2071+
assert!(rewritten.contains("amount"), "{rewritten}");
2072+
assert!(!rewritten.contains("MODEL (name customers"), "{rewritten}");
2073+
2074+
remove_definitions_file(&db_path);
2075+
}
2076+
20112077
#[test]
20122078
fn test_clear_resets_active_model() {
20132079
let _guard = test_lock();

0 commit comments

Comments
 (0)