1use std::fmt::Write;
2
3use crate::create_column::{CreateColumn, CreateColumnImpl};
4use crate::error::Error;
5use crate::Value;
6
7#[derive(Debug)]
11pub enum AlterTableOperation<'until_build, 'post_build> {
12 RenameTo {
14 name: String,
16 },
17 RenameColumnTo {
19 column_name: String,
21 new_column_name: String,
23 },
24 AddColumn {
26 operation: CreateColumnImpl<'until_build, 'post_build>,
28 },
29 DropColumn {
31 name: String,
33 },
34}
35
36pub trait AlterTable<'post_build> {
40 fn build(self) -> Result<Vec<(String, Vec<Value<'post_build>>)>, Error>;
44}
45
46#[derive(Debug)]
50pub struct AlterTableData<'until_build, 'post_build> {
51 pub(crate) name: &'until_build str,
53 pub(crate) operation: AlterTableOperation<'until_build, 'post_build>,
55 pub(crate) lookup: Vec<Value<'post_build>>,
56 pub(crate) statements: Vec<(String, Vec<Value<'post_build>>)>,
57}
58
59#[derive(Debug)]
65pub enum AlterTableImpl<'until_build, 'post_build> {
66 #[cfg(feature = "sqlite")]
70 SQLite(AlterTableData<'until_build, 'post_build>),
71 #[cfg(feature = "postgres")]
75 Postgres(AlterTableData<'until_build, 'post_build>),
76}
77
78impl<'post_build> AlterTable<'post_build> for AlterTableImpl<'_, 'post_build> {
79 fn build(self) -> Result<Vec<(String, Vec<Value<'post_build>>)>, Error> {
80 match self {
81 #[cfg(feature = "sqlite")]
82 AlterTableImpl::SQLite(mut d) => {
83 let mut s = format!("ALTER TABLE \"{}\" ", d.name);
84
85 match d.operation {
86 AlterTableOperation::RenameTo { name } => {
87 write!(s, "RENAME TO \"{name}\"").unwrap();
88 }
89 AlterTableOperation::RenameColumnTo {
90 column_name,
91 new_column_name,
92 } => write!(
93 s,
94 "RENAME COLUMN \"{column_name}\" TO \"{new_column_name}\""
95 )
96 .unwrap(),
97 AlterTableOperation::AddColumn { mut operation } => {
98 write!(s, "ADD COLUMN ").unwrap();
99
100 if let CreateColumnImpl::SQLite(ccd) = &mut operation {
101 ccd.statements = Some(&mut d.statements);
102 ccd.lookup = Some(&mut d.lookup);
103 }
104
105 operation.build(&mut s)?;
106 }
107 AlterTableOperation::DropColumn { name } => {
108 write!(s, "DROP COLUMN \"{name}\"").unwrap()
109 }
110 };
111
112 write!(s, ";").unwrap();
113
114 let mut statements = vec![(s, d.lookup)];
115 statements.extend(d.statements);
116
117 Ok(statements)
118 }
119 #[cfg(feature = "postgres")]
120 AlterTableImpl::Postgres(mut d) => {
121 let mut s = format!("ALTER TABLE \"{}\" ", d.name);
122
123 match d.operation {
124 AlterTableOperation::RenameTo { name } => {
125 write!(s, "RENAME TO \"{name}\"").unwrap();
126 }
127
128 AlterTableOperation::RenameColumnTo {
129 column_name,
130 new_column_name,
131 } => {
132 write!(
133 s,
134 "RENAME COLUMN \"{column_name}\" TO \"{new_column_name}\""
135 )
136 .unwrap();
137 }
138 AlterTableOperation::AddColumn { mut operation } => {
139 write!(s, "ADD COLUMN ").unwrap();
140
141 #[allow(irrefutable_let_patterns)]
142 if let CreateColumnImpl::Postgres(ccd) = &mut operation {
143 ccd.statements = Some(&mut d.statements);
144 }
145
146 operation.build(&mut s)?;
147 }
148 AlterTableOperation::DropColumn { name } => {
149 write!(s, "DROP COLUMN \"{name}\"").unwrap()
150 }
151 };
152
153 write!(s, ";").unwrap();
154
155 let mut statements = vec![(s, d.lookup)];
156 statements.extend(d.statements);
157
158 Ok(statements)
159 }
160 }
161 }
162}