vibesql_executor/
view_ddl.rs1use vibesql_ast::{CreateViewStmt, DropViewStmt};
4use vibesql_catalog::{ViewDefinition, ViewDropBehavior};
5use vibesql_storage::Database;
6
7use crate::errors::ExecutorError;
8
9pub struct ViewExecutor;
11
12impl ViewExecutor {
13 pub fn execute_create_view(
15 stmt: &CreateViewStmt,
16 database: &mut Database,
17 ) -> Result<String, ExecutorError> {
18 if stmt.or_replace {
20 let view_exists = database.catalog.get_view(&stmt.view_name).is_some();
21 if view_exists {
22 database
24 .catalog
25 .drop_view(&stmt.view_name, false)
26 .map_err(|e| ExecutorError::StorageError(format!("Failed to drop existing view: {:?}", e)))?;
27 }
28 }
29
30 let view_def = ViewDefinition::new(
32 stmt.view_name.clone(),
33 stmt.columns.clone(),
34 *stmt.query.clone(),
35 stmt.with_check_option,
36 );
37
38 database
40 .catalog
41 .create_view(view_def)
42 .map_err(|e| ExecutorError::StorageError(format!("Failed to create view: {:?}", e)))?;
43
44 if stmt.or_replace {
45 Ok(format!("View '{}' created or replaced", stmt.view_name))
46 } else {
47 Ok(format!("View '{}' created", stmt.view_name))
48 }
49 }
50
51 pub fn execute_drop_view(
53 stmt: &DropViewStmt,
54 database: &mut Database,
55 ) -> Result<String, ExecutorError> {
56 let drop_behavior = if stmt.cascade {
61 ViewDropBehavior::Cascade
62 } else if stmt.restrict {
63 ViewDropBehavior::Restrict
64 } else {
65 ViewDropBehavior::Silent };
67
68 let result = database
70 .catalog
71 .drop_view_with_behavior(&stmt.view_name, drop_behavior);
72
73 match result {
74 Ok(()) => Ok(format!("View '{}' dropped", stmt.view_name)),
75 Err(e) => {
76 if stmt.if_exists && matches!(e, vibesql_catalog::errors::CatalogError::ViewNotFound(_)) {
78 Ok(format!("View '{}' does not exist (skipped)", stmt.view_name))
79 } else {
80 Err(ExecutorError::StorageError(format!("Failed to drop view: {:?}", e)))
81 }
82 }
83 }
84 }
85}