I am trying to add the result of database to List. But I have one problem here. Elements are added to list and size is same as number of element at initial size. But while printing final size, it's always 0. I'm not sure what is the error.
Thanks in advance
#Singleton
class HomeController #Inject()(cc: ControllerComponents) extends AbstractController(cc) {
var result = ListBuffer[Item]()
val res = db.run(items.result)
for (r <- res) {
for (r1 <- r) {
result += r1
}
println("initial size = " + result.size)
}
/**
* Create an Action to render an HTML page.
*
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/`.
*/
def index() = Action { implicit request: Request[AnyContent] =>
println("final size = " + result.size)
Ok(views.html.index())
}
}
Related
I noticed the following code in org.scalacheck.Properties file:
/** Used for specifying properties. Usage:
* {{{
* property("myProp") = ...
* }}}
*/
class PropertySpecifier() {
def update(propName: String, p: Prop) = props += ((name+"."+propName, p))
}
lazy val property = new PropertySpecifier()
I'm not sure what is happening when property("myProp") = ... is invoked. There is no apply method in the class PropertySpecifier. So, what is being called here?
You may notice that the usage does not only show application but rather something else, the = sign. By having your class implement an update method you can let the compiler how the state of this class can be updated and allowing the property("myProp") = syntax.
You can find the same behavior on Arrays, where apply performs read access and update write access.
Here is a small example you can use to understand this:
final class Box[A](private[this] var item: A) {
def apply(): A =
item
def update(newItem: A): Unit =
item = newItem
}
val box = new Box(42)
println(box()) // prints 42
box() = 47 // updates box contents
println(box()) // prints 47
I have this error bellow and can't find the solution or how to debug what's being passed to apply.
Can anyone help?
too many arguments for method apply: (car:
play.api.data.Form[models.CarroFormData])(implicit messages:
play.api.i18n.Messages)play.twirl.api.HtmlFormat.Appendable in class
index
Controller Form
def add = Action { implicit request =>
CarroForm.form.bindFromRequest.fold(
// if any error in submitted data
errorForm => Ok(views.html.admin.index(errorForm, Seq.empty[Carro])),
data => repo.create(carro.name, carro.description, carro.img, carro.keywords).map { _ =>
// If successful, we simply redirect to the index page.
Redirect(routes.application.index)
})
}
This is the Model
package dal
import javax.inject.{ Inject, Singleton }
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile
import models._
import scala.concurrent.{ Future, ExecutionContext }
/**
* A repository for people.
*
* #param dbConfigProvider The Play db config provider. Play will inject this for you.
*/
#Singleton
class CarroRepository #Inject() (dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) {
// We want the JdbcProfile for this provider
private val dbConfig = dbConfigProvider.get[JdbcProfile]
// These imports are important, the first one brings db into scope, which will let you do the actual db operations.
// The second one brings the Slick DSL into scope, which lets you define the table and other queries.
import dbConfig._
import driver.api._
/**
* Here we define the table. It will have a name of people
*/
private class CarroTable(tag: Tag) extends Table[Carro](tag, "carro") {
/** The ID column, which is the primary key, and auto incremented */
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
/** The name column */
def name = column[String]("name")
/** The description column */
def description = column[String]("description")
/** The img column */
def img = column[String]("img")
/** The keywords column */
def keywords = column[String]("keywords")
/**
* This is the tables default "projection".
*
* It defines how the columns are converted to and from the Person object.
*
* In this case, we are simply passing the id, name and page parameters to the Person case classes
* apply and unapply methods.
*/
def * = (id, name, description, img, keywords) <> ((Carro.apply _).tupled, Carro.unapply)
}
/**
* The starting point for all queries on the people table.
*/
private val carro = TableQuery[CarroTable]
/**
* Create a person with the given name and age.
*
* This is an asynchronous operation, it will return a future of the created person, which can be used to obtain the
* id for that person.
*/
def create(name: String, description: String, img:String, keywords: String): Future[Carro] = db.run {
// We create a projection of just the name and age columns, since we're not inserting a value for the id column
(carro.map(p => (p.name, p.description, p.img, p.keywords))
// Now define it to return the id, because we want to know what id was generated for the person
returning carro.map(_.id)
// And we define a transformation for the returned value, which combines our original parameters with the
// returned id
into ((nameAge, id) => Carro(id, nameAge._1, nameAge._2, nameAge._3, nameAge._4))
// And finally, insert the person into the database
) += (name, description, img, keywords)
}
/**
* List all the people in the database.
*/
def list(): Future[Seq[Carro]] = db.run {
carro.result
}
}
package models
import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json._
case class Carro(id: Long, name:String, description:String, img:String, keywords:String)
case class CarroFormData(name: String, description: String, img: String, keywords: String)
object CarroForm {
val form = Form(
mapping(
"name" -> nonEmptyText,
"description" -> nonEmptyText,
"img" -> nonEmptyText,
"keywords" -> nonEmptyText
)(CarroFormData.apply)(CarroFormData.unapply)
)
}
object Carros {
var carros: Seq[Carro] = Seq()
def add(carros: Carro): String = {
carros = carros :+ carro.copy(id = carro.length) // manual id increment
"User successfully added"
}
def delete(id: Long): Option[Int] = {
val originalSize = carro.length
carro = carro.filterNot(_.id == id)
Some(originalSize - carro.length) // returning the number of deleted users
}
def get(id: Long): Option[Carro] = carro.find(_.id == id)
def listAll: Seq[Carro] = carro
implicit val carroFormat = Json.format[Carro]
}
View Code
#(car: Form[CarroFormData])(implicit messages: Messages)
#import helper._
#main(new Main("Car Dealers", "Compra e venda de carros", "logo.png", "carro, compra, venda")) {
<div class="container">
<h1>Hello</h1>
#form(routes.AdminCarro.add()) {
#inputText(person("name"))
#inputText(person("description"))
#inputText(person("img"))
#inputText(person("keywords"))
)
<div class="buttons">
<input type="submit" value="Add Car"/>
</div>
}
</div>
}
At your controller code:
def add = Action { implicit request =>
CarroForm.form.bindFromRequest.fold(
// if any error in submitted data
errorForm => Ok(views.html.admin.index(errorForm, Seq.empty[Carro])),
data => repo.create(carro.name, carro.description, carro.img, carro.keywords).map { _ =>
// If successful, we simply redirect to the index page.
Redirect(routes.application.index)
}
)
}
At the errorForm, you are calling the index view with two arguments:
Ok(views.html.admin.index(errorForm, Seq.empty[Carro]))
But your view declares just one argument:
#(car: Form[CarroFormData])(implicit messages: Messages)
Just remove the Seq.empty[Carro] from the call in your controller and everything should work as expected. If you still getting the same error, see if there are other places where this view is called the same wrong way (with two arguments) or try to sbt clean your project before sbt run.
I've found similar issues of this particular problem, however the problem was due to someone trying to instantiate T directly. Here I'm trying to create a trait that is a general interface to extend classes and store them automatically in a database such as Riak using classOf[T]. Using Scala 2.10.
Here's my code:
trait RiakWriteable[T] {
/**
* bucket name of data in Riak holding class data
*/
def bucketName: String
/**
* determine whether secondary indices will be added
*/
def enable2i: Boolean
/**
* the actual bucket
*/
val bucket: Bucket = enable2i match {
case true => DB.client.createBucket(bucketName).enableForSearch().execute()
case false => DB.client.createBucket(bucketName).disableSearch().execute()
}
/**
* register the scala module for Jackson
*/
val converter = {
val c = new JSONConverter[T](classOf[T], bucketName)
JSONConverter.registerJacksonModule(DefaultScalaModule)
c
}
/**
* store operation
*/
def store = bucket.store(this).withConverter(converter).withRetrier(DB.retrier).execute()
/**
* fetch operation
*/
def fetch(id: String): Option[T] = {
val u = bucket.fetch(id, classOf[T]).withConverter(converter).withRetrier(DB.retrier).r(DB.N_READ).execute()
u match {
case null => None
case _ => Some(u)
}
}
}
Compiler error is class type required but T found.
Example usage (pseudo-code):
class Foo
object Foo extends RiakWriteable[Foo]
Foo.store(object)
So I'm guessing that a manifest of T is not being properly defined. Do I need to implicitly define this somewhere?
Thanks!
Here's an intermediary solution, though it leaves out the converter registration (which I may leave permanently for this use case, not sure yet).
/**
* trait for adding write methods to classes
*/
trait RiakWriteable[T] {
/**
* bucket name of data in Riak holding class data
*/
def bucketName: String
/**
* determine whether secondary indices will be added
*/
def enable2i: Boolean
/**
* the actual bucket
*/
val bucket: Bucket = enable2i match {
case true => DB.client.createBucket(bucketName).enableForSearch().execute()
case false => DB.client.createBucket(bucketName).disableSearch().execute()
}
/**
* store operation
*/
def store(o: T) = bucket.store(o).withRetrier(DB.retrier).execute()
/**
* fetch operation
*/
def fetch(id: String)(implicit m: ClassTag[T]) = {
val u = bucket.fetch(id, classTag[T].runtimeClass).withRetrier(DB.retrier).r(DB.N_READ).execute()
u match {
case null => None
case _ => Some(u)
}
}
}
the code below runs perfectly fine if I simply make it a "case class". However, I certainly do not want that for a mutable object - but by changing it to a regular class, it no longer seems to understand the anonymous function parameter at the end. Not sure why I can't get past this, i've tried a few variations and can't understand why making it a case class works. (scala 2.10.2) - thanks
/**
*
* #param target - can be any large target number
* #param perPiece - at what percentage interval is todo called
* #param todo - passed current percentage complete
*/
class ProgressTool(target:Double, perPiece:Double) (todo: (Double)=>Unit) extends Mutable {
private[this] var lastUpdate:Double =0.0
def update(atPos:Double) = {
val step = atPos - lastUpdate
if (step/target >=perPiece) {
lastUpdate += step
todo(lastUpdate)
}
}
}
object TestProgressTool extends App {
val x = new ProgressTool(1000,.01) { x:Double =>
println("Hello "+ x)
}
}
missing arguments for constructor ProgressTool in class ProgressTool
val x = new ProgressTool(1000,.01) { x:Double =>
^
Not sure why it seems to work, but try this (note extra parentheses around constructor with first arguments):
object TestProgressTool extends App {
val x = (new ProgressTool(1000,.01)) { x:Double =>
println("Hello "+ x)
}
}
Using round parens around the second param list heals the code too and might be less surprising:
object TestProgressTool extends App {
val x = new ProgressTool(1000,.01) ({ x:Double =>
println("Hello "+ x)
})
}
I'm implementing a class that acts as three stacks that rely on the same array (from Gayle Laakmann's cracking the coding interview).
I'm having trouble understanding why this code results in type mismatches:
class ThreeStacks[A, B, C ](val stackSize:Int = 1000) {
/**
* Push a value on to the first stack
* #param value value of type A */
def push1[A](value :A): Unit = stack1.push(value)
/**
* Push a value on to the second stack
* #param value value of type B */
def push2[B](value: B): Unit = stack2.push(value)
/**
* Push a value on to the third stack
* #param value value of type C */
def push3[C](value: C): Unit = stack3.push(value)
/**
* Pops the top value off the first stack
* #return Some(value) at the top of the stack, None if the stack is empty */
def pop1[A](): Option[A] = stack1.pop()
/**
* Pops the top value off the second stack
* #return Some(value) at the top of the stack, None if the stack is empty */
def pop2[B](): Option[B] = stack2.pop()
/**
* Pops the top value off the second stack
* #return Some(value) at the top of the stack, None if the stack is empty */
def pop3[C](): Option[C] = stack3.pop()
// the shared stacks
private val stack1 = SharedStack[A]()
private val stack2 = SharedStack[B]()
private val stack3 = SharedStack[C]()
// the shared stack class is simply a container for push and pop functions
class SharedStack[T](val push: T => Unit, val pop: () => Option[T])
// the sharedstack object is a factory setups a shared stack object with its proper push/pop functions that are received
// from the stackmemory instance
private object SharedStack{
val stackMemory = new StackMemory(stackSize)
def apply[T](): SharedStack[T] = {
val stackTuple = stackMemory.registerStack[T]()
new SharedStack(stackTuple._1, stackTuple._2)
}
}
// the memory object responsible for handling the sharing of the array
private class StackMemory(val stackSize: Int = 1000){
// helps prevent the conflict warnings with immutable and mutable collections
private val MutableMap = scala.collection.mutable.Map
// the array that contains the stack nodes
private val array = new Array[Option[StackNode[Any]]](stackSize)
// keeps track of the heads of all the stacks
private val registeredStackHeads = MutableMap[Int, Int]()
// an index to help assign every new stack a unique key
private var nextRegistrationIndex = 1
// a list of indices in the array that have been freed
private var freedIndices = List[Int]()
// the next available free index, increments till it reaches the end of the array, different from the freeIndices list
// in that it only is concerned with free cells while they are available at the end of the array
private var nextFreeIndex = 0
/**
* Registers a stack within the memory object and returns the push/pop functions
* #return the push/pop functions relevant for that stack */
def registerStack[T](): (T => Unit, () => Option[T]) = {
val index = nextRegistrationIndex
val noPreviousValueIndex = -1
// register the index in the stack heads with an empty value
registeredStackHeads(index) = noPreviousValueIndex
nextRegistrationIndex += 1
(push[T](index), pop[T](index) )
}
/**
* Returns the push function for a stack at the given index
* #param stackIndex the index of the requesting stack
* #return the push function for the stack */
def push[T](stackIndex: Int) = {
(value: T) => {
// get the indices and initialize a stack node
val headIndex = registeredStackHeads(stackIndex)
val index = nextAvailableIndex()
val stackNode = new StackNode[T](headIndex, value)
// store the new stack head and place it in to the array
registeredStackHeads(stackIndex) = index
array(index) = Some(stackNode)
}
}
/**
* The pop function for the stack at a given index
* #param stackIndex the index of the requesting stack
* #return the pop function for the stack */
def pop[T](stackIndex: Int): () => Option[T] = {
() => {
val headIndex = registeredStackHeads(stackIndex)
if(headIndex < 0) None else {
array(headIndex) match {
case Some(s : StackNode[T]) => {
registeredStackHeads(stackIndex) = s.previousIndex
freeIndex(headIndex)
Some(s.value)
}
case _ => None
}
}
}
}
// retrieve the next available index, throws an exception if there are no available indices
private def nextAvailableIndex():Int = {
// return a new index if the array isn't full otherwise throw an exception
def newIndex() : Int = {
if(nextFreeIndex >= stackSize){
throw new Exception("No more room in stack array available")
}
else{
val index = nextFreeIndex
nextFreeIndex += 1
index
}
}
// first check if any of the old indices have been freed
freedIndices match {
case Nil => newIndex()
case head::tail => freedIndices = tail; head
}
}
// frees an index and adds it to the free indices list
private def freeIndex(i: Int): Unit = {
if (i >= array.length) throw new ArrayIndexOutOfBoundsException("The index to be freed does not exist in the array")
array(i) = None
freedIndices = i::freedIndices
}
// covariant node that helps keep track of the previous index of the stack
private class StackNode[+S](val previousIndex: Int, val value: S)
}
}
The code works like its suppose to if I call stack1.push or stack1.pop but it causes type mismatches on wrappers push1 and pop1, why is this happenning?
example for push1:
type mismatch;
found : value.type (with underlying type A)
required: A
def push1[A](value :A): Unit = stack1.push(value)
example for pop1:
type mismatch;
found : Option[A(in class ThreeStacks)]
required: Option[A(in method pop1)]
def pop1[A](): Option[A] = stack1.pop()
The problem in your code is type parameter shadowing.
You have:
class ThreeStacks[A, B, C](val stackSize:Int = 1000) {
def push1[A](value: A): Unit = stack1.push(value)
...
}
It should be:
class ThreeStacks[A, B, C](val stackSize:Int = 1000) {
def push1(value: A): Unit = stack1.push(value)
...
}
The way you have done it, type parameter A of class ThreeStacks and type parameter A of method push1 are completely different ones and thus, are incompatible with each other.
The same applies to B and C.