Skip to main content

reinhardt_query/query/
create_view.rs

1//! CREATE VIEW statement builder
2//!
3//! This module provides the `CreateViewStatement` type for building SQL CREATE VIEW queries.
4
5use crate::{
6	backend::QueryBuilder,
7	query::SelectStatement,
8	types::{DynIden, IntoIden},
9};
10
11use super::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
12
13/// CREATE VIEW statement builder
14///
15/// This struct provides a fluent API for constructing CREATE VIEW queries.
16///
17/// # Examples
18///
19/// ```rust,ignore
20/// use reinhardt_query::prelude::*;
21///
22/// let select = Query::select()
23///     .column(Expr::col("name"))
24///     .column(Expr::col("email"))
25///     .from("users")
26///     .and_where(Expr::col("active").eq(true));
27///
28/// let query = Query::create_view()
29///     .name("active_users")
30///     .as_select(select)
31///     .if_not_exists();
32/// ```
33#[derive(Debug, Clone)]
34pub struct CreateViewStatement {
35	pub(crate) name: Option<DynIden>,
36	pub(crate) select: Option<SelectStatement>,
37	pub(crate) if_not_exists: bool,
38	pub(crate) or_replace: bool,
39	pub(crate) columns: Vec<DynIden>,
40	pub(crate) materialized: bool,
41}
42
43impl CreateViewStatement {
44	/// Create a new CREATE VIEW statement
45	pub fn new() -> Self {
46		Self {
47			name: None,
48			select: None,
49			if_not_exists: false,
50			or_replace: false,
51			columns: Vec::new(),
52			materialized: false,
53		}
54	}
55
56	/// Take the ownership of data in the current [`CreateViewStatement`]
57	pub fn take(&mut self) -> Self {
58		Self {
59			name: self.name.take(),
60			select: self.select.take(),
61			if_not_exists: self.if_not_exists,
62			or_replace: self.or_replace,
63			columns: std::mem::take(&mut self.columns),
64			materialized: self.materialized,
65		}
66	}
67
68	/// Set the view name
69	///
70	/// # Examples
71	///
72	/// ```rust,ignore
73	/// use reinhardt_query::prelude::*;
74	///
75	/// let query = Query::create_view()
76	///     .name("active_users");
77	/// ```
78	pub fn name<N>(&mut self, name: N) -> &mut Self
79	where
80		N: IntoIden,
81	{
82		self.name = Some(name.into_iden());
83		self
84	}
85
86	/// Set the SELECT statement for the view
87	///
88	/// # Examples
89	///
90	/// ```rust,ignore
91	/// use reinhardt_query::prelude::*;
92	///
93	/// let select = Query::select()
94	///     .column(Expr::col("name"))
95	///     .from("users");
96	///
97	/// let query = Query::create_view()
98	///     .name("user_names")
99	///     .as_select(select);
100	/// ```
101	pub fn as_select(&mut self, select: SelectStatement) -> &mut Self {
102		self.select = Some(select);
103		self
104	}
105
106	/// Add IF NOT EXISTS clause
107	///
108	/// # Examples
109	///
110	/// ```rust,ignore
111	/// use reinhardt_query::prelude::*;
112	///
113	/// let query = Query::create_view()
114	///     .name("active_users")
115	///     .if_not_exists();
116	/// ```
117	pub fn if_not_exists(&mut self) -> &mut Self {
118		self.if_not_exists = true;
119		self
120	}
121
122	/// Add OR REPLACE clause
123	///
124	/// Note: Cannot be used with IF NOT EXISTS
125	///
126	/// # Examples
127	///
128	/// ```rust,ignore
129	/// use reinhardt_query::prelude::*;
130	///
131	/// let query = Query::create_view()
132	///     .name("active_users")
133	///     .or_replace();
134	/// ```
135	pub fn or_replace(&mut self) -> &mut Self {
136		self.or_replace = true;
137		self
138	}
139
140	/// Set column names for the view
141	///
142	/// # Examples
143	///
144	/// ```rust,ignore
145	/// use reinhardt_query::prelude::*;
146	///
147	/// let query = Query::create_view()
148	///     .name("active_users")
149	///     .columns(["user_name", "user_email"]);
150	/// ```
151	pub fn columns<I, C>(&mut self, cols: I) -> &mut Self
152	where
153		I: IntoIterator<Item = C>,
154		C: IntoIden,
155	{
156		for col in cols {
157			self.columns.push(col.into_iden());
158		}
159		self
160	}
161
162	/// Set MATERIALIZED flag (PostgreSQL only)
163	///
164	/// # Examples
165	///
166	/// ```rust,ignore
167	/// use reinhardt_query::prelude::*;
168	///
169	/// let query = Query::create_view()
170	///     .name("active_users")
171	///     .materialized(true);
172	/// ```
173	pub fn materialized(&mut self, materialized: bool) -> &mut Self {
174		self.materialized = materialized;
175		self
176	}
177}
178
179impl Default for CreateViewStatement {
180	fn default() -> Self {
181		Self::new()
182	}
183}
184
185impl QueryStatementBuilder for CreateViewStatement {
186	fn build_any(&self, query_builder: &dyn QueryBuilderTrait) -> (String, crate::value::Values) {
187		// Downcast to concrete QueryBuilder type
188		use std::any::Any;
189		if let Some(builder) =
190			(query_builder as &dyn Any).downcast_ref::<crate::backend::PostgresQueryBuilder>()
191		{
192			return builder.build_create_view(self);
193		}
194		if let Some(builder) =
195			(query_builder as &dyn Any).downcast_ref::<crate::backend::MySqlQueryBuilder>()
196		{
197			return builder.build_create_view(self);
198		}
199		if let Some(builder) =
200			(query_builder as &dyn Any).downcast_ref::<crate::backend::SqliteQueryBuilder>()
201		{
202			return builder.build_create_view(self);
203		}
204		panic!("Unsupported query builder type");
205	}
206}
207
208impl QueryStatementWriter for CreateViewStatement {}