Skip to content

Commit 67eec2a

Browse files
committed
refactor(WIP)!: rollback the introduction of the querybuilder on the crud operations macros
1 parent a0a64cd commit 67eec2a

27 files changed

Lines changed: 276 additions & 272 deletions

File tree

canyon_core/src/connection/clients/mssql.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ pub(crate) mod sqlserver_query_launcher {
153153
params: &[&'a dyn QueryParameter],
154154
) -> Query<'a> {
155155
let mut stmt = String::from(stmt);
156+
println!("Detected query mssql: {stmt}");
156157
if stmt.contains("RETURNING") {
157158
// TODO: when the InsertQuerybuilder with a api on the builder for the returning clause
158159
let c = stmt.clone();

canyon_core/src/connection/clients/postgresql.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl DbConnection for PostgresConnector {
3434
stmt: &str,
3535
params: &[&'_ dyn QueryParameter],
3636
) -> Result<CanyonRows, Box<dyn Error + Send + Sync>> {
37+
println!("Postgres query rows: {:?}", stmt);
3738
let r = self
3839
.get_pooled()
3940
.await?
@@ -70,6 +71,7 @@ impl DbConnection for PostgresConnector {
7071
where
7172
R: RowMapper,
7273
{
74+
println!("Postgres query one: {}", stmt);
7375
let result = self
7476
.get_pooled()
7577
.await?

canyon_core/src/query/operators.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub trait Operator: Display {
77

88
/// Enumerated type for represent the comparison operations
99
/// in SQL sentences
10-
#[derive(Debug)]
10+
#[derive(Debug, PartialEq, Copy, Clone)]
1111
pub enum Comp {
1212
/// Operator "=" equals
1313
Eq,
@@ -41,7 +41,7 @@ impl Display for Comp {
4141
}
4242
}
4343

44-
#[derive(Debug)]
44+
#[derive(Debug, PartialEq, Copy, Clone)]
4545
pub enum LikeKind {
4646
/// Operator "LIKE" as '%pattern%'
4747
Full,

canyon_core/src/query/querybuilder/contracts/mod.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
//! of the behaviour of the Canyon-SQL QueryBuilder
33
44
use std::error::Error;
5-
use crate::query::bounds::{FieldIdentifier, FieldValueIdentifier, TableMetadata};
5+
use crate::query::bounds::{FieldIdentifier, FieldValueIdentifier};
66
use crate::query::operators::Comp;
77
use crate::query::parameters::QueryParameter;
88
use crate::query::querybuilder::syntax::column::ColumnRef;
9+
use crate::query::querybuilder::syntax::table_metadata::TableMetadata;
910

1011
pub trait DeleteQueryBuilderOps<'a>: QueryBuilderOps<'a> {}
1112

@@ -46,9 +47,9 @@ pub trait SelectQueryBuilderOps<'a>: QueryBuilderOps<'a> {
4647
/// > Note: The order on the column parameters is irrelevant
4748
fn left_join(
4849
self,
49-
join_table: impl TableMetadata<'a>,
50-
col1: impl FieldIdentifier,
51-
col2: impl FieldIdentifier,
50+
join_table: impl Into<TableMetadata<'a>>,
51+
col1: impl Into<ColumnRef<'a>>,
52+
col2: impl Into<ColumnRef<'a>>,
5253
) -> Self;
5354

5455
/// Adds a *INNER JOIN* SQL statement to the underlying
@@ -61,9 +62,9 @@ pub trait SelectQueryBuilderOps<'a>: QueryBuilderOps<'a> {
6162
/// > Note: The order on the column parameters is irrelevant
6263
fn inner_join(
6364
self,
64-
join_table: impl TableMetadata<'a>,
65-
col1: impl FieldIdentifier,
66-
col2: impl FieldIdentifier,
65+
join_table: impl Into<TableMetadata<'a>>,
66+
col1: impl Into<ColumnRef<'a>>,
67+
col2: impl Into<ColumnRef<'a>>,
6768
) -> Self;
6869

6970
/// Adds a *RIGHT JOIN* SQL statement to the underlying
@@ -76,9 +77,9 @@ pub trait SelectQueryBuilderOps<'a>: QueryBuilderOps<'a> {
7677
/// > Note: The order on the column parameters is irrelevant
7778
fn right_join(
7879
self,
79-
join_table: impl TableMetadata<'a>,
80-
col1: impl FieldIdentifier,
81-
col2: impl FieldIdentifier,
80+
join_table: impl Into<TableMetadata<'a>>,
81+
col1: impl Into<ColumnRef<'a>>,
82+
col2: impl Into<ColumnRef<'a>>,
8283
) -> Self;
8384

8485
/// Adds a *FULL JOIN* SQL statement to the underlying
@@ -91,10 +92,16 @@ pub trait SelectQueryBuilderOps<'a>: QueryBuilderOps<'a> {
9192
/// > Note: The order on the column parameters is irrelevant
9293
fn full_join(
9394
self,
94-
join_table: impl TableMetadata<'a>,
95-
col1: impl FieldIdentifier,
96-
col2: impl FieldIdentifier,
95+
join_table: impl Into<TableMetadata<'a>>,
96+
col1: impl Into<ColumnRef<'a>>,
97+
col2: impl Into<ColumnRef<'a>>,
9798
) -> Self;
99+
100+
/// Generates a `ORDER BY` SQL clause for constraint the query.
101+
///
102+
/// * `order_by` - A [`FieldIdentifier`] that will provide the target column name
103+
/// * `desc` - a boolean indicating if the generated `ORDER_BY` must be in ascending or descending order
104+
fn order_by<Z: FieldIdentifier + Into<ColumnRef<'a>>>(self, order_by: Z, desc: bool) -> Self;
98105
}
99106

100107
/// The [`QueryBuilder`] trait is the root of a kind of hierarchy
@@ -145,8 +152,11 @@ pub trait QueryBuilderOps<'a> {
145152
/// * `column` - An [`&str`] that will provide the target column name
146153
/// * `op` - Any element that implements [`Operator`] for create the comparison
147154
/// or equality binary operator
148-
/// * `value` - Any implementor of [`QueryParameter] that will be the value to filter
149-
fn r#where(self, column: &'a str, op: Comp, value: &'a dyn QueryParameter) -> Self;
155+
///
156+
/// It will generate a SQL statement with the where constraint value generated as a placeholder,
157+
/// depending on the underlying database driver and the number of elements already added to the
158+
/// querybuilder
159+
fn r#where(self, column: &'a str, op: Comp) -> Self;
150160

151161
/// Generates a `WHERE` SQL clause for constraint the query.
152162
///
@@ -198,10 +208,4 @@ pub trait QueryBuilderOps<'a> {
198208
/// * `op` - Any element that implements [`Operator`] for create the comparison
199209
/// or equality binary operator
200210
fn or<Z: FieldValueIdentifier>(self, column: &'a Z, op: Comp) -> Self;
201-
202-
/// Generates a `ORDER BY` SQL clause for constraint the query.
203-
///
204-
/// * `order_by` - A [`FieldIdentifier`] that will provide the target column name
205-
/// * `desc` - a boolean indicating if the generated `ORDER_BY` must be in ascending or descending order
206-
fn order_by<Z: FieldIdentifier>(self, order_by: Z, desc: bool) -> Self;
207211
}

canyon_core/src/query/querybuilder/syntax/ast/select.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,29 @@ use crate::query::querybuilder::syntax::emitter::{AsEmitBody, AsEmitFrom, AsEmit
44
use crate::query::querybuilder::syntax::having::HavingClause;
55
use crate::query::querybuilder::syntax::join::JoinClause;
66
use crate::query::querybuilder::syntax::order::OrderByClause;
7+
use crate::query::querybuilder::syntax::symbol::Symbol;
78
use crate::query::querybuilder::syntax::table_metadata::TableMetadata;
8-
use crate::query::querybuilder::syntax::tokens::{SqlToken, Symbol, ToSqlTokens};
9+
use crate::query::querybuilder::syntax::tokens::{SqlToken, ToSqlTokens};
910

1011
#[derive(Default)]
1112
pub struct SelectAst<'a> {
1213
pub columns: Vec<ColumnRef<'a>>,
1314
pub joins: Vec<JoinClause<'a>>,
14-
pub group_by: Vec<&'a str>,
15-
pub having: Vec<HavingClause<'a>>,
16-
pub order_by: Vec<OrderByClause<'a>>,
15+
pub order_by: Option<OrderByClause<'a>>,
16+
pub having: Option<HavingClause<'a>>,
17+
pub group_by: Vec<ColumnRef<'a>>, // TODO: ColumnRef
1718
pub limit: Option<u64>, // TODO: strong typing
1819
pub offset: Option<u64>,
1920
}
2021

2122
impl<'a> SelectAst<'a> {
22-
pub fn new() -> Self {
23+
pub const fn new() -> Self {
2324
Self {
2425
columns: Vec::new(),
2526
joins: Vec::new(),
27+
order_by: None,
2628
group_by: Vec::new(),
27-
having: Vec::new(),
28-
order_by: Vec::new(),
29+
having: None,
2930
limit: None,
3031
offset: None,
3132
}

canyon_core/src/query/querybuilder/syntax/clause.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
use crate::query::operators::Comp;
2-
use crate::query::parameters::QueryParameter;
3-
use crate::query::querybuilder::syntax::tokens::SqlToken;
2+
use crate::query::querybuilder::syntax::column::ColumnRef;
43

5-
pub struct ConditionClause<'a> {
6-
// TODO: where are missing complex where usages, like in joins, so we should consider to add the table
7-
// to the column like where table.column = ...
4+
#[derive(Clone)] pub struct ConditionClause<'a> {
85
pub(crate) kind: ConditionClauseKind,
9-
pub(crate) column_name: SqlToken<'a>,
6+
pub(crate) column_name: ColumnRef<'a>,
107
pub(crate) operator: Comp,
11-
pub(crate) value: &'a dyn QueryParameter
8+
pub(crate) value_index: usize,
129
}
13-
#[derive(Eq, PartialEq)]
10+
#[derive(Eq, PartialEq, Clone)]
1411
pub enum ConditionClauseKind {
1512
Where,
1613
And,

canyon_core/src/query/querybuilder/syntax/column.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
use crate::query::querybuilder::syntax::symbol::Symbol::Dot;
12
use crate::query::querybuilder::syntax::tokens::{SqlToken, ToSqlTokens};
2-
use crate::query::querybuilder::syntax::tokens::Symbol::Dot;
33

4-
#[derive(Debug, Clone)]
4+
#[derive(Debug, Clone, Default)]
55
pub struct ColumnRef<'a> {
6-
pub column: &'a str,
76
pub table: Option<&'a str>,
8-
// TODO: we need the table <table.column> no?
9-
// TODO: so we need a ColumnRefBuilder, to avoid have 70 new different new methods?
7+
pub column: &'a str,
108
pub alias: Option<&'a str>,
119
}
1210

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::query::operators::Comp;
22
use crate::query::parameters::QueryParameter;
3+
use crate::query::querybuilder::syntax::column::ColumnRef;
34

45
pub struct HavingClause<'a> {
5-
pub column: &'a str,
6+
pub column: ColumnRef<'a>,
67
pub operator: Comp,
78
pub value: &'a dyn QueryParameter, // TODO: shouldn't this be a placeholder?
89
}
910

1011
impl<'a> HavingClause<'a> {
11-
pub fn new(column: &'a str, operator: Comp, value: &'a dyn QueryParameter) -> Self {
12-
Self { column, operator, value }
12+
pub fn new<I: Into<ColumnRef<'a>>>(column: I, operator: Comp, value: &'a dyn QueryParameter) -> Self {
13+
Self { column: column.into(), operator, value }
1314
}
1415
}

canyon_core/src/query/querybuilder/syntax/join.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::query::operators::Comp;
2+
use crate::query::querybuilder::syntax::column::ColumnRef;
23
use crate::query::querybuilder::syntax::table_metadata::TableMetadata;
4+
use crate::query::querybuilder::syntax::tokens::{SqlToken, ToSqlTokens};
35

46
#[derive(Debug, Clone, Copy)]
57
pub enum JoinKind {
@@ -22,14 +24,53 @@ impl JoinKind {
2224

2325
pub struct JoinClause<'a> {
2426
pub kind: JoinKind,
25-
pub table: TableMetadata<'a>, // TODO: this should be the target table, and the origin table
26-
pub left: &'a str, // e.g. "t1.id" // TODO: we need to filter and check the syntax
27+
pub target_table: TableMetadata<'a>, // TODO: this should be the target table, and the origin table
28+
pub left: ColumnRef<'a>, // e.g. "t1.id" // TODO: we need to filter and check the syntax
2729
pub operator: Comp, // usually Eq
28-
pub right: &'a str, // e.g. "t2.t1_id"
30+
pub right: ColumnRef<'a>, // e.g. "t2.t1_id" // TODO: this is always the base or the previous (at least, in one of the sides)
31+
// so we could look in the vector for the previous clause and auto-add the join
2932
}
3033

3134
impl<'a> JoinClause<'a> {
32-
pub fn new(kind: JoinKind, table: TableMetadata<'a>, left: &'a str, operator: Comp, right: &'a str) -> Self {
33-
Self { kind, table, left, operator, right }
35+
pub fn new<I: Into<ColumnRef<'a>>>(kind: JoinKind, target_table: TableMetadata<'a>, left: I, operator: Comp, right: I) -> Self {
36+
Self { kind, target_table, left: left.into(), operator, right: right.into() }
3437
}
3538
}
39+
40+
impl<'a> ToSqlTokens<'a> for JoinClause<'a> {
41+
fn to_tokens(&self, out: &mut Vec<SqlToken<'a>>) {
42+
out.push(SqlToken::new_ident(self.kind.as_str()));
43+
self.target_table.to_tokens(out);
44+
45+
46+
}
47+
}
48+
#[test]
49+
fn test_join_clause_basic() {
50+
use crate::query::operators::Comp;
51+
use crate::query::querybuilder::syntax::tokens::{SqlToken, Symbol};
52+
53+
let mock_value = 99;
54+
55+
let join = JoinClause {
56+
kind: JoinKind::Inner,
57+
target_table: TableMetadata::new("target_table"),
58+
left: "t.id".into(),
59+
operator: Comp::Eq,
60+
right: "users.team_id".into()
61+
};
62+
63+
let mut tokens = Vec::new();
64+
join.to_tokens(&mut tokens);
65+
66+
let expected = vec![
67+
SqlToken::Keyword("INNER JOIN".into()),
68+
SqlToken::Ident("users".into()),
69+
SqlToken::Keyword("ON".into()),
70+
SqlToken::Ident("t.id".into()),
71+
SqlToken::Symbol(Symbol::Equals),
72+
SqlToken::Ident("users.team_id".into()),
73+
];
74+
75+
assert_eq!(tokens, expected);
76+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub enum Keyword {
2+
3+
}

0 commit comments

Comments
 (0)