Coder Social home page Coder Social logo

scalikejdbc-async's Introduction

ScalikeJDBC-Async

ScalikeJDBC Extension: Non-blocking APIs in the JDBC way

ScalikeJDBC-Async provides non-blocking APIs to talk with PostgreSQL and MySQL in the JDBC way.

This library is built with jasync-sql.

ScalikeJDBC Logo

ScalikeJDBC:

https://github.com/scalikejdbc/scalikejdbc

ScalikeJDBC is a tidy SQL-based DB access library for Scala developers. This library naturally wraps JDBC APIs and provides you easy-to-use APIs.

Important Notice

ScalikeJDBC-Async is still in the beta stage. If you don't have motivation to investigate or fix issues by yourself, we recommend you waiting until stable version release someday.

Supported RDBMS

  • PostgreSQL
  • MySQL

Dependencies

Add scalikejdbc-async to your dependencies.

libraryDependencies ++= Seq(
  "org.scalikejdbc"       %% "scalikejdbc-async" % "0.19.+",
  "com.github.jasync-sql" %  "jasync-postgresql" % "2.2.+", // Add this if you go with PostgreSQL
  "com.github.jasync-sql" %  "jasync-mysql"      % "2.2.+", // Add this if you go with MySQL / MariaDB
  "org.slf4j"             %  "slf4j-simple"      % "1.7.+" // Add you preferred slf4j implementation
)

Example

import scalikejdbc._, async._
import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

// set up connection pool (that's all you need to do)
AsyncConnectionPool.singleton("jdbc:postgresql://localhost:5432/scalikejdbc", "sa", "sa")

// create a new record within a transaction
val created: Future[Company] = AsyncDB.localTx { implicit tx =>
  for {
    company <- Company.create("ScalikeJDBC, Inc.", Some("https://scalikejdbc.org/"))
    seratch <- Programmer.create("seratch", Some(company.id))
    gakuzzzz <- Programmer.create("gakuzzzz", Some(company.id))
    xuwei_k <- Programmer.create("xuwei-k", Some(company.id))
  } yield company
}

Await.result(created, 5.seconds)

created.foreach { (newCompany: Company) =>

  // delete a record and rollback
  val withinTx: Future[Unit] = AsyncDB.localTx { implicit tx =>
    for {
      restructuring <- Programmer.findAllBy(sqls.eq(p.companyId, newCompany.id)).map { 
        programmers => programmers.foreach(_.destroy()) 
      }
      dissolution <- newCompany.destroy()
      failure <- sql"Just joking!".update.future
    } yield ()
  }

  try Await.result(withinTx, 5.seconds)
  catch { case e: Exception => log.debug(e.getMessage, e) }

  // rollback expected
  val company = AsyncDB.withPool { implicit s =>
    Company.find(newCompany.id)
  }
  Await.result(company, 5.seconds)
  val found: Option[Company]= company.value.get.get
  found.isDefined should be(true)
}

Transactional queries should be executed in series. You cannot use Future.traverse or Future.sequence.

FAQ

Is it production-ready?

ScalikeJDBC-Async and jasync-sql basically works fine. However, to be honest, ScalikeJBDC-Async doesn't have much of a record of production applications.

Is it possible to combine scalikejdbc-async with normal scalikejdbc?

Yes, it's possible. See this example.

Why isn't it a part of scalikejdbc project now?

This library is still in alpha stage. If this library becomes stable enough, it will be merged into the ScalikeJDBC project.

How to contribute?

Before sending pull requests, please install docker and run sbt +test

License

Published binary files have the following copyright:

Copyright scalikejdbc.org

Apache License, Version 2.0

http://www.apache.org/licenses/LICENSE-2.0.html

scalikejdbc-async's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scalikejdbc-async's Issues

AsyncConnectionPool settings improvement

https://groups.google.com/forum/#!topic/scalikejdbc-users-group/hm8LZNSLfnA

Hello,

I'm using an RDS as a db that has a certain connections number. I've thus set in the config the "db.default.poolMaxSize=X" where X is aproximately equal to the total number of connections supported by the RDS.

The issue is I have a bunch of queries Y > X running in parallel and I get errors: "com.github.mauricio.async.db.pool.PoolExhaustedException: There are no objects available and the waitQueue is full"

I can see that Mauricio's mysql-async library supports a "maxQueueSize" parameter that allows to enqueue requests if the pool is full. So, eventually, all queries would be executed. Of course, if they stay enqueued for too long the "maxIdle" argument should close them (am I right?).

Nevertheless, the scalikejdbc-async uses the "db.default.poolMaxSize" to define the maximum number of connections in a pool and the total queue size. That is, if you have more connections than the pool supports, all of them will be rejected. Is there any reason for this?

Let's say the RDS supports 34 connections in parallel. I would have "poolMaxSize" equal to 33 but a sufficiently big queue: 99 requests. A reasonable timeout of 2 seconds would be used for API reliability.

Is the "reject all connections that don't fit in current pool" better than what I've given as an example? If no, can you add the possibility to mention in config the total number of objects in a queue?

Kind regards,

-- Marius

NPE with ScalikeJDBC 1.6.11 - 1.7.0

Since ScalikeJDBC's WrappedResultSet has been changed internally in 1.6.11, ScalikeJDBC-Async's AsyncResultSet#long(Int) and so on throw NPE when working with it.

Package update for compatibility

Looking at the master-branch, I can see that there are quite a few dependency updates flowing in: jasync-sql has been updated to 2.0.2 and scala-java8-compat has been updated to 1.0.1

[error] this can be overridden using libraryDependencySchemes or evictionErrorLevel
[error] (mqtt / ssExtractDependencies) found version conflict(s) in library dependencies; some are suspected to be binary incompatible:
[error] 
[error] 	* org.scala-lang.modules:scala-java8-compat_2.13:1.0.0 (early-semver) is selected over 0.9.1
[error] 	    +- com.typesafe.akka:akka-actor_2.13:2.6.17           (depends on 1.0.0)
[error] 	    +- org.scalikejdbc:scalikejdbc-async_2.13:0.14.0      (depends on 0.9.1)

For compatibility with akka-actor and similar libraries, I think it would be really great if you could publish a new release to Maven so that this library remains compatible with other major packages.

Support for setting isolation level for DB/DBConnection

Would it be interesting to implement a special pass-through parameter to set an isolation level for a transaction? Right now, it's possible to set an isolation level in scalikejdbc, but scalikejdbc-async misses this feature.

I haven't given much thought about the impact of this in an async setting, so please tell me if there are any unforeseen issues with such an addition.

Background details

Versions clash of com.github.mauricio.* jars causes test failure on Travis CI

Hello,

I believe, the last build on Travis CI failed because, for some reason, several versions of com.github.mauricio:db-async-common, com.github.mauricio:mysql-async and com.github.mauricio:postgresql-async were used during build and test phases: you can find output from sbt about loading versions 0.2.17 and 0.2.18 in log of scala 2.10 build; 0.2.16 and 0.2.18 for scala 2.11 build.

Now, I'm really new with sbt, so I don't necessary have enough knowledge to investigate why it loads several versions of the same dependency. But I've tried to use different version pattern to make 0.2.18 a minimal acceptable version from currently specified range 0.2.+, and it works. So this is at least one way to fix the build.

updateAndReturnGeneratedKey doesn't work on postgress

updateAndReturnGeneratedKey doesn't work on postgress when using sql interpolation.
It doesn't have the option to add returningId (like you do when using SQLSyntaxSupport).
Had to add it manually to the statement

Lots of error logging when running tests

Tests are passed.

[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_1" does not exist, skipping, Severity -> NOTICE))
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_1" does not exist, skipping, Severity -> NOTICE))
[error] c.g.m.a.d.p.PostgreSQLConnection:1 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:2 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:3 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:4 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_2" does not exist, skipping, Severity -> NOTICE))
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_2" does not exist, skipping, Severity -> NOTICE))
[error] c.g.m.a.d.p.PostgreSQLConnection:5 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:6 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:7 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:8 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:10 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:9 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_3" does not exist, skipping, Severity -> NOTICE))
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_3" does not exist, skipping, Severity -> NOTICE))
[error] c.g.m.a.d.p.PostgreSQLConnection:11 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:12 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:14 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:13 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:15 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:16 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:17 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:18 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:19 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:20 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:21 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:22 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_4" does not exist, skipping, Severity -> NOTICE))
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Received notice NoticeMessage(fields=Map(Line -> 705, File -> tablecmds.c, SQLSTATE -> 00000, Routine -> DropErrorMsgNonExistent, Message -> table "user_4" does not exist, skipping, Severity -> NOTICE))
[error] c.g.m.a.d.p.PostgreSQLConnection:23 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:24 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:25 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:26 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:27 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:28 - Trying to give back a connection that is not ready for query
[info] c.g.m.a.d.p.c.PostgreSQLConnectionHandler - Connection disconnected - localhost/127.0.0.1:5432
[error] c.g.m.a.d.p.PostgreSQLConnection:29 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:30 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:31 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:32 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:33 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:34 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:35 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:36 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:37 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:38 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:39 - Trying to give back a connection that is not ready for query
[error] c.g.m.a.d.p.PostgreSQLConnection:40 - Trying to give back a connection that is not ready for query

Compatibility jasync-sql 2.1.9+

With the later updates of jasync-sql, there was a bug that could be triggered by changing the settings using scalikejdbc-async 0.16.0. I made an issue related to this, but it also means that you'll have to look at the changes to keep your project compatible:

jasync-sql/jasync-sql#359

sqlsyntax definer bug

val codinatorSQL = sqls.eq(cod.createdDate, DateTime.now().toString("yyyy-MM-dd"))

Im generating a sqlsyntax and pass over error show Retriving Group Failed.com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'created_date' in where clause is ambiguous

But if i use it direct at model
.eq(cod.createdDate, DateTime.now().toString("yyyy-MM-dd"))
.append(sqls"${where}")

cod.createdDate are working fine with definer cod.*

Testing without "external" database

Hi,
thank you very much for this project!
In the environment I would like to use scalalikejdbc-async I cant rely on a running "external" MySQL database for the tests. Is it somehow possible to use an h2 in memory database for this purpose?

Using "jdbc:h2:mem" while adding a connection to the pool leads to an "java.lang.UnsupportedOperationException: This RDBMS is not supported yet.". Is an in memory database no option for testing purposes? Is there maybe another way to run unit tests without an external database?

Message: Error 1059 - #42000 - Identifier name too long

I was using scalikejdbc-sync and now i want to use

scalikejdbc-async.

I have added

      "org.scalikejdbc"       %% "scalikejdbc-async" % "0.14.+",
      "com.github.jasync-sql" %  "jasync-mysql"      % "1.1.+"

to my dependencies

I am trying to setup a connection pool using

     val ds: HikariDataSource = {

  // read from config file 
   }

  AsyncConnectionPool.singleton(ds.getJdbcUrl, ds.getUsername, ds.getPassword)

        val query = SQLSyntax.createUnsafely(filteredQuery)
        val result = AsyncDB.localTx { implicit tx =>
        sql"$query"
              .map(rs => rs.long(1))
       .single()
       .future()
   }

but I get

Message: Error 1059 - #42000 - Identifier name is too long
The is nothing but my JDBC URL.
Is this a bug in the library ?

Wait Queue is full

After querying the database for the 9th time, the com.github.jasync.sql.db.pool.PoolExhaustedException occurs.
I tryed the jasync libary directly and it seemed to work fine.
My find function looks as follows:

  def find(id: Long)(implicit session: AsyncDBSession = AsyncDB.sharedSession, cxt: EC = ECGlobal): Future[Option[Duck]] =
    withSQL {
      select.from(Duck as duck).where.eq(duck.id, id)
    }.map(Duck(duck))

Invoking my create method does not yield this behavior.

  def create(entity: Duck)(implicit session: AsyncDBSession = AsyncDB.sharedSession, cxt: EC = ECGlobal): Future[Duck] =
    for {
      id <- withSQL {
        insert.into(Duck).namedValues(
          column.name -> entity.name,
          column.column("slot_id") -> entity.slot.map(_.id)
        ).returningId
      }.updateAndReturnGeneratedKey
    } yield Duck(Some(id), now, now, entity.name, entity.slot)
java.util.concurrent.ExecutionException: com.github.jasync.sql.db.pool.PoolExhaustedException: There are no objects available and the waitQueue is full
	at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2093)
	at scalikejdbc.async.internal.PoolableAsyncConnection.underlying$lzycompute(PoolableAsyncConnection.scala:40)
	at scalikejdbc.async.internal.PoolableAsyncConnection.underlying(PoolableAsyncConnection.scala:40)
	at scalikejdbc.async.internal.AsyncConnectionCommonImpl.sendPreparedStatement(AsyncConnectionCommonImpl.scala:55)
	at scalikejdbc.async.internal.AsyncConnectionCommonImpl.sendPreparedStatement$(AsyncConnectionCommonImpl.scala:51)
	at scalikejdbc.async.internal.PoolableAsyncConnection.sendPreparedStatement(PoolableAsyncConnection.scala:33)
	at scalikejdbc.async.AsyncDBSession.iterable(AsyncDBSession.scala:95)
	at scalikejdbc.async.AsyncDBSession.iterable$(AsyncDBSession.scala:91)
	at scalikejdbc.async.SharedAsyncDBSession.iterable(AsyncDBSession.scala:222)
	at scalikejdbc.async.AsyncDBSession.single(AsyncDBSession.scala:107)
	at scalikejdbc.async.AsyncDBSession.single$(AsyncDBSession.scala:103)
	at scalikejdbc.async.SharedAsyncDBSession.single(AsyncDBSession.scala:222)
	at scalikejdbc.async.AsyncSQLToOption.future(AsyncSQLs.scala:51)
	at scalikejdbc.async.AsyncSQLToOption.future$(AsyncSQLs.scala:50)
	at scalikejdbc.async.AsyncSQLToOptionImpl.future(AsyncSQLs.scala:54)
	at scalikejdbc.async.FutureImplicits$.fromSQLToSingleFuture(FutureImplicits.scala:35)
	at data.Duck$.find(Duck.scala:46)
	at rest.duck.DuckResource.get(DuckResource.scala:32)
java.util.concurrent.TimeoutException
	at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1957)
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2092)
	at scalikejdbc.async.internal.PoolableAsyncConnection.underlying$lzycompute(PoolableAsyncConnection.scala:40)
	at scalikejdbc.async.internal.PoolableAsyncConnection.underlying(PoolableAsyncConnection.scala:40)
	at scalikejdbc.async.internal.AsyncConnectionCommonImpl.sendPreparedStatement(AsyncConnectionCommonImpl.scala:55)
	at scalikejdbc.async.internal.AsyncConnectionCommonImpl.sendPreparedStatement$(AsyncConnectionCommonImpl.scala:51)
	at scalikejdbc.async.internal.PoolableAsyncConnection.sendPreparedStatement(PoolableAsyncConnection.scala:33)
	at scalikejdbc.async.AsyncDBSession.iterable(AsyncDBSession.scala:95)
	at scalikejdbc.async.AsyncDBSession.iterable$(AsyncDBSession.scala:91)
	at scalikejdbc.async.SharedAsyncDBSession.iterable(AsyncDBSession.scala:222)
	at scalikejdbc.async.AsyncDBSession.single(AsyncDBSession.scala:107)
	at scalikejdbc.async.AsyncDBSession.single$(AsyncDBSession.scala:103)
	at scalikejdbc.async.SharedAsyncDBSession.single(AsyncDBSession.scala:222)
	at scalikejdbc.async.AsyncSQLToOption.future(AsyncSQLs.scala:51)
	at scalikejdbc.async.AsyncSQLToOption.future$(AsyncSQLs.scala:50)
	at scalikejdbc.async.AsyncSQLToOptionImpl.future(AsyncSQLs.scala:54)
	at scalikejdbc.async.FutureImplicits$.fromSQLToSingleFuture(FutureImplicits.scala:35)
	at data.Duck$.find(Duck.scala:46)
	at rest.duck.DuckResource.get(DuckResource.scala:34)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)

Programmer.create fails when creating more than 8

Using this example in ExampleSpec.scala

  it should "work for more than 8 items" in {
    val futureProgrammers8 = Future.sequence((1 to 8) map { i => Programmer.create(s"nkgm $i of 8", Some(1)) })
    val programmers8 = Await.result(futureProgrammers8, 5.seconds)
    println(programmers8) // so far so good

    val f = Programmer.create(s"new", Some(1)) // the 9th programmer
    val p = Await.result(f, 5.seconds) // this will fail after 5 seconds
  }

Editing a model in Scala-IDE is very slow

First of all thanx for this project!

I tried to port the computer database sample to scalikejdbc-async but working with eclipse (scala-ide 3.0.2-rc01) isn't really possible - I have to wait for single letters I'm typing. I'm experiencing the same when I try to edit programmerlist.Company.

I just wanted to check what's your experience, perhaps you can already hint me to a solution. Otherwise I probably should submit an issue for scala-ide.

Thanx for your feedback,
Martin

migrate to "dist: xenial"

scalikejdbc/scalikejdbc#1014

WIP 93853f4

[info] PersonSpec:
[info] parameterbinderfactory.AccountSpec *** ABORTED ***
[info]   com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Invalid default value for 'deleted_at'
[info]   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[info]   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[info]   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[info]   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[info]   at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
[info]   at com.mysql.jdbc.Util.getInstance(Util.java:408)
[info]   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
[info]   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3978)
[info]   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3914)
[info]   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
[info]   ...
[info] parameterbinderfactory.PersonSpec *** ABORTED ***
[info]   com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Invalid default value for 'deleted_at'
[info]   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[info]   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[info]   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[info]   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[info]   at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
[info]   at com.mysql.jdbc.Util.getInstance(Util.java:408)
[info]   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
[info]   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3978)
[info]   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3914)
[info]   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
[info]   ...
[info] Run completed in 3 seconds, 797 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 0, aborted 5
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0m
[info] *** 5 SUITES ABORTED ***
[error] Error during tests:
[error] 	sample.MySQLSampleSpec
[error] 	programmerlist.ExampleSpec
[error] 	sample.PostgreSQLSampleSpec
[error] 	parameterbinderfactory.AccountSpec
[error] 	parameterbinderfactory.PersonSpec
[error] (core / Test / test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 59 s, completed Jun 14, 2019 4:23:24 AM

ParameterBinderFactory not fully supported in where clause

I have the following statement in sync scalikejdbc:

DB readOnly { implicit session =>
        withSQL {
          select
            .from(personMapping as person)
            .where.eq(person.id, id)
        }.map(personMapping(person)).single.apply

where id is an instance of a case class PersonId with a ParameterBinderFactory created based on Binder.long:

case class PersonId(id: Long)
implicit val personIdParameterBinderFactory: Binders[PersonId] = Binders.long.xmap(PersonId.apply, _.id)

When I now create the same query with the async driver:

withSQL {
          select
            .from(personMapping as person)
            .where.eq(person.id, id)
        }.map(personMapping(person)).single.future

I get the following MySql Error where the statement got executed:

Caused by: scala.MatchError: PersonId(40000) (of class ch.openolitor.core.models.PersonId)
    at com.github.mauricio.async.db.mysql.binary.BinaryRowEncoder.encoderFor(BinaryRowEncoder.scala:70) ~[mysql-async_2.11-0.2.19.jar:0.2.19]
    at com.github.mauricio.async.db.mysql.encoder.PreparedStatementExecuteEncoder.encodeValue(PreparedStatementExecuteEncoder.scala:78) ~[mysql-async_2.11-0.2.19.jar:0.2.19]
    at com.github.mauricio.async.db.mysql.encoder.PreparedStatementExecuteEncoder.encodeValues(PreparedStatementExecuteEncoder.scala:61) ~[mysql-async_2.11-0.2.19.jar:0.2.19]
    at com.github.mauricio.async.db.mysql.encoder.PreparedStatementExecuteEncoder.encode(PreparedStatementExecuteEncoder.scala:39) ~[mysql-async_2.11-0.2.19.jar:0.2.19]
    at com.github.mauricio.async.db.mysql.codec.MySQLOneToOneEncoder.encode(MySQLOneToOneEncoder.scala:75) ~[mysql-async_2.11-0.2.19.jar:0.2.19]
    at com.github.mauricio.async.db.mysql.codec.MySQLOneToOneEncoder.encode(MySQLOneToOneEncoder.scala:35) ~[mysql-async_2.11-0.2.19.jar:0.2.19]

I tried to track down this error but couldn't find the code lines where the convertion through the ParameterBinderFactory wasn't called as expected.

Database does not exist error due to bad JDBCUrl parsing

I am using AsyncConnectionPool.singleton(url, user, pass) to setup the connection where url is jdbc:postgresql://localhost:64161/test?loggerLevel=OFF but I get the following error

com.github.jasync.sql.db.postgresql.exceptions.GenericDatabaseException: ErrorMessage(fields=[(Severity, FATAL), (V, FATAL), (SQLSTATE, 3D000), (Message, database "test?loggerLevel=OFF" does not exist), (File, postinit.c), (Line, 841), (Routine, InitPostgres)]

The problem is that scalikejdbc.JDBCUrl.apply does not correctly parse the querystring part, and uses returns test?loggerLevel=OFF as the database name.

The workaround is to just use jdbc:postgresql://localhost:64161/test as the url

Error: database name is too long

I'm using scalikejdbc-async with Play 2.1.3. I've added to play.plugins the line 888:scalikejdbc.async.PlayPlugin and to Build.scala those three lines

"com.github.seratch"  %% "scalikejdbc-async"             % "[0.2,)",
"com.github.seratch"  %% "scalikejdbc-async-play-plugin" % "[0.2,)",
"com.github.mauricio" %% "mysql-async"                   % "[0.2,)",

A query example is:

    def readAll(implicit session: AsyncDBSession = AsyncDB.sharedSession, cxt: EC = ECGlobal): Future[Seq[Country]] = {
        sql"select id, name from country order by id".map(*).list.future
    }

The issue is that I'm getting the following error at runtime: https://gist.github.com/Marius-Stroe/c751b0c57d199cb79daf

Any help is appreciated!

Support additional jasync configuration parameters

First of all, thank you for this library. I have a suggestion for supporting additional jasync config parameters.

Maybe AsyncConnectionSettings.scala can be updated like so:

case class AsyncConnectionPoolSettings(
    maxPoolSize: Int = 8,
    maxQueueSize: Int = 8,
    maxIdleMillis: Long = 1000L,

    // these 5 parameters are new
    validationInterval: Long = 5000L,
    createTimeout: Long = 5000L,
    testTimeout: Long = 5000L,
    queryTimeout: Option[Long] = None,
    maxObjectTtl: Option[Long] = None,

    connectionSettings: AsyncConnectionSettings = AsyncConnectionSettings()
)

 case class AsyncConnectionSettings(
    ssl: Option[SSLConfiguration] = None,
    charset: Option[Charset] = None,
    maximumMessageSize: Option[Int] = None,
    allocator: Option[ByteBufAllocator] = None,
    connectTimeout: Option[Duration] = None,

    // testTimeout seems out of place and
    // probably belongs in the poolsettings
    testTimeout: Option[Duration] = None,

    queryTimeout: Option[Duration] = None
)

And the following lines can be added to AsyncConnectionPoolCommonImpl.scala like so:

  builder.setConnectionValidationInterval(settings.validationInterval)
  builder.setConnectionCreateTimeout(settings.createTimeout)
  builder.setConnectionTestTimeout(settings.testTimeout)
  settings.queryTimeout match {
    case Some(timeout) =>
      builder.setQueryTimeout(timeout)
    case None =>
      builder.setQueryTimeout(null)
  }
  settings.maxObjectTtl match {
    case Some(ttl) =>
      builder.setMaxConnectionTtl(ttl)
    case None =>
      builder.setMaxConnectionTtl(null)
  }

Error inserting emoji into the database

I am sorry, my English is not good, I use Google Translate to write this issue.
I want to insert emoji into the mysql database, but he failed.

Exception in thread "main" com.github.mauricio.async.db.mysql.exceptions.MySQLException: Error 1366 - #HY000 - Incorrect string value: '\xF0\x9F\x98\x80 1...' for column 'uuid' at row 1
	at com.github.mauricio.async.db.mysql.MySQLConnection.onError(MySQLConnection.scala:126)
	at com.github.mauricio.async.db.mysql.codec.MySQLConnectionHandler.channelRead0(MySQLConnectionHandler.scala:107)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
	at java.lang.Thread.run(Thread.java:748)

build.sbt

libraryDependencies ++= Seq(
  "org.scalikejdbc" %% "scalikejdbc" % "3.2.4",
  "org.scalikejdbc" %% "scalikejdbc-async" % "0.8.2",
  "com.github.mauricio" %% "mysql-async" % "0.2.21",
  "mysql" % "mysql-connector-java" % "8.0.12"
)

According to the online tutorial, I changed the character encoding of the MySQL database, table and field toutf8mb4.And upgraded mysql-connector-java to 8.0.12,But still failed。

Then I tried to update with sql in navicat, and it succeeded.

update token set uuid = '😀 123', country_code = 'CN', language_code = 'en'  where  token = 'XXXX'

Below is my scala code configuration:

    val acs = AsyncConnectionSettings(
      ssl = Some(SSLConfiguration(SSLConfiguration.Mode.Require)),
      charset = Option(StandardCharsets.UTF_8)
    )
    val acps = AsyncConnectionPoolSettings(connectionSettings = acs)
    AsyncConnectionPool.add('mysql, url, user, pwd, acps)

this is mysql charset configuration:

character_set_client	utf8mb4
character_set_connection	utf8mb4
character_set_database	utf8mb4
character_set_filesystem	binary
character_set_results	utf8mb4
character_set_server	utf8mb4
character_set_system	utf8
character_sets_dir	C:\Program Files\MySQL\MySQL Server 8.0\share\charsets\

I want to know what is causing me to be unable to insert emoji, thank you very much !

Cannot port computer database sample - NoSuchElementException: key not found: i1_on_computer

I want to port the computer database sample, but while compilation works, at runtime it fails with

While compilation works, the request for http://localhost:9000/computers
fails with

[NoSuchElementException: key not found: i1_on_computer]
In /home/magro/proj/play-coda-reactive/app/models/Models.scala at line 33.
30
31  def apply(c: SyntaxProvider[Computer])(rs: WrappedResultSet): Computer = apply(c.resultName)(rs)
32  def apply(c: ResultName[Computer])(rs: WrappedResultSet): Computer = new Computer(
33    id = rs.longOpt(c.id),
34    name = rs.string(c.name), 
35    introduced = rs.dateOpt(c.introduced),
36    discontinued = rs.dateOpt(c.discontinued),
37    companyId = rs.longOpt(c.companyId)
38  )

Can you help be to resolve this issue?

You can check out the project at https://github.com/magro/play-coda-reactive in branch scalikejdbc-async, this is the direct link to the code that's failing: Model.scala.

The stack trace on the console is

play.api.Application$$anon$1: Execution exception[[NoSuchElementException: key not found: i1_on_computer]]
        at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.1]
        at play.api.DefaultApplication.handleError(Application.scala:383) ~[play_2.10.jar:2.1.1]
        at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:144) ~[play_2.10.jar:2.1.1]
        at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:140) ~[play_2.10.jar:2.1.1]
        at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) ~[play_2.10.jar:2.1.1]
        at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) ~[play_2.10.jar:2.1.1]
java.util.NoSuchElementException: key not found: i1_on_computer
        at scala.collection.MapLike$class.default(MapLike.scala:228) ~[scala-library.jar:na]
        at scala.collection.AbstractMap.default(Map.scala:58) ~[scala-library.jar:na]
        at scala.collection.MapLike$class.apply(MapLike.scala:141) ~[scala-library.jar:na]
        at scala.collection.AbstractMap.apply(Map.scala:58) ~[scala-library.jar:na]
        at com.github.mauricio.async.db.general.ArrayRowData.apply(ArrayRowData.scala:44) ~[db-async-common_2.10-0.2.7.jar:0.2.7]
        at scalikejdbc.async.internal.AsyncResultSetImpl$$anonfun$any$2.apply(AsyncResultSetImpl.scala:42) ~[scalikejdbc-async_2.10-0.2.5.jar:0.2.5]

Connection pool is not yet initialized

Hi, thank you very much for this project.
I've faced the issue with SQLSyntaxSupport. When I use it I get Connection pool is not yet initialized error. When I use plain sql everything works fine. I took a look at the code and found direct calls to scalikejdbc.ConnectionPool instead of AsyncConnectionPool. What do I do wrong?

Can't compile core/programmerlist project

main sbt makefile does not compile core/programmerlist (but it does compile play-sample/app)
switching to core and invoking sbt compile gives error:
error: not found: value scalariformSettings
scalariformSettings
^
[error] Type error in expression

AsyncDBSession.queryLogging does not log query duration

AsyncDBSession does queryLogging upfront and does not include query duration like StatementExecutor does. It looks like a wrong implementation. Or is there a specific reason to it?
queryLogging does use loggingSQLAndTime.enabled to determine if it needs to log but does not log time/duration.

tests fail on jdk 8u292 or later

https://github.com/scalikejdbc/scalikejdbc-async/runs/2531693706?check_suite_focus=true#step:5:186

he last packet successfully received from the server was 1 milliseconds ago.  The last packet sent successfully to the server was 1 milliseconds ago.
[info]   at sun.reflect.GeneratedConstructorAccessor34.newInstance(Unknown Source)
[info]   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[info]   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[info]   at com.mysql.jdbc.Util.handleNewInstance(Util.java:403)
[info]   at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
[info]   at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:202)
[info]   at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4869)
[info]   at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1656)
[info]   at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1217)
[info]   at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2189)
[info]   ...
[info]   Cause: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
[info]   at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
[info]   at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:98)
[info]   at sun.security.ssl.TransportContext.kickstart(TransportContext.java:220)
[info]   at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:428)
[info]   at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:187)
[info]   at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4869)
[info]   at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1656)
[info]   at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1217)
[info]   at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2189)
[info]   at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2220)

"Async" AutoRollback

Hi,

First, thanks for this early integration of async drivers.

I'm trying to test my model with specs2 and I don't find a way to make an auto rollback trait.

Can you help me?

Patterns for LISTEN/NOTIFY

Are there any examples available for how to make use of the underlying support for Postgres LISTEN/NOTIFY in postgresql-async? I've tried getting access to the session connection within a withPool block, but it seems to expose a different API than the underlying driver.

Even if no docs are available, I wouldn't mind digging around the source for more clues if you could show me where to look.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.