database_replicator/jsonb/
mod.rs1pub mod writer;
5
6use anyhow::{bail, Result};
7
8pub fn validate_table_name(table_name: &str) -> Result<()> {
36 if table_name.is_empty() {
37 bail!("Table name cannot be empty");
38 }
39
40 if table_name.len() > 63 {
41 bail!("Table name too long (max 63 characters): {}", table_name);
42 }
43
44 for ch in table_name.chars() {
46 if !ch.is_ascii_alphanumeric() && ch != '_' {
47 bail!(
48 "Invalid table name '{}': contains invalid character '{}'. \
49 Only alphanumeric characters and underscores are allowed.",
50 table_name,
51 ch
52 );
53 }
54 }
55
56 let lower = table_name.to_lowercase();
58 let reserved_keywords = [
59 "select",
60 "insert",
61 "update",
62 "delete",
63 "drop",
64 "create",
65 "alter",
66 "table",
67 "database",
68 "index",
69 "view",
70 "function",
71 "procedure",
72 "trigger",
73 "user",
74 "role",
75 "grant",
76 "revoke",
77 ];
78
79 if reserved_keywords.contains(&lower.as_str()) {
80 bail!(
81 "Invalid table name '{}': cannot use SQL reserved keyword",
82 table_name
83 );
84 }
85
86 Ok(())
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_valid_table_names() {
95 assert!(validate_table_name("users").is_ok());
96 assert!(validate_table_name("user_events").is_ok());
97 assert!(validate_table_name("UserEvents2024").is_ok());
98 assert!(validate_table_name("_private").is_ok());
99 assert!(validate_table_name("table123").is_ok());
100 }
101
102 #[test]
103 fn test_invalid_table_names() {
104 assert!(validate_table_name("users; DROP TABLE users;").is_err());
106 assert!(validate_table_name("users'--").is_err());
107 assert!(validate_table_name("users OR 1=1").is_err());
108 assert!(validate_table_name("users/**/").is_err());
109
110 assert!(validate_table_name("users-events").is_err());
112 assert!(validate_table_name("users.events").is_err());
113 assert!(validate_table_name("users@host").is_err());
114 assert!(validate_table_name("users$var").is_err());
115
116 assert!(validate_table_name("").is_err());
118 assert!(validate_table_name(&"a".repeat(64)).is_err());
119
120 assert!(validate_table_name("select").is_err());
122 assert!(validate_table_name("SELECT").is_err());
123 assert!(validate_table_name("table").is_err());
124 assert!(validate_table_name("drop").is_err());
125 }
126}