Skip to content

Instantly share code, notes, and snippets.

@Grohden
Last active February 5, 2019 23:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Grohden/b700cddb07546f6d0843f4e6c1dee12c to your computer and use it in GitHub Desktop.
Save Grohden/b700cddb07546f6d0843f4e6c1dee12c to your computer and use it in GitHub Desktop.
what have i done
abstract class QuerySpec<Manager, Entity, TRepository : Repository<Manager, Entity>, Return> {
abstract fun fetchResult(arg: Manager): Return
}
abstract class Repository<Manager, Entity> {
abstract val manager: Manager
fun <TQuerySpec : QuerySpec<Manager, Entity, Repository<Manager, Entity>, Return>, Return> executeQuery(querySpec: TQuerySpec): Return {
return querySpec.fetchResult(manager)
}
}
class EquipmentRepository : Repository<Realm, Equipment>() {
override val manager: Realm = Realm.getDefaultInstance()
}
class ProductRepository : Repository<Realm, Product>() {
override val manager: Realm = Realm.getDefaultInstance()
}
class EquipmentByCode(
private val code: String
//) : QuerySpec<Realm, Equipment, EquipmentRepository, RealmResults<Equipment>>() { // this breaks the inference. (why?)
) : QuerySpec<Realm, Equipment, Repository<Realm, Equipment>, RealmResults<Equipment>>() {
override fun fetchResult(arg: Realm): RealmResults<Equipment> {
return arg
.where(Equipment::class.java)
.equalTo(EquipmentFields.CODE, code)
.findAll()
}
}
class ProductByCode(
private val code: String
// ) : QuerySpec<Realm, Product, ProductRepository, RealmResults<Product>>() { // this breaks the inference. (why?)
) : QuerySpec<Realm, Product, Repository<Realm, Product>, RealmResults<Product>>() {
override fun fetchResult(arg: Realm): RealmResults<Product> {
return arg
.where(Product::class.java)
.equalTo(ProductFields.CODE, code)
.findAll()
}
}
fun main() {
val equipmentRepository = EquipmentRepository()
val productRepository = ProductRepository()
// I expect this from the compiler:
equipmentRepository.executeQuery(EquipmentByCode("teste")) // okay
equipmentRepository.executeQuery(ProductByCode("teste")) // error
productRepository.executeQuery(EquipmentByCode("teste")) // error
productRepository.executeQuery(ProductByCode("teste")) // okay
}
@Grohden
Copy link
Author

Grohden commented Feb 5, 2019

I could improve (?????) the readability with this type alias
typealias AQuerySpec<M, E, R> = QuerySpec<M, E, Repository<M, E>, R>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment