Getting the following error:
error[E0277]: the trait bound `Data<DatabaseConnection>: ConnectionTrait` is not satisfied
--> src/main.rs:27:34
|
27 | let q = Articles::find().all(&data).await;
| --- ^^^^^ the trait `ConnectionTrait` is not implemented for `Data<DatabaseConnection>`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `ConnectionTrait`:
DatabaseConnection
DatabaseTransaction
note: required by a bound in `sea_orm::executor::select::<impl sea_orm::Select<E>>::all`
--> /Users//.cargo/registry/src/git/sea-orm-0.10.6/src/executor/select.rs:267:12
|
267 | C: ConnectionTrait,
| ^^^^^^^^^^^^^^^ required by this bound in `sea_orm::executor::select::<impl sea_orm::Select<E>>::all`
main.rs:
async fn test(data: web::Data<DatabaseConnection>) -> HttpResponse {
dbg!(&data);
let q = Articles::find().all(&data).await;
HttpResponse::Ok().json("test")
}
async fn get_connection() -> DatabaseConnection {
Database::connect("postgres://...")
.await
.expect("Failed to connect to database!")
}
#[actix_web::main]
async fn main() -> Result<()> {
let db = get_connection().await;
HttpServer::new(move || {
App::new()
.service(web::resource("/").route(web::get().to(test)))
.app_data(web::Data::new(db.clone()))
})
.bind(("127.0.0.1", 8888))?
.run()
.await?;
Ok(())
}
Related
I am doing type class derivation in Scala3.
My typeclass is BarOf[T] extending Bar. T is expected to be an ADT.
Bar has a children method returning the BarOf[X] of the children types of T.
Here the derived method is based on Quotes rather than on Mirrors. This is needed for the rest of my code, which has been removed here.
The essential step to find out the BarOf[X] (for each of the X children types) is based on a quoted type match. (Full code at the end of the post)
A.memberType(childSymbol).asType match {
case '[f] => Expr.summon[BarOf[f]]
}
This works fine for product types and particularly case classes.
But, when applying to sum types, the compiler fires an assertion :
assertion failure for class C1 <:< f, frozen = false
6 |sealed class Foo1 derives BarOf
| ^
|Exception occurred while executing macro expansion.
|java.lang.AssertionError: assertion failed: ClassInfo(ThisType(TypeRef(NoPrefix,module class <empty>)), class C0, List(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class Foo)))
| at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
| at dotty.tools.dotc.core.Types$TypeBounds.<init>(Types.scala:4918)
| at dotty.tools.dotc.core.Types$RealTypeBounds.<init>(Types.scala:4994)
| at dotty.tools.dotc.core.Types$TypeBounds$.apply(Types.scala:5038)
| at dotty.tools.dotc.core.Types$TypeBounds.derivedTypeBounds(Types.scala:4926)
| at dotty.tools.dotc.core.ConstraintHandling.addOneBound(ConstraintHandling.scala:116)
| at dotty.tools.dotc.core.ConstraintHandling.addOneBound$(ConstraintHandling.scala:27)
| at dotty.tools.dotc.core.ProperGadtConstraint.addOneBound(GadtConstraint.scala:60)
| at dotty.tools.dotc.core.ConstraintHandling.addBoundTransitively(ConstraintHandling.scala:170)
| at dotty.tools.dotc.core.ConstraintHandling.addBoundTransitively$(ConstraintHandling.scala:27)
| at dotty.tools.dotc.core.ProperGadtConstraint.addBoundTransitively(GadtConstraint.scala:60)
| at dotty.tools.dotc.core.ProperGadtConstraint.addBound(GadtConstraint.scala:159)
| at dotty.tools.dotc.core.TypeComparer.gadtAddLowerBound(TypeComparer.scala:118)
| at dotty.tools.dotc.core.TypeComparer.narrowGADTBounds(TypeComparer.scala:1913)
| at dotty.tools.dotc.core.TypeComparer.compareGADT$1(TypeComparer.scala:521)
| at dotty.tools.dotc.core.TypeComparer.thirdTryNamed$1(TypeComparer.scala:524)
| at dotty.tools.dotc.core.TypeComparer.thirdTry$1(TypeComparer.scala:573)
| at dotty.tools.dotc.core.TypeComparer.secondTry$1(TypeComparer.scala:504)
| at dotty.tools.dotc.core.TypeComparer.compareNamed$1(TypeComparer.scala:313)
| at dotty.tools.dotc.core.TypeComparer.firstTry$1(TypeComparer.scala:319)
| at dotty.tools.dotc.core.TypeComparer.recur(TypeComparer.scala:1321)
| at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:201)
| at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:211)
| at dotty.tools.dotc.core.TypeComparer.topLevelSubType(TypeComparer.scala:128)
| at dotty.tools.dotc.core.TypeComparer$.topLevelSubType(TypeComparer.scala:2729)
| at dotty.tools.dotc.core.Types$Type.$less$colon$less(Types.scala:1035)
| at scala.quoted.runtime.impl.QuoteMatcher$.$eq$qmark$eq(QuoteMatcher.scala:336)
| at scala.quoted.runtime.impl.QuoteMatcher$.treeMatch(QuoteMatcher.scala:129)
| at scala.quoted.runtime.impl.QuotesImpl.scala$quoted$runtime$impl$QuotesImpl$$treeMatch(QuotesImpl.scala:3021)
| at scala.quoted.runtime.impl.QuotesImpl$TypeMatch$.unapply(QuotesImpl.scala:2991)
| at bar.BarOf$.childExpr$1(bar.scala:21)
| at bar.BarOf$.$anonfun$6(bar.scala:26)
| at scala.collection.immutable.List.map(List.scala:246)
| at bar.BarOf$.derivedImpl(bar.scala:26)
The assertion is triggered by the quoted type match : case '[f] =>. But I cannot figure out what I am missing.
Is my code legal ?
if no : what is the alternative ?
if yes : is it compiler bug ?
Full bar package source:
package bar
import scala.quoted.*
trait Bar:
def children : List[Bar]
trait BarOf[A] extends Bar
object BarOf :
inline def derived[A]: BarOf[A] = ${derivedImpl[A]}
def derivedImpl[A:Type](using Quotes):Expr[BarOf[A]] =
import quotes.reflect._
val A = TypeRepr.of[A]
val mySymbol = A.typeSymbol
val terms = mySymbol.children
def childExpr(childSymbol:Symbol) =
A.memberType(childSymbol).asType match {
case '[f] => Expr.summon[BarOf[f]]
} getOrElse {
report.errorAndAbort(s"ChildType ${childSymbol} of ${mySymbol} does not derive BarOf")
}
val termsExpr = Expr.ofList(terms.map(childExpr))
'{ new BarOf[A]
{ def children = ${termsExpr}
}
}
Test Code:
import bar.BarOf
// works
enum Foo0 derives BarOf :
case C0
// does not work
enum Foo1 derives BarOf :
case C1(x:Int)
// does not work either :
sealed class Foo2 derives BarOf
class C2(x:Int) extends Foo2
#main def run:Unit =
val x = summon[BarOf[Foo1]]
println(x.children)
The issue was not in the type pattern matching as I thought, but on the symbol being matched.
The correct look-up is :
childSymbol.typeRef.asType match {
case '[f] => Expr.summon[BarOf[f]]
}
instead of :
A.memberType(childSymbol).asType match {
case '[f] => Expr.summon[BarOf[f]]
}
Complete Functional Code :
package bar
import scala.quoted.*
trait Bar:
def children : List[Bar]
trait BarOf[A] extends Bar
object BarOf :
inline def derived[A]: BarOf[A] = ${derivedImpl[A]}
def derivedImpl[A:Type](using Quotes):Expr[BarOf[A]] =
import quotes.reflect._
val A = TypeRepr.of[A]
val mySymbol = A.typeSymbol
val terms = mySymbol.children
def childExpr(childSymbol:Symbol) =
childSymbol.typeRef.asType match {
case '[f] => Expr.summon[BarOf[f]]
} getOrElse {
report.errorAndAbort(s"ChildType ${childSymbol} of ${mySymbol} does not derive BarOf")
}
val termsExpr = Expr.ofList(terms.map(childExpr))
'{ new BarOf[A]
{ def children = ${termsExpr}
override def toString = ${Expr(s"BarOf[${mySymbol.fullName}]")}
}
}
I have generic repository interface:
type RecursivePartial<T> = {
[P in keyof T]?:
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
T[P] extends object ? RecursivePartial<T[P]> :
T[P];
};
interface Repository<T> {
all(filters?: RecursivePartial<T>): T[] | Promise<T[]>;
find(filters: RecursivePartial<T>): T | undefined | Promise<T | undefined>;
create(entity: T): T | Promise<T>;
update(entity: T, fields: RecursivePartial<T>): T | Promise<T>;
}
When I want to find an entity
repository.find({ property: value })
works fine. But now when I have repository which queries data from MongoDB, I need a type which both supports exact filtering as well as query like
repository.find({ property: { $exists: true } })
P.S. Maybe you know how to deal with Promise<T> | T
You can just add an extra union type to the T[P] base case:
type HigherFilter = {
$exists?: boolean,
};
type RecursivePartial<T> = {
[P in keyof T]?:
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
T[P] extends object ? RecursivePartial<T[P]> :
T[P] | HigherFilter; // <---- HERE
};
Playground Link
I want to iterate throgh requests: Seq[Request] and run on each element a function getSingleResponse(request). Normally it yields Response(request, Some(...)) but if it fails I want it to yield Response(response, None).
With this code the returning type of getResponse don't match:
private def getResponse(requests: Seq[Request]): Seq[Response] = {
def getSingleResponse(request: Request) = {
val count = getCount()
Response(request, Some(count))
}
def getEmptyResponse(request: Request) = {
Response(request, None)
}
for (request <- requests) yield {
delay
try{
Some(getSingleResponse(request))
} catch {
case e: Exception => {getEmptyResponse(request)}
}
}
}
Required: scala.Seq[Response]
Found: scala.collection.Seq[Product with Serializable]
It's because the compiler infer the common nearest supertype of try expression as Product with Serializable of Response (result type of catch block) and Option[Response] (result type of try block.)
To make the common supertype of both blocks as Response you should omit wrapping the result of getSingleResponse to Some:
val result: Seq[Response] =
for (request <- requests) yield {
delay
try {
getSingleResponse(request)
} catch {
case e: Exception => getEmptyResponse(request)
}
}
From the Scala Language Specification:
Let pt be the expected type of the try expression. The block b is
expected to conform to pt. The handler h is expected conform to type
scala.PartialFunction[scala.Throwable, pt]. The type of the try
expression is the weak least upper bound of the type of b and the
result type of h
Also, as #Luis Miguel Mejía Suárez suggests, you can use scala.util.Try instead of try expression:
import scala.util.Try
val result: Seq[Response] =
for (request <- requests) yield {
delay
Try(getSingleResponse(request)).getOrElse(getEmptyResponse(request))
}
My project has similar structure:
Application
|
|--> /ApplicationA
| -> /app
| ->Filters.scala
| ->AuthenticationComponent.scala
| -> /build.sbt
|
|--> /ApplicationB
| -> /app
| ->Module.scala
| ->VanillaAuthenticationUtil.scala
| -> /build.sbt
|
|-> /conf
|-> /build.sbt
The code of Module.scala is listed:
class Module extends AbstractModule {
override def configure(): Unit = {
bind(classOf[AuthenticationUtil])
.annotatedWith(Names.named("authUtil"))
.to(classOf[VanillaAuthenticationUtil]).asEagerSingleton()
}
}
Also, ApplicationA does not know about ApplicationB and ApplicationB depends on ApplicationA.
The code of Filters.scala and AuthenticationComponent.scala also listed:
class Filters #Inject()(corsFilter: CORSFilter) extends HttpFilters {
#Inject
#Named("authUtil")
var authUtil:AuthenticationUtil = _
def filters = Seq(corsFilter, authUtil)
}
class AuthenticationComponent {
#Inject
#Named("authUtil")
var authUtil:AuthenticationUtil = _
def getAuthUtil():AuthenticationFilter ={
println(authUtil == null)
authUtil
}
}
So, when I'm calling getAuthUtil from AuthenticationComponent it says that authUtil is equals null, but in case of Filters it's false. The same situation is when I'm trying to inject into scala object I'm also receiving null.
Any ideas?
I don't recommend mixing field and constructor injection. Move it to a constructor param, and it will probably work.
I am interacting with an external Java API which looks like this:
val obj: SomeBigJavaObj = {
val _obj = new SomeBigJavaObj(p1, p2)
_obj.setFoo(p3)
_obj.setBar(p4)
val somethingElse = {
val _obj2 = new SomethingElse(p5)
_obj2.setBar(p6)
_obj2
}
_obj.setSomethingElse(somethingElse)
_obj
}
Basically the Java API exposes bunch of .setXXXX methods which returns void and sets something. I have no control over these external POJOs.
I would therefore like to write a fluent build Scala macro which inspects the object and creates a builder-pattern type .withXXXX() method for each of the void setXXXX() methods which returns this:
val obj: SomeBigJavaObj =
build(new SomeBigJavaObj(p1, p2))
.withFoo(p3)
.withBar(p4)
.withSomethingElse(
build(new SomethingElse(p5))
.withBar(p6)
.result()
)
.result()
Is this possible? I know I cannot generate new top level objects with def macros so open to other suggestions where I would have the similar ergonomics.
It is not complicated to use macros; just unfriendly to IDE (like:code completion;...);
//edit 1 : support multiple arguments
entity:
public class Hello {
public int a;
public String b;
public void setA(int a) {
this.a = a;
}
public void setB(String b) {
this.b = b;
}
public void setAB(int a , String b){
this.a = a;
this.b = b;
}
}
macro code :
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
trait BuildWrap[T] {
def result(): T
}
object BuildWrap {
def build[T](t: T): Any = macro BuildWrapImpl.impl[T]
}
class BuildWrapImpl(val c: whitebox.Context) {
import c.universe._
def impl[T: c.WeakTypeTag](t: c.Expr[T]) = {
val tpe = c.weakTypeOf[T]
//get all set member
val setMembers = tpe.members
.filter(_.isMethod)
.filter(_.name.toString.startsWith("set"))
.map(_.asMethod)
.toList
// temp value ;
val valueName = TermName("valueName")
val buildMethods = setMembers.map { member =>
if (member.paramLists.length > 1)
c.abort(c.enclosingPosition,"do not support Currying")
val params = member.paramLists.head
val paramsDef = params.map(e=>q"${e.name.toTermName} : ${e.typeSignature}")
val paramsName = params.map(_.name)
val fieldName = member.name.toString.drop(3)//drop set
val buildFuncName = TermName(s"with$fieldName")
q"def $buildFuncName(..$paramsDef ) = {$valueName.${member.name}(..$paramsName);this} "
}
val result =
q"""new BuildWrap[$tpe] {
private val $valueName = $t
..${buildMethods}
def result() = $valueName
}"""
// debug
println(showCode(result))
result
}
}
test code :
val hello1: Hello = BuildWrap.build(new Hello).withA(1).withB("b").result()
assert(hello1.a == 1)
assert(hello1.b == "b")
val hello2: Hello = BuildWrap.build(new Hello).withAB(1, "b").result()
assert(hello2.a == 1)
assert(hello2.b == "b")
Not a solution, just a very preliminary mock-up
+---------------------------------------------------------+
| |
| D I S C L A I M E R |
| |
| This is a mock-up. It is not type-safe. It relies on |
| runtime reflection (even worse: it relies on |
| Java-reflection!). Do not use this in production. |
| |
| If you can come up with a type-safe solution, I will |
| definitely take a look at it and upvote your answer. |
| |
+---------------------------------------------------------+
You have said explicitly that type-safety is a must, so the code below cannot count as a solution. However, before investigating any further, maybe you would like to experiment with a purely runtime-reflection based implementation, to understand the requirements better. Here is a very quick-and-dirty mock-up implementation:
import scala.language.dynamics
class DynamicBuilder[X](underConstruction: X) extends Dynamic {
val clazz = underConstruction.getClass
def applyDynamic(name: String)(arg: Any): DynamicBuilder[X] = {
if (name.startsWith("with")) {
val propertyName = name.drop(4)
val setterName = "set" + propertyName
clazz.getDeclaredMethods().
find(_.getName == setterName).
fold(throw new IllegalArgumentException("No method " + setterName)) {
m =>
m.invoke(underConstruction, arg.asInstanceOf[java.lang.Object])
this
}
} else {
throw new IllegalArgumentException("Expected 'result' or 'withXYZ'")
}
}
def result(): X = underConstruction
}
object DynamicBuilder {
def build[A](a: A) = new DynamicBuilder[A](a)
}
Once the build-method is imported
import DynamicBuilder.build
and the definitions of the classes that correspond to POJOs are in scope
class SomethingElse(val p5: String) {
var bar: String = _
def setBar(s: String): Unit = { bar = s }
override def toString = s"SomethingElse[p5 = $p5, bar = $bar]"
}
class SomeBigJavaObj(val p1: Float, val p2: Double) {
var foo: Int = 0
var bar: String = _
var sthElse: SomethingElse = _
def setFoo(i: Int): Unit = { foo = i }
def setBar(s: String): Unit = { bar = s }
def setSomethingElse(s: SomethingElse): Unit = { sthElse = s }
override def toString: String =
s"""|SomeBigJavaObj[
| p1 = $p1, p2 = $p2,
| foo = $foo, bar = $bar,
| sthElse = $sthElse
|]""".stripMargin
}
and also all the required variables p1,...,p6 from your example are defined
val p1 = 3.1415f
val p2 = 12345678d
val p3 = 42
val p4 = "BAR"
val p5 = "P5"
val p6 = "b-a-r"
you can use exactly the syntax from your question:
val obj: SomeBigJavaObj =
build(new SomeBigJavaObj(p1, p2))
.withFoo(p3)
.withBar(p4)
.withSomethingElse(
build(new SomethingElse(p5))
.withBar(p6)
.result()
)
.result()
The result looks as follows:
println(obj)
// Output:
// SomeBigJavaObj[
// p1 = 3.1415, p2 = 1.2345678E7,
// foo = 42, bar = BAR,
// sthElse = SomethingElse[p5 = P5, bar = b-a-r]
// ]
For now, the idea is just to see how badly it fails when you try to use it with a somewhat more realistic example. It might turn out that in reality, everything is a little bit more complicated:
Maybe some setters are generic
Maybe some of them use Java wildcards with Java's strange call-site variance
Maybe instead of setters there are some other methods that take multiple parameters as varargs
Maybe there are overloaded setters with same name but different types of arguments.
etc.
I understand that this cannot be a solution, however, I hope that this might be useful as an additional feasibility check, and that it maybe helps to make the requirements a tiny bit more precise, before investing more time and energy in type-safe macro-based solutions.
If this does roughly what you wanted, I might consider to update the answer. If this is not helpful at all, I'll delete the answer.