Packages
cake
1.0.0
4.1.0
4.0.0
3.0.0
2.2.2
2.2.1
2.2.0
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.0
retired
0.15.0
retired
0.14.0
retired
0.13.0
retired
0.12.0
retired
0.11.0
retired
0.10.1
retired
0.10.0
retired
0.9.2
retired
0.9.1
retired
0.9.0
retired
0.8.0
retired
0.7.0
retired
0.6.0
retired
0.5.0
retired
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.0
retired
0.0.1
retired
🎂 An SQL query builder for Gleam for SQL dialects 🐘PostgreSQL, 🪶SQLite, 🦭MariaDB, and 🐬MySQL
Current section
Files
Jump to
Current section
Files
src/cake/combined.gleam
//// A DSL to build combined queries, such as:
////
//// - `UNION`
//// - `UNION ALL`
//// - `EXCEPT`
//// - `EXCEPT ALL`
//// - `INTERSECT`
//// - `INTERSECT ALL`
////
//// ## Compatibility
////
//// - SQLite does not support `EXCEPT ALL` and `INTERSECT ALL`.
////
import cake/internal/read_query.{
Combined, CombinedQuery, Comment, Epilog, ExceptAll, ExceptDistinct,
IntersectAll, IntersectDistinct, NoComment, NoEpilog, NoLimit, NoOffset,
NoOrderBy, OrderBy, OrderByColumn, UnionAll, UnionDistinct,
}
import gleam/string
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ read_query type re-exports │
// └───────────────────────────────────────────────────────────────────────────┘
pub type Combined =
read_query.Combined
pub type Comment =
read_query.Comment
pub type Epilog =
read_query.Epilog
pub type Limit =
read_query.Limit
pub type Offset =
read_query.Offset
pub type OrderBy =
read_query.OrderBy
pub type OrderByDirection =
read_query.OrderByDirection
pub type ReadQuery =
read_query.ReadQuery
pub type Select =
read_query.Select
/// Creates a `ReadQuery` from a `Combined` read_query.
///
pub fn to_query(combined cmbnd: Combined) -> ReadQuery {
cmbnd |> CombinedQuery
}
// ▒▒▒ Combined Kind ▒▒▒
/// Creates a `UNION` query out of two queries as a `Combined` read_query.
///
pub fn union(query_a qry_a: Select, query_b qry_b: Select) -> Combined {
UnionDistinct |> read_query.combined_query_new([qry_a, qry_b])
}
/// Creates a `UNION` query out of two or more queries as a `Combined` read_query.
///
pub fn unions(
query_a qry_a: Select,
query_b qry_b: Select,
more_queries mr_qrys: List(Select),
) -> Combined {
UnionDistinct |> read_query.combined_query_new([qry_a, qry_b, ..mr_qrys])
}
/// Creates a `UNION ALL` query out of two queries as a `Combined` read_query.
///
pub fn union_all(query_a qry_a: Select, query_b qry_b: Select) -> Combined {
UnionAll |> read_query.combined_query_new([qry_a, qry_b])
}
/// Creates a `UNION ALL` query out of two or more queries as a `Combined`
/// read_query.
///
/// NOTICE: Not supported by SQLite.
///
pub fn unions_all(
query_a qry_a: Select,
query_b qry_b: Select,
more_queries mr_qrys: List(Select),
) -> Combined {
UnionAll |> read_query.combined_query_new([qry_a, qry_b, ..mr_qrys])
}
/// Creates an `EXCEPT` query out of two queries as a `Combined` read_query.
///
pub fn except(query_a qry_a: Select, query_b qry_b: Select) -> Combined {
ExceptDistinct |> read_query.combined_query_new([qry_a, qry_b])
}
/// Creates an `EXCEPT` query out of two or more queries as a `Combined` read_query.
///
pub fn excepts(
query_a qry_a: Select,
query_b qry_b: Select,
more_queries mr_qrys: List(Select),
) -> Combined {
ExceptDistinct |> read_query.combined_query_new([qry_a, qry_b, ..mr_qrys])
}
/// Creates an `EXCEPT ALL` query out of two queries as a `Combined` read_query.
///
/// NOTICE: Not supported by SQLite.
///
pub fn except_all(query_a qry_a: Select, query_b qry_b: Select) -> Combined {
ExceptAll |> read_query.combined_query_new([qry_a, qry_b])
}
/// Creates an `EXCEPT ALL` query out of two or more queries as a `Combined`
/// read_query.
///
/// NOTICE: Not supported by SQLite.
///
pub fn excepts_all(
query_a qry_a: Select,
query_b qry_b: Select,
more_queries mr_qrys: List(Select),
) -> Combined {
ExceptAll |> read_query.combined_query_new([qry_a, qry_b, ..mr_qrys])
}
/// Creates an `INTERSECT` query out of two queries as a `Combined` read_query.
///
pub fn intersect(query_a qry_a: Select, query_b qry_b: Select) -> Combined {
IntersectDistinct |> read_query.combined_query_new([qry_a, qry_b])
}
/// Creates an `INTERSECT` query out of two or more queries as a `Combined`
/// read_query.
///
pub fn intersects(
query_a qry_a: Select,
query_b qry_b: Select,
more_queries mr_qrys: List(Select),
) -> Combined {
IntersectDistinct |> read_query.combined_query_new([qry_a, qry_b, ..mr_qrys])
}
/// Creates an `INTERSECT ALL` query out of two queries as a `Combined` read_query.
///
/// NOTICE: Not supported by SQLite.
///
pub fn intersect_all(query_a qry_a: Select, query_b qry_b: Select) -> Combined {
IntersectAll |> read_query.combined_query_new([qry_a, qry_b])
}
/// Creates an `INTERSECT ALL` query out of two or more queries as a `Combined`
/// read_query.
///
/// NOTICE: Not supported by SQLite.
///
pub fn intersects_all(
query_a qry_a: Select,
query_b qry_b: Select,
more_queries mr_qrys: List(Select),
) -> Combined {
IntersectAll |> read_query.combined_query_new([qry_a, qry_b, ..mr_qrys])
}
/// Gets the queries from a `Combined` read_query.
///
pub fn get_queries(combined cmbnd: Combined) -> List(Select) {
cmbnd.queries
}
// ▒▒▒ LIMIT & OFFSET ▒▒▒
/// Sets a `Limit` in the `Combined` read_query.
///
pub fn limit(query qry: Combined, limit lmt: Int) -> Combined {
let lmt = lmt |> read_query.limit_new
Combined(..qry, limit: lmt)
}
/// Removes `Limit` from the `Combined` read_query.
///
pub fn no_limit(query qry: Combined) -> Combined {
Combined(..qry, limit: NoLimit)
}
/// Gets `Limit` in the `Combined` read_query.
///
pub fn get_limit(query qry: Combined) -> Limit {
qry.limit
}
/// Sets an `Offset` in the `Combined` read_query.
///
pub fn offset(query qry: Combined, offst offst: Int) -> Combined {
let offst = offst |> read_query.offset_new
Combined(..qry, offset: offst)
}
/// Removes `Offset` from the `Combined` read_query.
///
pub fn no_offset(query qry: Combined) -> Combined {
Combined(..qry, offset: NoOffset)
}
/// Gets `Offset` in the `Combined` read_query.
///
pub fn get_offset(query qry: Combined) -> Offset {
qry.offset
}
// ▒▒▒ ORDER BY ▒▒▒
/// Defines the direction of an `OrderBy`.
///
pub type Direction {
Asc
Desc
}
fn map_order_by_direction_constructor(in: Direction) -> OrderByDirection {
case in {
Asc -> read_query.Asc
Desc -> read_query.Desc
}
}
/// Creates or appends an ascending `OrderBy`.
///
pub fn order_by_asc(query qry: Combined, by ordb: String) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.Asc)] |> OrderBy,
append: True,
)
}
/// Creates or appends an ascending `OrderBy` with `NULLS FIRST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS FIRST` out of the box.
///
pub fn order_by_asc_nulls_first(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.AscNullsFirst)] |> OrderBy,
append: True,
)
}
/// Creates or appends an ascending `OrderBy` with `NULLS LAST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS LAST` out of the box.
///
pub fn order_by_asc_nulls_last(query qry: Combined, by ordb: String) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.AscNullsFirst)] |> OrderBy,
append: True,
)
}
/// Replaces the `OrderBy` a single ascending `OrderBy`.
///
pub fn replace_order_by_asc(query qry: Combined, by ordb: String) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.Asc)] |> OrderBy,
append: False,
)
}
/// Replaces the `OrderBy` a single ascending `OrderBy` with `NULLS FIRST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS FIRST` out of the box.
///
pub fn replace_order_by_asc_nulls_first(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.AscNullsFirst)] |> OrderBy,
append: False,
)
}
/// Replaces the `OrderBy` a single ascending `OrderBy` with `NULLS LAST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS LAST` out of the box.
///
pub fn replace_order_by_asc_nulls_last(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.AscNullsFirst)] |> OrderBy,
append: False,
)
}
/// Creates or appends a descending `OrderBy`.
///
pub fn order_by_desc(query qry: Combined, by ordb: String) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.Desc)] |> OrderBy,
append: True,
)
}
/// Creates or appends a descending order with `NULLS FIRST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS FIRST` out of the box.
///
pub fn order_by_desc_nulls_first(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.DescNullsFirst)] |> OrderBy,
append: True,
)
}
/// Creates or appends a descending `OrderBy` with `NULLS LAST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS LAST` out of the box.
///
pub fn order_by_desc_nulls_last(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.DescNullsFirst)] |> OrderBy,
append: True,
)
}
/// Replaces the `OrderBy` a single descending order.
///
pub fn replace_order_by_desc(query qry: Combined, by ordb: String) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.Desc)] |> OrderBy,
append: False,
)
}
/// Replaces the `OrderBy` a single descending order with `NULLS FIRST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS FIRST` out of the box.
///
pub fn replace_order_by_desc_nulls_first(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.DescNullsFirst)] |> OrderBy,
append: False,
)
}
/// Replaces the `OrderBy` a single descending `OrderBy` with `NULLS LAST`.
///
/// NOTICE: MariaDB/MySQL do not support `NULLS LAST` out of the box.
///
pub fn replace_order_by_desc_nulls_last(
query qry: Combined,
by ordb: String,
) -> Combined {
qry
|> read_query.combined_order_by(
by: [ordb |> OrderByColumn(read_query.DescNullsFirst)] |> OrderBy,
append: False,
)
}
/// Creates or appends an `OrderBy` a column with a direction.
///
/// The direction can either `ASC` or `DESC`.
///
pub fn order_by(
query qry: Combined,
by ordb: String,
direction dir: Direction,
) -> Combined {
let dir = dir |> map_order_by_direction_constructor
qry
|> read_query.combined_order_by(
[ordb |> OrderByColumn(direction: dir)] |> OrderBy,
True,
)
}
/// Replaces the `OrderBy` a column with a direction.
///
pub fn replace_order_by(
query qry: Combined,
by ordb: String,
direction dir: Direction,
) -> Combined {
let dir = dir |> map_order_by_direction_constructor
qry
|> read_query.combined_order_by(
[ordb |> OrderByColumn(direction: dir)] |> OrderBy,
False,
)
}
/// Removes the `OrderBy` from the `Combined` read_query.
///
pub fn no_order_by(query qry: Combined) -> Combined {
Combined(..qry, order_by: NoOrderBy)
}
/// Gets the `OrderBy` from the `Combined` read_query.
///
pub fn get_order_by(query qry: Combined) -> OrderBy {
qry.order_by
}
// ▒▒▒ EPILOG ▒▒▒
/// Appends an `Epilog` to the `Combined` read_query.
///
pub fn epilog(query qry: Combined, epilog eplg: String) -> Combined {
let eplg = eplg |> string.trim
case eplg {
"" -> Combined(..qry, epilog: NoEpilog)
_ -> Combined(..qry, epilog: { " " <> eplg } |> Epilog)
}
}
/// Removes the `Epilog` from the `Combined` read_query.
///
pub fn no_epilog(query qry: Combined) -> Combined {
Combined(..qry, epilog: NoEpilog)
}
/// Gets the `Epilog` from the `Combined` read_query.
///
pub fn get_epilog(query qry: Combined) -> Epilog {
qry.epilog
}
// ▒▒▒ COMMENT ▒▒▒
/// Appends a `Comment` to the `Combined` read_query.
///
pub fn comment(query qry: Combined, comment cmmnt: String) -> Combined {
let cmmnt = cmmnt |> string.trim
case cmmnt {
"" -> Combined(..qry, comment: NoComment)
_ -> Combined(..qry, comment: { " " <> cmmnt } |> Comment)
}
}
/// Removes the `Comment` from the `Combined` read_query.
///
pub fn no_comment(query qry: Combined) -> Combined {
Combined(..qry, comment: NoComment)
}
/// Gets the `Comment` from the `Combined` read_query.
///
pub fn get_comment(query qry: Combined) -> Comment {
qry.comment
}