fire_postgres/table/
util.rs

1use super::column::{Column, IndexKind};
2use super::{ColumnData, TableTemplate};
3use crate::Result;
4
5use tokio_postgres::row::Row;
6use tokio_postgres::types::ToSql;
7
8pub fn data_into_sql_params<'a>(
9	data: &'a [ColumnData],
10) -> Vec<&'a (dyn ToSql + Sync)> {
11	data.iter().map(|d| d as &(dyn ToSql + Sync)).collect()
12}
13
14pub fn rows_into_data<T>(rows: Vec<Row>) -> Result<Vec<T>>
15where
16	T: TableTemplate,
17{
18	let mut new_rows = Vec::with_capacity(rows.len());
19
20	for row in rows {
21		let mut data: Vec<ColumnData> = Vec::with_capacity(row.len());
22		for i in 0..row.len() {
23			data.push(row.try_get(i)?);
24		}
25		new_rows.push(T::from_data(data)?);
26	}
27
28	Ok(new_rows)
29}
30
31pub fn info_data_to_sql(name: &str, data: &[Column]) -> String {
32	let mut primary_indexes = vec![];
33	let mut normal_indexes = vec![];
34	let mut unique_indexes = vec![]; // (name, vec![])
35
36	let mut cols_sql = vec![];
37
38	for col in data {
39		let kind = col.kind.to_string(col.name);
40		let not_null = col.kind.not_null_str();
41		let quoted_name = quote(col.name);
42
43		cols_sql.push(format!("{} {} {}", quoted_name, kind, not_null));
44
45		match col.index {
46			IndexKind::Primary => primary_indexes.push(quoted_name),
47			IndexKind::Unique => {
48				unique_indexes.push((col.name, vec![quoted_name]))
49			}
50			IndexKind::NamedUnique(n) => 'match_arm: loop {
51				for ind in unique_indexes.iter_mut() {
52					if ind.0 == n {
53						ind.1.push(quoted_name);
54						break 'match_arm;
55					}
56				}
57				unique_indexes.push((n, vec![quoted_name]));
58				break;
59			},
60			IndexKind::Index => normal_indexes.push(col.name),
61			IndexKind::None => {}
62		}
63	}
64
65	cols_sql.push(format!("PRIMARY KEY ({})", primary_indexes.join(", ")));
66	for ind in unique_indexes {
67		cols_sql.push(format!("UNIQUE ({})", ind.1.join(", ")));
68	}
69
70	let mut sqls = vec![format!(
71		"CREATE TABLE IF NOT EXISTS \"{}\" ({})",
72		name,
73		cols_sql.join(", ")
74	)];
75
76	for ind in normal_indexes {
77		let index_name = format!("{}_{}_nidx", name, ind);
78		sqls.push(format!(
79			"CREATE INDEX IF NOT EXISTS {} ON \"{}\" (\"{}\")",
80			index_name, name, ind
81		));
82	}
83
84	sqls.join("; ")
85}
86
87pub fn quote(s: &str) -> String {
88	format!("\"{}\"", s)
89}
90
91// maybe this is not important because table name can't be -
92/*pub fn sanitize_index_name(name: String) -> String {
93	name
94		.replace("-", "_")
95		.replace(" ", "_")
96}*/