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 Explain(String),
38 Describe(crate::db::EntitySchemaDescription),
39 ShowIndexes(Vec<String>),
40 ShowColumns(Vec<crate::db::EntityFieldDescription>),
41 ShowEntities(Vec<String>),
42}
43
44#[derive(Clone, Debug)]
53pub struct SqlParsedStatement {
54 pub(in crate::db::session::sql) statement: SqlStatement,
55 route: SqlStatementRoute,
56}
57
58impl SqlParsedStatement {
59 pub(in crate::db::session::sql) const fn new(
61 statement: SqlStatement,
62 route: SqlStatementRoute,
63 ) -> Self {
64 Self { statement, route }
65 }
66
67 #[must_use]
69 pub const fn route(&self) -> &SqlStatementRoute {
70 &self.route
71 }
72
73 pub(in crate::db::session::sql) fn prepare(
75 &self,
76 expected_entity: &'static str,
77 ) -> Result<CorePreparedSqlStatement, QueryError> {
78 prepare_sql_statement(self.statement.clone(), expected_entity)
79 .map_err(QueryError::from_sql_lowering_error)
80 }
81
82 #[inline(never)]
84 pub fn lower_query_lane_for_entity(
85 &self,
86 expected_entity: &'static str,
87 primary_key_field: &str,
88 ) -> Result<LoweredSqlCommand, QueryError> {
89 let lowered = lower_sql_command_from_prepared_statement(
90 self.prepare(expected_entity)?,
91 primary_key_field,
92 )
93 .map_err(QueryError::from_sql_lowering_error)?;
94 let lane = lowered_sql_command_lane(&lowered);
95
96 match lane {
97 LoweredSqlLaneKind::Query | LoweredSqlLaneKind::Explain => Ok(lowered),
98 LoweredSqlLaneKind::Describe
99 | LoweredSqlLaneKind::ShowIndexes
100 | LoweredSqlLaneKind::ShowColumns
101 | LoweredSqlLaneKind::ShowEntities => {
102 Err(QueryError::unsupported_query_lane_dispatch())
103 }
104 }
105 }
106}
107
108impl SqlStatementRoute {
109 #[must_use]
114 pub const fn entity(&self) -> &str {
115 match self {
116 Self::Query { entity }
117 | Self::Explain { entity }
118 | Self::Describe { entity }
119 | Self::ShowIndexes { entity }
120 | Self::ShowColumns { entity } => entity.as_str(),
121 Self::ShowEntities => "",
122 }
123 }
124
125 #[must_use]
127 pub const fn is_explain(&self) -> bool {
128 matches!(self, Self::Explain { .. })
129 }
130
131 #[must_use]
133 pub const fn is_describe(&self) -> bool {
134 matches!(self, Self::Describe { .. })
135 }
136
137 #[must_use]
139 pub const fn is_show_indexes(&self) -> bool {
140 matches!(self, Self::ShowIndexes { .. })
141 }
142
143 #[must_use]
145 pub const fn is_show_columns(&self) -> bool {
146 matches!(self, Self::ShowColumns { .. })
147 }
148
149 #[must_use]
151 pub const fn is_show_entities(&self) -> bool {
152 matches!(self, Self::ShowEntities)
153 }
154}
155
156pub(in crate::db::session::sql) fn sql_statement_route_from_statement(
158 statement: &SqlStatement,
159) -> SqlStatementRoute {
160 match statement {
161 SqlStatement::Select(select) => SqlStatementRoute::Query {
162 entity: select.entity.clone(),
163 },
164 SqlStatement::Delete(delete) => SqlStatementRoute::Query {
165 entity: delete.entity.clone(),
166 },
167 SqlStatement::Explain(explain) => match &explain.statement {
168 SqlExplainTarget::Select(select) => SqlStatementRoute::Explain {
169 entity: select.entity.clone(),
170 },
171 SqlExplainTarget::Delete(delete) => SqlStatementRoute::Explain {
172 entity: delete.entity.clone(),
173 },
174 },
175 SqlStatement::Describe(describe) => SqlStatementRoute::Describe {
176 entity: describe.entity.clone(),
177 },
178 SqlStatement::ShowIndexes(show_indexes) => SqlStatementRoute::ShowIndexes {
179 entity: show_indexes.entity.clone(),
180 },
181 SqlStatement::ShowColumns(show_columns) => SqlStatementRoute::ShowColumns {
182 entity: show_columns.entity.clone(),
183 },
184 SqlStatement::ShowEntities(_) => SqlStatementRoute::ShowEntities,
185 }
186}