All Projects → mfarsikov → Kotgres

mfarsikov / Kotgres

Licence: apache-2.0
SQL generator and result set mapper for Postgres and Kotlin

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Kotgres

Xorm
Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm
Stars: ✭ 6,464 (+30680.95%)
Mutual labels:  orm, postgresql, postgres
Prisma
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite & MongoDB (Preview)
Stars: ✭ 18,168 (+86414.29%)
Mutual labels:  orm, postgresql, postgres
Zeeql3
The ZeeQL (EOF/CoreData/AR like) Database Toolkit for Swift
Stars: ✭ 29 (+38.1%)
Mutual labels:  orm, postgresql, postgres
Hunt Entity
An object-relational mapping (ORM) framework for D language (Similar to JPA / Doctrine), support PostgreSQL and MySQL.
Stars: ✭ 51 (+142.86%)
Mutual labels:  orm, entity, postgresql
With advisory lock
Advisory locking for ActiveRecord
Stars: ✭ 409 (+1847.62%)
Mutual labels:  transaction, postgresql, postgres
Ship Hold
data access framework for Postgresql on nodejs
Stars: ✭ 110 (+423.81%)
Mutual labels:  orm, postgresql, postgres
Pqt
Postgres schema definition, sql/go, code generation package.
Stars: ✭ 65 (+209.52%)
Mutual labels:  orm, entity, postgresql
Beam
A type-safe, non-TH Haskell SQL library and ORM
Stars: ✭ 454 (+2061.9%)
Mutual labels:  orm, postgresql, postgres
Sqlboiler
Generate a Go ORM tailored to your database schema.
Stars: ✭ 4,497 (+21314.29%)
Mutual labels:  orm, postgresql, postgres
Mikro Orm
TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL and SQLite databases.
Stars: ✭ 3,874 (+18347.62%)
Mutual labels:  orm, entity, postgresql
Zapatos
Zero-abstraction Postgres for TypeScript: a non-ORM database library
Stars: ✭ 448 (+2033.33%)
Mutual labels:  orm, postgresql, postgres
Go Kallax
Kallax is a PostgreSQL typesafe ORM for the Go language.
Stars: ✭ 853 (+3961.9%)
Mutual labels:  orm, postgresql, postgres
Monogamy
Add table-level database locking to ActiveRecord
Stars: ✭ 12 (-42.86%)
Mutual labels:  postgresql, postgres
Bookshelf
A simple Node.js ORM for PostgreSQL, MySQL and SQLite3 built on top of Knex.js
Stars: ✭ 6,252 (+29671.43%)
Mutual labels:  orm, postgresql
Guardian auth
The Guardian Authentication Implementation Using Ecto/Postgresql Elixir Phoenix [ User Authentication ]
Stars: ✭ 15 (-28.57%)
Mutual labels:  postgresql, postgres
Vscode Sqltools
Database management for VSCode
Stars: ✭ 741 (+3428.57%)
Mutual labels:  postgresql, postgres
Smartsql
SmartSql = MyBatis in C# + .NET Core+ Cache(Memory | Redis) + R/W Splitting + PropertyChangedTrack +Dynamic Repository + InvokeSync + Diagnostics
Stars: ✭ 775 (+3590.48%)
Mutual labels:  orm, postgresql
Schemats
Generate typescript interface definitions from SQL database schema
Stars: ✭ 799 (+3704.76%)
Mutual labels:  postgresql, postgres
Diesel
A safe, extensible ORM and Query Builder for Rust
Stars: ✭ 7,702 (+36576.19%)
Mutual labels:  orm, postgresql
Supabase
The open source Firebase alternative. Follow to stay updated about our public Beta.
Stars: ✭ 25,142 (+119623.81%)
Mutual labels:  postgresql, postgres

Kotgres[ql]

Not an ORM.

Generates inspectable SQL queries before compile time rather than in runtime.

Kotgres = ORM - bullshit

Quick start

Gradle

plugins {
    kotlin("kapt")
    kotlin("plugin.serialization") // for serializing collections as JSON
}

repositories {
    jcenter()
}

dependencies {
  implementation("com.github.mfarsikov:kotgres-core:0.1.0") // library containing annotations and classes used in compile time

  kapt("com.github.mfarsikov:kotgres-kapt:0.1.0") // Kotlin annotation processor, generates repositories code before compilation
}

kapt {
  arguments {
    arg("kotgres.db.qualifiedName", "my.pack.DB") // default database class name
    arg("kotgres.spring", "false") // marks database class as Spring's component
  }
}

Create entities and declare repositories

import kotgres.annotations.Id
import kotgres.annotations.PostgresRepository
import kotgres.aux.Repository

data class Person(
  @Id
  val id: UUID,
  val name: String,
  val birthDate: LocalDate,
)

@PostgresRepository
interface PersonRepository : Repository<Person> {
    fun save(person: Person)
    fun findBy(birthDate: LocalDate): List<Person>
}

Generate the code

./gradlew kaptKotlin generates in the folder build/generated/source/kapt two classes: PersonRepositoryImpl and DB

Generated code
@Generated
internal class PersonRepositoryImpl(
  private val connection: Connection
) : PersonRepository {
  
  public override fun findBy(birthDate: LocalDate): List<Person> {
    val query = """
        |SELECT "birth_date", "id", "name"
        |FROM "person"
        |WHERE "birth_date" = ?
        """.trimMargin()
    return connection.prepareStatement(query).use {
      it.setObject(1, birthDate)
      it.executeQuery().use {
        val acc = mutableListOf<Person>()
        while (it.next()) {
          acc +=
             Person(
              birthDate = it.getObject("birth_date", java.time.LocalDate::class.java),
              id = it.getObject("id", UUID::class.java),
              name = it.getString("name"),
            )
        }
        acc
      }
    }
  }

  public override fun save(person: Person): Unit {
    val query = """
        |INSERT INTO "person"
        |("birth_date", "id", "name")
        |VALUES (?, ?, ?)
        |ON CONFLICT (id) DO 
        |UPDATE SET "birth_date" = EXCLUDED."birth_date", "id" = EXCLUDED."id", "name" = EXCLUDED."name"
        |""".trimMargin()
    return connection.prepareStatement(query).use {
      it.setObject(1, person.birthDate)
      it.setObject(2, person.id)
      it.setString(3, person.name)
      it.executeUpdate()
    }
  }
}

Usage

val db = DB(dataSource) // create DB access object

db.transaction {
  // inside the transaction all repositories are accessible through 'this'
  personRepository.save(
    Person(
      id = UUID.random(),
      name = "John Doe",
      birthDate = LocalDate.now(),
    )
  )
}

val bornToday = db.transaction(readOnly = true) {
    personRepository.findBy(birthDate = LocalDate.now())
}

Synopsis

  • Maps Kotlin classes to Postgres tables
  • Generates SpringData-like repositories with
    • predefined query methods(saveAll, deleteAll, findAll)
    • custom query methods (like findByLastName)
    • methods using native SQL (@Query("select ..."))
    • query methods returning projections, scalar types and their lists
  • Code and queries are generated during build process, before compilation
  • Generated code is properly formatted and human-friendly
  • Explicit transaction management (DSL instead of annotations driven)
  • Postgres specific 🐘
  • Uses native SQL and JDBC
  • Uses immutable Kotlin data classes as 'entities'
  • Maps nested object's properties into a single table (like JPA @Embeddable)
  • Serializes Kotlin collections as JSONB type in postgres
  • Generates schema validations

Unlike popular ORM:

  • No reflection and runtime magic
  • No lazy loading
  • No automatic joins, and sub selects (no "N+1" problem)
  • No query languages other than SQL
  • No vendor agnostic
  • No implicit type conversions
  • No queries triggered by entity's getters
  • No "managed" state
  • No caches
  • No "object relational impedance mismatch"
  • No inheritance resolve strategies
  • No transaction managers

Rationale

The intention was to make database interactions (queries and transactions) explicit. Generate boiler plate code (like trivial queries, and result mappings). Give ability to write complex queries, and map their results automatically. Use full power of Postrgesql (such as JSON queries and full text search queries).

Avoid accidental complexity

Documentation

https://mfarsikov.github.io/kotgres/

Example

See example project

./gradlew example:kaptKotlin generates database classes in example/build/generated/source/kapt/main

./gradlew example:test runs real queries against DB in docker container (requires Docker)

./gradlew example:run runs Main application in example project, requires running Postgres.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].