IN clause with jooq and kotlin - kotlin

I have the following code which works fine:
fun <T> createComparisonOperator(field: Field<T>, value: T, op: String): Condition {
return when(op) {
"eq" -> field.eq(DSL.inline(value))
else -> throw Exception("No Op)
}
}
Now what I want to do is test for membership in an array and I do something like:
fun<T> createMembershipOperator(field: Field<T>, value: Collection<T>, op: String): Condition {
return when(op) {
"in" -> field.`in`(DSL.inline(value))
else -> throw Exception("No op")
}
}
The membership test is called as:
val wrappedValue = listOf("100")
val sqlField = DSL.field(column, SQLDataType.VARCHAR)
return createMembershipOperator<String>(sqlField, wrappedValue, op)
It does not fail but does not return any data.

Write this:
"in" -> field.`in`(value.map(DSL::inline))

Related

Kotlin constrain generic method's type parameter to be a supertype of class's type parameter

I'm trying to get a class similar to this (contrived) example to compile:
class Foo<T> {
val value: T
val condition: Boolean
fun <R> transform(func: () -> R): R {
return if (condition) {
func()
} else {
// Type mismatch: required: R, found: T
value
}
}
}
The transform method can return either value or the result of func(), so T should be assignable to R. Is there a way to express this in Kotlin?
I tried using where T : R, but the compiler doesn't understand that T should refer to the class's T. An extension function could work, but I want to avoid that because it complicates Java interoperability.
You can try this , it works. You need to pass two type params while initializing.
class Foo<T:R,R> constructor(val value: T,val condition: Boolean) {
fun transform(func: () -> R): R {
return if (condition) {
func()
} else {
value
}
}
}
Example:
var s = Foo<String,CharSequence>("12",false).transform {
"as"
}
You pass "12" as string . Transform return "as" value as CharSequence .
Update:
As far as I know, only using extension function might be solve your requirement.
Here is the extension function solution.
class Foo<T> constructor(val value: T,val condition: Boolean){}
fun <T:R,R> Foo<T>.transform(func: () -> R):R{
return if (condition) {
func()
} else {
value
}
}
Example of using extension function solution.
fun main() {
var s1 = Foo(setOf("Hello"),false).transform<Set<String>,Iterable<String>> {
setOf("World")
}
var s2 = Foo(listOf("Hello"),false).transform<List<String>,Iterable<String>> {
listOf("World")
}
}
You just use the type parameter from the class directly. Your method doesn't need to introduce another type parameter:
class Foo<T> {
val value: T
val condition: Boolean
fun transform(func: () -> T): T {
return if (condition) {
func()
} else {
value
}
}
}

how can I delete When statement on this code (Kotlin)

val customerInfo = when {
visitor.isCustomer -> customerService.getCustomerInfo(visitorId )
else -> null
}
In this Code, visitor.isCustomer is Boolean ( true / false)
Now then, I don't like specify else -> null into the code.
so i want to delete when statement and convert other ways..
How can I do that?
(I prefer to convert it with StandardKt (like let, apply, also... ))
You can just use an if/else
val customerInfo = if (visitor.isCustomer) customerService.getCustomerInfo(visitorId) else null
You could do something like
val customerInfo = vistorId.takeIf { visitor.isCustomer }?.let { customerService.getCustomerInfo(it) }
But I think a when or if statement is cleaner and more readable.
I think JetBrains coding convention would recommend an if statement instead of a when statement here.
Hope this will be more readable.
Without any additional things,
val customerInfo = if (visitor.isCustomer) customerService.getCustomerInfo(visitorId) else null
With your own extension functions
2)Without infix: (condition).ifTrueElseNull{ return value}
inline fun <T> Boolean?.ifTrueElseNull(block: () -> T): T? {
if (this == true) {
return block()
}
return null
}
var a = visitor.isCustomer.ifTrueElseNull{customerService.getCustomerInfo(visitorId)}
With infix: (condition) ifTrueElseNull{ return value}
inline infix fun <T> Boolean?.ifTrueElseNull(block: () -> T): T? {
if (this == true) {
return block()
}
return null
}
var a = visitor.isCustomer ifTrueElseNull{customerService.getCustomerInfo(visitorId)}

Boolean expression with nullable variables

I am tinkering around with Kotlin and I am trying to wrap my head around how nullable variables work in Kotlin. Here I have a piece of code that does a boolean check to see if a vehicle is over capacity. Is the implementation a good way to work with nullable variables or is there a more elegant way ?
class Route(var vehicle: Vehicle?, var jobs: List<Job>?) {
constructor()
constructor(vehicle: Vehicle?)
fun isOverCapacity() : Boolean {
val vehicleCapacity = vehicle?.capacity
if (vehicleCapacity != null){
val totalDemand = jobs?.sumBy { job -> job.demand }
if (totalDemand != null) {
return totalDemand > vehicleCapacity
}
}
return false
}
}
Thanks a lot!
fun isOverCapacity(): Boolean {
val vehicleCapacity = vehicle?.capacity ?: return false
val totalDemand = jobs?.sumBy { job -> job.demand } ?: return false
return totalDemand > vehicleCapacity
}
What does ?: do in Kotlin? (Elvis Operator)
By using kotlin std-lib dsl functional operators like let, run, also, apply, use.
Use of ?. -> if the object/value is not null then only call the next function.
let -> returns the result of lambda expression.
run -> returns the result of lambda expression passing this as receiver.
also -> does operation and returns itself unlike the result of lambda.
apply -> does operation and returns itself unlike the result of lambda passing this as receiver.
use -> returns the result of lambda expression and closes the Closeable resource.
You can simplify the code as follows:
fun isOverCapacity() : Boolean =
vehicle?.capacity?.let { vehicleCapacity ->
jobs?.sumBy { job -> job.demand }?.let { totalDemand ->
totalDemand > vehicleCapacity
}
} ?: false

Discard return value to return Unit?

I am just starting with kotlin, so, forgive me if this is a basic question, I did do some googling, but that didn't turn up anything useful.
The question is how do I convert a value to Unit.
For example, in scala, if I write something like this:
def foo: Int = ???
def bar(x: String): Unit = x match {
case "error" => println("There was an error")
case _ => foo
}
The return type of the match expression is Any, but it is discarded by the compiler and Unit is returned by the function.
But doing something like this in kotlin:
fun bar(x: String): Unit = when(x) {
"error" -> println("There was an error")
else -> foo()
}
it complains about the foo part: inferred type is Int but Unit was expected
I know, that in this case, I can just get rid of the =, and put the body inside a block instead, that works, but I am looking for a general solution. What I was able to come with so far is just foo.let {}, but it seems kinda clumsy, especially if there are many cases like this where it needs to be done.
You can create an extension method on Any object and call it. I just prefer to use the name discard() rather than toUnit(), since I feel it conveys better the intent:
fun Any?.discard() = Unit
fun foo(): Int = 3
fun bar(x: String): Unit = when (x) {
"error" -> println("There was an error")
else -> foo().discard()
}
There's no way to do that out of the box, but you can make an extension function for this:
fun Any?.unit() = Unit
Then use it as:
fun bar(x: String): Unit = when(x) {
"error" -> println("There was an error")
else -> foo().unit()
}
Alternatively, make when a statement and not an expression:
fun bar(x: String) {
when(x) {
"error" -> println("There was an error")
else -> foo()
}
}
There are three solutions to your problem, which come to my mind:
Make when a statement instead of expression, so its result does not get returned:
fun bar(x: String) {
when(x) {
"error" -> println("There was an error")
else -> foo()
}
}
Use an extension to convert values to Unit:
fun Any?.asUnit() = Unit
Usage:
fun bar(x: String): Unit =
when (x) {
"error" -> println("There was an error")
else -> foo().asUnit()
}
Wrap the call into higher-order function call that returns Unit, e.g. with:
fun bar(x: String): Unit = with(x){
when (x) {
"error" -> println("There was an error")
else -> foo()
}
}

Is there a less ugly way to return function in Kotlin?

This declaration works, but is not the most beautiful code. Is there a way to return functions less ugly? I tried (s: String) -> writer.println(s) but this didn't work.
val writeStuff: (PrintWriter) -> (String) -> Unit = {
val writer = it
val f: (String) -> Unit = {
writer.println(it)
}
f
}
PrintWriter("test").use { writeStuff(it)("TEST") }
EDIT: a bit more concrete example:
val writeStuff: (PrintWriter) -> (String) -> Unit = { writer ->
{ writer.println(it) }
}
val sendStuff: (Any) -> (String) -> Unit = { sender ->
{ sender.equals(it) }
}
#Test fun test1() {
val li = listOf("a", "b", "c")
val process: List<(String) -> Unit> =
listOf(writeStuff(PrintWriter("a")), sendStuff(Object()))
process.map { li.map(it) }
}
First, you can simplify your code using lambda syntax with explicit parameter and inlining val f:
val writeStuff: (PrintWriter) -> (String) -> Unit = { writer ->
{ writer.println(it) }
}
But since Kotlin supports local function declarations, you can even make writeStuff a local fun instead of a val.
This would lead to the following code:
fun writeStuff(writer: PrintWriter): (String) -> Unit {
return { writer.println(it) }
}
Or, using the single expression syntax,
fun writeStuff(writer: PrintWriter): (String) -> Unit = { writer.println(it) }
The usage, however, will be the same:
PrintWriter("...").use { writeStuff(it)("...") }
I stumbled across this question while trying to figure out how to return a Function (the java interface) in Kotlin. While this doesn't directly answer the question, hopefully it'll help someone else who has the same query:
override fun myFun(param1: Object): Function<in Object, out String?> {
if (!param1.meetsCriteria())
return Function { obj -> null }
return Function { obj ->
"success"
}
}
In this case, I was overriding a method in a java interface that required me to return a Function instance. (Note that since the param is not used in my particular implementation above, I could remove it and just have the return result. eg return Function { null })
Edit: After some research, it turns out Kotlin covers this subject with their discussion on "SAM (single abstract method) conversions" here and here, though it may not be the most intuitive thing to look up when figuring out how to return Functions.