playframework 2.1 - What is the proper way to generate evolutions and models in Play 2? -


i know evolutions applied automatically in dev mode. question is, how generate evolutions? , how generate models correspond them? i'm faced lot of typing enter simple model. isn't dry , there's lots of boilerplate. seems counter culture of play.

here code i'm faced typing, better way?:

1.sql: # --- first database schema

# --- !ups  create table task (   id                        bigint not null primary key,   title                     varchar(255) not null,   done                      boolean,   due_date                  timestamp,   assigned_to               varchar(255),   project                   bigint not null,   folder                    varchar(255),   foreign key(assigned_to)  references user(email) on delete set null,   foreign key(project)      references project(id) on delete cascade );  # --- !downs  drop table if exists task; 

task.scala:

package models  import java.util.{date}  import play.api.db._ import play.api.play.current  import anorm._ import anorm.sqlparser._  case class task(id: pk[long], folder: string, project: long, title: string, done: boolean, duedate: option[date], assignedto: option[string])  object task {    // -- parsers    /**    * parse task resultset    */   val simple = {     get[pk[long]]("task.id") ~     get[string]("task.folder") ~     get[long]("task.project") ~     get[string]("task.title") ~     get[boolean]("task.done") ~     get[option[date]]("task.due_date") ~     get[option[string]]("task.assigned_to") map {       case id~folder~project~title~done~duedate~assignedto => task(         id, folder, project, title, done, duedate, assignedto       )     }   }    // -- queries    /**    * retrieve task id.    */   def findbyid(id: long): option[task] = {     db.withconnection { implicit connection =>       sql("select * task id = {id}").on(         'id -> id       ).as(task.simple.singleopt)     }   }    /**    * retrieve todo tasks user.    */   def findtodoinvolving(user: string): seq[(task,project)] = {     db.withconnection { implicit connection =>       sql(         """           select * task            join project_member on project_member.project_id = task.project            join project on project.id = project_member.project_id           task.done = false , project_member.user_email = {email}         """       ).on(         'email -> user       ).as(task.simple ~ project.simple map {         case task~project => task -> project       } *)     }   }    /**    * find tasks related project    */   def findbyproject(project: long): seq[task] = {     db.withconnection { implicit connection =>       sql(         """           select * task            task.project = {project}         """       ).on(         'project -> project       ).as(task.simple *)     }   }    /**    * delete task    */   def delete(id: long) {     db.withconnection { implicit connection =>       sql("delete task id = {id}").on(         'id -> id       ).executeupdate()     }   }    /**    * delete task in folder.    */   def deleteinfolder(projectid: long, folder: string) {     db.withconnection { implicit connection =>       sql("delete task project = {project} , folder = {folder}").on(         'project -> projectid, 'folder -> folder       ).executeupdate()     }   }    /**    * mark task done or not    */   def markasdone(taskid: long, done: boolean) {     db.withconnection { implicit connection =>       sql("update task set done = {done} id = {id}").on(         'id -> taskid,         'done -> done       ).executeupdate()     }   }    /**    * rename folder.    */   def renamefolder(projectid: long, folder: string, newname: string) {     db.withconnection { implicit connection =>       sql("update task set folder = {newname} folder = {name} , project = {project}").on(         'project -> projectid, 'name -> folder, 'newname -> newname       ).executeupdate()     }   }    /**    * check if user owner of task    */   def isowner(task: long, user: string): boolean = {     db.withconnection { implicit connection =>       sql(         """           select count(task.id) = 1 task            join project on task.project = project.id            join project_member on project_member.project_id = project.id            project_member.user_email = {email} , task.id = {task}         """       ).on(         'task -> task,         'email -> user       ).as(scalar[boolean].single)     }   }    /**    * create task.    */   def create(task: task): task = {     db.withconnection { implicit connection =>        // task id       val id: long = task.id.getorelse {         sql("select next value task_seq").as(scalar[long].single)       }        sql(         """           insert task values (             {id}, {title}, {done}, {duedate}, {assignedto}, {project}, {folder}           )         """       ).on(         'id -> id,         'folder -> task.folder,         'project -> task.project,         'title -> task.title,         'done -> task.done,         'duedate -> task.duedate,         'assignedto -> task.assignedto       ).executeupdate()        task.copy(id = id(id))      }   }  } 

ebean doesn't support ddl changes, therefore using automatic evolutions can create first ddl scratch.

next evolutions, need (literally) write yourself, containing ups , downs planning initial ddl @ beginning important step.

danger: realized yet automatically created 'scratch-evoulution' performs downs of previous ddl means, data lost.


Comments