1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//! Alias format for different table aliases.
/// This determines how the [AliasTranslator](crate::alias_translator::AliasTranslator) formats table aliases in SQL code.
/// Toql uses table aliases for every column.
/// E.g. in `user_address_country.id` the table alias is `user_address_country` and `id` is the column.
///
/// There are 4 different formats to cater for development and production environments:
/// - [Canonical](AliasFormat::Canonical), this is the internal and default alias.
/// It is the most verbose and useful for debugging, it can however heavily blow up SQL statements. Example: `user_address_country`.
/// - [MediumIndex](AliasFormat::MediumIndex), last part of the canonical alias plus number: `country1`
/// - [ShortIndex](AliasFormat::ShortIndex), first 2 characters of the last part of the canonical alias plus number: `co1`
/// - [TinyIndex](AliasFormat::TinyIndex) the shortest possible alias, not human friendly, but useful for production as it's fast for databases to parse.
/// Its made up of the letter t plus a number:`t1`
#[derive(Clone, Debug)]
pub enum AliasFormat {
/// Letter _t_ plus number
TinyIndex,
/// First 2 characters of last canonical path node plus number
ShortIndex,
/// Last canonical path node plus number
MediumIndex,
/// Full canonical path
Canonical,
}
impl AliasFormat {
/// Creates a tiny alias from an index number
pub fn tiny_index(index: u16) -> String {
let mut tiny_name = String::from("t");
tiny_name.push_str(index.to_string().as_str());
tiny_name
}
/// Creates a short alias from a name and an index number.
/// If the name ends with a number an underscore is added to separate it from the index.
pub fn short_index(name: &str, index: u16) -> String {
let medium_name = String::from(if name.is_empty() {
"t"
} else {
let x = name.rfind('_');
if let Some(xi) = x {
&name[(xi + 1)..]
} else {
name
}
});
let mut it = medium_name.chars();
let f = it.next().unwrap_or('t');
let mut short_name = String::new();
short_name.push(f);
let s = it.next();
if let Some(sv) = s {
short_name.push(sv);
if sv.is_ascii_digit() {
short_name.push('_');
}
}
short_name.push_str(index.to_string().as_str());
short_name
}
/// Creates a medium alias from a name and an index number.
/// If the name ends with a number an underscore is added to separate it from the index.
pub fn medium_index(name: &str, index: u16) -> String {
// let mut wrap = false;
let mut medium_name = String::from(if name.is_empty() {
"t"
} else {
let x = name.rfind('_');
if let Some(xi) = x {
&name[(xi + 1)..]
} else {
name
}
});
let c = medium_name.chars().last().unwrap();
if c.is_ascii_digit() {
medium_name.push('_');
}
medium_name.push_str(index.to_string().as_str());
medium_name
}
}
#[cfg(test)]
mod test {
use super::AliasFormat;
#[test]
fn format_tiny() {
assert_eq!(AliasFormat::tiny_index(1), "t1");
}
#[test]
fn format_short() {
assert_eq!(AliasFormat::short_index("red_green_blue", 1), "bl1");
assert_eq!(AliasFormat::short_index("level1_level2_level3", 1), "le1");
assert_eq!(AliasFormat::short_index("l1_l2_l3", 1), "l3_1");
assert_eq!(AliasFormat::short_index("", 1), "t1");
}
#[test]
fn format_medium() {
assert_eq!(AliasFormat::medium_index("red_green_blue", 1), "blue1");
assert_eq!(
AliasFormat::medium_index("level1_level2_level3", 1),
"level3_1"
);
assert_eq!(AliasFormat::medium_index("", 1), "t1");
}
}