I tryed to fix a problem with encodings. So, I sent from 'Postman', from web browser request to server, where I search data in database by keys in request. Request can be like this:
http://localhost:8080/books.getBooksByGenre/Документальное/0/10
(in browser).
Server receive string, like
http://localhost:8080/books.getBooksByGenre/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5/0/10
then, takes params from url:
genreName: 'Документальное'
start: 0
count: 10.
Then, this data sends to dao:
override fun findGenreByName(genreName: String): DatabaseGenre {
return transaction(db) { getGenreByName(genreName) }
}
private fun getGenreByName(genreName: String): DatabaseGenre {
return try {
val foundGenre = GenreEntity.find { Genres.genre eq genreName }.single()
DatabaseGenre(foundGenre.id.value, foundGenre.genre, foundGenre.link)
} catch (e: Exception) {
throw NothingFoundInDatabaseException("no one genre found by '$genreName'")
} catch (e: NoSuchElementException) {
val m = "Duplicates of genre with name '$genreName'"
throw DuplicatedDataInDatabaseException(m)
}
}
In log I see, that sql-query for finding genres is correct, but I receive an exception:
java.util.NoSuchElementException: Collection is empty.
The sql-query, as I said, is correct:
SELECT genres.id, genres.genre, genres.link FROM genres WHERE genres.genre = 'Документальное'
Structure of genres table:
genres
id: int(10)
genre: varchar(100)
link: varchar(100
I tryied, to select all genres, and this query executed almost correctly. So, I decided, to check this query with english word, and this query correctly executed:
SELECT genres.id, genres.genre, genres.link FROM genres WHERE genres.genre = 'simpleGenre'
I have not exceptions with this query.
So, what I've done wrong and how to fix problem with collations?
UPD:
As I said at github (issue), I've tryied this query it mysql cli and I receive correct answer.
Also, I've tryed to decode url params (with java URLDecoder class). It doesn't helps too.
Thanks, #madhead.
I tryied an advance of #madhead, and it works. So, from this time my DB connection URL looks like this:
val connect = Database.connect(
url = "jdbc:mysql://localhost:3306/my_database_name?characterEncoding=utf8&useUnicode=true",
driver = "com.mysql.jdbc.Driver",
user = user_name,
password = password
)
Related
thanks reading this question.
I created simple kotlin project and I want to learn kotlin exposed.
I use H2 database.
I wrote code like below.
package learn.exposed.tables
import org.jetbrains.exposed.sql.Table
object AuthorTable : Table("author") {
val name = varchar("name", 30)
}
fun main() {
// this url based on http://www.h2database.com/html/features.html#execute_sql_on_connection
val url = "jdbc:h2:mem:test;INIT=runscript from 'classpath:/create.sql'\\;runscript from 'classpath:/init.sql'"
Database.connect(url, driver = "org.h2.Driver", user = "root", password = "")
transaction {
AuthorTable.insert {
it[name] = "hoge"
}
println("insert done.") // this message can show on console. I think Insert is successfull.
}
transaction {
AuthorTable.selectAll().firstOrNull()
}
}
and sql files below.
create table author (name varchar(30));
insert into author values ('author1');
When execute main(), console showing insert done.. in short, I think insert is doing well, but when execute AuthorTable.selectAll().firstOrNull(), happend Exception like below,
Exception in thread "main" org.jetbrains.exposed.exceptions.ExposedSQLException: org.h2.jdbc.JdbcSQLNonTransientException: 一般エラー: "java.lang.NullPointerException"
General error: "java.lang.NullPointerException" [50000-200]
SQL: [Failed on expanding args for SELECT: org.jetbrains.exposed.sql.Query#27406a17]
at org.jetbrains.exposed.sql.statements.Statement.executeIn$exposed_core(Statement.kt:62)
at org.jetbrains.exposed.sql.Transaction.exec(Transaction.kt:135)
at org.jetbrains.exposed.sql.Transaction.exec(Transaction.kt:121)
at org.jetbrains.exposed.sql.AbstractQuery.iterator(AbstractQuery.kt:65)
at kotlin.collections.CollectionsKt___CollectionsKt.firstOrNull(_Collections.kt:267)
at learn.exposed.MainKt$main$2.invoke(Main.kt:22)
at learn.exposed.MainKt$main$2.invoke(Main.kt)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.inTopLevelTransaction$run(ThreadLocalTransactionManager.kt:179)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.access$inTopLevelTransaction$run(ThreadLocalTransactionManager.kt:1)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$inTopLevelTransaction$1.invoke(ThreadLocalTransactionManager.kt:205)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:213)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.inTopLevelTransaction(ThreadLocalTransactionManager.kt:204)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$transaction$1.invoke(ThreadLocalTransactionManager.kt:156)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:213)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:126)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:123)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction$default(ThreadLocalTransactionManager.kt:122)
at learn.exposed.MainKt.main(Main.kt:21)
at learn.exposed.MainKt.main(Main.kt)
can I solve this? do you know something how to solve this?
thanks.
Seems like you need at least one Primary Key(PK) or Constraint because of H2 bug.
https://github.com/h2database/h2database/issues/2191
https://github.com/JetBrains/Exposed/issues/801
I am an amateur Kotlin programming. And I have one task which I am not sure how to solve.
So any help would come in handy.
More about this task:
I get this message via HTTP post request
AL:OK:XX:XX:XX:XX:XX:YY~~TYPE:3~~FOF:v1.0~~RSSI:-68~~PORT:8215~~TEMP:34.22~~CH1:OK~~CH2:KS~~CH3:PR~~CH4:VL~~CH5:KS~~CH6:OK~~AUX1:OK~~AUX2:KS~~AUX3:OK
And I need to parse this message into following output format.
XX:XX:XX:XX:XX:XY - MAC ADDRESS
3 - Type of device
v1.0 - Version of device
-68 - Signal strenght
8215 - Server Port
34.22 - Processor temperature
I only need to get this output in console
I would be really thankfull for any kind of help or hints about this problem.
Thank you in advance,
You can use regex group for this purpose and get each part with index. also you can Assign name to each group and then select each part you want with name.
import java.util.regex.Pattern
fun main() {
val request = "AL:OK:XX:XX:XX:XX:XX:YY~~TYPE:3~~FOF:v1.0~~RSSI:-68~~PORT:8215~~TEMP:34.22" +
"~~CH1:OK~~CH2:KS~~CH3:PR~~CH4:VL~~CH5:KS~~CH6:OK" +
"~~AUX1:OK~~AUX2:KS~~AUX3:OK"
extractValues(request)
}
fun extractValues(request: String) {
val patternWithName = "AL:OK:(?<macAddress>.+)~~TYPE:(?<type>\\d+)~~FOF:(?<fof>v\\d+.\\d+)~~RSSI:(?<rssi>[-+]\\d+)~~PORT:(?<port>\\d+)~~TEMP:(?<temp>\\d+.\\d+)" +
"~~CH1:(?<ch1>.+)~~CH2:(?<ch2>.+)~~CH3:(?<ch3>.+)~~CH4:(?<ch4>.+)~~CH5:(?<ch5>.+)~~CH6:(?<ch6>.+)" +
"~~AUX1:(?<aux1>.+)~~AUX2:(?<aux2>.+)~~AUX3:(?<aux3>.+)"
val patternWithoutName = "AL:OK:(.+)~~TYPE:(\\d+)~~FOF:(v\\d+.\\d+)~~RSSI:([-+]\\d+)~~PORT:(\\d+)~~TEMP:(\\d+.\\d+)" +
"~~CH1:(.+)~~CH2:(.+)~~CH3:(.+)~~CH4:(.+)~~CH5:(.+)~~CH6:(.+)" +
"~~AUX1:(.+)~~AUX2:(.+)~~AUX3:(.+)"
val matcher = Pattern.compile(patternWithoutName).matcher(request)
if (matcher.find()) {
// get with their name --> use [patternWithName]
// val macAddress = matcher.group("macAddress")
// val type = matcher.group("type")
// val fof = matcher.group("fof")
// or
// get with index -- use [patternWithName] or [patternWithoutName]
for (i in 1..matcher.groupCount()) {
println(matcher.group(i))
}
} else {
error("$request doesn't match.")
}
}
I am trying to send images to .net core server with retrofit. There is no problem sending a single image with Multipartbody.Part. okay. But I try List or Array , the image array doesn't go to the server.
I've been trying for days, but I can't reach a conclusion, please help me.
.NetCore API
public IActionResult AddPost([FromForm]string title, [FromForm]string description, [FromForm]string[] steps, [FromForm]string[] ingredients, [FromForm]IFormFile[] photos)
{}
Debug note;
title: okey, data exist.
description: okey, data exist.
steps: okey, data exist.
ingredients: okey, data exist.
**photos: COUNT:0, DATA NOT EXIST.*****************
Retrofit method;
#Multipart
#POST("Post/addpost")
fun sendPost(#Part ("title") title: String,
#Part ("description") description: String,
#Part ("steps") steps: Array<String>,
#Part ("ingredients") ingredients: Array<String>,
#Part photos: Array<MultipartBody.Part> ): Call<String>
Use of Method;
viewModel.sendPost(
title = postTitle.text.toString(),
description = postDescription.text.toString(),
steps = steps,
ingredients = ingredients,
photos = photos
)
this method create Array
val photos = Array<MultipartBody.Part>(mediaList.size){MultipartBody.Part.createFormData("", "")}
mediaList.forEachIndexed { index, part ->
photos[index] = part
}
getPostMedia() Method
private fun getPostMedia(): MutableList<MultipartBody.Part> {
var postList = mutableListOf<MultipartBody.Part>()
PostList.instance!!.forEachIndexed { index, post ->
if (!post.isAddPost) {
postList.add(prepareFilePart("post[$index]", post.postUri))
}
}
return postList
}
I solved the problem *
Solution, in getPostMedia() method.
postList.add(prepareFilePart("photos", post.postUri))
I'm quite new to Spring MVC, and I'm having problems getting a simple entity update to work.
My data class looks like this...
#Entity
#Table(uniqueConstraints=[UniqueConstraint(columnNames=["name_search"])])
data class ArticleType(
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val name : String = "",
val order: Int? = null,
var name_search : String = ""
)
The repository looks like so...
interface ArticleTypeRepository : JpaRepository<ArticleType, Long> {
fun findFirstById(id: Long) : ArticleType?
fun findAllByOrderByOrderAsc(): List<ArticleType>
fun findByName(name: String): ArticleType?
}
I'm trying to update the name_search column like so...
val article_type:ArticleType? = articleTypeRepository.findFirstById(1234)
if (article_type !== null) {
article_type.name_search = "abc"
articleTypeRepository.save(article_type)
}
This results in the following error...
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'order=99 where id=1234' at line 1
I'm assuming this means the binding isn't working correctly, and it's missing the "name_search" binding, or missing the quotes or something. I've turned on logging, and I can see the following...
org.hibernate.SQL : update article_type set name=?, name_search=?, order=? where id=?
Then it lists the binding parameters "o.h.type.descriptor.sql.BasicBinder", which all appear to be correct.
I'm not sure what's going wrong, or where I need to start to try to fix it.
This is a legacy system I've inherited, and I don't fully understand it. If there is some extra information I need to provide here, please let me know.
Background:
I have attempted to accomplish the question defined here, and I have not been able to succeed. Acolyte requires you to define the queries and parameters you want to handle within a match expression, and the values used in match expressions must be known at compile time. (Note, however, that this StackOverflow answer appears to provide a way around this limitation).
If this is indeed not possible, the inability to dynamically define the parameters and queries for Acolyte would be, for my use case, a severe limitation of the framework. I suspect this would be a limitation for others as well.
One SO user who has advocated for the use of Acolyte across a handful of questions stated in this comment that it is possible to dynamically define queries and their responses. So, I have opened this question as an invitation for someone to show that to be the case.
Question:
Using Acolyte, I want to be able to encapsulate the logic for matching queries and generating their responses. This is a desired feature because I want to keep my code DRY. In other words, I am looking for something like the following pseudo-code:
def generateHandler(query: String, accountId: Int, parameters: Seq[String]): ScalaCompositeHandler = AcolyteDSL.handleQuery {
parameters.foreach(p =>
// Tell the handler to handle this specific parameter
case acolyte.jdbc.QueryExecution(query, ExecutedParameter(accountId) :: ExecutedParameter(p) :: Nil) =>
someResultFunction(p)
)
}
Is this possible in Acolyte? If so, please provide an example.
It is indeed possible to parameterize queries and/or parameters by utilizing pattern matching.
See the code below for an example:
import java.sql.DriverManager
import acolyte.jdbc._
import acolyte.jdbc.Implicits._
import org.scalatest.FunSpec
class AcolyteTest extends FunSpec {
describe("Using pattern matching to extract a query parameter") {
it("should extract the parameter and make it usable for dynamic result returning") {
val query = "SELECT someresult FROM someDB WHERE id = ?"
val rows = RowLists.rowList1(classOf[String] -> "someresult")
val handlerName = "testOneHandler"
val handler = AcolyteDSL.handleQuery {
case acolyte.jdbc.QueryExecution(`query`, ExecutedParameter(id) :: _) =>
rows.append(id.toString)
}
Driver.register(handlerName, handler)
val connection = DriverManager.getConnection(s"jdbc:acolyte:anything-you-want?handler=$handlerName")
val preparedStatement = connection.prepareStatement(query)
preparedStatement.setString(1, "hello world")
val resultSet = preparedStatement.executeQuery()
resultSet.next()
assertResult(resultSet.getString(1))("hello world")
}
it("should support a slightly more complex example") {
val firstResult = "The first result"
val secondResult = "The second result"
val query = "SELECT someresult FROM someDB WHERE id = ?"
val rows = RowLists.rowList1(classOf[String] -> "someresult")
val results: Map[String, RowList1.Impl[String]] = Map(
"one" -> rows.append(firstResult),
"two" -> rows.append(secondResult)
)
def getResult(parameter: String): QueryResult = {
results.get(parameter) match {
case Some(row) => row.asResult()
case _ => acolyte.jdbc.QueryResult.Nil
}
}
val handlerName = "testTwoHandler"
val handler = AcolyteDSL.handleQuery {
case acolyte.jdbc.QueryExecution(`query`, ExecutedParameter(id) :: _) =>
getResult(id.toString)
}
Driver.register(handlerName, handler)
val connection = DriverManager.getConnection(s"jdbc:acolyte:anything-you-want?handler=$handlerName")
val preparedStatement = connection.prepareStatement(query)
preparedStatement.setString(1, "one")
val resultSetOne = preparedStatement.executeQuery()
resultSetOne.next()
assertResult(resultSetOne.getString(1))(firstResult)
preparedStatement.setString(1, "two")
val resultSetTwo = preparedStatement.executeQuery()
resultSetTwo.next()
assertResult(resultSetTwo.getString(1))(secondResult)
}
}
}