hi all,, is there any method which convert list to...
# getting-started
t
hi all,, is there any method which convert list to int separate with ” , ” likes
joinToString()
I means
Copy code
val list = listOf(1,2,3)

// i want the result like this
// 1,2,3 <= each is int value
t
t
thanks,
Copy code
list.joinToString()
but how to change each string to int
t
I guess that the function name already has an answer for your question, the result is going to be string
image.png
The return type is a string
t
thx
is there any method likes joinToString() which return int type
t
I guess you should google it
👍 1
s
@Tuang what would that method do exactly? Since Int is just a single integer
Do you want to go back from the string
"1,2,3"
to a list of ints?
t
hi @Simon Kågedal Reimer actually i am runinng queryRunner() and my query is something like this
Copy code
select name from someTable where id in (?, ?, ?)
and i have ids list
val ids: MutableList<Int> = mutableListOf<Int>()
, i am going to pass the ids to queryRunner() parameter likes
QueryRunner().query(connection, query, ColumnListHandler<Int>(), 1,2,3
<= i need to pass like this, so i did
ids.joinToString()
and it is not int. sorry for bad english.
s
Ah ok - you don't want joinToString, that will be the query runner's job
t
do u have any idea for that please
s
So you want to pass each int individually, like
.query(connection, query, handler, firstInt, secondInt, thirdInt)
t
yes, but we don’t know how much element in ids list
s
If you have them in a list, you could do that with something like
myList.get(0), myList.get(1), myList.get(2)
– but that's not very pretty
I would unwrap the list into insividual variables first, before the call to query
And confirm that I have the values I need
t
yeah, this is hard coding right?
what if myList have over 3 elements
s
Ah wait – so you want the query to handle any number of ids
t
yes
here is my sample code
Copy code
val ids = ArrayList<Any>()
		// add ids

        val relQuery = StringBuilder()
        relQuery.append("SELECT name FROM table WHERE id IN (")
        var separate = ""
        repeat(domainIds.size) {
            relQuery.append(separate)
            separate = ","
            relQuery.append("?")
        }
        relQuery.append(");")

        val rel = QueryRunner().query(connection, relQuery.toString(), ColumnListHandler<Int>(), Ids)
s
Not sure how to do that. SQL replacement parameters generally don't support that afaik. You could go with building that part of the query yourself:
Copy code
... where id in ${myList.joinToString()}
That's generally considered bad form because of the risk of SQL injections, but if you know it's a list of ints you should be safe I guess....
t
ummm
j
image.png
m
@Tuang if I understood right, you want to pass a variable number of int ids to the function, right? This could be accomplished using varargs (I’m guessing the types here):
Copy code
fun query(conn: Connection, query: String, handler: ColumnListHandler<Int>, vararg ids: Int) { ... }
then you can invoke your method with any number of ids you like:
Copy code
query(connection, relQuery.toString(), ColumnListHandler<Int>(), 1, 2, 3)
or if you have them in an array you can pass it using the spread operator:
Copy code
val ids = arrayOf(1, 2, 3, 4)
//...
query(connection, relQuery.toString(), ColumnListHandler<Int>(), *ids)
anyway I quote what Simon wrote above: if the values you’re replacing come from user input this code is vulnerable to SQL injection attacks, so don’t manually substitute strings but use an SQL library, for example https://github.com/JetBrains/Exposed
t
thank you very much @Simon Kågedal Reimer and @Matteo Mirk finally i just solved by myself. I code like this
Copy code
....
....
val paramIds = connection.createArrayOf("int", ids.toArray())

val query = "SELECT name FROM table WHERE id = ANY(?)"
val result = QueryRunner().query(connection, query, MapListHandler(), paramIds)
.....
.....
this worked perfectly.
m
Just out of curiosity, what library are you using? Or is it your own?
t
u means queryRunner?
i just using queryRunner only
m
yes QueryRunner, connection,etc. is it your custom library?
just to understand the context 🙂
t
yes, my custom library
m
Ok thanks
t
may be java.sql.connection 😀
t
apart from this, let me ask some advice for my below code.
Copy code
val carMst: List<(Mutable)Map<String!, Any!>!>!
val carUserIds: List<(Mutable)Map<String!, Any!>!>!
....
....
val result = ArrayList<Car>()
for (mst in carMst) {
    val userIds = ArrayList<Int>()
    for (uids in carUserIds) {
        if (carMst["car_id"] == uids["car_id"]) {
            userIds.add(uids["user_id"] as Int)
        }
    }
    val car = Car(
        mst["car_id"] as Int,
        mst["model"] as String,
        userIds
    )
    result.add(car)
}
dont u think this is messy code? i dont know too much about collection, but with collection this can be more simple and beautiful right? 😀
m
Ohhh I see, thanks @Simon Kågedal Reimer it’s commons-dbutils! Now all is clear… so @Tuang, when you call
query()
it expects a varargs as last arguments, so if you have your id list just call it like this
Copy code
QueryRunner().query(connection, query, MapListHandler(), *ids.toArray())
For now, forget what we said about security since the lib will take care of that for you.
To get advice on a piece of code it would be better to post it in #codereview, people will help cleaning it 😉
s
@Matteo Mirk Will that work though..? Like what would you put as the sql replacement string, just
where id in ?
– does that handle getting a list of values?
m
Oh sorry, I didn’t see the
in
SQL clause, my bad! Well in that case we go back to your original suggestion, watching out for injections I guess…
s
You could generate the replacement string instead 🙂 I.e. a string of
?,?,?,?
with as many question marks as you have things in the list. And then use the trick with the * operator
Should be safe against injections
m
Yes you’re right… I was thinking exactly about that while answering you, but for some reason abandoned the idea 😆 That’s the way I would go to avoid sql injections!
I would compose the string like this:
Copy code
"SELECT name FROM table WHERE id IN (${"?,".repeat(ids.size).substringBeforeLast(",")})"
There’s only a problem if the id list gets too big we could get an error from the db, because many drivers or db engines put a limit on the query length.