{"id":13605166,"url":"https://github.com/AniTrend/support-query-builder","last_synced_at":"2025-04-12T02:32:56.881Z","repository":{"id":54148529,"uuid":"344721999","full_name":"AniTrend/support-query-builder","owner":"AniTrend","description":"A simple SQLite spec compliant query builder that integrates with room to create raw queries","archived":false,"fork":false,"pushed_at":"2024-09-15T08:29:03.000Z","size":784,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2024-09-15T11:09:18.076Z","etag":null,"topics":["android","anitrend","annotation-processor","entity","kotlin","processor","query-builder","rawquery","room","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AniTrend.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-05T06:54:05.000Z","updated_at":"2024-09-15T08:22:55.000Z","dependencies_parsed_at":"2023-02-18T12:40:27.127Z","dependency_job_id":"5368cd23-97b0-40b4-b428-399927462033","html_url":"https://github.com/AniTrend/support-query-builder","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AniTrend%2Fsupport-query-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AniTrend%2Fsupport-query-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AniTrend%2Fsupport-query-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AniTrend%2Fsupport-query-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AniTrend","download_url":"https://codeload.github.com/AniTrend/support-query-builder/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223489748,"owners_count":17153822,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","anitrend","annotation-processor","entity","kotlin","processor","query-builder","rawquery","room","sqlite"],"created_at":"2024-08-01T19:00:55.336Z","updated_at":"2024-11-07T09:31:35.107Z","avatar_url":"https://github.com/AniTrend.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# support-query-builder \u0026nbsp; [![Run unit tests](https://github.com/AniTrend/support-query-builder/actions/workflows/android-test.yml/badge.svg)](https://github.com/AniTrend/support-query-builder/actions/workflows/android-test.yml) \u0026nbsp; [![Codacy Badge](https://app.codacy.com/project/badge/Grade/2bcc9217df74403a9d4afd8664b20c34)](https://www.codacy.com/gh/AniTrend/support-query-builder/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=AniTrend/support-query-builder\u0026amp;utm_campaign=Badge_Grade) \u0026nbsp; [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FAniTrend%2Fsupport-query-builder.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FAniTrend%2Fsupport-query-builder?ref=badge_shield) \u0026nbsp; [![](https://jitpack.io/v/AniTrend/support-query-builder.svg)](https://jitpack.io/#AniTrend/support-query-builder)\n\nA simple yet comprehensive sql **select** query builder with featuring an annotation processor to generate schema objects from [Room](https://developer.android.com/reference/androidx/room/Room) annotations that plugs straight into [RawQuery](https://developer.android.com/reference/androidx/room/RawQuery)\n\n## Why This Project Exists?\n\nWhile [Room](https://developer.android.com/reference/androidx/room/Room) offers an excelent service loader based approach to generate an ORM layer for android application through static annotated queries, if you need to have some form of dynamic queries that might be user generated at runtime you would have to consider using [SupportSQLiteQueryBuilder](https://developer.android.com/reference/androidx/sqlite/db/SupportSQLiteQueryBuilder) to generate dynamic queries. However the [SupportSQLiteQueryBuilder](https://developer.android.com/reference/androidx/sqlite/db/SupportSQLiteQueryBuilder) API does a great job of constructing fairly simple queries, but lacks a fluent builder style API with joins, unions and large chains. In addition to this you have to write out table and column names as plain strings which is not only cumbersome but also error prone and adds additional overhead as you'd have to make sure that any changes you make to the entity related names are reflected throughout all your query builder references.\n\n**support-query-builder** aims to solve these problems and comes in the form of 3 libraries with the following features:\n- **annotations** - Annotation only which is used to inform the **processor** of entities to inspect\n- **core** - The main query builder library for constructing queries\n- **core-ext** - Contains helper extention functions for the `core` modules, specifically `asSupportSQLiteQuery`\n- **processor** - Kotlin annotation proccessor that generates kotlin object classes that mirror your Room entity annotations supporting inspection `@Entity`, `@ColumnInfo` and `@Embedded`\n\n\nSee a list of changes from [releases](https://github.com/AniTrend/support-query-builder/releases)\n\n\u003e Inspired by [QueryBuilder](https://github.com/reinaldoarrosi/QueryBuilder)\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FAniTrend%2Fsupport-query-builder.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FAniTrend%2Fsupport-query-builder?ref=badge_large)\n\n____\n\n## How Everything Works\n\n### Getting Started\n\n- __Add the JitPack repository to your build file__\n\n```javascript\nallprojects {\n    repositories {\n        ...\n        maven { url 'https://www.jitpack.io' }\n    }\n}\n```\n\n- __Add the dependency__\n\n```javascript\ndependencies {\n    implementation 'com.github.anitrend:support-query-builder:module_name:{latest_version}'\n}\n```\n\n### Examples\n\nIn all the instances you need to build a query you have to create an instance of the query builder:\n```kotlin\nimport co.anitrend.support.query.builder.core.QueryBuilder\n\nval builder = QueryBuilder()\n```\n\nSubmitting your query builder into a [RawQuery](https://developer.android.com/reference/androidx/room/RawQuery) dao method for room to consume simply call:\n```kotlin\nval builder = QueryBuilder()\n// ... statements here\nbuilder.asSupportSQLiteQuery()\n```\n\n\u003e **N.B.** Most of the builder extension functions are infix, please see the `co.anitrend.support.query.builder.dsl.*` package for more details and `co.anitrend.support.query.builder.core` test directory for a list of different examples\n\n### Annotation processor\n\nIf you want to have your entity classes inspected and generate schema objects add the following to yout module gradle file\n\n```javascript\ndependencies {\n    implementation 'com.github.anitrend:support-query-builder:annotaion:{latest_version}'\n    kapt 'com.github.anitrend:support-query-builder:processor:{latest_version}'\n}\n```\n\nAfter you can annotate your entity classes with `@EnititySchema` as shown below, which should only be on your top level entity e.g.:\n\n```kotlin\n@EntitySchema\n@Entity(tableName = \"pet\")\ninternal data class PetEntity(\n    @PrimaryKey(autoGenerate = true)\n    @ColumnInfo(name = \"id\") val id: Long,\n    @ColumnInfo(name = \"name\") val name: String,\n    @ColumnInfo(name = \"owner_id\") val owner: Long,\n    @Embedded(prefix = \"breed_\") val breed: Breed,\n) {\n    data class Breed(\n        @ColumnInfo(name = \"group\") val group: String,\n        @ColumnInfo(name = \"origin\") val origin: String\n    )\n\n    // This should not be generated since it is not referenced in the entity\n    data class SomeConstruct(\n        @ColumnInfo(name = \"id\") val id: Long,\n        @Embedded(prefix = \"prob_\") val property: Property\n    ) {\n        data class Property(\n            @ColumnInfo(name = \"option_a\") val optionA: String\n        )\n    }\n}\n```\n\nWhen your build completes your should be able to access a generated object called `PetEntitySchema` which would have the following format.\n\n```kotlin\npublic object PetEntitySchema {\n  public const val tableName: String = \"pet\"\n\n  public const val id: String = \"id\"\n\n  public const val name: String = \"name\"\n\n  public const val owner: String = \"owner_id\"\n\n  public const val breedGroup: String = \"breed_group\"\n\n  public const val breedOrigin: String = \"breed_origin\"\n}\n```\n\nYou may use the newly created schema object when building out your queries\n\n\u003e **N.B.** If you do not set the `tableName` protery on @Entity then the class name is used instead, the same applies to `name` property on `@ColumnInfo` and `prefix` on `@Embedded`\n\u003e **Check out the sample project and tests located [in the core module](./core/src/test/kotlin/co/anitrend/support/query/builder/core) for more samples**\n\n### Basic statement\n\n\u003e ```sql\n\u003eSELECT * FROM table_name\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nbuilder select \"*\" from \"table_name\"\n```\n\nWhich can also be written as\n\n```kotlin\nval builder = QueryBuilder()\nbuilder from \"table_name\"\n```\n\n\n### Basic statement with alias\n\n\u003e ```sql\n\u003eSELECT column_name AS t FROM table_name\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nval column = \"column_name\".asColumn()\nbuilder select (column `as` \"t\") from \"table_name\"\n```\n\nWhich can also be applied on the table name\n\n\u003e ```sql\n\u003eSELECT * FROM table_name AS n\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nbuilder from (\"table_name\".asTable() `as` \"n\")\n```\n\n\n### Basic statement with where clause\n\n\u003e ```sql\n\u003eSELECT * FROM table_name WHERE column_name = 'something'\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nval column = \"column_name\".asColumn()\nbuilder from table where {\n    column equal \"something\"\n}\n```\n\nWhich can also be written as\n```kotlin\nval builder = QueryBuilder()\nval column = \"column_name\".asColumn()\nbuilder.from(table).where(column.equal(\"something\"))\n```\n\n\n### Statement with inner join clause\n\n\u003e ```sql\n\u003eSELECT * FROM table_name INNER JOIN other_table_name ON other_column_id = column_id\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nbuilder from table.innerJoin(\"other_table_name\") {\n    on(\"other_column_id\", \"column_id\")\n}\n```\n\nWhich can also be written as\n```kotlin\nval builder = QueryBuilder()\nbuilder.from(table.innerJoin(\"other_table_name\").on(\"other_column_id\", \"column_id\"))\n```\n\n\n### Statement with inner join and where clause and order by\n\n\u003e ```sql\n\u003eSELECT * FROM table_name INNER JOIN other_table_name ON other_column_id = column_id WHERE column_name = 'something'\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nval column = \"column_name\".asColumn()\n// You can ommit the `.asTable` if you want\nbuilder from table.innerJoin(\"other_table_name\".asTable()) {\n    on(\"other_column_id\", \"column_id\")\n} where {\n    column equal \"something\"\n} orderByDesc column\n```\n\n### Statement with inner join and where clause and filter\n\n\u003e ```sql\n\u003eSELECT * FROM table_name INNER JOIN other_table_name ON other_column_id = column_id WHERE (column_name = 'something' AND column_name LIKE '%pe')\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nval column = \"column_name\".asColumn()\nbuilder from {\n    table.innerJoin(\"other_table_name\").on(\n        \"other_column_id\", \"column_id\"\n    )\n} where {\n    column.equal(\"something\") and column.endsWith(\"pe\")\n}\n```\n\n\n### Statement with multiple join and where clause and filter\n\n\u003e ```sql\n\u003eSELECT * FROM table_name INNER JOIN other_table_name ON other_column_id = column_id LEFT JOIN some_table_name ON some_other_column_id = column_id WHERE (column_name = 'something' AND column_name LIKE '%pe')\n\u003e```\n```kotlin\nval builder = QueryBuilder()\nval column = \"column_name\".asColumn()\nbuilder from {\n    table.innerJoin(\"other_table_name\").on(\n        \"other_column_id\", \"column_id\"\n    )\n    .leftJoin(\"some_table_name\").\n        on(\"some_other_column_id\", \"column_id\")\n\n} where {\n    (column equal \"something\") and (column endsWith \"pe\")\n}\n```\n\nWhich can also be written as:\n\n```kotlin\nbuilder from table\nbuilder from {\n    innerJoin(\"other_table_name\") {\n        on(\"other_column_id\", \"column_id\")\n    }\n}\nbuilder from {\n    leftJoin(\"some_table_name\").on(\n        \"some_other_column_id\", \"column_id\"\n    )\n}\nbuilder where {\n    (column equal \"something\") and (column endsWith \"pe\")\n}\n```\n\n\n## License\n\n```\nCopyright 2021 AniTrend\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAniTrend%2Fsupport-query-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAniTrend%2Fsupport-query-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAniTrend%2Fsupport-query-builder/lists"}