7 days in kotlin and Anko a novice question on database object old leter envelop pattern


#1

I’ve seen in Anko SQLite this piece of code

The documentation states:"So what’s the sense? Instead of enclosing your code into try blocks, now you can just write this:

database.use {
insert(“User”,
“id” to 42,
“name” to “John”,
“email” to "user@domain.org"
}

and then
db.select(“User”, “email”).exec {
// Doing some stuff with emails
}

But well, I need to now if some has gone wrong so I started to try and catch again, then I tried the following:

fun envelope (leter:(Unit) -> List ): List {
try {
return leter.invoke(Unit)
} catch (e: Exception) {
log.warn(“envelope exception: {e.message} {e.toString()} ${e.stackTrace.toString()}”)
} finally {
}
return emptyList()
}

and use it like this:

fun loadLessons(): List {
val L2: List = envelope() { DB2.use { select(“LESSONS”, “NAME”, “ID”).exec { parseList(classParser()) } } }
return L2
}

It’s amazing I can get whatever list of entities in my db almost with no coding so far so good…
But now suppose I have to resort to insert or update, that is database.use, they return numbers Long for insert and Int for the updates, I expected that I could find a generic form, but alas I could not and end up with tree envelop classes

fun envelope2 (leter:(Unit) -> Unit):Unit{
// envelope2 no return updates

    try {
        leter.invoke(Unit)
   
    } catch (e: Exception) {
        log.warn("envelope exception:  ${e.message}   ${e.toString()}  ${e.stackTrace.toString()}")
    } finally {
    }

}

fun<T> envelope (leter:(Unit) -> List<T> ): List<T> {
    //envelope  return list  select
    try {
        return leter.invoke(Unit)
    } catch (e: Exception) {
        log.warn("envelope exception:  ${e.message}   ${e.toString()}  ${e.stackTrace.toString()}")
    } finally {
    }
    return emptyList()
}

fun envelope3 (leter:(Unit) -> Long ): Long {
    // envelope  return long, insert
    try {
        return leter.invoke(Unit)
    } catch (e: Exception) {
        log.warn("envelope exception:  ${e.message}   ${e.toString()}  ${e.stackTrace.toString()}")
    } finally {
    }
    return 0
}

The point is that I’m absolutely convinced that this can be trivially generalized to a just one function.
I’ll very thankfully if someone can bring me a hint.


#2

Maybe:

fun <T> envelop(default: T, letter: () -> T) = try {
    letter()
} catch (e: Exception) {
    log.warn("envelope exception:  ${e.message}   ${e.toString()}  ${e.stackTrace.toString()}")
    default
}

#3

maybe, but to be honest I don’t know how to deal with the default parameter, and the compiler cries like a fool when trying in (but it does it constantly)

But well all I can say is that kotlin is an amazing language bear in mind it’s only my 7 day (also in android)
All I want is to find out a common expression for those so similar calls:

fun envelope (leter:(Unit) -> List ): List{ return List } for selects
fun envelope2 (leter:(Unit) -> Unit):Unit{ return Unit} for creates (that return nothing)
fun envelope3 (leter:(Unit) -> Long ): Long{ return Long} for inserts and updates that return long and int

Maybe your’s is the answer, but don’t know, in any case a bewildering peace of software that kotlin

Thanks for the hint


#4

Here is how to use it:

//fun envelope (leter:(Unit) -> List ): List{ return List } for selects
val myList = envelop(emptyList()) { listOf(1, 2, 3) }

//fun envelope2 (leter:(Unit) -> Unit):Unit{ return Unit} for creates (that return nothing)
envelop(Unit) { println("returns Unit here") }

//fun envelope3 (leter:(Unit) -> Long ): Long{ return Long} for inserts and updates that return long and int
val myLong = envelop(0L) { 10000L }

You could also make the “default” be “() -> T” so it only create the default object on exception.
As emptyList()/Unit are cached it should be fine. Not sure about 0L but I think its cached by JVM also(I know small integers are).


#5

Thank you so much!