Store.kt

  1. package com.hexagontk.store

  2. import kotlin.reflect.KClass
  3. import kotlin.reflect.KProperty1

  4. /**
  5.  * TODO All methods accepting maps rely on `mapOf` returning an insertion ordered map. Take care of
  6.  *   this in the future to avoid possible bugs
  7.  */
  8. interface Store<T : Any, K : Any> {
  9.     val type: KClass<T>
  10.     val key: KProperty1<T, K>
  11.     val name: String
  12.     val encoder: (T) -> Map<String, *>
  13.     val decoder: (Map<String, *>) -> T

  14.     fun insertOne(instance: T): K

  15.     fun insertMany(instances: List<T>): List<K>

  16.     fun insertMany(vararg instances: T): List<K> =
  17.         insertMany(instances.toList())

  18.     fun saveOne(instance: T): K? // returns key if created, null if updated

  19.     fun saveMany(instances: List<T>): List<K?>

  20.     fun replaceOne(instance: T): Boolean

  21.     fun replaceMany(instances: List<T>): List<T>

  22.     fun replaceMany(vararg instances: T): List<T> =
  23.         replaceMany(instances.toList())

  24.     fun updateOne(key: K, updates: Map<String, *>): Boolean

  25.     fun updateOne(key: K, vararg updates: Pair<KProperty1<T, *>, *>): Boolean =
  26.         updateOne(key, fields(*updates))

  27.     fun updateMany(filter: Map<String, *>, updates: Map<String, *>): Long

  28.     fun deleteOne(id: K): Boolean

  29.     fun deleteMany(filter: Map<String, *>): Long

  30.     fun findOne(key: K): T?

  31.     fun findOne(key: K, fields: List<String>): Map<String, *>?

  32.     fun findOne(filter: Map<String, *>): T? =
  33.         findMany(filter).apply { check(size < 2) }.firstOrNull()

  34.     fun findOne(filter: Map<String, *>, fields: List<String>): Map<String, *>? =
  35.         findMany(filter, fields).apply { check(size < 2) }.firstOrNull()

  36.     fun findMany(
  37.         filter: Map<String, *>,
  38.         limit: Int? = null,
  39.         skip: Int? = null,
  40.         sort: Map<String, Boolean> = emptyMap()): List<T>

  41.     fun findMany(
  42.         filter: Map<String, *>,
  43.         fields: List<String>,
  44.         limit: Int? = null,
  45.         skip: Int? = null,
  46.         sort: Map<String, Boolean> = emptyMap()): List<Map<String, *>>

  47.     fun findAll(
  48.         limit: Int? = null,
  49.         skip: Int? = null,
  50.         sort: Map<String, Boolean> = emptyMap()): List<T> =
  51.             findMany(emptyMap<String, Any>(), limit, skip, sort)

  52.     fun findAll(
  53.         fields: List<String>,
  54.         limit: Int? = null,
  55.         skip: Int? = null,
  56.         sort: Map<String, Boolean> = emptyMap()): List<Map<String, *>> =
  57.             findMany(emptyMap<String, Any>(), fields, limit, skip, sort)

  58.     fun count(filter: Map<String, *> = emptyMap<String, Any>()): Long

  59.     fun drop()

  60.     fun fields(updates: Map<KProperty1<T, *>, *>): Map<String, *> =
  61.         updates.mapKeys { it.key.name }

  62.     fun fields(vararg updates: Pair<KProperty1<T, *>, *>): Map<String, *> =
  63.         fields(updates.toMap())
  64. }