Idiomatic persistence layer for Kotlin

Overview

Krush

Maven Central CircleCI Sputnik

Krush is a lightweight persistence layer for Kotlin based on Exposed SQL DSL. It’s similar to Requery and Micronaut-data jdbc, but designed to work idiomatically with Kotlin and immutable data classes.

It’s based on a compile-time JPA annotation processor that generates Exposed DSL table and objects mappings for you. This lets you instantly start writing type-safe SQL queries without need to write boilerplate infrastructure code.

Rationale

  • (type-safe) SQL-first - use type-safe SQL-like DSL in your queries, no string or method name parsing
  • Minimal changes to your domain model - no need to extend external interfaces and used special types - just add annotations to your existing domain model
  • Explicit fetching - you specify explicitly in query what data you want to fetch, no additional fetching after data is loaded
  • No runtime magic - no proxies, lazy loading, just data classes containing data fetched from DB
  • Pragmatic - easy to start, but powerful even in not trivial cases (associations, grouping queries)

Example

Given a simple Book class:

data class Book(
   val id: Long? = null,
   val isbn: String,
   val title: String,
   val author: String,
   val publishDate: LocalDate
)

we can turn it into Krush entity by adding @Entity and @Id annotations:

@Entity
data class Book(
   @Id @GeneratedValue
   val id: Long? = null,
   val isbn: String,
   val title: String,
   val author: String,
   val publishDate: LocalDate
)

When we build the project we’ll have BookTable mapping generated for us. So we can persist the Book:

val book = Book(
   isbn = "1449373321", publishDate = LocalDate.of(2017, Month.APRIL, 11),
   title = "Designing Data-Intensive Applications", author = "Martin Kleppmann"
)

// insert method is generated by Krush
val persistedBook = BookTable.insert(book)
assertThat(persistedBook.id).isNotNull()

So we have now a Book persisted in DB with autogenerated Book.id field. And now we can use type-safe SQL DSL to query the BookTable:

val bookId = book.id ?: throw IllegalArgumentException()

// toBook method is generated by Krush
val fetchedBook = BookTable.select { BookTable.id eq bookId }.singleOrNull()?.toBook()
assertThat(fetchedBook).isEqualTo(book)

// toBookList method is generated by Krush
val selectedBooks = (BookTable)
   .select { BookTable.author like "Martin K%" }
   .toBookList()

assertThat(selectedBooks).containsOnly(persistedBook)

Installation

Gradle:

repositories {
    mavenCentral()
}

apply plugin: 'kotlin-kapt'

dependencies {
    api "pl.touk.krush:krush-annotation-processor:$krushVersion"
    kapt "pl.touk.krush:krush-annotation-processor:$krushVersion"
    api "pl.touk.krush:krush-runtime:$krushVersion" 
}

Maven:

<dependencies>
    <dependency>
        <groupId>pl.touk.krush</groupId>
        <artifactId>krush-runtime</artifactId>
        <version>${krush.version}</version>
    </dependency>
</dependencies>

...

<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>kapt</id>
            <goals>
                <goal>kapt</goal>
            </goals>
            <configuration>
                ...
                <annotationProcessorPaths>
                    <annotationProcessorPath>
                        <groupId>pl.touk.krush</groupId>
                        <artifactId>krush-annotation-processor</artifactId>
                        <version>${krush.version}</version>
                    </annotationProcessorPath>
                </annotationProcessorPaths>
            </configuration>
        </execution>
        ...
    </executions>
</plugin>

Dependencies

Features

  • generates table mappings and functions for mapping from/to data classes
  • type-safe SQL DSL without reading schema from existing database (code-first)
  • explicit association fetching (via leftJoin / innerJoin)
  • multiple data types support, including type aliases
  • custom data type support (with @Converter), also for wrapped auto-generated ids
  • you can still persist associations not directly reflected in domain model (eq. article favorites)

However, Krush is not a full-blown ORM library. This means following JPA features are not supported:

  • lazy association fetching
  • dirty checking
  • caching
  • versioning / optimistic locking

Updating

Given following entity:

@Entity
data class Reservation(
    @Id
    val uid: UUID = UUID.randomUUID(),

    @Enumerated(EnumType.STRING)
    val status: Status = Status.FREE,

    val reservedAt: LocalDateTime? = null,
    val freedAt: LocalDateTime? = null
) {
    fun reserve() = copy(status = Status.RESERVED, reservedAt = LocalDateTime.now())
    fun free() = copy(status = Status.FREE, freedAt = LocalDateTime.now())
}

enum class Status { FREE, RESERVED }

you can call Exposed update with generated from metod to overwrite it's data:

val reservation = Reservation().reserve().let(ReservationTable::insert)

val freedReservation = reservation.free()
ReservationTable.update({ ReservationTable.uid eq reservation.uid }) { it.from(freedReservation) }

val updatedReservation = ReservationTable.select({ ReservationTable.uid eq reservation.uid }).singleOrNull()?.toReservation()
assertThat(updatedReservation?.status).isEqualTo(Status.FREE)
assertThat(updatedReservation?.reservedAt).isEqualTo(reservation.reservedAt)
assertThat(updatedReservation?.freedAt).isEqualTo(freedReservation.freedAt)

For simple cases you can still use Exposed native update syntax:

val freedAt = LocalDateTime.now()
ReservationTable.update({ ReservationTable.uid eq reservation.uid }) {
  it[ReservationTable.status] = Status.FREE
  it[ReservationTable.freedAt] = freedAt
}

Complete example

Associations

@Entity
@Table(name = "articles")
data class Article(
    @Id @GeneratedValue
    val id: Long? = null,

    @Column(name = "title")
    val title: String,

    @ManyToMany
    @JoinTable(name = "article_tags")
    val tags: List<Tag> = emptyList()
)

@Entity
@Table(name = "tags")
data class Tag(
    @Id @GeneratedValue
    val id: Long? = null,

    @Column(name = "name")
    val name: String
)

Persisting

val tag1 = Tag(name = "jvm")
val tag2 = Tag(name = "spring")

val tags = listOf(tag1, tag2).map(TagTable::insert)
val article = Article(title = "Spring for dummies", tags = tags)
val persistedArticle = ArticleTable.insert(article)

Querying and fetching

val (selectedArticle) = (ArticleTable leftJoin ArticleTagsTable leftJoin TagTable)
    .select { TagTable.name inList listOf("jvm", "spring") }
    .toArticleList()

assertThat(selectedArticle).isEqualTo(persistedArticle)

Update logic for associations not implemented (yet!) - you have to manually add/remove records from ArticleTagsTable.

Example projects

Contributors

Special thanks to Łukasz Jędrzejewski for original idea of using Exposed in our projects.

Licence

Krush is published under Apache License 2.0.

Comments
  • Added support for self references (#10)

    Added support for self references (#10)

    I found this project appealing enough to implement this myself :D

    I added support for objects having M2M-relations to themselves by distinguishing the attributes of the join-table with "source" and "target" keywords, and changed buildToEntityMapFunc() to avoid infinite recursions in that case (and it also now passes the proper object references of related objects).

    Because this PR changes how krush expects a join-table to look, this can be considered a breaking change.

    Also: I did not do much testing of this change apart from running the unit tests and testing it with my use case (~~both work without issue~~ Looks like I overlooked the "example" tests - will look into this), so this will likely need to be tested with more examples before it can be merged with confidence that there will be no unfortunate surprises.

    opened by Namnodorel 10
  • Mapping rewrite

    Mapping rewrite

    This PR introduces a new implementation of the toEntityMap() function generators and related methods. The improvements are:

    • better performance of the generated code, because every result row is only read exactly once. I have not made a detailed performance analysis/comparison yet, but I could add that here if you'd prefer to have it before merging.
    • the new approach gets rid of the real/copied references distinction, because it combines the benefits of both while avoiding the drawbacks of using real references.
      • this implementation reuses entities it has already created, making sure that all references to the same entity point to the same object
      • there is one exception to that: bidirectional one-to-one relations have an imperfect copy on one end, because two immutable data objects can not reference each other. This isn't perfect, but should at least be as good as the old copied-reference-version.
      • self-referential entities are supported
    • a little bit of extra flexibility: the generated code no longer fails when a relational column that was expected isn't there (as long as it can still construct the entity, for example with an empty list). This allows users to create "shallow" queries that don't go into all the relation details if it's not needed. For example if I only need the list of names of all employees, I no longer need to include all employee relations like address, check-in-history, etc. in that query.
    **click to view explanation of the new mapping algorithm**
    fun ResultRow.toEntityMap(): Map<Id, Entity> {
      // The entity store holds a map for each entity type name containing 
      // all entities we've read so far, mapped by their ids
      val entityStore: Map<EntityName, Map<Id, Entity>>  = emptyMap()
      // If any entity wants to reference another entity of the same type, 
      // it adds its own ID to the set of entites referencing that target entity.
      // those requests get handled below.
      val selfReferenceRequests: Map<EntityName, Map<TargetEntityId, Set<SourceEntityId>>>
      rows.forEach { row ->
          // toEntity() either creates the entity for this row if the ID is new, 
          // or reuses the object if we already have an entity with this ID stored
          val entity = row.toEntity(entityStore)
          // addSubEntitiesToEntity() goes through all relations of the entity and checks 
          // if there is a new sub-entity in this row that hasn't been added to this entity yet.
          // If there is, it adds that entity and iteratively calls its variants to make sure we
          // accurately reconstruct the entity tree at any depth.
          row.addSubEntitiesToEntity(entity, entityStore, selfReferenceRequests)
      }
      // After we've created objects for all entities in this table, we can now add self-references.
      // We do this by iterating through all self reference requests, finding the entities they're
      // referring to, and adding the reference to the relation-lists.
      selfReferenceRequests.forEach { (typeName, unsatisfiedMap) ->
          when(typeName) {
              "OtherEntity" -> {
                    unsatisfiedMap.forEach { (subjectOtherEntityId, referencingOtherEntityIds) ->
                        val subjectOtherEntity = entityStore["OtherEntity"][subjectOtherEntityId]
                            referencingOtherEntityIds.forEach { referencingOtherEntityId -> 
                            entityStore["OtherEntity"][referencingOtherEntityd].relationList.add(subjectOtherEntity)
                        }
               }
              // ...
          }
      }
    }
    
    fun ResultRow.toEntity(entityStore: ...): Entity {
      // <if the entity Id of this row is not new, return the entity found in the entity store>
     val result = Entity(
        	id = id,
        	simpleAttr = this[EntityTable.simpleAttr],
          // Use a mutable list so we can sneakily add the relation references later
        	relationList = mutableListOf(),
          bidirO2O = null
        )
      // <store the new object in the entity store map so that it is available when constructing the bidir-O2O object>
      // Add the bidir-objects. They will reuse the object already stored in the entity store, 
      // which avoids an endless loop
      val resultWithBidirAssocs = result.copy(
        	bidirO2O = this.toOtherEntity(entityStore)
       )
      // <update the entity store with the new object>
      return resultWithBidirAssocs
    }
    
    fun ResultRow.addSubEntitesToEntity(entity: Entity, entityStore: ..., selfReferenceRequests: ...) {
      // <for every O2O attribute, call the equivalent of this method for that entity>
      
      // <for every list-relation attribute, check if the sub-entity id matches 
      // the one that we last added to the list.
      // If it doesn't, create a new entity and add it to the list. 
      // If it does, just call addSubEntities...() on that sub-entity.>
    
      // <for every self-referential attribute list, add a self-referencing request 
      // containing the ID of this and the target entity>
    }
    
    opened by Namnodorel 9
  • Fix for naming scheme of M2M IDs

    Fix for naming scheme of M2M IDs

    The EmbeddedId-PR (#36) switched the column names of M2M IDs from <target table name> + <source/target> + "id" to <target table id column name> + <source/target> + "id". In non-embedded cases, that caused some not-very-sensible column names to be used, like id_source_id and id_target_id.

    This PR simply switches the naming to a different variant, <target table name> + <source/target> + <target table id column name>, which should hopefully be sensible for all use cases.

    opened by Namnodorel 7
  • Add support for type aliases

    Add support for type aliases

    As the title says, adds support for type aliases.

    This should help resolve issue #9 because it becomes possible to do

    typealias StringMap = Map<String, String>
    

    and have a converter to convert from say StringMap to String which krush seems to find acceptable. Then just replace any instances of Map<String, String> with StringMap and it's off to the races.

    This request was written out of a need to resolve issue #9 for a personal project, so it was either this or implement type properties correctly. Please let me know if I am missing any conventions! I didn't write any examples but could probably get some going in short order. Thanks!

    opened by EMH333 6
  • Update kotlin, exposed and kotlinpoet versions

    Update kotlin, exposed and kotlinpoet versions

    fixes #50, #54. Tests are running, although I didn't handle any of the compiler warnings because they all are design decisions I couldn't make for you

    opened by ChristianSch 5
  • Self-referenced entities generate invalid code

    Self-referenced entities generate invalid code

    When attempting to create self referencing entities, the app fails to build because the generated code creates an invalid getOrNull method.

    example:

    @Entity
    @Table(name = "category")
    data class Category(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Long? = null,
    
        @Column
        val name: String,
    
        @OneToOne
        @JoinColumn(name = "parent_id")
        val parent: Category?,
    
        @OneToMany(mappedBy = "parent")
        val children: List<Category> = emptyList()
    )
    

    generates:

      resultRow.getOrNull(CategoryTable.id)?.let {
      	val children_category = children_map.filter { category -> category.key == it }
      		.mapValues { (_, category) -> category.copy(category = category) }
      		.values.toMutableSet()
      	category_children[categoryId]?.addAll(children_category) ?: category_children.put(categoryId, children_category)
      }
    

    The issue is here mapValues { (_, category) -> category.copy(category = category) }, where the copy method is using a category parameter that doesn't exist. I believe the proper code should be mapValues { (_, category) -> category.copy(parent = category) }.

    Any help would be appreciated!

    EDIT: Actually, it seems like any self-referenced parent-child entity causes problems. I tried this code to use a join table instead and got a error: Exception while building entity graph: java.lang.NullPointerException

    @Entity
    @Table(name = "category")
    data class Category(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Long? = null,
    
        @Column
        val name: String,
    
        @ManyToMany
        @JoinTable(name="category_category",
            joinColumns=[JoinColumn(name="category_id_1")],
            inverseJoinColumns=[JoinColumn(name="category_id_2")])
        val parentCategories: List<Category> = emptyList(),
    
        @ManyToMany(mappedBy="parentCategories")
        val childrenCategories: List<Category> = emptyList()
    )
    
    0.6.0 
    opened by cbadger85 4
  • @JoinColumn name ignored when using @ManyToOne

    @JoinColumn name ignored when using @ManyToOne

    Taking this test case as an example with these entities, the generated sql looks something like this:

    CREATE TABLE IF NOT EXISTS tree (
        id BIGINT AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(255) NOT NULL);
    
    CREATE TABLE IF NOT EXISTS branch (
        id BIGINT AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(255) NOT NULL,
        treeId_id BIGINT NULL,
        CONSTRAINT fk_branch_treeId_id_id FOREIGN KEY (treeId_id) REFERENCES tree(id) ON DELETE RESTRICT ON UPDATE RESTRICT);
    
    CREATE TABLE IF NOT EXISTS leaf (
        id BIGINT AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(255) NOT NULL,
        branchId_id BIGINT NULL,
        CONSTRAINT fk_leaf_branchId_id_id FOREIGN KEY (branchId_id) REFERENCES branch(id) ON DELETE RESTRICT ON UPDATE RESTRICT);
    

    It appears that the @JoinColumn is ignored. Compare tree_id with treeId_id, where I would've expected tree_id to be used for the column name. I feel like that is a recent change because it's caused by updating to 0.4.1 and I can't get back because the previous repository seems to be gone. Is this a bug? If not, is there a way to control the name of the join column in this case?

    I would much rather not change the migrations

    opened by ChristianSch 3
  • Bump junit-jupiter from 1.17.2 to 1.17.3

    Bump junit-jupiter from 1.17.2 to 1.17.3

    Bumps junit-jupiter from 1.17.2 to 1.17.3.

    Release notes

    Sourced from junit-jupiter's releases.

    1.17.3

    What's Changed

    🚀 Features & Enhancements

    ☠️ Deprecations

    🐛 Bug Fixes

    📖 Documentation

    🧹 Housekeeping

    📦 Dependency updates

    ... (truncated)

    Commits
    • 4a14ecc Elasticsearch: Fix startup check for 8.3 and above (#5521)
    • e23f378 [clickhouse] Add new JDBC driver name (#5474)
    • 5a2d76f Switch default image to ghcr.io and update default tag to 2.4.0 (#5173)
    • 56d0cf1 Check admin endpoint instead of metrics for Pulsar WaitStrategy. (#5514)
    • c0eb042 Polish examples (#5520)
    • afde5d3 JdbcDatabaseContainer: fix wrong instance call (#5465)
    • a9c2e9e [LocalStack] Remove usage of deprecated methods (#5491)
    • cfc64bd Add clickhouse/clickhouse-server compatibility (#5488)
    • 1f7dc46 Use sshd container 1.1.0 (#5486)
    • 00faa95 [HiveMQ] do not delete /opt/hivemq/temp-extensions in startup command (#5509)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 2
  • Support for batch insert

    Support for batch insert

    Exposed has EntityTable.batchInsert() for inserting multiple items at once. Having something similar generated by krush would be more efficient than calling EntityTable.insert(entity) for every item individually.

    opened by Namnodorel 2
  • Bump flyway-core from 8.5.13 to 9.10.1

    Bump flyway-core from 8.5.13 to 9.10.1

    Bumps flyway-core from 8.5.13 to 9.10.1.

    Release notes

    Sourced from flyway-core's releases.

    Flyway 9.10.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.10.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.9.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.3

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.2

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.7.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.6.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.5.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.htmls#9.5.1

    CLI artifact available here

    ... (truncated)

    Commits
    • d2a6c39 Bump version to flyway-9.10.1
    • 9e8910a Bump version to flyway-9.10.0
    • a0d26ea Bump version to flyway-9.9.0
    • 16bb199 Bump version to flyway-9.8.3
    • c121aca Bump version to flyway-9.8.2
    • f4a2a5d Bump version to flyway-9.8.1
    • c015f2d Bump version to flyway-9.8.0
    • ead6a7a Bump version to flyway-9.7.0
    • e361d8e Bump version to flyway-9.6.0
    • c0e2e26 Bump version to flyway-9.5.1
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 1
  • Bump flyway-core from 8.5.13 to 9.10.0

    Bump flyway-core from 8.5.13 to 9.10.0

    Bumps flyway-core from 8.5.13 to 9.10.0.

    Release notes

    Sourced from flyway-core's releases.

    Flyway 9.10.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.9.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.3

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.2

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.7.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.6.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.5.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.htmls#9.5.1

    CLI artifact available here

    Flyway 9.5.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html#9.5.0

    CLI artifact available here

    ... (truncated)

    Commits
    • 9e8910a Bump version to flyway-9.10.0
    • a0d26ea Bump version to flyway-9.9.0
    • 16bb199 Bump version to flyway-9.8.3
    • c121aca Bump version to flyway-9.8.2
    • f4a2a5d Bump version to flyway-9.8.1
    • c015f2d Bump version to flyway-9.8.0
    • ead6a7a Bump version to flyway-9.7.0
    • e361d8e Bump version to flyway-9.6.0
    • c0e2e26 Bump version to flyway-9.5.1
    • ffe7df6 Bump version to flyway-9.5.0
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 1
  • Bump plugin.serialization from 1.7.10 to 1.8.0

    Bump plugin.serialization from 1.7.10 to 1.8.0

    Bumps plugin.serialization from 1.7.10 to 1.8.0.

    Release notes

    Sourced from plugin.serialization's releases.

    Kotlin 1.8.0

    Changelog

    Analysis API

    • KT-50255 Analysis API: Implement standalone mode for the Analysis API

    Analysis API. FIR

    • KT-54292 Symbol Light classes: implement PsiVariable.computeConstantValue for light field
    • KT-54293 Analysis API: fix constructor symbol creation when its accessed via type alias

    Android

    • KT-53342 TCS: New AndroidSourceSet layout for multiplatform
    • KT-53013 Increase AGP compile version in KGP to 4.1.3
    • KT-54013 Report error when using deprecated Kotlin Android Extensions compiler plugin
    • KT-53709 MPP, Android SSL2: Conflicting warnings for androidTest/kotlin source set folder

    Backend. Native. Debug

    • KT-53561 Invalid LLVM module: "inlinable function call in a function with debug info must have a !dbg location"

    Compiler

    New Features

    • KT-52817 Add @JvmSerializableLambda annotation to keep old behavior of non-invokedynamic lambdas
    • KT-54460 Implementation of non-local break and continue
    • KT-53916 Support Xcode 14 and new Objective-C frameworks in Kotlin/Native compiler
    • KT-32208 Generate method annotations into bytecode for suspend lambdas (on invokeSuspend)
    • KT-53438 Introduce a way to get SourceDebugExtension attribute value via JVMTI for profiler and coverage

    Performance Improvements

    • KT-53347 Get rid of excess allocations in parser
    • KT-53689 JVM: Optimize equality on class literals
    • KT-53119 Improve String Concatenation Lowering

    Fixes

    • KT-53465 Unnecessary checkcast to array of reified type is not optimized since Kotlin 1.6.20
    • KT-49658 NI: False negative TYPE_MISMATCH on nullable type with when
    • KT-48162 NON_VARARG_SPREAD isn't reported on *toTypedArray() call
    • KT-43493 NI: False negative: no compilation error "Operator '==' cannot be applied to 'Long' and 'Int'" is reported in builder inference lambdas
    • KT-54393 Change in behavior from 1.7.10 to 1.7.20 for java field override.
    • KT-55357 IllegalStateException when reading a class that delegates to a Java class with a definitely-not-null type with a flexible upper bound
    • KT-55068 Kotlin Gradle DSL: No mapping for symbol: VALUE_PARAMETER SCRIPT_IMPLICIT_RECEIVER on JVM IR backend
    • KT-51284 SAM conversion doesn't work if method has context receivers
    • KT-48532 Remove old JVM backend

    ... (truncated)

    Changelog

    Sourced from plugin.serialization's changelog.

    1.8.0

    Analysis API

    • KT-50255 Analysis API: Implement standalone mode for the Analysis API

    Analysis API. FIR

    • KT-54292 Symbol Light classes: implement PsiVariable.computeConstantValue for light field
    • KT-54293 Analysis API: fix constructor symbol creation when its accessed via type alias

    Android

    • KT-53342 TCS: New AndroidSourceSet layout for multiplatform
    • KT-53013 Increase AGP compile version in KGP to 4.1.3
    • KT-54013 Report error when using deprecated Kotlin Android Extensions compiler plugin
    • KT-53709 MPP, Android SSL2: Conflicting warnings for androidTest/kotlin source set folder

    Backend. Native. Debug

    • KT-53561 Invalid LLVM module: "inlinable function call in a function with debug info must have a !dbg location"

    Compiler

    New Features

    • KT-52817 Add @JvmSerializableLambda annotation to keep old behavior of non-invokedynamic lambdas
    • KT-54460 Implementation of non-local break and continue
    • KT-53916 Support Xcode 14 and new Objective-C frameworks in Kotlin/Native compiler
    • KT-32208 Generate method annotations into bytecode for suspend lambdas (on invokeSuspend)
    • KT-53438 Introduce a way to get SourceDebugExtension attribute value via JVMTI for profiler and coverage

    Performance Improvements

    • KT-53347 Get rid of excess allocations in parser
    • KT-53689 JVM: Optimize equality on class literals
    • KT-53119 Improve String Concatenation Lowering

    Fixes

    • KT-53465 Unnecessary checkcast to array of reified type is not optimized since Kotlin 1.6.20
    • KT-49658 NI: False negative TYPE_MISMATCH on nullable type with when
    • KT-48162 NON_VARARG_SPREAD isn't reported on *toTypedArray() call
    • KT-43493 NI: False negative: no compilation error "Operator '==' cannot be applied to 'Long' and 'Int'" is reported in builder inference lambdas
    • KT-54393 Change in behavior from 1.7.10 to 1.7.20 for java field override.
    • KT-55357 IllegalStateException when reading a class that delegates to a Java class with a definitely-not-null type with a flexible upper bound
    • KT-55068 Kotlin Gradle DSL: No mapping for symbol: VALUE_PARAMETER SCRIPT_IMPLICIT_RECEIVER on JVM IR backend
    • KT-51284 SAM conversion doesn't work if method has context receivers
    • KT-48532 Remove old JVM backend
    • KT-55065 Kotlin Gradle DSL: Reflection cannot find class data for lambda, produced by JVM IR backend

    ... (truncated)

    Commits
    • da1a843 Add ChangeLog for 1.8.0-RC2
    • d325cf8 Call additional publishToMavenLocal in maven build scripts and enable info
    • 0403d70 Don't leave Gradle daemons after build scripts
    • 52b225d Fix task module-name is not propagated to compiler arguments
    • d40ebc3 Specify versions-maven-plugin version explicitly
    • 2e829ed Fix version parsing crash on Gradle rich version string
    • f603c0e Scripting, IR: fix capturing of implicit receiver
    • 06cbf8f Scripting, tests: enable custom script tests with IR
    • d61cef0 Fix deserialization exception for DNN types from Java
    • ea33e72 JVM IR: script is a valid container for local delegated properties
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump flyway-core from 8.5.13 to 9.10.2

    Bump flyway-core from 8.5.13 to 9.10.2

    Bumps flyway-core from 8.5.13 to 9.10.2.

    Release notes

    Sourced from flyway-core's releases.

    Flyway 9.10.2

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.10.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.10.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.9.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.3

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.2

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.1

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.8.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.7.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    Flyway 9.6.0

    See https://documentation.red-gate.com/fd/release-notes-for-flyway-engine-179732572.html

    CLI artifact available here

    ... (truncated)

    Commits
    • 8367518 Bump version to flyway-9.10.2
    • b0162b7 Merge pull request #3587 from eddumelendez/update_tc_docs
    • ca15875 Merge pull request #3585 from eddumelendez/fix_testcontainers
    • 398bbe5 Update Testcontainers doc
    • d2a6c39 Bump version to flyway-9.10.1
    • a6adbac Fix Testcontainers project name
    • 9e8910a Bump version to flyway-9.10.0
    • a0d26ea Bump version to flyway-9.9.0
    • 16bb199 Bump version to flyway-9.8.3
    • c121aca Bump version to flyway-9.8.2
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump pl.allegro.tech.build.axion-release from 1.13.14 to 1.14.3

    Bump pl.allegro.tech.build.axion-release from 1.13.14 to 1.14.3

    Bumps pl.allegro.tech.build.axion-release from 1.13.14 to 1.14.3.

    Release notes

    Sourced from pl.allegro.tech.build.axion-release's releases.

    v1.14.3

    What's Changed

    Changes:

    Updates:

    New Contributors

    Full Changelog: https://github.com/allegro/axion-release-plugin/compare/v1.14.2...v1.14.3

    v1.14.2

    What's Changed

    Full Changelog: https://github.com/allegro/axion-release-plugin/compare/v1.14.1...v1.14.2

    v1.14.1

    What's Changed

    New Contributors

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump kotlinx-serialization-json from 1.4.0-RC to 1.4.1

    Bump kotlinx-serialization-json from 1.4.0-RC to 1.4.1

    Bumps kotlinx-serialization-json from 1.4.0-RC to 1.4.1.

    Release notes

    Sourced from kotlinx-serialization-json's releases.

    1.4.1

    This patch release contains several bug fixes and improvements. Kotlin 1.7.20 is used by default.

    Improvements

    • Add @​MustBeDocumented to certain annotations (#2059)
    • Deprecate .isNullable in SerialDescriptor builder (#2040)
    • Unsigned primitives and unsigned arrays serializers can be retrieved as built-ins (#1992)
    • Serializers are now cached inside reflective lookup, leading to faster serializer retrieval (#2015)
    • Compiler plugin can create enum serializers using static factories for better speed (#1851) (Kotlin 1.7.20 required)
    • Provide a foundation for compiler plugin intrinsics available in Kotlin 1.8.0 (#2031)

    Bugfixes

    • Support polymorphism in Properties format (#2052) (thanks to Rodrigo Vedovato)
    • Added support of UTF-16 surrogate pairs to okio streams (#2033)
    • Fix dependency on core module from HOCON module (#2020) (thanks to Osip Fatkullin)

    1.4.0

    This release contains all features and bugfixes from 1.4.0-RC plus some bugfixes on its own (see below). Kotlin 1.7.10 is used as a default.

    Bugfixes

    • Fixed decoding of huge JSON data for okio streams (#2006)
    Changelog

    Sourced from kotlinx-serialization-json's changelog.

    1.4.1 / 2022-10-14

    This is patch release contains several bugfixes and improvements. Kotlin 1.7.20 is used by default.

    Improvements

    • Add @​MustBeDocumented to certain annotations (#2059)
    • Deprecate .isNullable in SerialDescriptor builder (#2040)
    • Unsigned primitives and unsigned arrays serializers can be retrieved as built-ins (#1992)
    • Serializers are now cached inside reflective lookup, leading to faster serializer retrieval (#2015)
    • Compiler plugin can create enum serializers using static factories for better speed (#1851) (Kotlin 1.7.20 required)
    • Provide foundation for compiler plugin intrinsics available in Kotlin 1.8.0 (#2031)

    Bugfixes

    • Support polymorphism in Properties format (#2052) (thanks to Rodrigo Vedovato)
    • Added support of UTF-16 surrogate pairs to okio streams (#2033)
    • Fix dependency on core module from HOCON module (#2020) (thanks to Osip Fatkullin)

    1.4.0 / 2022-08-18

    This release contains all features and bugfixes from 1.4.0-RC plus some bugfixes on its own (see below). Kotlin 1.7.10 is used as a default.

    Bugfixes

    • Fixed decoding of huge JSON data for okio streams (#2006)
    Commits
    • d7e58c2 Prepare 1.4.1 release (#2063)
    • de6864a Merge remote-tracking branch 'origin/master' into dev
    • 0a1b6d8 Fix minor documentation and comment typos (#2061)
    • 0f35682 Fix incorrect behavior while deserializing maps to sealed classes (#2052)
    • dc9983a Update test assertions to use IntelliJ "Click to see difference" format (#2062)
    • cb6bcbb Add @​MustBeDocumented to certain annotations
    • 182c53e Add documentation on using typealias for means of global configuration
    • 98529cd Remove kotlin.Experimental from opt-ins as it would be removed in 1.8.20
    • 687d917 Updated builtin-classes.md to mention Duration
    • e311eb8 Added support for the unsigned primitives and arrays as built-in
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Fix assumption that selfref table ID columns are always named

    Fix assumption that selfref table ID columns are always named "id"

    This PR fixes a smaller naming issue that occurred when using M2O-Relations in a selfreference context.

    While working on that, I also noticed that ManyToOne-Annotated lists do not currently get filled out by krush (see for example the children attribute in the Category example). This should be fixable by applying M2M selfreference logic (or something similar) to M2O relations as well, but I currently do not have a time to properly try that out.

    opened by Namnodorel 1
  • Kapt task fails if @kotlinx.serialization.Serializable is also applied to the class

    Kapt task fails if @kotlinx.serialization.Serializable is also applied to the class

    @Entity
    @kotlinx.serialization.Serializable
    data class User(
        @Id
        val userId: String,
        val name: String
    )
    

    if I have a class like this, the build fails with the following error: Exception while building entity graph: pl.touk.krush.validation.ElementTypeNotFoundException: Could not resolve Companion type

    opened by hamza-maqsood 0
Releases(krush-1.0.0)
Owner
TouK
We’re a software house based in Warsaw. We deliver custom IT systems.
TouK
Active record style SQLite persistence for Android

ActiveAndroid ActiveAndroid is an active record style ORM (object relational mapper). What does that mean exactly? Well, ActiveAndroid allows you to s

Michael Pardo 4.7k Dec 29, 2022
Active record style SQLite persistence for Android

ActiveAndroid ActiveAndroid is an active record style ORM (object relational mapper). What does that mean exactly? Well, ActiveAndroid allows you to s

Michael Pardo 4.7k Dec 29, 2022
ORMDroid is a simple ORM persistence framework for your Android applications.

ORMDroid is a simple ORM persistence framework for your Android applications, providing an easy to use, almost-zero-config way to handle model persist

Ross Bamford 87 Nov 10, 2022
Compile time processed, annotation driven, no reflection SQLite database layer for Android

SqliteMagic Simple yet powerful SQLite database layer for Android that makes database handling feel like magic. Overview: Simple, intuitive & typesafe

Siim Kinks 118 Dec 22, 2022
Kotlin-Exposed-SQL - Example of using Exposed with Kotlin for the consumption of relational SQL Databases

Kotlin Exposed SQL Sencillo ejemplo sobre el uso y abuso de Exposed ORM de Jetbr

José Luis González Sánchez 3 Jun 14, 2022
Upsert DSL extension for Exposed, Kotlin SQL framework

Exposed Upsert Upsert DSL extension for Exposed, Kotlin SQL framework. Project bases on various solutions provided by community in the official "Expos

Dzikoysk 23 Oct 6, 2022
Samples demonstrating the usage of Realm-Kotlin SDK

Realm-Kotlin Samples This repository contains a set of projects to help you learn about using Realm-Kotlin SDK Each sample demonstrates different use

Realm 52 Dec 31, 2022
Collection of Kotlin APIs/tools to make using Realm Mobile database easier

Compass Kotlin API and tools to make working with Realm easier Components Compass is designed to make working with Realm easier through collection of

Arunkumar 16 Oct 4, 2022
Upsert DSL extension for Exposed, Kotlin SQL framework

Exposed Upsert Upsert DSL extension for Exposed, Kotlin SQL framework. Project bases on various solutions provided by community in the official "Expos

Reposilite Playground 23 Oct 6, 2022
sql-delight example, a plugin by Square which is pure kotlin and it is useful in kmm

Sql-Delight-Example01 Developed by Mahdi Razzaghi Ghaleh first example of sql-delight What is SqlDelight? Kotlin Multiplatform is one of the most inte

rq_mehdi 0 Jan 24, 2022
RecordMe - Record your voice application with kotlin

RecordMe A simple voice recording app. Made Using : Kotlin, Navigation Component

Steve Waweru 2 Apr 28, 2022
Starter code for Android Kotlin Fundamentals Codelab 6.1 Room

TrackMySleepQuality - Starter Code Starter code for Android Kotlin Fundamentals Codelab 6.1 Room Introduction TrackMySleepQuality is an app for record

YamanAswal 0 Jan 15, 2022
BookSearchApp - Book Search App With Kotlin

BookSearchApp IT Book Search App Search IT books with keyword and view informati

null 1 Feb 7, 2022
Memory objects for Kotlin/JVM and Java

Memoria Why should an object care about where to store their bytes? Examples Basics RAM can used as a memory storage: val ram: BytesMemory = RamMemory

null 6 Jul 29, 2022
JAKO: Just Another Kotlin Orm (PostgreSQL)

JAKO: Just Another Kotlin Orm (PostgreSQL) JAKO is a simple, minimal, no-dependency library to build and execute postgresql statements using a fluent

Alessio 6 May 27, 2022
A MySQL connector wrapper that supports mapping to Kotlin classes.

Racoon Racoon is a wrapper for the MySQL connector. It makes communicating with the database easier by providing a bunch of functionalities: Mapping q

null 1 Jun 3, 2022
Room Database Queries with Kotlin Flow

Room Database Queries with Flow This app displays a list of bus stops and arrival times. Tapping a bus stop on the first screen will display a list of

asifj96 0 Apr 26, 2022
Code samples for the second edition of "Kotlin in Action".

Code samples for Kotlin in Action, Second Edition This project contains the code samples from book "Kotlin in Action, Second Edition" by Roman Elizaro

Kotlin 16 Dec 29, 2022
SurrealDB Kotlin implementation.

Kotlin Surreal Database API KSDB | by Necrosis SurrealDB framework for Kotlin Documentation · Report Bug · Request Feature ?? Table of Contents ?? Tab

Necrosis 5 Nov 22, 2022