{"id":21593453,"url":"https://github.com/tamimattafi/kabin","last_synced_at":"2025-08-20T20:32:42.881Z","repository":{"id":220471265,"uuid":"702197843","full_name":"tamimattafi/kabin","owner":"tamimattafi","description":"Kotlin Multiplatform library for database storage inspired by Room and built on SQLDelight","archived":false,"fork":false,"pushed_at":"2025-05-06T22:46:56.000Z","size":714,"stargazers_count":54,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-06T23:28:57.917Z","etag":null,"topics":["android","browser","database","desktop","ios","js","jvm","kabin","kmm","kmp","kotlin","kotlinmultiplatform","library","native","orm","query","room","sql","sqldelight","sqlite"],"latest_commit_sha":null,"homepage":"https://tamimattafi.github.io/kabin/","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/tamimattafi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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,"zenodo":null}},"created_at":"2023-10-08T19:18:16.000Z","updated_at":"2025-05-06T22:46:59.000Z","dependencies_parsed_at":"2025-05-06T23:24:44.281Z","dependency_job_id":"20ff1632-4623-4968-ac2c-93cfcd95f6c5","html_url":"https://github.com/tamimattafi/kabin","commit_stats":null,"previous_names":["tamimattafi/kabin"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/tamimattafi/kabin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamimattafi%2Fkabin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamimattafi%2Fkabin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamimattafi%2Fkabin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamimattafi%2Fkabin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tamimattafi","download_url":"https://codeload.github.com/tamimattafi/kabin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamimattafi%2Fkabin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271378680,"owners_count":24749192,"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","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","browser","database","desktop","ios","js","jvm","kabin","kmm","kmp","kotlin","kotlinmultiplatform","library","native","orm","query","room","sql","sqldelight","sqlite"],"created_at":"2024-11-24T17:12:53.604Z","updated_at":"2025-08-20T20:32:42.857Z","avatar_url":"https://github.com/tamimattafi.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Kabin Release](https://img.shields.io/github/release/tamimattafi/kabin.svg?style=for-the-badge\u0026color=darkgreen)](https://github.com/tamimattafi/kabin/releases)\n[![Kotlin](https://img.shields.io/github/languages/top/tamimattafi/kabin.svg?style=for-the-badge\u0026color=blueviolet)](https://kotlinlang.org/)\n[![License Apache 2.0](https://img.shields.io/github/license/tamimattafi/kabin.svg?style=for-the-badge\u0026color=purple)](https://github.com/tamimattafi/kabin/blob/main/LICENSE)\n\n\u003ch1 align=\"center\"\u003e\n    \u003cimg height=\"150\" src=\"./art/kabin.png\"/\u003e\n    \u003cbr\u003e\n    \u003ca\u003eKabin\u003c/a\u003e: Multiplatform Database Library\n\u003c/h1\u003e\n\nA Kotlin Multiplatform library for database storage, which aims to support all functionality offered by [Room](https://developer.android.com/training/data-storage/room).\n\nKabin uses drivers from **SQLDelight**, offering a stable interaction with `SQL` on all targets supported by the latter.\n\n\u003e [!CAUTION]\n\u003e This library is still under development. Avoid using it in production.\n\u003e\n\u003e Room already has Kotlin Multiplatform support and is stable. Please consider using it instead.\n\u003e\n\u003e Kabin will be maintained less often and more like a pet project. \n\u003e You are very welcome to create issues and Pull Requests.\n\u003e Contribution will accelerate development, and pave the way for a production ready solution.\n\n## Showcase\nUsing Kabin is straight forward. Annotations are identical to those in Room, which means usage is identical too.\nHere's how you declare a simple database:\n\n1. Create an `Entity`:\n```kotlin\n@Entity\ndata class UserEntity(\n    @PrimaryKey\n    val id: Int,\n    val name: String\n)\n```\n\n2. Create a `Dao`:\n```kotlin\n@Dao\ninterface UserDao {\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    suspend fun insertOrReplace(entity: UserEntity)\n}\n```\n\n3. Create a `Database`:\n```kotlin\n@Database(\n    entities = [\n        UserEntity::class\n    ],\n    version = 1\n)\ninterface SampleDatabase : KabinDatabase {\n    val userDao: UserDao\n}\n```\n\nKabin will generate code for you and glue everything together.\n\n4. Finally, create a platform configuration, then pass it to the `newInstance` method, to initialize `SampleDatabase`:\n```kotlin\n// Create configuration for every platform, here's an example for android\nval configuration = KabinDatabaseConfiguration(\n    context = this,\n    name = \"sample-database\"\n)\n\nval sampleDatabase = SampleDatabase::class.newInstance(\n    configuration,\n    migrations = emptyList(),\n    migrationStrategy = KabinMigrationStrategy.DESTRUCTIVE\n)\n```\n\nFor more advanced topics, read [Room](https://developer.android.com/training/data-storage/room) documentation and tutorials, and apply the same logic using Kabin.\n\n## Installation\nLatest Kabin version\n\n[![Kabin Release](https://img.shields.io/github/release/tamimattafi/kabin.svg?style=for-the-badge\u0026color=darkgreen)](https://github.com/tamimattafi/kabin/releases)\n\nAdd `common` modules to your `sourceSet`:\n```kotlin\nkotlin {\n    sourceSets {\n        val commonMain by getting {\n            dependencies {\n                // Kabin\n                implementation(\"com.attafitamim.kabin:core:$kabin_version\")\n            }\n\n            // Make generated code visible for commonMain\n            kotlin.srcDir(\"$buildDir/generated/ksp/metadata/commonMain/kotlin/\")\n        }\n    }\n}\n```\n\nAdd `ksp` compiler:\n```kotlin\nplugins {\n    alias(libs.plugins.kotlin.multiplatform)\n    alias(libs.plugins.ksp)\n}\n\ndependencies {\n    add(\"kspCommonMainMetadata\", \"com.attafitamim.kabin:compiler:$kabin_version\")\n}\n\n// Workaround for using KSP in common\ntasks.withType\u003cKotlinCompile\u003c*\u003e\u003e().configureEach {\n    if (name != \"kspCommonMainKotlinMetadata\") {\n        dependsOn(\"kspCommonMainKotlinMetadata\")\n    }\n}\n\nafterEvaluate {\n    tasks.filter { task -\u003e\n        task.name.contains(\"SourcesJar\", true)\n    }.forEach { task -\u003e\n        task.dependsOn(\"kspCommonMainKotlinMetadata\")\n    }\n}\n```\n\n## Optional\nConfigure `ksp` processor to generate more suitable code for you\n```kotlin\nksp {\n    // Use this prefix for fts tables to keep the old room scheme\n    arg(\"FTS_TRIGGER_NAME_PREFIX\", \"room_fts_content_sync\")\n}\n```\n\nAvailable keys, with their default values\n```kotlin\nTABLE_SUFFIX(\"KabinTable\")\nENTITY_MAPPER_SUFFIX(\"KabinMapper\")\nDATABASE_SUFFIX(\"KabinDatabase\")\nDAO_SUFFIX(\"KabinDao\")\nDAO_QUERIES_SUFFIX(\"KabinQueries\")\nINDEX_NAME_PREFIX(\"index\")\nFTS_TRIGGER_NAME_PREFIX(\"kabin_fts_content_sync\")\nBEFORE_UPDATE_TRIGGER_NAME_SUFFIX(\"BEFORE_UPDATE\")\nAFTER_UPDATE_TRIGGER_NAME_SUFFIX(\"AFTER_UPDATE\")\nBEFORE_DELETE_TRIGGER_NAME_SUFFIX(\"BEFORE_DELETE\")\nAFTER_INSERT_TRIGGER_NAME_SUFFIX(\"AFTER_INSERT\")\n```\n\n## Supported Room Features\nThis list shows Room features, which are already supported by Kabin, or under development\n\n\u003e [!NOTE]\n\u003e To accelerate the development of certain features, create issues to increase priority, or upvote existing ones\n\n### @Entity\n- [x] `tableName`\n- [x] `indices`\n- [ ] `inheritSuperIndices`\n- [x] `primaryKeys`\n- [x] `foreignKeys`\n- [x] `ignoredColumns`\n\n### @PrimaryKey\n- [x] `autoGenerate`\n- [x] Use `@PrimaryKey` on multiple columns\n- [x] Use `@PrimaryKey` on `@Embedded` columns\n\n### @Embedded\n- [x] `prefix`\n- [x] Nested `@Embedded` (`@Embedded` inside an `@Embedded`)\n- [x] Compound (`@Embedded` entity inside a class for working with `@Relations`)\n- [x] `@Embedded` columns as primary keys using `@PrimaryKey`\n\n### @ColumnInfo\n- [x] `name`\n- [x] `typeAffinity`\n- [x] `index`\n- [ ] `collate`\n- [x] `defaultValue`\n\n### @Ignore\n- [x] Skip columns annotated with `@Ignore`\n\n### @ForeignKey\n- [x] `entity`\n- [x] `parentColumns`\n- [x] `childColumns`\n- [x] `onDelete`\n- [x] `onUpdate`\n- [x] `deferred`\n\n### @Index\n- [x] `columns`\n- [x] `orders`\n- [x] `name`\n- [x] `unique`\n\n### @Relation\n- [x] `entity`\n- [x] `parentColumn`\n- [x] `entityColumn`\n- [x] `associateBy`\n- [ ] `projection`\n- [x] Detect entity from property type\n- [x] Detect entity from list property type\n- [x] Insert entities automatically when inserting Compound classes with `@Embedded` entities\n\n### @Junction\n- [x] `value`\n- [x] `parentColumn`\n- [x] `entityColumn`\n- [x] Retrieve data using `@Junction` table\n- [x] Create and insert `@Junction` entities automatically when inserting classes with `@Relation`\n\n### @Fts4\n- [x] `contentEntity`\n- [ ] `tokenizerArgs`\n- [ ] `languageId`\n- [ ] `notIndexed`\n- [ ] `prefix`\n- [ ] `order`\n- [x] Create virtual table with triggers\n\n### @Dao\n- [x] Use coroutines and `suspend` functions\n- [x] Support `Collection` and `Flow` return types\n- [x] Execute operations on `Dispatcher.IO`\n- [x] Interfaces annotated with `@Dao`\n- [ ] Abstract classes annotated with `@Dao`\n\n### @Insert\n- [x] `entity`\n- [x] `onConflict`\n- [x] Insert single entity, multiple entities as distinct parameters or lists of entities\n- [x] Insert Compound classes with `@Embedded` entities including their `@Relation` and `@Junction`\n\n### @Delete\n- [x] `entity`\n- [x] Delete single entity, multiple entities as distinct parameters or lists of entities\n- [x] Delete Compound classes with `@Embedded` entities including their `@Relation` and `@Junction`\n\n### @Update\n- [x] `entity`\n- [x] `onConflict`\n- [x] Update single entity, multiple entities as distinct parameters or lists of entities\n- [x] Update Compound classes with `@Embedded` entities including their `@Relation` and `@Junction`\n\n### @Upsert\n\u003e [!CAUTION]\n\u003e This annotation is currently treated as @Insert with REPLACE strategy\n- [x] `entity`\n- [ ] Use Upsert logic instead of simple insert with REPLACE strategy\n- [x] Upsert single entity, multiple entities as distinct parameters or lists of entities\n- [x] Upsert Compound classes with `@Embedded` entities including their `@Relation` and `@Junction`\n\n### @RawQuery\n- [x] `observedEntities`\n- [x] Detect observed entities by return type\n\n### @Query\n- [x] `value`\n- [x] Detect observed entities by return type\n- [x] Detect observed entities by queried tables\n- [x] Named parameters declared as `:parameter`\n- [x] Nullable parameters\n- [x] List and nullable list parameters\n- [ ] Parameters declared as `?`\n- [ ] Highlight SQL Syntax\n- [ ] Validate SQL Syntax\n- [ ] Auto complete SQL Syntax and named parameters\n\n### @Transaction\n- [x] Functions with `@Transaction` annotation\n- [x] Functions working with multiple entity parameters, collections and compounds\n\n### @Database\n- [x] `entities`\n- [ ] `views`\n- [x] `version`\n- [ ] `exportSchema`\n- [ ] `autoMigrations`\n- [x] Interfaces annotated with `@Database`\n- [ ] Abstract classes annotated with `@Database`\n- [x] Generate adapters for primitive and enum classes\n- [x] Manual migration\n- [x] Destructive migration\n- [ ] Validate Schema\n\n### @TypeConverters\n\u003e [!CAUTION]\n\u003e This annotation can only accept converter `object` that implement `app.cash.sqldelight.ColumnAdapter`\n- [x] `value`\n- [ ] `builtInTypeConverters`\n\n### @BuiltInTypeConverters\n- [ ] `enums` (Enums are supported by default)\n- [ ] `uuid`\n\n### @AutoMigration\n- [ ] `from`\n- [ ] `to`\n- [ ] `spec`\n- [ ] Support auto migration functionality\n\n## Additional Features\n### @Mappers\n- Used to map results returned by a dao to data classes that are not entities or primitives\n- This annotation is meant to be used with `Database` class\n- `value` accepts `object` that implements `KabinMapper\u003cT\u003e`\n\n### Compound\n- Classes that use `@Embedded` and `@Relation` annotations can be used with `@Insert`, `@Upsert`, `@Delete` and `@Update`\n- `@Junction` inside a compound is automatically created and inserted as well\n\n## Plans and Priorities\n1. [ ] Add Tests\n2. [ ] Clean and refactor `compiler` and `processor` logic, make it more flexible and maintainable\n3. [ ] Generate more optimized code\n4. [ ] Fix bugs and issues\n5. [ ] Implement more **Room** features, especially the essential ones for basic and simple apps\n6. [ ] Add more features to make working with SQL easier and more interesting\n7. [ ] Add multiplatform sample with UI\n8. [ ] Make a stable release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftamimattafi%2Fkabin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftamimattafi%2Fkabin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftamimattafi%2Fkabin/lists"}