1use std::fmt::{Display, Formatter};
16
17use api::v1::TableName as PbTableName;
18use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
19use serde::{Deserialize, Serialize};
20use snafu::ensure;
21
22use crate::error;
23use crate::error::InvalidTableNameSnafu;
24use crate::table_reference::TableReference;
25
26#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize, Serialize)]
27pub struct TableName {
28 pub catalog_name: String,
29 pub schema_name: String,
30 pub table_name: String,
31}
32
33impl Display for TableName {
34 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35 f.write_str(&common_catalog::format_full_table_name(
36 &self.catalog_name,
37 &self.schema_name,
38 &self.table_name,
39 ))
40 }
41}
42
43impl TableName {
44 pub fn new(
45 catalog_name: impl Into<String>,
46 schema_name: impl Into<String>,
47 table_name: impl Into<String>,
48 ) -> Self {
49 Self {
50 catalog_name: catalog_name.into(),
51 schema_name: schema_name.into(),
52 table_name: table_name.into(),
53 }
54 }
55
56 pub fn table_ref(&self) -> TableReference<'_> {
57 TableReference {
58 catalog: &self.catalog_name,
59 schema: &self.schema_name,
60 table: &self.table_name,
61 }
62 }
63}
64
65impl From<TableName> for PbTableName {
66 fn from(table_name: TableName) -> Self {
67 Self {
68 catalog_name: table_name.catalog_name,
69 schema_name: table_name.schema_name,
70 table_name: table_name.table_name,
71 }
72 }
73}
74
75impl From<PbTableName> for TableName {
76 fn from(table_name: PbTableName) -> Self {
77 Self {
78 catalog_name: table_name.catalog_name,
79 schema_name: table_name.schema_name,
80 table_name: table_name.table_name,
81 }
82 }
83}
84
85impl From<TableReference<'_>> for TableName {
86 fn from(table_ref: TableReference) -> Self {
87 Self::new(table_ref.catalog, table_ref.schema, table_ref.table)
88 }
89}
90
91impl TryFrom<Vec<String>> for TableName {
92 type Error = error::Error;
93
94 fn try_from(v: Vec<String>) -> Result<Self, Self::Error> {
95 ensure!(
96 !v.is_empty() && v.len() <= 3,
97 InvalidTableNameSnafu {
98 s: format!("{v:?}")
99 }
100 );
101 let mut v = v.into_iter();
102 match (v.next(), v.next(), v.next()) {
103 (Some(catalog_name), Some(schema_name), Some(table_name)) => Ok(Self {
104 catalog_name,
105 schema_name,
106 table_name,
107 }),
108 (Some(schema_name), Some(table_name), None) => Ok(Self {
109 catalog_name: DEFAULT_CATALOG_NAME.to_string(),
110 schema_name,
111 table_name,
112 }),
113 (Some(table_name), None, None) => Ok(Self {
114 catalog_name: DEFAULT_CATALOG_NAME.to_string(),
115 schema_name: DEFAULT_SCHEMA_NAME.to_string(),
116 table_name,
117 }),
118 _ => unreachable!(),
121 }
122 }
123}