How to successfully change `FakeRequest` to `RequestBuilder` - scala

As the Play 2.4 migration guide specifies:
FakeRequest has been replaced by RequestBuilder.
I have a question how to change or migrate play.api.test.FakeRequest to Http.RequestBuilder when I have something like:
val result = controller.update.apply {
FakeRequest()
.withLoggedIn(config)(loggedInUser)
}
So how to use withLoggedIn in RequestBuilder. I don't see anything similar.

Related

How to get ROUTE_PATTERN from request in play 2.6 scala

I've extracted ROUTE_PATTERN in play 2.5 with:
request.tags.get("ROUTE_PATTERN")
now I updated play 2.6 and this code doesn't work anymore. I read play documentation here:
What’s new in Play 2.6
I tried:
object Attrs {
val RoutePattern: TypedKey[String] = TypedKey("ROUTE_PATTERN")
}
request.attrs.get(Attrs.RoutePattern)
It always returns None. How I can get the RoutePattern of request in play 2.6?
From the 2.6 migration guide:
If you used any of the Router.Tags.* tags, you should change your code to use the new Router.Attrs.HandlerDef (Scala)....
This new attribute contains a HandlerDef object with all the information that is currently in the tags. The current tags all correspond to a field in the HandlerDef object....
The field in HandlerDef that corresponds to the old ROUTE_PATTERN tag is path:
import play.api.routing.{ HandlerDef, Router }
import play.api.mvc.RequestHeader
val handler = request.attrs(Router.Attrs.HandlerDef)
val routePattern = handler.path

Scala - play2 config get section

I decided to try scala out with play2. I am trying to somehow get a config section out of application config. It looks like this (by section I mean whole mail part)
services: {
rest: {
mail: {
uri: "xyz",
authorization: {
username: "xyz",
password: "xyz"
}
}
}
}
Code
import com.typesafe.config.ConfigObject
import play.api.Play.current
val config: Option[ConfigObject] = current.configuration.getObject("services.rest.mail")
This gives Some(SimpleConfigObject()) and trough there the only way I am able to actually get mail section and use it as a ConfigObject is trough
config.get.toConfig.getString("uri")
Or I can get the actual value with
config.get.get("uri").unwrapped().toString
Or for fun:
config.get.toConfig.getObject("authorization").toConfig.getString("username")
Either way it seems to me I am doing it overly complicated. Is there some easier way to get a section from config?
Since the config library has a Java API, it can feel a bit verbose using it from Scala. There are some Scala wrappers though that enable more compact syntax. See https://github.com/typesafehub/config#scala-wrappers-for-the-java-library.
I will post this as an answer for future reference.
After another while of playing with the code I have found parseResourcesAnySyntax method which does exactly what I want and since I have my config split into multiple parts for separate environments (application.dev.conf, etc.) I can simply do
import com.typesafe.config.{Config, ConfigFactory}
import play.api.Play._
val config: Config = ConfigFactory.parseResourcesAnySyntax("application.%s.conf" format current.mode)
and then use
config.getString("uri")
// or
config.getString("authorization.username")
// or if I want to use part of it as another section
val section: Config = config.getConfig("authorization")
section.getString("username")
Of course, another viable alternative is using a wrapper as mister Stebel recommended.

Are imports and conditionals in Play's routes file possible?

I know that the earlier versions of Play used to support routes and conditionals (if blocks) in the routes file but I cannot find any such documentation for Play 2.2.x and HTTP routing says nothing about such a feature.
I want to replace this:
GET /api/users/:id com.corporate.project.controllers.UserController.get(id)
with a shorter version using import as follows:
import com.corporate.project.controllers._
GET /api/users/:id UserController.get(id)
Also, is it possible to have conditionals in the routes file? e.g.
if Play.isDev(Play.current())
GET /displayConfig DebugController.displayServerConfigs()
Package imports used to be possible with an SBT setting: routesImport += "com.corporate.project.controllers._". Not sure if it is still the case.
Also, is it possible to have conditionals in the routes file?
It might not be an ideal solution but we use routes tags to deal with this kind of conditional routes. You need a filter that checks if the route is annotated and runs your conditional logic.
Routes:
# #devmode
GET /displayConfig DebugController.displayServerConfigs()
Filter:
object DevmodeRouteFilter extends Filter {
private val DevmodeAnnotation = "#devmode"
override def apply(next: RequestHeader => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = {
if(isDevRoute(request) && !Play.isDev(Play.current()) {
Play.current.global.onHandlerNotFound(request)
} else {
next(request)
}
}
private def isDevRoute(request: RequestHeader): Boolean = {
val comments = request.tags.getOrElse(Routes.ROUTE_COMMENTS, "")
comments.lines.exists { comment =>
comment.trim == DevmodeAnnotation
}
}
}
Don't forget to add the filter to the filter chain.
Thank you for your question, it is an interesting idea, so I went to the sources of Play2 and found that in my checkout of Play 2.2.3 in the play.core.Router.scala: object HandlerInvoker constructs controller as
handlerDef.ref.getClass.getClassLoader.loadClass(handlerDef.controller)
So I am afraid that support for partial class names (stored in handlerDef.controller) is not implemented in 2.2.x.
In 2.3.x there is commit https://github.com/playframework/playframework/commit/ba98dabd7ba374ed98f14f721835b898d27dd55b
that brought notion of package/namespace for the routes.
Please see changes in Routes.scala and RoutesCompiler.scala from that commit.
But I can't find description of that functionality in the documentation and I do not have Play 2.3.x to play with it now.
P.S.: Sample magic for advanced routing for 2.3.x described in http://java.dzone.com/articles/advanced-routing-play .

How can I connect to a postgreSQL database in scala?

I want to know how can I do following things in scala?
Connect to a postgreSQL database.
Write SQL queries like SELECT , UPDATE etc. to modify a table in that database.
I know that in python I can do it using PygreSQL but how to do these things in scala?
You need to add dependency "org.postgresql" % "postgresql" % "9.3-1102-jdbc41" in build.sbt and you can modify following code to connect and query database. Replace DB_USER with your db user and DB_NAME as your db name.
import java.sql.{Connection, DriverManager, ResultSet}
object pgconn extends App {
println("Postgres connector")
classOf[org.postgresql.Driver]
val con_st = "jdbc:postgresql://localhost:5432/DB_NAME?user=DB_USER"
val conn = DriverManager.getConnection(con_str)
try {
val stm = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)
val rs = stm.executeQuery("SELECT * from Users")
while(rs.next) {
println(rs.getString("quote"))
}
} finally {
conn.close()
}
}
I would recommend having a look at Doobie.
This chapter in the "Book of Doobie" gives a good sense of what your code will look like if you make use of this library.
This is the library of choice right now to solve this problem if you are interested in the pure FP side of Scala, i.e. scalaz, scalaz-stream (probably fs2 and cats soon) and referential transparency in general.
It's worth nothing that Doobie is NOT an ORM. At its core, it's simply a nicer, higher-level API over JDBC.
Take look at the tutorial "Using Scala with JDBC to connect to MySQL", replace the db url and add the right jdbc library. The link got broken so here's the content of the blog:
Using Scala with JDBC to connect to MySQL
A howto on connecting Scala to a MySQL database using JDBC. There are a number of database libraries for Scala, but I ran into a problem getting most of them to work. I attempted to use scala.dbc, scala.dbc2, Scala Query and Querulous but either they aren’t supported, have a very limited featured set or abstracts SQL to a weird pseudo language.
The Play Framework has a new database library called ANorm which tries to keep the interface to basic SQL but with a slight improved scala interface. The jury is still out for me, only used on one project minimally so far. Also, I’ve only seen it work within a Play app, does not look like it can be extracted out too easily.
So I ended up going with basic Java JDBC connection and it turns out to be a fairly easy solution.
Here is the code for accessing a database using Scala and JDBC. You need to change the connection string parameters and modify the query for your database. This example was geared towards MySQL, but any Java JDBC driver should work the same with Scala.
Basic Query
import java.sql.{Connection, DriverManager, ResultSet};
// Change to Your Database Config
val conn_str = "jdbc:mysql://localhost:3306/DBNAME?user=DBUSER&password=DBPWD"
// Load the driver
classOf[com.mysql.jdbc.Driver]
// Setup the connection
val conn = DriverManager.getConnection(conn_str)
try {
// Configure to be Read Only
val statement = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)
// Execute Query
val rs = statement.executeQuery("SELECT quote FROM quotes LIMIT 5")
// Iterate Over ResultSet
while (rs.next) {
println(rs.getString("quote"))
}
}
finally {
conn.close
}
You will need to download the mysql-connector jar.
Or if you are using maven, the pom snippets to load the mysql connector, you’ll need to check what the latest version is.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.12</version>
</dependency>
To run the example, save the following to a file (query_test.scala) and run using, the following specifying the classpath to the connector jar:
scala -cp mysql-connector-java-5.1.12.jar:. query_test.scala
Insert, Update and Delete
To perform an insert, update or delete you need to create an updatable statement object. The execute command is slightly different and you will most likely want to use some sort of parameters. Here’s an example doing an insert using jdbc and scala with parameters.
// create database connection
val dbc = "jdbc:mysql://localhost:3306/DBNAME?user=DBUSER&password=DBPWD"
classOf[com.mysql.jdbc.Driver]
val conn = DriverManager.getConnection(dbc)
val statement = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
// do database insert
try {
val prep = conn.prepareStatement("INSERT INTO quotes (quote, author) VALUES (?, ?) ")
prep.setString(1, "Nothing great was ever achieved without enthusiasm.")
prep.setString(2, "Ralph Waldo Emerson")
prep.executeUpdate
}
finally {
conn.close
}
We are using Squeryl, which is working well so far for us. Depending on your needs it may do the trick.
Here is a list of supported DB's and the adapters
If you want/need to write your own SQL, but hate the JDBC interface, take a look at O/R Broker
I would recommend the Quill query library. Here is an introduction post by Li Haoyi to get started.
TL;DR
{
import io.getquill._
import com.zaxxer.hikari.{HikariConfig, HikariDataSource}
val pgDataSource = new org.postgresql.ds.PGSimpleDataSource()
pgDataSource.setUser("postgres")
pgDataSource.setPassword("example")
val config = new HikariConfig()
config.setDataSource(pgDataSource)
val ctx = new PostgresJdbcContext(LowerCase, new HikariDataSource(config))
import ctx._
}
Define a class ORM:
// mapping `city` table
case class City(
id: Int,
name: String,
countryCode: String,
district: String,
population: Int
)
and query all items:
# ctx.run(query[City])
cmd11.sc:1: SELECT x.id, x.name, x.countrycode, x.district, x.population FROM city x
val res11 = ctx.run(query[City])
^
res11: List[City] = List(
City(1, "Kabul", "AFG", "Kabol", 1780000),
City(2, "Qandahar", "AFG", "Qandahar", 237500),
City(3, "Herat", "AFG", "Herat", 186800),
...
ScalikeJDBC is quite easy to use. It allows you to write raw SQL using interpolated strings.
http://scalikejdbc.org/

MVC on Lift/Scala

Has anyone tried to do a scala/lift application using MVC instead of view-first?
I know that you can create Controllers/views as:
package test.test.test.view
...
Lots of imports
...
class MvcRocks extends LiftView {
def dispatch = {
case "rule" => ruleDispatch _
case "bar" => barDispatch _
}
def barDispatch(): Box[NodeSeq] = {
Full(<lift:embed what="/mvc_rucks/bar" />)
}
}
And this code will be accessible if you add it to the menu(in the boot), even if its hidden as:
val entries = Menu(Loc("Home", List("index"), "Home")) ::
List(Menu(Loc("MvcRock", List("mvc_rocks", "bar"), "Mvc really Rocks", Hidden)))
LiftRules.setSiteMap(SiteMap(entries:_*))
Now, of course this will make it so, you declare every action in the menu, then have a case for each action(per controller) and that would open the "view" (that would be a file in /mvc_rucks/bar.html).
My question is, if you would implement a full mvc, you would need to put all your logic in the action barDispatch, but how would you send those variables to the HTML template? and how would you receive post/get information?
(Notice that if you html code has lift bindings, it will of course act as view-first, even after you did MVC before).
Since your question is not specific to Lift, I'd recommend you the Playframework. The version 1.1 supports Scala 2.8.
Playframework is totally MVC with a fantastic template engine and allows you to choose freely between java/scala.
And I say: To use Play, you don't need 'nuclear scientist knowledge'. Try it!