Skip to content

Commit 57618ef

Browse files
committed
Add persistence of todo table
1 parent abf3bf3 commit 57618ef

File tree

7 files changed

+225
-2
lines changed

7 files changed

+225
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ docker/db/data/
1212
.bloop
1313
.bsp
1414
.project
15+
.DS_Store

app/lib/persistence/package.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
*
44
*/
55

6-
package lib
6+
// package lib
77

88
package object persistence {
99

1010
val default = onMySQL
1111

1212
object onMySQL {
1313
implicit lazy val driver = slick.jdbc.MySQLProfile
14-
object UserRepository extends UserRepository
14+
object TodoRepository extends TodoRepository
1515
}
1616
}

app/model/todo/Todo.scala

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* This is a sample of Todo Application.
3+
*
4+
*/
5+
6+
package model.todo
7+
8+
import ixias.model._
9+
import ixias.util.EnumStatus
10+
11+
import java.time.LocalDateTime
12+
13+
// ユーザーを表すモデル
14+
//~~~~~~~~~~~~~~~~~~~~
15+
import Todo._
16+
case class Todo(
17+
id: Option[Id],
18+
categoryId: Long,
19+
title: String,
20+
body: String,
21+
state: Status,
22+
updatedAt: LocalDateTime = NOW,
23+
createdAt: LocalDateTime = NOW
24+
) extends EntityModel[Id]
25+
26+
// コンパニオンオブジェクト
27+
//~~~~~~~~~~~~~~~~~~~~~~~~
28+
object Todo {
29+
30+
val Id = the[Identity[Id]]
31+
type Id = Long @@ Todo
32+
type WithNoId = Entity.WithNoId [Id, Todo]
33+
type EmbeddedId = Entity.EmbeddedId[Id, Todo]
34+
35+
// ステータス定義
36+
//~~~~~~~~~~~~~~~~~
37+
sealed abstract class Status(val code: Short, val name: String) extends EnumStatus
38+
object Status extends EnumStatus.Of[Status] {
39+
case object TODO extends Status(code = 0, name = "TODO")
40+
case object PROGRESS extends Status(code = 1, name = "進行中")
41+
case object COMPLETE extends Status(code = 2, name = "完了")
42+
}
43+
44+
// INSERT時のIDがAutoincrementのため,IDなしであることを示すオブジェクトに変換
45+
def apply(categoryId: Long, title: String, body: String, state: Status): WithNoId = {
46+
new Entity.WithNoId(
47+
new Todo(
48+
id = None,
49+
categoryId = categoryId,
50+
title = title,
51+
body = body,
52+
state = state
53+
)
54+
)
55+
}
56+
}

app/persistence/TodoRepository.scala

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* This is a sample of Todo Application.
3+
*
4+
*/
5+
6+
package persistence
7+
8+
import scala.concurrent.Future
9+
import ixias.persistence.SlickRepository
10+
import model.todo.Todo
11+
import slick.jdbc.JdbcProfile
12+
import db.TodoTable
13+
14+
// TodoRepository: TodoTableへのクエリ発行を行うRepository層の定義
15+
//~~~~~~~~~~~~~~~~~~~~~~
16+
case class TodoRepository[P <: JdbcProfile]()(implicit val driver: P)
17+
extends SlickRepository[Todo.Id, Todo, P]
18+
with db.SlickResourceProvider[P] {
19+
20+
import api._
21+
22+
/**
23+
* Get Todo Data
24+
*/
25+
def get(id: Id): Future[Option[EntityEmbeddedId]] =
26+
RunDBAction(TodoTable, "slave") { _
27+
.filter(_.id === id)
28+
.result.headOption
29+
}
30+
31+
/**
32+
* Add Todo Data
33+
*/
34+
def add(entity: EntityWithNoId): Future[Id] =
35+
RunDBAction(TodoTable) { slick =>
36+
slick returning slick.map(_.id) += entity.v
37+
}
38+
39+
/**
40+
* Update Todo Data
41+
*/
42+
def update(entity: EntityEmbeddedId): Future[Option[EntityEmbeddedId]] =
43+
RunDBAction(TodoTable) { slick =>
44+
val row = slick.filter(_.id === entity.id)
45+
for {
46+
old <- row.result.headOption
47+
_ <- old match {
48+
case None => DBIO.successful(0)
49+
case Some(_) => row.update(entity.v)
50+
}
51+
} yield old
52+
}
53+
54+
/**
55+
* Delete Todo Data
56+
*/
57+
def remove(id: Id): Future[Option[EntityEmbeddedId]] =
58+
RunDBAction(TodoTable) { slick =>
59+
val row = slick.filter(_.id === id)
60+
for {
61+
old <- row.result.headOption
62+
_ <- old match {
63+
case None => DBIO.successful(0)
64+
case Some(_) => row.delete
65+
}
66+
} yield old
67+
}
68+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* This is a sample of Todo Application.
3+
*
4+
*/
5+
6+
package persistence.db
7+
8+
import slick.jdbc.JdbcProfile
9+
10+
// Tableを扱うResourceのProvider
11+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12+
trait SlickResourceProvider[P <: JdbcProfile] {
13+
14+
implicit val driver: P
15+
object TodoTable extends TodoTable
16+
// --[ テーブル定義 ] --------------------------------------
17+
lazy val AllTables = Seq(
18+
TodoTable
19+
)
20+
}

app/persistence/db/TodoTable.scala

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* This is a sample of Todo Application.
3+
*
4+
*/
5+
6+
package persistence.db
7+
8+
import java.time.LocalDateTime
9+
import slick.jdbc.JdbcProfile
10+
import ixias.persistence.model.Table
11+
12+
import model.todo.Todo
13+
14+
// TodoTable: Todoテーブルへのマッピングを行う
15+
//~~~~~~~~~~~~~~
16+
case class TodoTable[P <: JdbcProfile]()(implicit val driver: P)
17+
extends Table[Todo, P] {
18+
import api._
19+
20+
// Definition of DataSourceName
21+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22+
lazy val dsn = Map(
23+
"master" -> DataSourceName("ixias.db.mysql://master/Todo"),
24+
"slave" -> DataSourceName("ixias.db.mysql://slave/Todo")
25+
)
26+
27+
// Definition of Query
28+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29+
class Query extends BasicQuery(new Table(_)) {}
30+
lazy val query = new Query
31+
32+
// Definition of Table
33+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
34+
class Table(tag: Tag) extends BasicTable(tag, "Todo") {
35+
import Todo._
36+
// Columns
37+
/* @1 */ def id = column[Id] ("id", O.UInt64, O.PrimaryKey, O.AutoInc)
38+
/* @2 */ def categoryId = column[Long] ("category_id", O.UInt64)
39+
/* @3 */ def title = column[String] ("title", O.Utf8Char255)
40+
/* @4 */ def body = column[String] ("body", O.Utf8Char255)
41+
/* @5 */ def state = column[Status] ("state", O.UInt8)
42+
/* @6 */ def updatedAt = column[LocalDateTime] ("updated_at", O.TsCurrent)
43+
/* @7 */ def createdAt = column[LocalDateTime] ("created_at", O.Ts)
44+
45+
type TableElementTuple = (
46+
Option[Id], Long, String, String, Status, LocalDateTime, LocalDateTime
47+
)
48+
49+
// DB <=> Scala の相互のmapping定義
50+
def * = (id.?, categoryId, title,body, state, updatedAt, createdAt) <> (
51+
// Tuple(table) => Model
52+
(t: TableElementTuple) => Todo(
53+
t._1, t._2, t._3, t._4, t._5, t._6, t._7
54+
),
55+
// Model => Tuple(table)
56+
(v: TableElementType) => Todo.unapply(v).map { t => (
57+
t._1, t._2, t._3, t._4, t._5, LocalDateTime.now(), t._7
58+
)}
59+
)
60+
}
61+
}

app/persistence/package.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* This is a sample of Todo Application.
3+
*
4+
*/
5+
6+
7+
package persistence
8+
9+
package object persistence {
10+
11+
val default = onMySQL
12+
13+
object onMySQL {
14+
implicit lazy val driver = slick.jdbc.MySQLProfile
15+
object TodoRepository extends TodoRepository
16+
}
17+
}

0 commit comments

Comments
 (0)