|
1 | | -use std::borrow::Cow; |
2 | | -use crate::query::querybuilder::syntax::ast::delete::DeleteAst; |
3 | | -use crate::query::querybuilder::syntax::ast::insert::InsertAst; |
4 | | -use crate::query::querybuilder::syntax::ast::select::SelectAst; |
5 | | -use crate::query::querybuilder::syntax::ast::update::UpdateAst; |
6 | | -use crate::query::querybuilder::syntax::clause::ConditionClause; |
7 | | -use crate::query::querybuilder::syntax::query_kind::QueryKind; |
8 | 1 | use crate::query::querybuilder::syntax::table_metadata::TableMetadata; |
9 | | -use crate::query::querybuilder::syntax::tokens::{SqlToken, Symbol, ToSqlTokens}; |
10 | | -use crate::query::querybuilder::syntax::tokens::Symbol::{LParen, RParen}; |
| 2 | +use crate::query::querybuilder::syntax::tokens::SqlToken; |
11 | 3 |
|
12 | | -// ---------- AST Processor marker trait ---------- |
13 | | -pub trait AstProcessor: Default { |
14 | | - // TODO: get base? as mut ref for convenience? |
15 | | -} // TODO: maybe this and the other one are visitor related? |
16 | | - |
17 | | -// ---------- Emit traits ---------- |
18 | | -pub trait EmitKind<'a> { |
19 | | - fn emit_kind(&self, out: &mut Vec<SqlToken<'a>>); |
| 4 | +// default impl returns None; concrete ASTs override to return Some(&self as &dyn ...) |
| 5 | +pub trait AsEmitKind<'a> { |
| 6 | + fn as_emit_kind(&self) -> Option<&dyn EmitKind<'a>> { None } |
20 | 7 | } |
21 | | -pub trait EmitFrom<'a> { |
22 | | - fn emit_from<'b>(&self, meta: &TableMetadata<'b>, out: &mut Vec<SqlToken<'b>>) ; |
| 8 | +pub trait AsEmitFrom<'a> { |
| 9 | + fn as_emit_from(&self) -> Option<&dyn EmitFrom<'a>> { None } |
23 | 10 | } |
24 | | -pub trait EmitBody<'a> { |
25 | | - fn emit_body(&self, out: &mut Vec<SqlToken<'a>>); |
| 11 | +pub trait AsEmitBody<'a> { |
| 12 | + fn as_emit_body(&self) -> Option<&dyn EmitBody<'a>> { None } |
26 | 13 | } |
27 | | - |
28 | | - |
29 | | -// ---------- QueryEmitter enum ---------- |
30 | | -pub enum QueryEmitter<'a> { // Isn't this almost queryKind? |
31 | | - // Raw(BaseAst<'a>), |
32 | | - Select(SelectAst<'a>), |
33 | | - Insert(InsertAst<'a>), |
34 | | - Update(UpdateAst<'a>), |
35 | | - Delete(DeleteAst), |
36 | | -} |
37 | | -// ---------- QueryEmitter enum ---------- |
38 | | -// pub struct QueryEmitter<'a, P: AstProcessor> { // Isn't this almost queryKind? |
39 | | -// kind: QueryKind, |
40 | | -// ast: P, |
41 | | -// _p: &'a str, |
| 14 | +// pub trait AsEmitConditions<'a> { |
| 15 | +// fn as_emit_conditions(&self) -> Option<&dyn EmitConditions<'a>> { None } |
42 | 16 | // } |
43 | 17 |
|
44 | | -impl<'a> QueryEmitter<'a> { |
45 | | - /// façade: executes all phases in logical order: KIND -> FROM -> BODY -> CONDITIONS |
46 | | - pub fn emit_all_phases( |
| 18 | +// The façade trait: ToSql groups phases. |
| 19 | +// Require AsEmit* so we can call as_emit_* on any AST type P. |
| 20 | +pub trait ToSql<'a>: AsEmitKind<'a> + AsEmitFrom<'a> + AsEmitBody<'a> /*+ AsEmitConditions<'a> */ { |
| 21 | + fn emit_all( |
47 | 22 | &self, |
48 | 23 | meta: &TableMetadata<'a>, |
49 | | - conditions: &[ConditionClause<'a>], |
| 24 | + //conditions: &[ConditionClause<'a>], |
50 | 25 | out: &mut Vec<SqlToken<'a>> |
51 | 26 | ) { |
52 | | - // 1. kind |
53 | | - self.emit_kind(out); |
54 | | - // 2. from (if any) |
55 | | - self.emit_from(meta, out); |
56 | | - // 3. body (set/values/insert columns...) |
57 | | - self.emit_body(out); // TODO: swap body and conditions |
58 | | - // 4. conditions (WHERE / AND / OR) |
59 | | - for cond in conditions { |
60 | | - // cond.to_tokens(out); |
61 | | - } |
62 | | - } |
63 | | -} |
| 27 | + // KIND |
| 28 | + if let Some(k) = self.as_emit_kind() { k.emit_kind(out); } |
| 29 | + |
| 30 | + // FROM |
| 31 | + if let Some(f) = self.as_emit_from() { f.emit_from(meta, out); } |
64 | 32 |
|
65 | | -impl<'a> EmitKind<'a> for QueryEmitter<'a> { |
66 | | - fn emit_kind(&self, out: &mut Vec<SqlToken<'a>>) { |
67 | | - match self { |
68 | | - Self::Select(ast) => ast.emit_kind(out), |
69 | | - Self::Insert(ast) => ast.emit_kind(out), |
70 | | - Self::Update(ast) => ast.emit_kind(out), |
71 | | - Self::Delete(ast) => ast.emit_kind(out), |
72 | | - } |
| 33 | + // BODY |
| 34 | + if let Some(b) = self.as_emit_body() { b.emit_body(out); } |
| 35 | + |
| 36 | + // CONDITIONS (if AST wants to override condition emission) |
| 37 | + // if let Some(c) = self.as_emit_conditions() { |
| 38 | + // c.emit_conditions(conditions, out); |
| 39 | + // } else { |
| 40 | + // // fallback generic emission of base conditions (if base handles it) |
| 41 | + // for cond in conditions { |
| 42 | + // cond.to_tokens(out); // your ConditionClause -> SqlToken |
| 43 | + // } |
| 44 | + // } |
73 | 45 | } |
74 | 46 | } |
75 | 47 |
|
76 | | -impl<'a> EmitFrom<'a> for QueryEmitter<'a> { |
77 | | - fn emit_from<'b>(&self, meta: &TableMetadata<'b>, out: &mut Vec<SqlToken<'b>>) { |
78 | | - match self { |
79 | | - Self::Select(ast) => ast.emit_from(meta, out), |
80 | | - Self::Insert(ast) => ast.emit_from(meta, out), |
81 | | - Self::Update(_) => { }, |
82 | | - Self::Delete(ast) => ast.emit_from(meta, out) |
83 | | - } |
84 | | - } |
| 48 | + |
| 49 | +// ---------- AST Processor marker trait ---------- |
| 50 | +pub trait AstProcessor: Default { |
| 51 | + // TODO: get base? as mut ref for convenience? |
| 52 | +} // TODO: maybe this and the other one are visitor related? |
| 53 | + |
| 54 | +// ---------- Emit traits ---------- |
| 55 | +pub trait EmitKind<'a> { |
| 56 | + fn emit_kind(&self, out: &mut Vec<SqlToken<'a>>); |
85 | 57 | } |
86 | | -impl<'a> EmitBody<'a> for QueryEmitter<'a> { |
87 | | - fn emit_body(&self, out: &mut Vec<SqlToken<'a>>) { |
88 | | - match self { |
89 | | - Self::Select(ast) => ast.emit_body(out), |
90 | | - Self::Insert(ast) => ast.emit_body(out), |
91 | | - Self::Update(ast) => ast.emit_body(out), |
92 | | - Self::Delete(_) => { /* delete has no body */ } |
93 | | - } |
94 | | - } |
| 58 | +pub trait EmitFrom<'a> { |
| 59 | + fn emit_from(&self, meta: &TableMetadata<'a>, out: &mut Vec<SqlToken<'a>>) ; |
95 | 60 | } |
| 61 | +pub trait EmitBody<'a> { |
| 62 | + fn emit_body(&self, out: &mut Vec<SqlToken<'a>>); |
| 63 | +} |
| 64 | +// |
| 65 | +// |
| 66 | +// // ---------- QueryEmitter enum ---------- |
| 67 | +// pub enum QueryEmitter<'a> { // Isn't this almost queryKind? |
| 68 | +// // Raw(BaseAst<'a>), |
| 69 | +// Select(SelectAst<'a>), |
| 70 | +// Insert(InsertAst<'a>), |
| 71 | +// Update(UpdateAst<'a>), |
| 72 | +// Delete(DeleteAst), |
| 73 | +// } |
| 74 | +// |
| 75 | +// impl<'a> QueryEmitter<'a> { |
| 76 | +// /// façade: executes all phases in logical order: KIND -> FROM -> BODY -> CONDITIONS |
| 77 | +// pub fn emit_all_phases( |
| 78 | +// &self, |
| 79 | +// meta: &TableMetadata<'a>, |
| 80 | +// conditions: &[ConditionClause<'a>], |
| 81 | +// out: &mut Vec<SqlToken<'a>> |
| 82 | +// ) { |
| 83 | +// // 1. kind |
| 84 | +// self.emit_kind(out); |
| 85 | +// // 2. from (if any) |
| 86 | +// self.emit_from(meta, out); |
| 87 | +// // 3. body (set/values/insert columns...) |
| 88 | +// self.emit_body(out); // TODO: swap body and conditions |
| 89 | +// // 4. conditions (WHERE / AND / OR) |
| 90 | +// for cond in conditions { |
| 91 | +// // cond.to_tokens(out); |
| 92 | +// } |
| 93 | +// } |
| 94 | +// } |
| 95 | +// |
| 96 | +// impl<'a> EmitKind<'a> for QueryEmitter<'a> { |
| 97 | +// fn emit_kind(&self, out: &mut Vec<SqlToken<'a>>) { |
| 98 | +// match self { |
| 99 | +// Self::Select(ast) => ast.emit_kind(out), |
| 100 | +// Self::Insert(ast) => ast.emit_kind(out), |
| 101 | +// Self::Update(ast) => ast.emit_kind(out), |
| 102 | +// Self::Delete(ast) => ast.emit_kind(out), |
| 103 | +// } |
| 104 | +// } |
| 105 | +// } |
| 106 | +// |
| 107 | +// impl<'a> EmitFrom<'a> for QueryEmitter<'a> { |
| 108 | +// fn emit_from(&self, meta: &TableMetadata<'a>, out: &mut Vec<SqlToken<'a>>) { |
| 109 | +// match self { |
| 110 | +// Self::Select(ast) => ast.emit_from(meta, out), |
| 111 | +// Self::Insert(ast) => ast.emit_from(meta, out), |
| 112 | +// Self::Update(_) => { }, |
| 113 | +// Self::Delete(ast) => ast.emit_from(meta, out) |
| 114 | +// } |
| 115 | +// } |
| 116 | +// } |
| 117 | +// impl<'a> EmitBody<'a> for QueryEmitter<'a> { |
| 118 | +// fn emit_body(&self, out: &mut Vec<SqlToken<'a>>) { |
| 119 | +// match self { |
| 120 | +// Self::Select(ast) => ast.emit_body(out), |
| 121 | +// Self::Insert(ast) => ast.emit_body(out), |
| 122 | +// Self::Update(ast) => ast.emit_body(out), |
| 123 | +// Self::Delete(_) => { /* delete has no body */ } |
| 124 | +// } |
| 125 | +// } |
| 126 | +// } |
0 commit comments