-
-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: add the ability to copy query beans #3296
Comments
Actually, we have an even stronger motivation for wanting this. We like to create a wrapper query-building classes for our queries like class EaObjectPropertyQuery(
private val database: Database,
private override val ebeanQuery: QEaObjectProperty = QEaObjectProperty(database),
) : DbQuery<EaObjectProperty, QEaObjectProperty>(EaObjectProperty::class) {
fun withId(id: Long): EaObjectPropertyQuery =
chainQuery { where().id.eq(id) }
fun withName(name: String): EaObjectPropertyQuery =
chainQuery { where().property.eq(name) }
fun withValue(value: String): EaObjectPropertyQuery =
chainQuery { where().value.eq(value) }
fun withObject(eaObject: EaObject): EaObjectPropertyQuery =
chainQuery { where().eaObject.eq(eaObject) }
fun withObjectIn(objects: Collection<EaObject>): EaObjectPropertyQuery =
chainQuery { where().objectId.isIn(objects.map { it.id }) }
fun withObjectIn(objectQuery: EaObjectQuery): EaObjectPropertyQuery =
chainQuery { where().objectId.isIn(objectQuery.ebeanQuery.select(QEaObject._alias.id).query()) }
private fun chainQuery(chain: QEaObjectProperty.() -> QEaObjectProperty) =
// FIXME: this doesn't clone the query, it would be nice if we could call `ebeanQuery.copy()` here
EaObjectPropertyQuery(database, chain(ebeanQuery))
}
abstract class DbQuery<EntityType : Any, QueryType : TQRootBean<EntityType, QueryType>>(
private val entityClass: KClass<EntityType>,
) {
protected abstract val ebeanQuery: QueryType
override fun findOne(): EntityType? {
try {
return ebeanQuery.findOne()
} catch (error: NonUniqueResultException) {
throw FoundMoreThanOne(entityClass, error)
}
}
override fun findList(): List<EntityType> {
return ebeanQuery.findList()
}
override fun exists(): Boolean {
return ebeanQuery.exists()
}
override fun count(): Int = ebeanQuery.findCount()
override fun forEach(action: (EntityType) -> Unit) {
ebeanQuery.findEach(action)
}
override fun delete() {
ebeanQuery.delete()
}
} Then we can use this as The problem here (as stated in the comment in |
Yes, that should work. |
That would be perfect. Thank you for considering this. |
#3296 Add copy() method to query beans
Rationale
It happens to us quite often that we'd like to reuse some base part of a query built using query beans and then construct several queries on top of it using additional chaining methods. The problem is, the generated chaining methods (e.g.
name.eq("Tom")
) are all destructive - they mutate the underlyingQuery
in place and there doesn't seem to be a way to copy the current "version" of the query bean.Example
Implementation notes
I see
Query
already has acopy()
method andTQRootBean
already has a constructor variant takingQuery
, so (I might be completely wrong here of course) it might even be as simple as generating a similar constructor variant for each query bean along with acopy()
method which would 1) callcopy()
on the query and 2) call the new constructor variant with this copied query. Then we could use this asThe text was updated successfully, but these errors were encountered: