Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
agp = "8.13.0"
agp = "8.13.1"
kotlin = "2.0.21"
coreKtx = "1.17.0"
junit = "4.13.2"
Expand Down
10 changes: 8 additions & 2 deletions query/src/main/java/com/blipblipcode/query/InnerJoint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class InnerJoint private constructor(
override fun asSql(): String {
require(queries.isNotEmpty()) { "At least one query is required for an INNER JOIN" }
require(queries.size == onClauses.size) { "The number of queries must be equal to the number of ON clauses (including a placeholder for the base query)" }
val orders = queries.fold(mutableListOf<OrderBy>()) { acc, query ->
query.getOrderBy()?.let { acc.add(it) }
query.orderBy(null)
acc
}
orders.addAll(orderBy?.let { listOf(it) } ?: emptyList())

val baseQuery = queries.first()
val joins = queries.drop(1).zip(onClauses.drop(1)) { query, onClause ->
Expand All @@ -46,9 +52,9 @@ class InnerJoint private constructor(

return buildString {
append("${baseQuery.asSql()} ${joins.joinToString(" ")}")
if (orderBy != null) {
if (orders.isNotEmpty()) {
appendLine()
append(orderBy!!.asString())
append(OrderBy.Multiple(orders).asString())
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions query/src/main/java/com/blipblipcode/query/QueryDelete.kt
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ class QueryDelete private constructor(
* @param operator The SQL operator for this condition.
* @return The `QueryBuilder` instance for chaining.
*/
fun like(key: String, operator: SQLOperator<*>): QueryBuilder {
operations[key] = LogicalOperation(LogicalType.LIKE, operator)
fun like(key: String, operator: SQLOperator.Like): QueryBuilder {
operations[key] = LogicalOperation(LogicalType.AND, operator)
return this
}

Expand Down
30 changes: 22 additions & 8 deletions query/src/main/java/com/blipblipcode/query/QuerySelect.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import com.blipblipcode.query.operator.SQLOperator
* @property fields The list of columns to be returned in the result set. Defaults to "*".
*/
class QuerySelect private constructor(
private var where: SQLOperator<*>,
private var where: SQLOperator<*>?,
private val table: String,
private val operations: LinkedHashMap<String, LogicalOperation>,
private val fields: List<String>
Expand Down Expand Up @@ -87,9 +87,10 @@ class QuerySelect private constructor(
}
}


override fun getSqlOperators(): List<SQLOperator<*>> {
return buildList {
add(where)
where?.let { add(it) }
operations.values.forEach { add(it.operator) }
}
}
Expand All @@ -110,7 +111,11 @@ class QuerySelect private constructor(
val fieldStr = if (fields.isEmpty()) "*" else fields.joinToString(", ")
val operationsStr = if (operations.isNotEmpty()) operations.values.joinToString(" ") { it.asString() } else ""
return buildString {
append("SELECT $fieldStr FROM $table WHERE ${where.toSQLString()} $operationsStr".trim())
if (where == null) {
append("SELECT $fieldStr FROM $table")
}else{
append("SELECT $fieldStr FROM $table WHERE ${where?.toSQLString()} $operationsStr".trim())
}
if (orderBy != null) {
append(" ")
append(orderBy!!.asString())
Expand All @@ -129,7 +134,7 @@ class QuerySelect private constructor(
* @param operator A vararg of `[OrderBy]` objects specifying the columns and direction for sorting.
* @return A new `QuerySelect` instance representing the UNION query with the added ORDER BY clause.
*/
fun orderBy(operator: OrderBy): Queryable {
fun orderBy(operator: OrderBy?): Queryable {
orderBy = operator
return this
}
Expand Down Expand Up @@ -157,6 +162,10 @@ class QuerySelect private constructor(
return this
}

fun getOrderBy(): OrderBy? {
return this.orderBy
}


/**
* A builder for creating `QuerySelect` instances.
Expand Down Expand Up @@ -237,8 +246,8 @@ class QuerySelect private constructor(
* @param operator The SQL operator for this condition.
* @return The `QueryBuilder` instance for chaining.
*/
fun like(key: String, operator: SQLOperator<*>): QueryBuilder {
operations[key] = LogicalOperation(LogicalType.LIKE, operator)
fun like(key: String, operator: SQLOperator.Like): QueryBuilder {
operations[key] = LogicalOperation(LogicalType.AND, operator)
return this
}

Expand Down Expand Up @@ -292,6 +301,9 @@ class QuerySelect private constructor(
this.orderBy = orderBy
return this
}
fun getOrderBy(): OrderBy? {
return this.orderBy
}

/**
* Sets a LIMIT clause for the query to limit the number of rows returned.
Expand Down Expand Up @@ -320,9 +332,11 @@ class QuerySelect private constructor(
* @throws IllegalArgumentException if the WHERE clause is not set.
*/
fun build(): QuerySelect {
require(where != null) { "WHERE clause is required for QuerySelect" }
if(operations.isNotEmpty()){
require(where != null) { "WHERE clause is required for QuerySelect" }
}
return QuerySelect(
where = where!!,
where = where,
table = table,
operations = LinkedHashMap(operations),
fields = fields
Expand Down
13 changes: 9 additions & 4 deletions query/src/main/java/com/blipblipcode/query/UnionQuery.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,19 @@ class UnionQuery private constructor(
*/
override fun asSql(): String {
require(queries.size >= 2) { "At least two queries are required for a UNION" }

val orders = queries.fold(mutableListOf<OrderBy>()) { acc, query ->
query.getOrderBy()?.let { acc.add(it) }
query.orderBy(null)
acc
}
orders.addAll(orderBy?.let { listOf(it) } ?: emptyList())
val unionKeyword = if (useUnionAll) "UNION ALL" else "UNION"

return buildString {
append(queries.joinToString("\n$unionKeyword\n") { it.asSql() })
if (orderBy != null) {
if (orders.isNotEmpty()) {
appendLine()
append(orderBy!!.asString())
append(OrderBy.Multiple(orders).asString())
}
}
}
Expand All @@ -51,7 +56,7 @@ class UnionQuery private constructor(
* Appends an ORDER BY clause to the entire UNION query.
* Note that in most SQL dialects, an ORDER BY clause can only be applied to the final result of a UNION, not to individual `SELECT` statements within it.
*
* @param columns A vararg of `OrderExpression` objects specifying the columns and direction for sorting.
* @param operator A vararg of `OrderExpression` objects specifying the columns and direction for sorting.
* @return A new `QuerySelect` instance representing the UNION query with the added ORDER BY clause.
*/
fun orderBy(operator: OrderBy): Queryable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ enum class LogicalType(val sql: String) {
AND("AND"),
/** Represents a logical OR operation. */
OR("OR"),
/** Represents a SQL LIKE operation. */
LIKE("LIKE"),
/** Represents a SQL ALL operation. */
ALL("ALL"),

Expand Down
21 changes: 21 additions & 0 deletions query/src/main/java/com/blipblipcode/query/operator/OrdenBy.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ package com.blipblipcode.query.operator
sealed interface OrderBy {
val column: String
fun asString(): String

fun asSqlClause(): String {
return when (this) {
is Asc -> "$column ASC"
is Desc -> "$column DESC"
is Multiple -> orders.joinToString(", ") { it.asSqlClause() }
}
}
data class Asc(override val column: String) : OrderBy{
override fun asString(): String {
return "ORDER BY $column ASC"
Expand All @@ -19,4 +27,17 @@ sealed interface OrderBy {
return "ORDER BY $column DESC"
}
}

data class Multiple(val orders: List<OrderBy>) : OrderBy{
override val column: String
get() = orders.joinToString(", ") { it.column }

override fun asString(): String {
return "ORDER BY ${asSqlClause()}"
}

override fun toString(): String {
return "ORDER BY ${asSqlClause()}"
}
}
}
Loading