Статьи

Подсказка Play Framework 2: консоль Scala

Когда я впервые начал играть со Scala, меня поразил интерактивный переводчик Scala (также известный как REPL, read -valu-print-loop). Это была одна из тех вещей, которые вы никогда не ожидали найти в статически типизированном, скомпилированном языке, таком как java или scala.

Что бы вы сказали, если бы у нас было это для наших игровых приложений? … В scala ИЛИ JAVA! И да, с завершением счета и всеми прибамбасами …

Что ж, благодаря Peter Hausel ( @ pk11 ) из команды разработчиков, я узнал, как это сделать .

Просто откройте командную строку и введите:

01
02
03
04
05
06
07
08
09
10
cd <path_to_your_play2_app>
play console
 
[info] Loading project definition from /home/sas/Dropbox/Public/devel/play/apps/play2/todo/project
[info] Set current project to todo (in build file:/home/sas/Dropbox/Public/devel/play/apps/play2/todo/)
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_31).
Type in expressions to have them evaluated.
Type :help for more information.

Вот и все, вы находитесь в консоли Scala и, что лучше, с включенным завершением табуляции!

Здесь вы можете начать играть в Scala, а также в свое приложение, например так:

1
2
scala> val contact = models.Contact(1, "new contact", "new address")
contact: models.Contact = Contact(1,new contact,new address)

Вы можете проверить свои взгляды, и, конечно, вы также можете выполнить импорт, чтобы сэкономить довольно много нажатий клавиш

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
scala> import models._, views.html._
import models._
import views.html._
 
scala> val contacts = Seq( Contact(1, "@develsas", "Buenos Aires"), Contact(2, "@pk11", "Paris") )
contacts: Seq[models.Contact] = List(Contact(1,@develsas,Buenos Aires), Contact(2,@pk11,Paris))
 
scala> contact.list(contacts)
res1: play.api.templates.Html =
<!DOCTYPE html>
<html>
    <head>
        <title>Contact list</title>
        <link rel="styles
[...]
<tr>
 <td>@develsas</td>
 <td>Buenos Aires</td>
</tr>
<tr>
 <td>@pk11</td>
 <td>Paris</td>
</tr>
[...]

Но когда вы пытаетесь получить доступ к вашей базе данных, вы получите следующую ошибку:

1
2
3
4
scala> val contacts = Contact.all()
java.lang.RuntimeException: There is no started application
 at scala.sys.package$.error(package.scala:27)
[...]

Это просто, вам просто нужно запустить приложение

1
2
3
4
5
scala> import play.core._
scala> new StaticApplication(new java.io.File("."))
[info] play - database [default] connected at jdbc:h2:data/db
[info] play - Application started (Prod)
res1: play.core.StaticApplication = play.core.StaticApplication@10cdd4

И теперь вы можете интерактивно играть с вашим запущенным приложением

01
02
03
04
05
06
07
08
09
10
11
scala> val contacts = Contact.all
contacts: Seq[models.Contact] = List(Contact(1,Paul,Boston), Contact(3,Paolo,Roma), Contact(4,Paulain,Paris), Contact(5,Abelardo,San Justo))
 
scala> val newContact = Contact(6, "new contact", "new address")
newContact: models.Contact = Contact(6,new contact,new address)
 
scala> Contact.insert(newContact)
res2: Int = 1
 
scala> val contacts = Contact.all
contacts: Seq[models.Contact] = List(Contact(1,Paul,Boston), Contact(3,Paolo,Roma), Contact(4,Paulain,Paris), Contact(5,Abelardo,San Justo), Contact(6,new contact,new address))

Теперь проверьте вашу базу данных, и вы увидите, что новый контакт был сохранен в вашей базе данных.

Последний совет. Если вы работаете с базой данных в памяти, и вы определили любой сценарий развития, вы получите это сообщение при запуске игровой консоли формы приложения:

01
02
03
04
05
06
07
08
09
10
11
scala> new play.core.StaticApplication(new java.io.File("."))
[info] play - database [default] connected at jdbc:h2:mem:play
[warn] play - Your production database [default] needs evolutions!
 
# --- Rev:1,Ups - 74ff2d1
[...]
 
[warn] play - Run with -DapplyEvolutions.default=true if you want to run them automatically (be careful)
PlayException: Database 'default' needs evolution! [An SQL script need to be run on your database.]
 at play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1.apply(Evolutions.scala:422)
[...]

Решение довольно простое, просто начните играть с

1
play -DapplyEvolutions.default=true

И ваши сценарии развития будут автоматически применяться при запуске приложения.

Давай и попробуй. Возьмите, к примеру, компьютерную базу данных java demo

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
$ cd <path_to_your_play2_installation>/samples/java/computer-database
$ play -DapplyEvolutions.default=true
 
[computer-database] $ console
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.7.0_03).
Type in expressions to have them evaluated.
Type :help for more information.
 
 
scala> new play.core.StaticApplication(new java.io.File("."))
[info] play - database [default] connected at jdbc:h2:mem:play
[info] play - Application started (Prod)
res0: play.core.StaticApplication = play.core.StaticApplication@129796b

А теперь просто начните играть со своим приложением

1
2
3
4
5
6
7
8
scala> val page = models.Computer.page(1, 10, "name", "asc", "")
page: com.avaje.ebean.Page[models.Computer] = com.avaje.ebeaninternal.server.query.LimitOffsetPage@d386c9
 
scala> val computerList = page.getList()
computerList: java.util.List[models.Computer] = BeanList size[10] hasMoreRows[true] list[models.Computer@137, models.Computer@20d, models.Computer@12e, models.Computer@1b7, models.Computer@12d, models.Computer@14a, models.Computer@14b, models.Computer@21f, models.Computer@98, models.Computer@1a2]
 
scala> computerList.get(0).name
res2: java.lang.String = ASCI White

Тем не менее, как только вы начали играть с БД, я столкнулся с парой проблем. Я мог читать из базы данных, но не мог писать ни обновления, ни вставки. Я полагаю, что это магия бледной вуду, которая доставляет мне неприятности.

С версией scala я мог бы пойти гораздо дальше, взглянуть на это (продолжайте, не стесняйтесь и скопируйте этот код)

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$ cd <path_to_your_play2_installation>/samples/scala/computer-database
$ play -DapplyEvolutions.default=true
 
[computer-database] $ console
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.7.0_03).
Type in expressions to have them evaluated.
Type :help for more information.
 
scala> new play.core.StaticApplication(new java.io.File("."))
[info] play - database [default] connected at jdbc:h2:mem:play
[info] play - Application started (Prod)
res0: play.core.StaticApplication = play.core.StaticApplication@1eaf4b3
 
scala> import models._, anorm._, play.api.db._, play.api.Play.current, anorm.SqlParser._
 
import models._
import anorm._
import play.api.db._
import play.api.Play.current
import anorm.SqlParser._
 
scala> // clean-up everything
 
scala> DB.withConnection { implicit connection =>
     SQL("delete from computer").executeUpdate()
     SQL("delete from company").executeUpdate()
     }
res3: Int = 42
 
scala> // just checking
 
scala> DB.withConnection { implicit connection => SQL("select count(*) from computer").as(scalar[Long].single) }
res7: Long = 0
 
scala> DB.withConnection { implicit connection => SQL("select count(*) from company").as(scalar[Long].single) }
res8: Long = 0
 
scala> Company.options
res9: Seq[(String, String)] = List()

Хорошо, давайте создадим пару компаний

01
02
03
04
05
06
07
08
09
10
scala>
DB.withConnection { implicit connection =>
  Seq((1, "my Company"), (2, "my second company")).map { company =>
    SQL("insert into company values ( %s, '%s')".format(company._1, company._2) ).executeUpdate()
  }
}
res50: Seq[Int] = List(1, 1)
 
scala> Company.options
res51: Seq[(String, String)] = List((1,my Company), (2,my second company))

И пара компьютеров

01
02
03
04
05
06
07
08
09
10
11
12
13
scala> val newComputer = Computer(NotAssigned, "my computer", None, None, Some(1))
newComputer: models.Computer = Computer(NotAssigned,my computer,None,None,Some(1))
 
scala> Computer.insert(newComputer)
res67: Int = 1
 
scala> Computer.insert(Computer(NotAssigned, "my second comuter", None, None, Some(2)))
 
scala>
DB.withConnection { implicit connection =>
  SQL("select * from computer").as(Computer.withCompany *)
}
res8: List[(models.Computer, Option[models.Company])] = List((Computer(1000,my computer,None,None,Some(1)),None), (Computer(1001,my second comuter,None,None,Some(2)),None))

Да, этот пример немного преувеличен, но я думаю, вы поняли, что вы можете сделать с игровой консолью, так что продолжайте взламывать!

Справка: подсказка Play framework 2: играйте в интерактивном режиме с вашим приложением с консоли scala от нашего партнера по JCG Себастьяна Скарано на платформе « Развлекайтесь с Play»! блог.