qail_core/transformer/
traits.rs

1//! Core traits for the transformer system
2
3use sqlparser::ast::Statement;
4use std::fmt;
5
6/// Error during pattern extraction
7#[derive(Debug, Clone)]
8pub struct ExtractError {
9    pub message: String,
10}
11
12impl fmt::Display for ExtractError {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        write!(f, "{}", self.message)
15    }
16}
17
18impl std::error::Error for ExtractError {}
19
20/// Error during code generation
21#[derive(Debug, Clone)]
22pub struct TransformError {
23    pub message: String,
24}
25
26impl fmt::Display for TransformError {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        write!(f, "{}", self.message)
29    }
30}
31
32impl std::error::Error for TransformError {}
33
34/// Extracted data from a SQL pattern
35#[derive(Debug, Clone)]
36pub enum PatternData {
37    /// SELECT query data
38    Select {
39        table: String,
40        columns: Vec<String>,
41        filter: Option<FilterData>,
42        order_by: Option<Vec<OrderByData>>,
43        limit: Option<u64>,
44        joins: Vec<JoinData>,
45    },
46    /// INSERT query data
47    Insert {
48        table: String,
49        columns: Vec<String>,
50        values: Vec<ValueData>,
51        returning: Option<Vec<String>>,
52    },
53    /// UPDATE query data
54    Update {
55        table: String,
56        set_values: Vec<SetValueData>,
57        filter: Option<FilterData>,
58        returning: Option<Vec<String>>,
59    },
60    /// DELETE query data
61    Delete {
62        table: String,
63        filter: Option<FilterData>,
64        returning: Option<Vec<String>>,
65    },
66}
67
68/// Filter condition data
69#[derive(Debug, Clone)]
70pub struct FilterData {
71    pub column: String,
72    pub operator: String,
73    pub value: ValueData,
74}
75
76/// ORDER BY data
77#[derive(Debug, Clone)]
78pub struct OrderByData {
79    pub column: String,
80    pub descending: bool,
81}
82
83/// JOIN data
84#[derive(Debug, Clone)]
85pub struct JoinData {
86    pub table: String,
87    pub on_left: String,
88    pub on_right: String,
89    pub join_type: JoinType,
90}
91
92#[derive(Debug, Clone)]
93pub enum JoinType {
94    Inner,
95    Left,
96    Right,
97    Full,
98}
99
100/// Value data (column, literal, or parameter)
101#[derive(Debug, Clone)]
102pub enum ValueData {
103    Column(String),
104    Literal(String),
105    Param(usize), // $1, $2, etc.
106    Null,
107}
108
109/// SET clause data for UPDATE
110#[derive(Debug, Clone)]
111pub struct SetValueData {
112    pub column: String,
113    pub value: ValueData,
114}
115
116/// Context for pattern matching
117#[derive(Debug, Default)]
118pub struct MatchContext {
119    pub binds: Vec<String>,
120    pub return_type: Option<String>,
121    pub fetch_method: String,
122}
123
124/// Context for code generation
125#[derive(Debug, Default)]
126pub struct TransformContext {
127    pub indent: usize,
128    pub include_imports: bool,
129    pub binds: Vec<String>,
130    pub return_type: Option<String>,
131}
132
133/// Trait for SQL pattern matching and transformation
134pub trait SqlPattern: Send + Sync {
135    fn id(&self) -> &'static str;
136
137    fn priority(&self) -> u32 {
138        100
139    }
140
141    /// Check if this pattern matches the SQL statement
142    fn matches(&self, stmt: &Statement, ctx: &MatchContext) -> bool;
143
144    fn extract(&self, stmt: &Statement, ctx: &MatchContext) -> Result<PatternData, ExtractError>;
145
146    /// Generate QAIL code from extracted data
147    fn transform(&self, data: &PatternData, ctx: &TransformContext) -> Result<String, TransformError>;
148}
149
150/// Trait for target language code generation
151pub trait TargetLanguage: Send + Sync {
152    fn name(&self) -> &'static str;
153
154    fn emit_import(&self, items: &[&str]) -> String;
155
156    fn emit_variable(&self, name: &str, type_: &str, value: &str) -> String;
157
158    fn emit_method_chain(&self, receiver: &str, methods: &[(String, Vec<String>)]) -> String;
159
160    fn emit_await(&self, expr: &str) -> String;
161
162    fn emit_error_handling(&self, expr: &str) -> String;
163}