How to create nested GraphQL fields with Sangria's `#GraphQLField` annotation - sangria

I have a simple case class MyContext(queries: Query) that I provide to the schema with : sangria.schema.Schema(deriveContextObjectType[MyContext, Query, Unit](_.queries)
MyQuery is a trait of Query
trait MyQuery {
#GraphQLField
def item(ctx: Context[MyContext, Unit])(id: String) ...
}
This works great. But what if I want to nest resolvers?
query {
item {
status # status is resolved from source B
price # price is resolved from source C
}
}
Is that possible to achieve? Would I return an ObjectType[Item] that has properties status and price annotated with #GraphQLField?

I think you can use deriveObjectType for an Item. It is also able to handle the #GraphQLField annotation (as an alternative you can also use IncludeMethods macro setting). Here is an example:
implicit val ItemType = deriveObjectType[MyContext, Item]()

Really appreciate #tenshi's answer! I tried using the deriveObjectType but was getting a type error:
type mismatch;
found : sangria.schema.Context[MyContext,Item]
required: sangria.schema.Context[MyContext,Unit]
But using deriveContextObjectType in conjunction with AddFields is working:
def schema = sangria.schema.Schema(
deriveContextObjectType[MyContext, Query, Unit](_.queries,
AddFields(
Field(
name = "item",
fieldType = deriveContextObjectType[MyContext, Item, Unit](_ => new Item),
resolve = _ => ()
)
))
)
And the Schema looks good, yielding:
type Query {
item: Item!
}

Related

Room DAO function always returns null - Solved.. I forget .start() for thread. :-)

I have a DAO function as
Blockquote
#Query("SELECT DISTINCT name as pname FROM bevlista ORDER BY 1")
fun getaruk():MutableList<Product
Blockquote
and a class as
data class Product (
#ColumnInfo(name = "pname") var pname:String
)
When I test the Query in App Inspector , then the query result real :
Inspector
But when I call this funtion in the program then the result (test) is always null...
Debug
The test code in the rutin :
var test= mutableListOf<Product>() //=mutableListOf<Product>()
var szalt = Thread {
test = AppDatabase.getInstance(this#MainActivity).gradeDao().getaruk()
runOnUiThread {
println("breakpoint")
}
}
while(szalt.isAlive)
{Thread.sleep(10)}
println("breakpoint")
Can somebody help me to understand? Thanks in advance...

how to write costomselect query which returns Future in Flutter/moor

I'm developing apps by flutter/moor.
but I don't get how to write custom query which returns Future<List> class object.
I could wrote query which returns Stream class object.
but it's not enough.
does anyone now how to change it to one which returns Future class.
query I wrote is bellow
db.dart
Stream<List<QuestionHeader>> selectQuestionHeaderByKey(int businessYear,int period, int questionNo) {
return
customSelect(
'SELECT *'
+'From question_Headers '
+'WHERE business_Year = ? '
+'AND period = ? '
+'AND question_No = ?;',
variables: [Variable.withInt(businessYear),Variable.withInt(period),Variable.withInt(questionNo)],
readsFrom: {questionHeaders},
).watch().map((rows) {
return rows
.map((row) => QuestionHeader(
businessYear:row.readInt('businessYear')
,period:row.readInt('period')
,questionNo:row.readInt('questionNo')
,subjectId:row.readInt('subjectId')
,compulsoryType:row.readInt('compulsoryType')
,answerType:row.readInt('answerType')
,questionText:row.readString('questionText')
,numberAnswer:row.readInt('numberAnswer')
,correctType1:row.readInt('correctType1')
,correctType2:row.readInt('correctType2')
,correctType3:row.readInt('correctType3')
,favorite:row.readBool('favorite')
)).toList();
});
}
this works but I need Future<List> class to return.

queries in entity framework

i have written the following code
var resumeedit=(from t in db.Resumes where t.User.UserID==theUserID && t.ResumeID==theResumeID select t).Select(t=> new EditResumes
{
Iswizard=t.isWizard,
Resumeid=t.ResumeID.ToString()
}).First();
EditResumes ed = (EditResumes)resumeedit;
and it is giving error LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
this line
Resumeid=t.ResumeID.ToString()
what happens when you make it
Resumeid=t.ResumeID
?
or simple do:
select new { t.ResumeID, t.isWizard }
Like the message says, L2E doesn't do .ToString(). So use .AsEnumerable() to bring it into L2O:
var resumeedit= (from t in db.Resumes
where t.User.UserID==theUserID && t.ResumeID==theResumeID
select t)
.AsEnumerable()
.Select(t=> new EditResumes
{
Iswizard=t.isWizard,
Resumeid=t.ResumeID.ToString()
}).First();
This cast should be unnecessary:
EditResumes ed = (EditResumes)resumeedit;

Dynamic properties in Scala

Does Scala support something like dynamic properties? Example:
val dog = new Dynamic // Dynamic does not define 'name' nor 'speak'.
dog.name = "Rex" // New property.
dog.speak = { "woof" } // New method.
val cat = new Dynamic
cat.name = "Fluffy"
cat.speak = { "meow" }
val rock = new Dynamic
rock.name = "Topaz"
// rock doesn't speak.
def test(val animal: Any) = {
animal.name + " is telling " + animal.speak()
}
test(dog) // "Rex is telling woof"
test(cat) // "Fluffy is telling meow"
test(rock) // "Topaz is telling null"
What is the closest thing from it we can get in Scala? If there's something like "addProperty" which allows using the added property like an ordinary field, it would be sufficient.
I'm not interested in structural type declarations ("type safe duck typing"). What I really need is to add new properties and methods at runtime, so that the object can be used by a method/code that expects the added elements to exist.
Scala 2.9 will have a specially handled Dynamic trait that may be what you are looking for.
This blog has a big about it: http://squirrelsewer.blogspot.com/2011/02/scalas-upcoming-dynamic-capabilities.html
I would guess that in the invokeDynamic method you will need to check for "name_=", "speak_=", "name" and "speak", and you could store values in a private map.
I can not think of a reason to really need to add/create methods/properties dynamically at run-time unless dynamic identifiers are also allowed -and/or- a magical binding to an external dynamic source (JRuby or JSON are two good examples).
Otherwise the example posted can be implemented entirely using the existing static typing in Scala via "anonymous" types and structural typing. Anyway, not saying that "dynamic" wouldn't be convenient (and as 0__ pointed out, is coming -- feel free to "go edge" ;-).
Consider:
val dog = new {
val name = "Rex"
def speak = { "woof" }
}
val cat = new {
val name = "Fluffy"
def speak = { "meow" }
}
// Rock not shown here -- because it doesn't speak it won't compile
// with the following unless it stubs in. In both cases it's an error:
// the issue is when/where the error occurs.
def test(animal: { val name: String; def speak: String }) = {
animal.name + " is telling " + animal.speak
}
// However, we can take in the more general type { val name: String } and try to
// invoke the possibly non-existent property, albeit in a hackish sort of way.
// Unfortunately pattern matching does not work with structural types AFAIK :(
val rock = new {
val name = "Topaz"
}
def test2(animal: { val name: String }) = {
animal.name + " is telling " + (try {
animal.asInstanceOf[{ def speak: String }).speak
} catch { case _ => "{very silently}" })
}
test(dog)
test(cat)
// test(rock) -- no! will not compile (a good thing)
test2(dog)
test2(cat)
test2(rock)
However, this method can quickly get cumbersome (to "add" a new attribute one would need to create a new type and copy over the current data into it) and is partially exploiting the simplicity of the example code. That is, it's not practically possible to create true "open" objects this way; in the case for "open" data a Map of sorts is likely a better/feasible approach in the current Scala (2.8) implementation.
Happy coding.
First off, as #pst pointed out, your example can be entirely implemented using static typing, it doesn't require dynamic typing.
Secondly, if you want to program in a dynamically typed language, program in a dynamically typed language.
That being said, you can actually do something like that in Scala. Here is a simplistic example:
class Dict[V](args: (String, V)*) extends Dynamic {
import scala.collection.mutable.Map
private val backingStore = Map[String, V](args:_*)
def typed[T] = throw new UnsupportedOperationException()
def applyDynamic(name: String)(args: Any*) = {
val k = if (name.endsWith("_=")) name.dropRight(2) else name
if (name.endsWith("_=")) backingStore(k) = args.first.asInstanceOf[V]
backingStore.get(k)
}
override def toString() = "Dict(" + backingStore.mkString(", ") + ")"
}
object Dict {
def apply[V](args: (String, V)*) = new Dict(args:_*)
}
val t1 = Dict[Any]()
t1.bar_=("quux")
val t2 = new Dict("foo" -> "bar", "baz" -> "quux")
val t3 = Dict("foo" -> "bar", "baz" -> "quux")
t1.bar // => Some(quux)
t2.baz // => Some(quux)
t3.baz // => Some(quux)
As you can see, you were pretty close, actually. Your main mistake was that Dynamic is a trait, not a class, so you can't instantiate it, you have to mix it in. And you obviously have to actually define what you want it to do, i.e. implement typed and applyDynamic.
If you want your example to work, there are a couple of complications. In particular, you need something like a type-safe heterogenous map as a backing store. Also, there are some syntactic considerations. For example, foo.bar = baz is only translated into foo.bar_=(baz) if foo.bar_= exists, which it doesn't, because foo is a Dynamic object.

Reflection on a Scala case class

I'm trying to write a trait (in Scala 2.8) that can be mixed in to a case class, allowing its fields to be inspected at runtime, for a particular debugging purpose. I want to get them back in the order that they were declared in the source file, and I'd like to omit any other fields inside the case class. For example:
trait CaseClassReflector extends Product {
def getFields: List[(String, Any)] = {
var fieldValueToName: Map[Any, String] = Map()
for (field <- getClass.getDeclaredFields) {
field.setAccessible(true)
fieldValueToName += (field.get(this) -> field.getName)
}
productIterator.toList map { value => fieldValueToName(value) -> value }
}
}
case class Colour(red: Int, green: Int, blue: Int) extends CaseClassReflector {
val other: Int = 42
}
scala> val c = Colour(234, 123, 23)
c: Colour = Colour(234,123,23)
scala> val fields = c.getFields
fields: List[(String, Any)] = List((red,234), (green,123), (blue,23))
The above implementation is clearly flawed because it guesses the relationship between a field's position in the Product and its name by equality of the value on those field, so that the following, say, will not work:
Colour(0, 0, 0).getFields
Is there any way this can be implemented?
Look in trunk and you'll find this. Listen to the comment, this is not supported: but since I also needed those names...
/** private[scala] so nobody gets the idea this is a supported interface.
*/
private[scala] def caseParamNames(path: String): Option[List[String]] = {
val (outer, inner) = (path indexOf '$') match {
case -1 => (path, "")
case x => (path take x, path drop (x + 1))
}
for {
clazz <- getSystemLoader.tryToLoadClass[AnyRef](outer)
ssig <- ScalaSigParser.parse(clazz)
}
yield {
val f: PartialFunction[Symbol, List[String]] =
if (inner.isEmpty) {
case x: MethodSymbol if x.isCaseAccessor && (x.name endsWith " ") => List(x.name dropRight 1)
}
else {
case x: ClassSymbol if x.name == inner =>
val xs = x.children filter (child => child.isCaseAccessor && (child.name endsWith " "))
xs.toList map (_.name dropRight 1)
}
(ssig.symbols partialMap f).flatten toList
}
}
Here's a short and working version, based on the example above
trait CaseClassReflector extends Product {
def getFields = getClass.getDeclaredFields.map(field => {
field setAccessible true
field.getName -> field.get(this)
})
}
In every example I've seen the fields are in reverse order: the last item in the getFields array is the first one listed in the case class. If you use case classes "nicely", then you should just be able to map productElement(n) onto getDeclaredFields()( getDeclaredFields.length-n-1).
But this is rather dangerous, as I don't know of anything in the spec that insists that it must be that way, and if you override a val in the case class, it won't even appear in getDeclaredFields (it'll appear in the fields of that superclass).
You might change your code to assume things are this way, but check that the getter method with that name and the productIterator return the same value and throw an exception if they don't (which means that you don't actually know what corresponds to what).
You can also use the ProductCompletion from the interpreter package to get to attribute names and values of case classes:
import tools.nsc.interpreter.ProductCompletion
// get attribute names
new ProductCompletion(Colour(1, 2, 3)).caseNames
// returns: List(red, green, blue)
// get attribute values
new ProductCompletion(Colour(1, 2, 3)).caseFields
Edit: hints by roland and virtualeyes
It is necessary to include the scalap library which is part of the scala-lang collection.
Thanks for your hints, roland and virtualeyes.

Resources