icydb_core/db/session/sql/surface/
route.rs1use crate::db::{
7 QueryError,
8 sql::lowering::{
9 LoweredSqlCommand, LoweredSqlLaneKind, PreparedSqlStatement as CorePreparedSqlStatement,
10 lower_sql_command_from_prepared_statement, lowered_sql_command_lane, prepare_sql_statement,
11 },
12 sql::parser::{SqlExplainTarget, SqlStatement},
13};
14
15#[derive(Clone, Debug, Eq, PartialEq)]
20pub enum SqlStatementRoute {
21 Query { entity: String },
22 Explain { entity: String },
23 Describe { entity: String },
24 ShowIndexes { entity: String },
25 ShowColumns { entity: String },
26 ShowEntities,
27}
28
29#[derive(Debug)]
31pub enum SqlDispatchResult {
32 Projection {
33 columns: Vec<String>,
34 rows: Vec<Vec<crate::value::Value>>,
35 row_count: u32,
36 },
37 ProjectionText {
38 columns: Vec<String>,
39 rows: Vec<Vec<String>>,
40 row_count: u32,
41 },
42 Explain(String),
43 Describe(crate::db::EntitySchemaDescription),
44 ShowIndexes(Vec<String>),
45 ShowColumns(Vec<crate::db::EntityFieldDescription>),
46 ShowEntities(Vec<String>),
47}
48
49#[derive(Clone, Debug)]
58pub struct SqlParsedStatement {
59 pub(in crate::db::session::sql) statement: SqlStatement,
60 route: SqlStatementRoute,
61}
62
63impl SqlParsedStatement {
64 pub(in crate::db::session::sql) const fn new(
66 statement: SqlStatement,
67 route: SqlStatementRoute,
68 ) -> Self {
69 Self { statement, route }
70 }
71
72 #[must_use]
74 pub const fn route(&self) -> &SqlStatementRoute {
75 &self.route
76 }
77
78 pub(in crate::db::session::sql) fn prepare(
80 &self,
81 expected_entity: &'static str,
82 ) -> Result<CorePreparedSqlStatement, QueryError> {
83 prepare_sql_statement(self.statement.clone(), expected_entity)
84 .map_err(QueryError::from_sql_lowering_error)
85 }
86
87 #[inline(never)]
89 pub fn lower_query_lane_for_entity(
90 &self,
91 expected_entity: &'static str,
92 primary_key_field: &str,
93 ) -> Result<LoweredSqlCommand, QueryError> {
94 let lowered = lower_sql_command_from_prepared_statement(
95 self.prepare(expected_entity)?,
96 primary_key_field,
97 )
98 .map_err(QueryError::from_sql_lowering_error)?;
99 let lane = lowered_sql_command_lane(&lowered);
100
101 match lane {
102 LoweredSqlLaneKind::Query | LoweredSqlLaneKind::Explain => Ok(lowered),
103 LoweredSqlLaneKind::Describe
104 | LoweredSqlLaneKind::ShowIndexes
105 | LoweredSqlLaneKind::ShowColumns
106 | LoweredSqlLaneKind::ShowEntities => {
107 Err(QueryError::unsupported_query_lane_dispatch())
108 }
109 }
110 }
111}
112
113impl SqlStatementRoute {
114 #[must_use]
119 pub const fn entity(&self) -> &str {
120 match self {
121 Self::Query { entity }
122 | Self::Explain { entity }
123 | Self::Describe { entity }
124 | Self::ShowIndexes { entity }
125 | Self::ShowColumns { entity } => entity.as_str(),
126 Self::ShowEntities => "",
127 }
128 }
129
130 #[must_use]
132 pub const fn is_explain(&self) -> bool {
133 matches!(self, Self::Explain { .. })
134 }
135
136 #[must_use]
138 pub const fn is_describe(&self) -> bool {
139 matches!(self, Self::Describe { .. })
140 }
141
142 #[must_use]
144 pub const fn is_show_indexes(&self) -> bool {
145 matches!(self, Self::ShowIndexes { .. })
146 }
147
148 #[must_use]
150 pub const fn is_show_columns(&self) -> bool {
151 matches!(self, Self::ShowColumns { .. })
152 }
153
154 #[must_use]
156 pub const fn is_show_entities(&self) -> bool {
157 matches!(self, Self::ShowEntities)
158 }
159}
160
161pub(in crate::db::session::sql) fn sql_statement_route_from_statement(
163 statement: &SqlStatement,
164) -> SqlStatementRoute {
165 match statement {
166 SqlStatement::Select(select) => SqlStatementRoute::Query {
167 entity: select.entity.clone(),
168 },
169 SqlStatement::Delete(delete) => SqlStatementRoute::Query {
170 entity: delete.entity.clone(),
171 },
172 SqlStatement::Explain(explain) => match &explain.statement {
173 SqlExplainTarget::Select(select) => SqlStatementRoute::Explain {
174 entity: select.entity.clone(),
175 },
176 SqlExplainTarget::Delete(delete) => SqlStatementRoute::Explain {
177 entity: delete.entity.clone(),
178 },
179 },
180 SqlStatement::Describe(describe) => SqlStatementRoute::Describe {
181 entity: describe.entity.clone(),
182 },
183 SqlStatement::ShowIndexes(show_indexes) => SqlStatementRoute::ShowIndexes {
184 entity: show_indexes.entity.clone(),
185 },
186 SqlStatement::ShowColumns(show_columns) => SqlStatementRoute::ShowColumns {
187 entity: show_columns.entity.clone(),
188 },
189 SqlStatement::ShowEntities(_) => SqlStatementRoute::ShowEntities,
190 }
191}