feat(dynamodb): support querying, editing, and exporting

This commit is contained in:
zipg authored and GitHub committed 2026-08-17 03:27:44 +08:00
1 parent 92ab9bb0dc
commit e97c9ab5d7
73 files changed
+4493 -134

No files matched your search

@@ -247,12 +247,27 @@ pub fn is_write_sql_for_database(sql: &str, database_type: DatabaseType) -> bool
if database_type == DatabaseType::VictoriaMetrics {
return false;
}
if database_type == DatabaseType::DynamoDb {
if let Some(is_write) = classify_dynamodb_statement_write(sql) {
return is_write;
}
}
if let Some(risk) = classify_search_engine_query_risk(sql, database_type) {
return risk != SearchEngineQueryRisk::ReadOnly;
}
is_write_sql_with_database_type(sql, Some(database_type))
}
fn classify_dynamodb_statement_write(source: &str) -> Option<bool> {
let header = source.lines().find(|line| !line.trim().is_empty())?.trim().to_ascii_uppercase();
match header.as_str() {
"DBX DYNAMODB SCAN" | "DBX DYNAMODB QUERY / SCAN" => Some(false),
"DBX DYNAMODB INSERT ITEM" | "DBX DYNAMODB PUT ITEM" | "DBX DYNAMODB DELETE ITEM" => Some(true),
_ if header.starts_with("DBX DYNAMODB") => Some(true),
_ => None,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum SearchEngineQueryRisk {
ReadOnly,
@@ -1598,6 +1613,24 @@ mod tests {
assert_eq!(strip_sql_comments("SELECT 'hello /* not a comment */'"), "SELECT 'hello '");
}
#[test]
fn classifies_dynamodb_generated_statements_for_read_only_protection() {
assert!(!is_write_sql_for_database(
"DBX DYNAMODB SCAN\ntable: \"orders\"\nlimit: 1000",
DatabaseType::DynamoDb
));
assert!(!is_write_sql_for_database(
"DBX DYNAMODB QUERY / SCAN\ntable: \"orders\"\nfilter:\n{\"status\":\"SHIPPED\"}",
DatabaseType::DynamoDb
));
for operation in ["INSERT ITEM", "PUT ITEM", "DELETE ITEM", "UNKNOWN"] {
assert!(is_write_sql_for_database(
&format!("DBX DYNAMODB {operation}\ntable: \"orders\""),
DatabaseType::DynamoDb
));
}
}
#[test]
fn classifies_search_engine_rest_writes() {
assert!(!is_write_sql_for_database("GET /_cluster/health", DatabaseType::Easysearch));