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
Post a Comment