Skip to content

Commit

Permalink
refactor, rename, add group by
Browse files Browse the repository at this point in the history
  • Loading branch information
inoas committed May 30, 2024
1 parent bfb0888 commit 6a664e8
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 43 deletions.
20 changes: 20 additions & 0 deletions birdie_snapshots/query_group_by_test.accepted
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
version: 1.1.6
title: query_group_by_test
file: ./test/query_test.gleam
test_name: query_group_by_test
---
Select(
Selects([
SelectColumn("name"),
SelectColumn("MAX(age)"),
]),
FromTable("cats"),
NoJoins,
NoWhere,
GroupBy(["name", "breed"]),
NoWhere,
[],
NoLimitNoOffset,
NoEpilog,
)
62 changes: 47 additions & 15 deletions src/cake/internal/query.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,9 @@ pub type WhereValue {

fn where_apply(
prepared_statement prp_stm: PreparedStatement,
part prt: Where,
part wh: Where,
) -> PreparedStatement {
case prt {
case wh {
NoWhere -> prp_stm
WhereEqual(val_a, val_b) ->
prp_stm |> where_comparison_apply(val_a, "=", val_b)
Expand Down Expand Up @@ -377,12 +377,12 @@ fn where_apply(
WhereParam(param.StringParam(prm)),
)
|> prepared_statement.append_sql(" ESCAPE '/'")
AndWhere(prts) -> prp_stm |> where_apply_logical_operator("AND", prts)
OrWhere(prts) -> prp_stm |> where_apply_logical_operator("OR", prts)
NotWhere(prt) -> {
AndWhere(whs) -> prp_stm |> where_apply_logical_operator("AND", whs)
OrWhere(whs) -> prp_stm |> where_apply_logical_operator("OR", whs)
NotWhere(wh) -> {
prp_stm
|> prepared_statement.append_sql("NOT (")
|> where_apply(prt)
|> where_apply(wh)
|> prepared_statement.append_sql(")")
}
WhereIn(val, vals) -> prp_stm |> where_apply_value_in_values(val, vals)
Expand All @@ -393,12 +393,11 @@ fn where_apply(

fn where_clause_apply(
prepared_statement prp_stm: PreparedStatement,
part prt: Where,
where wh: Where,
) -> PreparedStatement {
case prt {
case wh {
NoWhere -> prp_stm
prt ->
prp_stm |> prepared_statement.append_sql(" WHERE ") |> where_apply(prt)
_ -> prp_stm |> prepared_statement.append_sql(" WHERE ") |> where_apply(wh)
}
}

Expand Down Expand Up @@ -488,20 +487,20 @@ fn where_apply_param(
fn where_apply_logical_operator(
prepared_statement prp_stm: PreparedStatement,
operator oprtr: String,
parts prts: List(Where),
where whs: List(Where),
) -> PreparedStatement {
let prp_stm = prp_stm |> prepared_statement.append_sql("(")

prts
whs
|> list.fold(
prp_stm,
fn(new_prp_stm: PreparedStatement, prt: Where) -> PreparedStatement {
fn(new_prp_stm: PreparedStatement, wh: Where) -> PreparedStatement {
case new_prp_stm == prp_stm {
True -> new_prp_stm |> where_apply(prt)
True -> new_prp_stm |> where_apply(wh)
False ->
new_prp_stm
|> prepared_statement.append_sql(" " <> oprtr <> " ")
|> where_apply(prt)
|> where_apply(wh)
}
},
)
Expand Down Expand Up @@ -599,6 +598,39 @@ pub type GroupBy {
GroupBy(columns: List(String))
}

pub fn group_by_clause_apply(
prepared_statement prp_stm: PreparedStatement,
group_by grpb: GroupBy,
) -> PreparedStatement {
case grpb {
NoGroupBy -> prp_stm
GroupBy(grpbs) ->
prp_stm
|> prepared_statement.append_sql(" GROUP BY ")
|> group_by_apply(grpbs)
}
}

fn group_by_apply(
prepared_statement prp_stm: PreparedStatement,
group_bys grpbs: List(String),
) -> PreparedStatement {
case grpbs {
[] -> prp_stm
_ ->
grpbs
|> list.fold(
prp_stm,
fn(new_prp_stm: PreparedStatement, s: String) -> PreparedStatement {
case new_prp_stm == prp_stm {
True -> new_prp_stm |> prepared_statement.append_sql(s)
False -> new_prp_stm |> prepared_statement.append_sql(", " <> s)
}
},
)
}
}

// ┌───────────────────────────────────────────────────────────────────────────┐
// │ Joins │
// └───────────────────────────────────────────────────────────────────────────┘
Expand Down
2 changes: 0 additions & 2 deletions src/cake/query/group_by.gleam

This file was deleted.

4 changes: 3 additions & 1 deletion src/cake/query/having.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
////
//// Becaue of this difference, WHERE can refer to columns that are not part of the GROUP BY clause, while HAVING cannot.
////
//// Please use where.gleam instead of this module.
//// Please use where.gleam instead of this module to specify HAVING constraints.
////
//// TODO: Add unit tests for specifing HAVING.
////

80 changes: 55 additions & 25 deletions src/cake/query/select.gleam
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import cake/internal/query.{
type Fragment, type From, type Join, type Joins, type LimitOffset,
type OrderByDirection, type Query, type Select, type SelectValue, type Selects,
type Where, Joins, NoEpilog, NoFrom, NoGroupBy, NoJoins, NoLimitNoOffset,
NoSelects, NoWhere, OrderByColumn, Select, SelectQuery, Selects,
type Where, GroupBy, Joins, NoEpilog, NoFrom, NoGroupBy, NoJoins,
NoLimitNoOffset, NoSelects, NoWhere, OrderByColumn, Select, SelectQuery,
Selects,
}
import cake/param
import gleam/list
Expand Down Expand Up @@ -128,6 +129,40 @@ pub fn get_selects(query qry: Select) -> Selects {
qry.selects
}

// ▒▒▒ JOIN ▒▒▒

pub fn join(query qry: Select, join_part prt: Join) -> Select {
case qry.joins {
Joins(prts) -> Select(..qry, joins: prts |> list.append([prt]) |> Joins)
NoJoins -> Select(..qry, joins: [prt] |> Joins)
}
}

pub fn join_replace(query qry: Select, join_part prt: Join) -> Select {
Select(..qry, joins: [prt] |> Joins)
}

pub fn joins(query qry: Select, joins jns: List(Join)) -> Select {
case jns, qry.joins {
[], _ -> Select(..qry, joins: Joins(jns))
jns, Joins(qry_joins) ->
Select(..qry, joins: qry_joins |> list.append(jns) |> Joins)
jns, NoJoins -> Select(..qry, joins: jns |> Joins)
}
}

pub fn joins_replace(query qry: Select, join_parts prts: List(Join)) -> Select {
Select(..qry, joins: prts |> Joins)
}

pub fn joins_remove(query qry: Select) -> Select {
Select(..qry, joins: NoJoins)
}

pub fn get_joins(query qry: Select) -> Joins {
qry.joins
}

// ▒▒▒ WHERE ▒▒▒

pub fn where(query qry: Select, where whr: Where) -> Select {
Expand Down Expand Up @@ -156,38 +191,33 @@ pub fn get_where(query qry: Select) -> Where {
qry.where
}

// ▒▒▒ JOIN ▒▒▒
// ▒▒▒ GROUP BY ▒▒▒

pub fn join(query qry: Select, join_part prt: Join) -> Select {
case qry.joins {
Joins(prts) -> Select(..qry, joins: prts |> list.append([prt]) |> Joins)
NoJoins -> Select(..qry, joins: [prt] |> Joins)
pub fn group_by(query qry: Select, group_by grpb: String) -> Select {
case qry.group_by {
NoGroupBy -> Select(..qry, group_by: GroupBy([grpb]))
GroupBy(grpbs) ->
Select(..qry, group_by: GroupBy(grpbs |> list.append([grpb])))
}
}

pub fn join_replace(query qry: Select, join_part prt: Join) -> Select {
Select(..qry, joins: [prt] |> Joins)
pub fn group_by_replace(query qry: Select, group_by grpb: String) -> Select {
Select(..qry, group_by: GroupBy([grpb]))
}

pub fn joins(query qry: Select, joins jns: List(Join)) -> Select {
case jns, qry.joins {
[], _ -> Select(..qry, joins: Joins(jns))
jns, Joins(qry_joins) ->
Select(..qry, joins: qry_joins |> list.append(jns) |> Joins)
jns, NoJoins -> Select(..qry, joins: jns |> Joins)
pub fn groups_by(query qry: Select, group_bys grpbs: List(String)) -> Select {
case qry.group_by {
NoGroupBy -> Select(..qry, group_by: GroupBy(grpbs))
GroupBy(grpbs) ->
Select(..qry, group_by: GroupBy(grpbs |> list.append(grpbs)))
}
}

pub fn joins_replace(query qry: Select, join_parts prts: List(Join)) -> Select {
Select(..qry, joins: prts |> Joins)
}

pub fn joins_remove(query qry: Select) -> Select {
Select(..qry, joins: NoJoins)
}

pub fn get_joins(query qry: Select) -> Joins {
qry.joins
pub fn group_bys_replace(
query qry: Select,
group_bys grpbs: List(String),
) -> Select {
Select(..qry, group_by: GroupBy(grpbs))
}

// ▒▒▒ LIMIT & OFFSET ▒▒▒
Expand Down
15 changes: 15 additions & 0 deletions test/query_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@ pub fn query_where_between_sqlite_test() {
|> to_string
|> birdie.snap("query_where_between_sqlite_test")
}

fn query_group_by_setup() {
f.table(name: "cats")
|> s.new_from
|> s.selects([s.col("name"), s.col("MAX(age)")])
|> s.group_by("id")
|> s.group_by("age")
|> s.group_bys_replace(["name", "breed"])
}

pub fn query_group_by_test() {
query_group_by_setup()
|> to_string
|> birdie.snap("query_group_by_test")
}

0 comments on commit 6a664e8

Please sign in to comment.