sea_schema/mysql/query/
table.rs1use super::{CharacterSetFields, InformationSchema, SchemaQueryBuilder};
2use crate::sqlx_types::SqlxRow;
3use sea_query::{Condition, DynIden, Expr, ExprTrait, Iden, Order, Query, SelectStatement};
4
5const MARIADB_FULL_COLLATION_NAME_SINCE: u32 = 101001;
6
7#[derive(Debug, Clone, Copy, sea_query::Iden)]
8pub enum TablesFields {
12 TableCatalog,
13 TableSchema,
14 TableName,
15 TableType,
16 Engine,
17 Version,
18 RowFormat,
19 TableRows,
20 AvgRowLength,
21 DataLength,
22 MaxDataLength,
23 IndexLength,
24 DataFree,
25 AutoIncrement,
26 CreateTime,
27 UpdateTime,
28 CheckTime,
29 TableCollation,
30 Checksum,
31 CreateOptions,
32 TableComment,
33}
34
35#[derive(Debug, sea_query::Iden)]
36pub enum TableType {
37 #[iden = "BASE TABLE"]
38 BaseTable,
39 #[iden = "VIEW"]
40 View,
41 #[iden = "SYSTEM VIEW"]
42 SystemView,
43 #[iden = "SYSTEM VERSIONED"]
44 SystemVersioned,
45}
46
47#[derive(Debug, Default)]
48pub struct TableQueryResult {
49 pub table_name: String,
50 pub engine: String,
51 pub auto_increment: Option<u64>,
52 pub table_char_set: Option<String>,
53 pub table_collation: Option<String>,
54 pub table_comment: String,
55 pub create_options: String,
56}
57
58impl SchemaQueryBuilder {
59 pub fn query_tables(&self, schema: DynIden) -> SelectStatement {
60 type Schema = InformationSchema;
61 let is_mariadb_and_ge_10_10_01 =
62 self.system.is_maria_db() && self.system.version >= MARIADB_FULL_COLLATION_NAME_SINCE;
63
64 Query::select()
65 .columns(vec![
66 TablesFields::TableName,
67 TablesFields::Engine,
68 TablesFields::AutoIncrement,
69 TablesFields::TableCollation,
70 TablesFields::TableComment,
71 TablesFields::CreateOptions,
72 ])
73 .column((
74 Schema::CollationCharacterSet,
75 CharacterSetFields::CharacterSetName,
76 ))
77 .from((Schema::Schema, Schema::Tables))
78 .left_join((Schema::Schema, Schema::CollationCharacterSet), {
79 let info_tables_collation = (Schema::Tables, TablesFields::TableCollation);
80 Condition::any()
81 .add_option(is_mariadb_and_ge_10_10_01.then(|| {
82 Expr::col((
83 Schema::CollationCharacterSet,
84 CharacterSetFields::FullCollationName,
85 ))
86 .equals(info_tables_collation)
87 }))
88 .add(
89 Expr::col((
90 Schema::CollationCharacterSet,
91 CharacterSetFields::CollationName,
92 ))
93 .equals(info_tables_collation),
94 )
95 })
96 .and_where(Expr::col(TablesFields::TableSchema).eq(schema.to_string()))
97 .and_where(Expr::col(TablesFields::TableType).is_in([
98 TableType::BaseTable.to_string(),
99 TableType::SystemVersioned.to_string(),
100 ]))
101 .order_by(TablesFields::TableName, Order::Asc)
102 .take()
103 }
104}
105
106#[cfg(feature = "sqlx-mysql")]
107impl From<SqlxRow> for TableQueryResult {
108 fn from(row: SqlxRow) -> Self {
109 use crate::mysql::discovery::GetMySqlValue;
110 use crate::sqlx_types::Row;
111 let row = row.mysql();
112 Self {
113 table_name: row.get_string(0),
114 engine: row.get_string(1),
115 auto_increment: row.get(2),
116 table_collation: row.get_string_opt(3),
117 table_comment: row.get_string(4),
118 create_options: row.get_string(5),
119 table_char_set: row.get_string_opt(6),
120 }
121 }
122}
123
124#[cfg(not(feature = "sqlx-mysql"))]
125impl From<SqlxRow> for TableQueryResult {
126 fn from(_: SqlxRow) -> Self {
127 Self::default()
128 }
129}