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
use {
	super::select::{refine_items, Manual},
	crate::{
		executor::{
			fetch::fetch_columns,
			types::{ColumnInfo, ComplexTableName},
		},
		Glue, Result,
	},
	async_recursion::async_recursion,
};

impl Glue {
	pub async fn get_columns(&self, table: ComplexTableName) -> Result<Vec<ColumnInfo>> {
		let context_tables = {
			let context = self.get_context().unwrap();
			context.tables.clone()
		};
		if let Some((context_table_labels, ..)) = context_tables.get(&table.name) {
			Ok(context_table_labels
				.iter()
				.map(|name| ColumnInfo {
					table: table.clone(),
					name: name.clone(),
					index: None,
				})
				.collect::<Vec<ColumnInfo>>())
		} else {
			let view_labels = self.get_view_columns(&table.name, &table.database).await?;
			if let Some(labels) = view_labels {
				let labels = labels
					.into_iter()
					.map(|name| ColumnInfo {
						table: table.clone(),
						name,
						index: None,
					})
					.collect();
				Ok(labels)
			} else {
				fetch_columns(&**self.get_database(&table.database)?, table).await
			}
		}
	}
	#[async_recursion(?Send)]
	pub async fn get_view_columns(
		&self,
		view_name: &str,
		database: &Option<String>,
	) -> Result<Option<Vec<String>>> {
		let query = self.get_view_query(view_name, database).await?;
		if let Some(query) = query {
			let plan = Manual::new(self, query)?;
			let (_, columns) = self.arrange_joins(plan.joins).await?;
			let labels = refine_items(plan.select_items, &columns, false)?
				.into_iter()
				.map(|(_recipe, label)| label)
				.collect();
			Ok(Some(labels))
		} else {
			Ok(None)
		}
	}
}