Develop#14
Merged
Merged
Conversation
…RE clause This commit introduces a convenience feature where the first logical operation (`AND` or `OR`) is automatically used as the `WHERE` clause if one is not explicitly set in the query builder. This simplifies query construction by removing the requirement to call `where()` first. The changes include: - Modifying the `build()` method in `QuerySelect.Builder` and `QueryDelete.Builder` to automatically identify and set the `WHERE` clause from the existing logical operations. - Updating `getSqlOperators()` in `QuerySelect`, `QueryDelete`, and `QueryUpdate` to correctly include the `where` operator in the returned list, improving query introspection.
This commit corrects a test case for `QueryDelete`. The test `build without where clause throws exception` was incorrectly including a WHERE condition, which prevented it from accurately verifying that building a `QueryDelete` without any conditions throws an `IllegalArgumentException`. The extraneous condition has been removed.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit modifies `QuerySelect` to support SQL queries without a `WHERE` clause. Previously, the `WHERE` clause was mandatory. This restriction has been lifted, but the requirement is maintained if other logical operations (like `AND` or `OR`) are present. The main changes include: - The `where` property in `QuerySelect` is now nullable (`SQLOperator<*>?`). - The `build()` method in the `QuerySelect.Builder` now only requires a `WHERE` clause if subsequent logical operations are added. - The SQL generation in `asSql()` has been updated to correctly build the `SELECT` statement when no `WHERE` clause is provided. - `getSqlOperators()` is updated to handle the nullable `where` property.
# Conflicts: # query/src/main/java/com/blipblipcode/query/QuerySelect.kt
Updates the Android Gradle Plugin version from 8.13.0 to 8.13.1.
feat(Query): Enhance `orderBy` and fix `like` operator
This commit introduces several improvements to the query builder, focusing on `ORDER BY` clause handling and correcting the behavior of the `like` operator.
Key changes include:
* **Fix `like` Operator Logic**: The `like()` method in `QuerySelect` and `QueryDelete` builders was incorrectly using a `LIKE` logical type. This has been corrected to use the `AND` logical type, ensuring it chains correctly with other conditions. The method signature is now restricted to `SQLOperator.Like`.
* **Enhanced `OrderBy` in Union and Join Queries**: `UnionQuery` and `InnerJoint` now correctly handle `ORDER BY` clauses. They aggregate `OrderBy` operators from all subqueries, clear them from the individual queries, and apply a combined `OrderBy` to the final result set. This prevents SQL errors and ensures predictable sorting. `QuerySelect` has been updated with `getOrderBy()` and nullable `orderBy()` methods to support this.
* **Improved `OrderBy` Implementation**:
* A new `OrderBy.Multiple` sealed class has been added to handle sorting by multiple columns with different sort directions.
* The `asSqlClause()` method was introduced for more flexible SQL string generation.
* **Extensive Testing**: Added comprehensive unit tests for the `orderBy` functionality in `QuerySelectTest`, covering various scenarios like single and multiple columns, mixed sort directions, aliases, and combinations with `LIMIT`.
This commit corrects the KDoc for the `orderBy` function in `UnionQuery`. The `@param` name has been updated from `columns` to `operator` to accurately match the function's parameter name.
This commit introduces support for case-insensitive comparisons in SQL operators by adding an optional `CaseConversion` parameter. This allows wrapping columns and values with `LOWER()` or `UPPER()` SQL functions.
The main changes include:
* **New `CaseConversion` Enum**: A new enum `CaseConversion` (`NONE`, `LOWER`, `UPPER`) has been created to specify the desired case conversion.
* **Updated `SQLOperator`**:
* The `SQLOperator` interface and all its implementing data classes now include a `caseConversion` property, which defaults to `NONE`.
* The `toSQLString()` methods have been updated to apply the corresponding SQL function (`LOWER()` or `UPPER()`) to both the column and the value when a conversion is specified.
* **New Test Cases**: Added tests to `QuerySelectTest` to verify the correct SQL generation for queries using `UPPER` case conversion in the `WHERE` clause.
This commit updates the following dependencies to their latest versions: * Kotlin: `2.0.21` -> `2.2.21` * AndroidX Lifecycle Runtime KTX: `2.9.4` -> `2.10.0` * AndroidX Activity Compose: `1.11.0` -> `1.12.1` * AndroidX Compose BOM: `2024.09.00` -> `2025.12.00` * AndroidX SQLite KTX: `2.6.1` -> `2.6.2`
This commit updates the Kotlin version badge in the `README.md` file. The version has been changed from `1.9+` to `2.2.21+` to reflect the current Kotlin version used in the project.
This commit refactors the `Field` data class to implement the `SQLOperator<T>` interface, standardizing its structure with other operators. The main changes include: - Implementing `SQLOperator` in `Field`, providing `symbol`, `column`, `value`, and `caseConversion` properties. - Updating the `asString()` method to use the newly added `symbol` property for SQL generation. - Adding a `clone()` method to the `OrderBy` sealed class and its subclasses (`Asc`, `Desc`, `Multiple`) to allow for deep cloning of instances, which improves immutability and flexibility in query construction. - Fixing the `IN` and `NOT IN` operators in `SQLOperator.kt` by ensuring that string values within the list are correctly quoted in the generated SQL.
This commit enhances the `Queryable` interface by adding a new overloaded `asSql` method. The new method accepts a predicate lambda, which allows for filtering the `SQLOperator`s that are included when generating the final SQL string. This provides more control and flexibility in SQL generation.
…nality
This commit introduces two main enhancements to the query builder classes: a new `asSql` method that accepts a predicate for filtering SQL operators, and a `clear` method for resetting query builders.
The key changes include:
* **Predicate-based `asSql(predicate)` Method**:
* All `Queryable` classes (`QuerySelect`, `QueryInsert`, `QueryUpdate`, `QueryDelete`, `UnionQuery`, `InnerJoint`) now implement an overloaded `asSql` method.
* This new method takes a predicate lambda, allowing for the conditional inclusion of SQL operators when generating the final SQL string.
* **`clear()` Method for Builders**:
* `QuerySelect` and `QueryDelete` (and their respective builders) now feature a `clear()` method.
* This method resets the query state by removing the `WHERE` clause and any subsequent logical operations (`AND`, `OR`), allowing builders to be reused for new queries.
This commit refactors `Limit`, `OrderBy`, `IsNull`, and `IsNotNull` to fully implement the `SQLOperator` interface. This standardization improves consistency across all SQL operators.
Key changes include:
* **`Limit` and `OrderBy` Implementation**:
* `Limit` and the sealed interface `OrderBy` (including `Asc`, `Desc`, and `Multiple`) now implement `SQLOperator`.
* They now define standard properties like `symbol`, `column`, `value`, and `caseConversion`.
* The `asString()` methods have been updated to use these properties for SQL generation.
* **`IsNull` and `IsNotNull` Adjustments**:
* The generic type for `IsNull` and `IsNotNull` has been changed from `Unit` to `String?`, with the `value` property now returning `null`.
* Their `toSQLString()` and `asString()` methods have been updated to support case conversion on the column.
This commit introduces `RepeatedQueryParameters`, a custom `LinkedHashMap` implementation designed to handle repeated query parameters in Retrofit. This utility class allows lists provided as values in a `@QueryMap` to be automatically expanded into multiple query parameters with the same key. This is useful for API endpoints that expect repeated keys, such as `?key=value1&key=value2`. Key features: - **`RepeatedQueryParameters` class**: Extends `LinkedHashMap` and overrides the `entries` property to transform list values into multiple `Map.Entry` objects. - **Factory methods**: Provides `create()`, `fromMap()`, and `empty()` for convenient instantiation. - **Handles lists**: Automatically expands `List<*>` values into separate key-value pairs. - **Null safety**: Throws exceptions for null keys and skips null values within lists.
This commit introduces a new extension function, `asQueryRepeatedQueryParameters`, for the `Queryable` interface. This function converts the SQL operators of a query into a `RepeatedQueryParameters` object, which is useful for integrations like Retrofit. Key features include: - A `predicate` parameter to conditionally filter which query parameters are included. - Support for regular parameters and repeated parameters (from `List` values). - Null-valued parameters are automatically excluded.
This commit enhances the `getSqlOperators()` method in `QuerySelect`. The `orderBy` and `limit` operators are now included in the returned list of SQL operators. This improves query introspection by providing a more complete representation of the query's components.
This commit introduces `RepeatedQueryParameters`, a utility class designed to bridge the gap between the `Query` library and Retrofit's `@QueryMap` annotation. It also adds a convenient extension function to convert `Queryable` objects directly into this new format.
The key changes include:
* **New `RepeatedQueryParameters` class**:
* This class extends `LinkedHashMap` and is designed to handle both single and repeated query parameters, which are common in REST APIs.
* It provides `addParameter()` for single values and `addRepeatedParameter()` for lists.
* A custom `entries` property expands list values into multiple `Map.Entry` objects, making it compatible with Retrofit's `@QueryMap` when used for repeated parameters (e.g., `?key=val1&key=val2`).
* **New `asQueryRepeatedQueryParameters()` extension function**:
* This function converts any `Queryable` object (like `QuerySelect`) into a `RepeatedQueryParameters` instance.
* It intelligently handles `SQLOperator` values, mapping single values directly and converting list-based operators (like `IN`) into repeated parameters.
* Operators with `Unit` or `null` values (e.g., `IsNull`) are automatically filtered out.
* An optional predicate allows for custom filtering of which operators are included.
* **Comprehensive Unit Tests**:
* Added `RepeatedQueryParametersTest.kt` to thoroughly validate the new class's behavior, including adding, overwriting, and expanding parameters.
* Added `QueryableRepeatedQueryParametersExtensionTest.kt` to test the conversion from `Queryable` to `RepeatedQueryParameters`, covering simple operators, list-based operators, and filtering logic.
This commit introduces `RepeatedQueryParameters`, a utility class designed to bridge the gap between the `Query` library and Retrofit's `@QueryMap` annotation. It also adds a convenient extension function to convert `Queryable` objects directly into this new format.
The key changes include:
* **New `RepeatedQueryParameters` class**:
* This class extends `LinkedHashMap` and is designed to handle both single and repeated query parameters, which are common in REST APIs.
* It provides `addParameter()` for single values and `addRepeatedParameter()` for lists.
* A custom `entries` property expands list values into multiple `Map.Entry` objects, making it compatible with Retrofit's `@QueryMap` when used for repeated parameters (e.g., `?key=val1&key=val2`).
* **New `asQueryRepeatedQueryParameters()` extension function**:
* This function converts any `Queryable` object (like `QuerySelect`) into a `RepeatedQueryParameters` instance.
* It intelligently handles `SQLOperator` values, mapping single values directly and converting list-based operators (like `IN`) into repeated parameters.
* Operators with `Unit` or `null` values (e.g., `IsNull`) are automatically filtered out.
* An optional predicate allows for custom filtering of which operators are included.
* **Comprehensive Unit Tests**:
* Added `RepeatedQueryParametersTest.kt` to thoroughly validate the new class's behavior, including adding, overwriting, and expanding parameters.
* Added `QueryableRepeatedQueryParametersExtensionTest.kt` to test the conversion from `Queryable` to `RepeatedQueryParameters`, covering simple operators, list-based operators, and filtering logic.
This commit enhances the KDoc for the `getOrderBy()` function in the `QuerySelect` builder. The new documentation clarifies that the function returns the `OrderBy` object for the query, or `null` if an `ORDER BY` clause has not been set.
This commit fixes a bug in the `Between` SQL operator where the start and end values were not being properly quoted in the generated SQL string. This could lead to SQL syntax errors when using string values. The `toSQLString()` and `asString()` methods in `SQLOperator.Between` have been updated to enclose the start and end values in single quotes.
feat(Query): Enhance `QuerySelect` and `UnionQuery` with builders and transformations
This commit introduces several improvements to the query building API, focusing on query mutability and builder reusability.
Key changes include:
* **Enhanced `QuerySelect`**:
* Added `newBuilder()` to create a builder from an existing query instance, facilitating query modification.
* Updated `where` clause storage to use a `Pair<String, SQLOperator<*>>` to support keyed identification of the primary condition.
* Added `getOperations()` to retrieve a map of all SQL operators (including WHERE) indexed by their keys.
* Introduced `transformOperation(key, transform)` in `QueryBuilder` to allow modifying specific logical operations by key.
* **Improved `UnionQuery`**:
* Renamed `UnionQuery.Builder` to `UnionQuery.QueryBuilder` for consistency.
* Added `newBuilder()` to allow extending or modifying existing union queries.
* Implemented `transformOperation(key, transform)` in the union builder, which applies the transformation recursively to all subqueries in the union.
* **Bug Fixes & Refactoring**:
* Corrected `QuerySelect` SQL generation to handle the updated `where` pair structure.
* Updated the `UnionQuery.addQuery` extension function to use the renamed `QueryBuilder`.
This commit cleans up the `UnionQuery.kt` file by removing several unused imports, including `QuerySelect.QueryBuilder`, `LogicalType`, and `kotlin.collections.set`.
This commit refactors the `LogicalOperation` class into a sealed interface with distinct implementations for each logical type (`Where`, `And`, `Or`, `Not`, etc.). This improves type safety and aligns the structure with other operator models in the library. The key changes include: * **`LogicalOperation` as a Sealed Interface**: Replaced the previous data class with a sealed interface, providing specific data classes for each logical operation (`Where`, `And`, `Or`, etc.). * **Standardized Structure**: Each `LogicalOperation` implementation now includes `symbol`, `operator`, `asString()`, and `clone()` members for consistency. * **Updated Query Builders**: `QuerySelect.QueryBuilder` and `QueryDelete.QueryBuilder` have been updated to use the new sealed interface implementations, replacing the previous `LogicalType` enum. * **Refined SQL Generation**: The `asSql()` methods in `QuerySelect` and `QueryDelete` now delegate the generation of the `WHERE` clause to the `LogicalOperation.Where.asString()` method, simplifying the logic.
…on and remove unused imports
# Conflicts: # query/src/main/java/com/blipblipcode/query/QuerySelect.kt
…ethod from QuerySelect and UnionQuery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces significant refactoring to the query builder logic, particularly in how logical operations are represented and handled in both
QuerySelectandQueryDelete. It also adds Maven publishing support to the Gradle build configuration. The main changes improve type safety and extensibility by replacing the use ofLogicalTypeenums with sealed subclasses ofLogicalOperation, and by updating the representation ofwhereclauses. Additionally, the Gradle build script is enhanced to support publishing the module as a Maven artifact.Query builder refactoring:
whereproperties in bothQuerySelectandQueryDeleteto usePair<String, LogicalOperation>instead of directly storingSQLOperatoror a pair withSQLOperator, enabling more expressive and type-safe logical operation handling. [1] [2]LogicalTypeenums with sealed subclasses ofLogicalOperation(e.g.,And,Or,Not,Exists,All,Where), simplifying the addition of logical operators and improving code readability. [1] [2] [3] [4] F23f2ea4L170R170, [5] [6] [7] [8] [9]LogicalOperationstructure, ensuring correct SQL output and operator extraction. [1] [2] [3] [4] [5] [6] [7] [8]API improvements:
getSqlOperationmethod toQuerySelect.QueryBuilderto retrieve the currentSQLOperatorfor a given key, improving usability for consumers of the API.Build and publishing enhancements:
query/build.gradle.kts, allowing the module to be published as a Maven artifact, including configuration for the release variant and source JARs. [1] [2]These changes collectively make the query builder more robust, maintainable, and easier to extend, while also enabling the module to be published and consumed via Maven.