[from now] 2013/03/29 09:09:16

diff --git a/app/controllers/Rental.scala b/app/controllers/Rental.scala
index 9d457c1..d0baedb 100644
--- a/app/controllers/Rental.scala
+++ b/app/controllers/Rental.scala
@@ -81,7 +81,7 @@ trait Rental extends Controller with JsonResponse with Composeable with DBEnable
     }
   }

-  // あるユーザーの本ついて、自分がレンタルしたことを示す。
+  // あるユーザーの本について、自分がレンタルしたことを示す。
   def doRental() = Authenticated {
     Action {
       implicit request =>
[from now] 2013/03/29 09:09:40

diff --git a/app/models/BookShelves.scala b/app/models/BookShelves.scala
index 0d3305b..0373b24 100644
--- a/app/models/BookShelves.scala
+++ b/app/models/BookShelves.scala
@@ -21,7 +21,7 @@ object BookShelves extends Table[BookShelf]("book_shelf") {

   def name = column[String]("shelf_name", O DBType "varchar (50)")

-  def description = column[String]("description", O DBType "varchar (100)")
+  def description = column[String]("shelf_description", O DBType "varchar (100)")

   def createdDate = column[Date]("created_date")

@@ -41,7 +41,7 @@ object BookShelves extends Table[BookShelf]("book_shelf") {
       b <- BookShelves
       u <- UserInforms
       c <- UserInforms
-      if b.createdUser === c.userId && b.updatedUser === u.userId
+      if b.createdUser === c.userId && b.updatedUser === u.userId && b.id === shelfId
     } yield (b, c.userDisplayName, u.userDisplayName)
     query.firstOption
   }
@@ -63,6 +63,10 @@ object BookShelves extends Table[BookShelf]("book_shelf") {
     }
   }

+  // 対象の本棚を削除する。
+  def delete(shelfId :Long)(implicit session:Session): Int =
+    (for {b <- BookShelves if b.id === shelfId} yield b).delete
+
   // 対象をjsonに変換する
   def toJson(target: BookShelf): JsValue = {
     implicit val dateWriter = Writes[Date] {date => Json.toJson("%tF %tT" format(date, date))}
diff --git a/app/models/Books.scala b/app/models/Books.scala
index faeab4d..79c3d68 100644
--- a/app/models/Books.scala
+++ b/app/models/Books.scala
@@ -42,7 +42,7 @@ object Books extends Table[Book]("book") {

   def createdUser = column[Long]("created_user")

-  def updatedDate = column[Date]("created_date")
+  def updatedDate = column[Date]("updated_date")

   def updatedUser = column[Long]("updated_user")

@@ -88,28 +88,13 @@ object Books extends Table[Book]("book") {
     }
   }

-  // // 一件追加
-  // def insert(book: BookRegister, userId: BigInteger): Either[String, BigInteger] = {
-  //   val currentDate = Calendar.getInstance().getTime();
-  //   DB.withConnection { implicit conn =>
-  //     BookShelf.selectById(book.shelfId) match {
-  //       case None => Left("BookShelf not found")
-  //       case Some(_) =>
-  //         SQL("""
-  //         insert into book (shelf_id, book_name, book_author, book_isbn, published_date,
-  //             large_image_url, medium_image_url, small_image_url,
-  //             created_date, created_user, updated_date, updated_user)
-  //         values ({id}, {name}, {author}, {isbn}, {publish}, {large}, {medium}, {small},
-  //             {created}, {createdUser}, {updated}, {updatedUser})
-  //         """).on('id -> book.shelfId, 'name -> book.name, 'author -> book.author, 'isbn -> book.isbn,
-  //           'large -> book.largeImageUrl, 'medium -> book.mediumImageUrl,
-  //           'small -> book.smallImageUrl, 'publish -> book.publishedDate,
-  //           'created -> currentDate, 'updated -> currentDate, 'createdUser -> userId.toString,
-  //           'updatedUser -> userId.toString()).executeUpdate()
-  //         Right(SQL("select last_insert_id() as lastnum from book").apply.head[BigInteger]("lastnum"))
-  //     }
-  //   }
-  // }
+  // 指定されたbookIdのBookを削除する
+  def delete(id : Long)(implicit session: Session): Int = {
+     (for {
+       b <- Books
+       if b.bookId === id
+     } yield (b)).delete
+  }

   def toJson(book: Book): JsValue = {
     implicit val dateWriter = Writes[Date] {
diff --git a/conf/evolutions/default/8.sql b/conf/evolutions/default/8.sql
new file mode 100644
index 0000000..55fc10b
--- /dev/null
+++ b/conf/evolutions/default/8.sql
@@ -0,0 +1,32 @@
+# --- !Ups
+
+alter table book_shelf modify column created_user BIGINT NOT NULL;
+alter table book_shelf modify column updated_user BIGINT NOT NULL;
+
+alter table book modify column created_user BIGINT NOT NULL;
+alter table book modify column updated_user BIGINT NOT NULL;
+
+alter table RentalInfo rename to rental_info;
+alter table rental_info modify column created_user BIGINT NOT NULL;
+alter table rental_info modify column updated_user BIGINT NOT NULL;
+
+alter table UserInfo rename to user_info;
+alter table user_info modify column created_user BIGINT NOT NULL;
+alter table user_info modify column updated_user BIGINT NOT NULL;
+
+# --- !Downs
+alter table book_shelf modify column created_user VARCHAR(100) NOT NULL;
+alter table book_shelf modify column updated_user VARCHAR(100) NOT NULL;
+
+alter table book modify column created_user VARCHAR(100) NOT NULL;
+alter table book modify column updated_user VARCHAR(100) NOT NULL;
+
+alter table rental_info rename to RentalInfo;
+alter table RentalInfo modify column created_user VARCHAR(100) NOT NULL;
+alter table RentalInfo modify column updated_user VARCHAR(100) NOT NULL;
+
+alter table user_info rename to UserInfo;
+alter table UserInfo modify column created_user VARCHAR(100) NOT NULL;
+alter table UserInfo modify column updated_user VARCHAR(100) NOT NULL;
+
+
diff --git a/conf/routes b/conf/routes
index 1e1caee..f1be196 100644
--- a/conf/routes
+++ b/conf/routes
@@ -24,7 +24,7 @@ GET     /api/user_info          application.Application.getLoginUserInfo
 PUT     /api/user_info          application.Application.updateUserInfo

 # Get and update rental infomations
-GET     /api/rental              application.Rental.getRentalInfos
+GET     /api/rental              application.Rental.getRentalInformAll
 GET     /api/rental/             application.Rental.getRentalInfoByBookId
 GET     /api/rental/*id          application.Rental.getRentalDetails(id: Long)
 POST    /api/rental              application.Rental.doRental
diff --git a/test/ApplicationSpec.scala b/test/ApplicationSpec.scala
index 74691b2..7a6b240 100644
--- a/test/ApplicationSpec.scala
+++ b/test/ApplicationSpec.scala
@@ -1,75 +1,71 @@
 package test

-import java.sql.Connection
 import java.text.SimpleDateFormat
-import java.util.Date
-import models.UserInform
+import java.sql.Date
+import java.util.Calendar
 import org.specs2.mutable._
-import play.api.db._
-import anorm._
 import play.api.test._
 import play.api.test.Helpers._
-import models.Book
 import org.specs2.matcher._
 import org.specs2.specification.Scope
-import models.Book
-import java.math.BigInteger
-import models.BookShelf
-import models.BookRegister
-import models.BookDetail
+import models._
 import play.api.mvc.SimpleResult
 import play.api.libs.json._
 import play.api.libs.functional.syntax._
-import play.api.libs.json.Json
-import views.html.defaultpages.badRequest
-import models.BookShelf
-import models.Book
+import scala.slick.driver.MySQLDriver.simple.{Session =>_, _}
+import scala.slick.driver.MySQLDriver.simple.{Session => DBSession}
+import db.wrapper.specs2.AutoRollback

 class ApplicationSpec extends Specification {
+  val now = new Date(Calendar.getInstance.getTimeInMillis)

   // 基本的なデータの追加・削除をするためのtrait
-  trait scope extends Scope with After {
-    val shelfId: BigInteger = BookShelf.insert("book shelf", "description", BigInteger.valueOf(0L))
-    val result: BigInteger = Book.insert(BookRegister(shelfId, "book name",
-      Some("book author"), Some("book isbn"),
-      None,None, None, None), BigInteger.valueOf(0L)).right.get
-
-    def after = {
-      BookShelf.delete(shelfId)
-      Book.delete(result)
+  trait OneDataAutoRollback extends AutoRollback {
+    override def fixture(implicit session: DBSession): Unit = {
+      val shelfId = BookShelves.ins.insert("book shelf", "description", now, 0L, now, 0L)
+      val book = Books.ins.insert(0L, "book name", Some("book author"), Some("book isbn"),
+        None, None, None, None, now, 0L, now, 0L)
+      val user = UserInforms.ins.insert("", "", "", "", "", "", None, None, None, now, 0L, now, 0L)
+      (for { s <- BookShelves if s.id === shelfId } yield (s.id)).update(0L)
+      (for { s <- Books if s.bookId === book } yield (s.bookId)).update(0L)
+      (for { s <- UserInforms if s.userId === user } yield (s.userId)).update(0L)
     }
   }

-  trait manyData extends Scope with After {
-    val shelfId: BigInteger = BookShelf.insert("book shelf", "description", BigInteger.valueOf(0L))
-    val results: List[BigInteger] = (1 to 10).map { e =>
-      Book.insert(BookRegister(shelfId, "book name" + e.toString, Some("book author" + e.toString),
-        Some(e.toString),None, None, None, None),
-      BigInteger.valueOf(0L)).right.get
-    }.toList
-
-    def after = {
-      results.map(Book.delete)
-      BookShelf.delete(shelfId)
+  trait ManyDataAutoRollback extends AutoRollback {
+    override def fixture(implicit session: DBSession): Unit = {
+      val shelfId = BookShelves.ins.insert("book shelf", "description", now, 0L, now, 0L)
+      val book = (1 to 10).map { e =>
+        Books.ins.insert(0L, "book name" + e.toString, Some("book author" + e.toString), Some("book isbn"),
+          None, None, None, None, now, 0L, now, 0L)
+      }.toList
+      (for { s <- BookShelves if s.id === shelfId } yield (s.id)).update(0L)
+      book.zipWithIndex.foreach {
+        case (b, index) =>
+          (for { s <- Books if s.bookId === b } yield (s.bookId)).update(index)
+      }
     }
   }

   "Application" should {
     "makes and delete an book shelf with name and description" in new WithApplication {
-      val data: Map[String, Seq[String]] = Map("shelf_name" -> Seq("name"),
-        "shelf_description" -> Seq("desc"))
-      val result = route(FakeRequest(POST, "/api/shelf").withHeaders(CONTENT_TYPE -> "application/x-www-form-urlencode"), data)
-
-      result must beSome
-      status(result.get) must beEqualTo(OK)
-      val node = Json.parse(contentAsString(result.get))
+      new AutoRollback {
+        val data: Map[String, Seq[String]] = Map("shelf_name" -> Seq("name"),
+          "shelf_description" -> Seq("desc"))
+        val result = route(FakeRequest(POST, "/api/shelf").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"), data)
+
+        result must beSome
+        status(result.get) must beEqualTo(OK)
+        val node = Json.parse(contentAsString(result.get))
         (node \ "totalCount").as[Long] must be_==(1L)
         ((node \ "result")(0) \ "id").as[Long] must be_>(1L)
-      val id = ((node \ "result")(0) \ "id").as[Long]
+        val id = ((node \ "result")(0) \ "id").as[Long]

-      val resultByDelete = route(FakeRequest(DELETE, "/api/shelf/" + id.toString))
-      resultByDelete must beSome
-      status(resultByDelete.get) must beEqualTo(OK)
+        val resultByDelete = route(FakeRequest(DELETE, "/api/shelf/" + id.toString))
+        resultByDelete must beSome
+        status(resultByDelete.get) must beEqualTo(OK)
+      }
     }

     "return BadRequest when give id is not found in data store" in new WithApplication {
@@ -80,165 +76,101 @@ class ApplicationSpec extends Specification {
     }

     "get infomation of a book shelf if it is registered" in new WithApplication {
+      new OneDataAutoRollback {

-      DB.withConnection {implicit conn:Connection =>
-        SQL(
-          """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val user = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> user).executeUpdate
-      }
-
-      val data: Map[String, Seq[String]] = Map("shelf_name" -> Seq("name"),
-        "shelf_description" -> Seq("desc"))
-      val result = route(FakeRequest(POST, "/api/shelf").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"), data)
+        val data: Map[String, Seq[String]] = Map("shelf_name" -> Seq("name"),
+          "shelf_description" -> Seq("desc"))
+        val result = route(FakeRequest(POST, "/api/shelf").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"), data)

-      result must beSome
-      val id = ((Json.parse(contentAsString(result.get)) \ "result")(0) \ "id").as[Long]
-      val shelf = route(FakeRequest(GET, "/api/shelf/" + id))
+        result must beSome
+        val id = ((Json.parse(contentAsString(result.get)) \ "result")(0) \ "id").as[Long]
+        id must be_>(0L)
+        val shelf = route(FakeRequest(GET, "/api/shelf/" + id))

-      shelf must beSome
-      status(shelf.get) must beEqualTo(OK)
-      val node = Json.parse(contentAsString(shelf.get))
+        shelf must beSome
+        status(shelf.get) must beEqualTo(OK)
+        val node = Json.parse(contentAsString(shelf.get))
         (node \ "totalCount").as[Long] must be_==(1L)
         ((node \ "result")(0) \ "shelf_id").as[Long] must be_==(id)
         ((node \ "result")(0) \ "shelf_name").as[String] must be_==("name")
         ((node \ "result")(0) \ "shelf_description").as[String] must be_==("desc")

-      val deleted = route(FakeRequest(DELETE, "/api/shelf/" + id))
-      deleted must beSome
-      status(deleted.get) must beEqualTo(OK)
+        val deleted = route(FakeRequest(DELETE, "/api/shelf/" + id))
+        deleted must beSome
+        status(deleted.get) must beEqualTo(OK)
         (Json.parse(contentAsString(deleted.get)) \ "totalCount").as[Long] must be_==(0L)
-
-      DB.withConnection {implicit conn => SQL("delete from UserInform").executeUpdate}
+      }
     }

     "makes and delete book information with" in new WithApplication {
+      new OneDataAutoRollback {

-      DB.withConnection {implicit conn:Connection =>
-        SQL(
-          """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val user = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> user).executeUpdate
-      }
-
-      val shelf: Map[String, Seq[String]] = Map("shelf_name" -> Seq("name"),
-        "shelf_description" -> Seq("desc"))
-      val result = route(FakeRequest(POST, "/api/shelf").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"), shelf)
+        val shelf: Map[String, Seq[String]] = Map("shelf_name" -> Seq("name"),
+          "shelf_description" -> Seq("desc"))
+        val result = route(FakeRequest(POST, "/api/shelf").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"), shelf)

-      result must beSome
-      val shelf_id = ((Json.parse(contentAsString(result.get)) \ "result")(0) \ "id").as[Long]
+        result must beSome
+        val shelf_id = ((Json.parse(contentAsString(result.get)) \ "result")(0) \ "id").as[Long]

-      val book_req : Map[String, Seq[String]]= Map("shelf_id" -> Seq(shelf_id.toString),
-        "book_name" -> Seq("book name"),
-        "published_date" -> Seq("2012/02/01"),
-        "large_image_url" -> Seq("large image url"))
-      val book_result = route(FakeRequest(POST, "/api/book").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"), book_req)
+        val book_req: Map[String, Seq[String]] = Map("shelf_id" -> Seq(shelf_id.toString),
+          "book_name" -> Seq("book name"),
+          "published_date" -> Seq("2012/02/01"),
+          "large_image_url" -> Seq("large image url"))
+        val book_result = route(FakeRequest(POST, "/api/book").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"), book_req)

-      book_result must beSome
-      status(book_result.get) must beEqualTo(OK)
+        book_result must beSome
+        status(book_result.get) must beEqualTo(OK)

-      val book_id = ((Json.parse(contentAsString(book_result.get)) \ "result")(0) \ "id").as[Long]
-      val book = route(FakeRequest(GET, "/api/book/" + book_id))
+        val book_id = ((Json.parse(contentAsString(book_result.get)) \ "result")(0) \ "id").as[Long]
+        val book = route(FakeRequest(GET, "/api/book/" + book_id))

-      book must beSome
-      val node = Json.parse(contentAsString(book.get))
-      val formatter = new SimpleDateFormat("yyyy/MM/dd")
+        book must beSome
+        val node = Json.parse(contentAsString(book.get))
+        val formatter = new SimpleDateFormat("yyyy/MM/dd")
         (node \ "totalCount").as[Long] must be_==(1L)
         ((node \ "result")(0) \ "book_id").as[Long] must be_==(book_id)
         ((node \ "result")(0) \ "book_name").as[String] must be_==("book name")
         ((node \ "result")(0) \ "book_author").asOpt[String] must beNone
         ((node \ "result")(0) \ "book_isbn").asOpt[String] must beNone
-        ((node \ "result")(0) \ "published_date").as[Date] must be_==("2012/02/01") ^^ ("%tY/%<tm/%<td" format (_:Date))
+        ((node \ "result")(0) \ "published_date").as[Date] must be_==("2012/02/01") ^^ ("%tY/%<tm/%<td" format (_: Date))
         ((node \ "result")(0) \ "large_image_url").as[String] must be_==("large image url")
         ((node \ "result")(0) \ "medium_image_url").asOpt[String] must beNone
         ((node \ "result")(0) \ "small_image_url").asOpt[String] must beNone

-      val deleted = route(FakeRequest(DELETE, "/api/shelf/" + shelf_id))
-      deleted must beSome
-      status(deleted.get) must beEqualTo(OK)
+        val deleted = route(FakeRequest(DELETE, "/api/shelf/" + shelf_id))
+        deleted must beSome
+        status(deleted.get) must beEqualTo(OK)
         (Json.parse(contentAsString(deleted.get)) \ "totalCount").as[Long] must be_==(0L)
-
-      DB.withConnection {implicit conn => SQL("""delete from UserInform""").executeUpdate}
-    }
-
-    "update user infomation" in new WithApplication {
-      DB.withConnection {implicit conn =>
-        SQL(
-          """
-          insert into UserInform values (0, '', '', '', '', '', '', '', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val id = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> id).executeUpdate
-      }
-
-      val userinfo: Map[String, Seq[String]] = Map("user_display_name" -> Seq("name"))
-      val result = route(FakeRequest(PUT, "/api/user_info").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"), userinfo)
-
-      result must beSome
-      status(result.get) must beEqualTo(OK)
-
-      val user = UserInform.selectById(BigInteger.valueOf(0L))
-      user must beSome
-      user.get.userDisplayName must be_==("name")
-
-      DB.withConnection {implicit conn =>
-        SQL("""delete from UserInform""").executeUpdate
       }
     }

-    "get user infomation" in new WithApplication {
-      DB.withConnection {implicit conn =>
-        SQL(
-          """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val id = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> id).executeUpdate
-      }
+    "update and get user infomation" in new WithApplication {
+      new OneDataAutoRollback {

-      val result = route(FakeRequest(GET, "/api/user_info").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"))
+        val userinfo: Map[String, Seq[String]] = Map("user_display_name" -> Seq("name"))
+        val result = route(FakeRequest(PUT, "/api/user_info").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"), userinfo)

-      result must beSome
-      status(result.get) must beEqualTo(OK)
+        result must beSome
+        status(result.get) must beEqualTo(OK)

-      val node = Json.parse(contentAsString(result.get))
+        val userInfo = route(FakeRequest(GET, "/api/user_info").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"))
+
+        userInfo must beSome
+        status(userInfo.get) must beEqualTo(OK)
+        val node = Json.parse(contentAsString(userInfo.get))
         (node \ "totalCount").as[Long] must be_==(1L)
         ((node \ "result")(0) \ "user_id").as[Long] must be_==(0L)
         ((node \ "result")(0) \ "user_display_name").as[String] must be_==("name")
-        ((node \ "result")(0) \ "google_user_id").as[String] must be_==("gid")
-        ((node \ "result")(0) \ "google_display_name").as[String] must be_==("guser")
-        ((node \ "result")(0) \ "google_public_profile_url").as[String] must be_==("gurl")
-        ((node \ "result")(0) \ "google_public_profile_photo_url").as[String] must be_==("gphoto")
-
-      DB.withConnection {implicit conn =>
-        SQL("""delete from UserInform""").executeUpdate
+        ((node \ "result")(0) \ "google_user_id").as[String] must be_==("")
+        ((node \ "result")(0) \ "google_display_name").as[String] must be_==("")
+        ((node \ "result")(0) \ "google_public_profile_url").as[String] must be_==("")
+        ((node \ "result")(0) \ "google_public_profile_photo_url").as[String] must be_==("")
       }
     }
-
   }
 }
diff --git a/test/BookShelfSpec.scala b/test/BookShelfSpec.scala
deleted file mode 100644
index 1efc925..0000000
--- a/test/BookShelfSpec.scala
+++ /dev/null
@@ -1,89 +0,0 @@
-package test
-
-import org.specs2.mutable._
-import play.api.test._
-import play.api.test.Helpers._
-import models.BookShelf
-import org.specs2.matcher._
-import org.specs2.specification.Scope
-import models.BookShelf
-import java.math.BigInteger
-import models.BookShelf
-
-class BookShelfSpec extends Specification {
-
-  // 基本的なデータの追加・削除をするためのtrait
-  trait scope extends Scope with After {
-    val result: BigInteger = BookShelf.insert("book shelf", "shelf description", BigInteger.valueOf(0L))
-
-    def after = {
-      BookShelf.delete(result)
-    }
-  }
-
-  trait manyData extends Scope with After {
-    val results: List[BigInteger] = (1 to 10).map { e =>
-      BookShelf.insert("book shelf" + e.toString, "shelf description" + e.toString, BigInteger.valueOf(0L))
-    }.toList
-
-    def after = {
-      results.map(BookShelf.delete)
-    }
-
-  }
-
-  "BookShelf" should {
-    "can insert and delete a book shelf information" in {
-      running(FakeApplication()) {
-        val result = BookShelf.insert("book shelf", "shelf description", BigInteger.valueOf(0L))
-        result must beGreaterThan(BigInteger.valueOf(0L))
-        BookShelf.delete(result) must beEqualTo(1)
-      }
-    }
-
-    "can be selected a registered book shelfs by the ID" in {
-      running(FakeApplication()) {
-        new scope {
-          val shelf: Option[BookShelf] = BookShelf.selectById(result)
-          shelf must beSome
-          val s = shelf.get
-          s.name must beEqualTo("book shelf")
-          s.description must beEqualTo("shelf description")
-          val jsoned = BookShelf.toJson(s)
-          (jsoned \ "created_date").as[String] must be_==("%tF %<tT" format s.created)
-          (jsoned \ "updated_date").as[String] must be_==("%tF %<tT" format s.updated)
-        }
-      }
-    }
-
-    "can select many registered book shelf with limitation" in {
-      running(FakeApplication()) {
-        new manyData {
-          {
-            val shelfs: List[BookShelf] = BookShelf.all(None, None)
-            shelfs.size must beEqualTo(10)
-          }
-
-          {
-            val shelfs = BookShelf.all(Some(3), None)
-            shelfs.size must beEqualTo(10)
-            shelfs.map { s => s.name.startsWith("book shelf") must beTrue }
-          }
-
-          {
-            val shelfs = BookShelf.all(None, Some(2))
-            shelfs.size must beEqualTo(2)
-            shelfs.map { s => s.name.startsWith("book shelf") must beTrue }
-          }
-
-          {
-            val shelfs = BookShelf.all(Some(4), Some(2))
-            shelfs.size must beEqualTo(2)
-            shelfs.map { s => s.name.startsWith("book shelf") must beTrue }
-          }
-        }
-      }
-    }
-  }
-
-}
diff --git a/test/BookShelvesSpec.scala b/test/BookShelvesSpec.scala
new file mode 100644
index 0000000..01ba5ca
--- /dev/null
+++ b/test/BookShelvesSpec.scala
@@ -0,0 +1,102 @@
+package test
+
+import java.sql.Date
+import java.util.Calendar
+import org.specs2.mutable._
+import play.api.test._
+import play.api.test.Helpers._
+import models._
+import org.specs2.matcher._
+import org.specs2.specification._
+import db.wrapper.specs2.AutoRollback
+import scala.slick.driver.MySQLDriver.simple._
+
+class BookShelvesSpec extends Specification {
+
+  def now = new Date(Calendar.getInstance.getTimeInMillis)
+
+  // 基本的なデータの追加・削除をするためのtrait
+  trait OneDataAutoRollback extends AutoRollback {
+    override def fixture(implicit session:Session): Unit = {
+      val result = BookShelves.ins.insert("book shelf", "shelf description", now, 0L, now, 0L)
+      val userId = UserInforms.ins.insert("name", "gid", "guser", "gurl", "gphoto", "token", Some("refresh"),
+        Some(0L), Some(0L), now, 0L, now, 0L)
+
+      (for (r <- UserInforms if r.userId === userId) yield (r.userId)).update(0L)
+      (for {b <- BookShelves if b.id === result} yield b.id).update(0L)
+    }
+  }
+
+  trait ManyDataAutoRollback extends AutoRollback {
+
+    override def fixture(implicit session:Session): Unit = {
+      val results: List[Long] = (1 to 10).map { e =>
+        BookShelves.ins.insert("book shelf", "shelf description", now, 0L, now, 0L)
+      }.toList
+      results.zipWithIndex.foreach {case (r : Long, index: Int) =>
+        (for {b <- BookShelves if b.id === r} yield b.id).update(index)
+      }
+      val userId = UserInforms.ins.insert("name", "gid", "guser", "gurl", "gphoto", "token", Some("refresh"),
+        Some(0L), Some(0L), now, 0L, now, 0L)
+
+      (for (r <- UserInforms if r.userId === userId) yield (r.userId)).update(0L)
+    }
+  }
+
+  "BookShelf" should {
+    "can insert and delete a book shelf information" in {
+      running(FakeApplication()) {
+        new AutoRollback {
+          val result = BookShelves.ins.insert("book shelf", "shelf description", now, 0L, now, 0L)
+          result must beGreaterThan(0L)
+          BookShelves.delete(result) must beEqualTo(1)
+        }
+      }
+    }
+
+    "can be selected a registered book shelfs by the ID" in {
+      running(FakeApplication()) {
+        new OneDataAutoRollback {
+          val shelf= BookShelves.selectById(0L)
+          shelf must beSome
+          val s = shelf.get._1
+          s.name must beEqualTo("book shelf")
+          s.description must beEqualTo("shelf description")
+          val jsoned = BookShelves.toJson(s)
+          (jsoned \ "created_date").as[String] must be_==("%tF %<tT" format s.created)
+          (jsoned \ "updated_date").as[String] must be_==("%tF %<tT" format s.updated)
+        }
+      }
+    }
+
+    "can select many registered book shelf with limitation" in {
+      running(FakeApplication()) {
+        new ManyDataAutoRollback {
+          {
+            val shelfs = BookShelves.findAll(None, None)
+            shelfs.size must beEqualTo(10)
+          }
+
+          {
+            val shelfs = BookShelves.findAll(Some(3), None)
+            shelfs.size must beEqualTo(7)
+            shelfs.map {case (s,_, _) => s.name.startsWith("book shelf") must beTrue }
+          }
+
+          {
+            val shelfs = BookShelves.findAll(None, Some(2))
+            shelfs.size must beEqualTo(2)
+            shelfs.map { case (s,_,_) => s.name.startsWith("book shelf") must beTrue }
+          }
+
+          {
+            val shelfs = BookShelves.findAll(Some(4), Some(2))
+            shelfs.size must beEqualTo(2)
+            shelfs.map { case (s, _,_) => s.name.startsWith("book shelf") must beTrue }
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/test/BookSpec.scala b/test/BookSpec.scala
deleted file mode 100644
index 8d27fe9..0000000
--- a/test/BookSpec.scala
+++ /dev/null
@@ -1,147 +0,0 @@
-package test
-
-import anorm._
-import java.sql.Connection
-import java.util.Date
-import models.UserInform
-import org.specs2.mutable._
-import play.api.db._
-import play.api.Play.current
-import play.api.test._
-import play.api.test.Helpers._
-import models.Book
-import org.specs2.matcher._
-import org.specs2.specification.Scope
-import models.Book
-import java.math.BigInteger
-import models.BookShelf
-import models.BookRegister
-import models.BookDetail
-import models.BookShelf
-import models.Book
-
-class BookSpec extends Specification {
-
-  // 基本的なデータの追加・削除をするためのtrait
-  trait scope extends Scope with After {
-    val shelfId : BigInteger = BookShelf.insert("book shelf", "description", BigInteger.valueOf(0L))
-    val result: BigInteger = Book.insert(
-      BookRegister(shelfId, "book name", Some("book author"), Some("book isbn"),
-        None, Some("large image url"), Some("medium image url"), Some("small image url")),
-      BigInteger.valueOf(0L)
-    ).right.get
-    println(Book.selectById(result))
-
-    DB.withConnection {implicit conn:Connection =>
-      SQL(
-        """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-      val user = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-      SQL(
-        """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> user).executeUpdate
-    }
-
-    def after = {
-      BookShelf.delete(shelfId)
-      Book.delete(result)
-      UserInform.delete(BigInteger.valueOf(0L))
-    }
-  }
-
-  trait manyData extends Scope with After {
-    val shelfId : BigInteger = BookShelf.insert("book shelf", "description", BigInteger.valueOf(0L))
-    val results: List[BigInteger] = (1 to 10).map { e =>
-      Book.insert(BookRegister(shelfId, "book name" + e.toString, Some("book author" + e.toString),
-        Some(e.toString), None, Some("large image url"), Some("medium image url"), Some("small image url")
-      ),BigInteger.valueOf(0L)).right.get
-    }.toList
-
-    DB.withConnection {implicit conn:Connection =>
-      SQL(
-        """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-      val user = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-      SQL(
-        """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> user).executeUpdate
-    }
-
-    def after = {
-      results.map(Book.delete)
-      BookShelf.delete(shelfId)
-      UserInform.delete(BigInteger.valueOf(0L))
-    }
-  }
-
-  "Book" should {
-    "can insert and delete a book information in the book shelf" in {
-      running(FakeApplication()) {
-        val shelfId = BookShelf.insert("book shelf", "description", BigInteger.valueOf(0L))
-        val result = Book.insert(BookRegister(shelfId, "book name", Some("author"), Some("isbn"),
-          None, None, None, None), BigInteger.valueOf(0L))
-
-        result must beAnInstanceOf[Either[String, BigInteger]]
-        val id = result.right.get
-        id must beGreaterThan(BigInteger.valueOf(0L))
-        Book.delete(id) must beEqualTo(1)
-        BookShelf.delete(shelfId) must beEqualTo(1)
-      }
-    }
-
-    "can be selected a registered book in the book shelf by the ID" in {
-      running(FakeApplication()) {
-        new scope {
-          val shelf: Option[BookDetail] = Book.selectById(result)
-          shelf must beSome
-          val s = shelf.get
-          s.name must beEqualTo("book name")
-          s.author must beEqualTo(Some("book author"))
-          s.isbn must beEqualTo(Some("book isbn"))
-          s.publishedDate must beNone
-          s.largeImageUrl must be_==(Some("large image url"))
-          s.mediumImageUrl must be_==(Some("medium image url"))
-          s.smallImageUrl must be_==(Some("small image url"))
-          val jsoned = Book.toJson(s)
-          (jsoned \ "created_date").as[String] must be_==("%tF %<tT" format s.created)
-          (jsoned \ "updated_date").as[String] must be_==("%tF %<tT" format s.updated)
-        }
-      }
-    }
-
-    "can select many registered book shelf with limitation" in {
-      running(FakeApplication()) {
-        new manyData {
-          {
-            val books: List[BookDetail] = Book.allInShelf(shelfId, None, None)
-            books.size must beEqualTo(10)
-          }
-
-          {
-            val books = Book.allInShelf(shelfId, Some(3), None)
-            books.size must beEqualTo(10)
-            books.map { s => s.name.startsWith("book name") must beTrue }
-          }
-
-          {
-            val books = Book.allInShelf(shelfId, None, Some(2))
-            books.size must beEqualTo(2)
-            books.map { s => s.name.startsWith("book name") must beTrue }
-          }
-
-          {
-            val books = Book.allInShelf(shelfId, Some(4), Some(2))
-            books.size must beEqualTo(2)
-            books.map { s => s.name.startsWith("book name") must beTrue }
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/test/BooksSpec.scala b/test/BooksSpec.scala
new file mode 100644
index 0000000..3bbfa06
--- /dev/null
+++ b/test/BooksSpec.scala
@@ -0,0 +1,116 @@
+package test
+
+import anorm._
+import java.util.Calendar
+import java.sql.Date
+import models._
+import org.specs2.mutable._
+import play.api.test._
+import play.api.test.Helpers._
+import org.specs2.matcher._
+import org.specs2.specification.Scope
+import scala.slick.driver.MySQLDriver.simple.{Session =>_, _}
+import scala.slick.driver.MySQLDriver.simple.{Session => DBSession}
+import db.wrapper.specs2._
+
+class BookSpec extends Specification {
+
+  def now = new Date(Calendar.getInstance.getTimeInMillis)
+
+  trait OneDataWithAutoRollback extends AutoRollback {
+    override def fixture(implicit session:DBSession): Unit = {
+      val shelfId = BookShelves.ins.insert("book shelf", "description", now, 0L, now, 0L)
+      val bookId = Books.ins.insert(0L, "book name", Some("book author"), Some("book isbn"),
+        None, Some("large image url"), Some("medium image url"), Some("small image url"),
+        now, 0L, now, 0L)
+      val userId = UserInforms.ins.insert("name", "gid", "guser", "gurl", "gphoto", "token", Some("refresh"),
+        Some(0L), Some(0L), now, 0L, now, 0L)
+
+      (for (r <- UserInforms if r.userId === userId) yield (r.userId)).update(0L)
+      (for (r <- Books if r.bookId === bookId) yield (r.bookId)).update(0L)
+      (for (r <- BookShelves if r.id === shelfId) yield (r.id)).update(0L)
+    }
+  }
+
+  trait manyData extends AutoRollback {
+    override def fixture(implicit session:DBSession): Unit = {
+      val shelfId = BookShelves.ins.insert("book shelf", "description", now, 0L, now, 0L)
+
+      val bookIds: List[Long] = (1 to 10).map { e =>
+        Books.ins.insert(0L, "book name" + e.toString, Some("book author" + e.toString),
+          Some(e.toString), None, Some("large image url"), Some("medium image url"), Some("small image url"),
+          now, 0L, now, 0L)
+      }.toList
+      val userId = UserInforms.ins.insert("name", "gid", "guser", "gurl", "gphoto", "token", Some("refresh"),
+        Some(0L), Some(0L), now, 0L, now, 0L)
+
+      bookIds.zipWithIndex.foreach{case (bid, index) =>
+          (for {b <- Books if b.bookId === bid} yield (b.bookId)).update(index)}
+      (for (r <- UserInforms if r.userId === userId) yield (r.userId)).update(0L)
+      (for (r <- BookShelves if r.id === shelfId) yield (r.id)).update(0L)
+    }
+  }
+
+  "Book" should {
+    "can insert and delete a book information in the book shelf" in {
+      running(FakeApplication()) {
+        new AutoRollback {
+          val result = Books.ins.insert(0L, "book name", Some("author"), Some("isbn"),
+            None, None, None, None, now, 0L, now, 0L)
+
+          result must beGreaterThan(0L)
+          Books.delete(result) must beEqualTo(1)
+        }
+      }
+    }
+
+    "can be selected a registered book in the book shelf by the ID" in {
+      running(FakeApplication()) {
+        new OneDataWithAutoRollback {
+          val book = Books.selectById(0L)
+          book must beSome
+          val s = book.get._1
+          s.name must beEqualTo("book name")
+          s.author must beEqualTo(Some("book author"))
+          s.isbn must beEqualTo(Some("book isbn"))
+          s.publishedDate must beNone
+          s.largeImageUrl must be_==(Some("large image url"))
+          s.mediumImageUrl must be_==(Some("medium image url"))
+          s.smallImageUrl must be_==(Some("small image url"))
+          val jsoned = Books.toJson(s)
+            (jsoned \ "created_date").as[String] must be_==("%tF %<tT" format s.created)
+            (jsoned \ "updated_date").as[String] must be_==("%tF %<tT" format s.updated)
+        }
+      }
+    }
+
+    "can select many registered book shelf with limitation" in {
+      running(FakeApplication()) {
+        new manyData {
+          {
+            val books = Books.findAllInShelf(0L, None, None)
+            books.size must beEqualTo(10)
+          }
+
+          {
+            val books = Books.findAllInShelf(0L, Some(3), None)
+            books.size must beEqualTo(7)
+            books.map { case (s, _, _) => s.name.startsWith("book name") must beTrue }
+          }
+
+          {
+            val books = Books.findAllInShelf(0L, None, Some(2))
+            books.size must beEqualTo(2)
+            books.map { case (s, _, _) => s.name.startsWith("book name") must beTrue }
+          }
+
+          {
+            val books = Books.findAllInShelf(0L, Some(4), Some(2))
+            books.size must beEqualTo(2)
+            books.map { case (s, _, _) => s.name.startsWith("book name") must beTrue }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/test/RentalSpec.scala b/test/RentalSpec.scala
index 0e03133..ca789a3 100644
--- a/test/RentalSpec.scala
+++ b/test/RentalSpec.scala
@@ -1,124 +1,75 @@
 package test

-import anorm._
-import java.math.BigInteger
-import models.RentalInform
-import models.UserInform
+import java.sql.Date
+import java.util.Calendar
+import models._
 import org.specs2.matcher._
 import org.specs2.mutable._
-import org.specs2.specification.Scope
-import play.api.db._
 import play.api.test._
 import play.api.test.Helpers._
 import play.api.libs.json._
 import play.api.libs.functional.syntax._
+import db.wrapper.specs2.AutoRollback
+import scala.slick.driver.MySQLDriver.simple.{Session =>_, _}
+import scala.slick.driver.MySQLDriver.simple.{Session => DBSession}

 class RentalSpec extends Specification {

-  "Rental" should {
-    "be able to rental book" in new WithApplication {
-      DB.withConnection {implicit conn =>
-        SQL(
-          """
-          insert into book values (0, 0, '', '', '', '2012-01-01 00:00:00', '', '', '', '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val id = SQL("select last_insert_id() as lastnum from book").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update book set book_id = 0 where book_id = {id}
-          """).on('id -> id).executeUpdate
-        SQL(
-          """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val user = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> user).executeUpdate
-      }
+  val now = new Date(Calendar.getInstance.getTimeInMillis())

-      val req: Map[String, Seq[String]] = Map("rental_book" -> Seq("0"))
-      val result = route(FakeRequest(POST, "/api/rental").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"), req)
+  trait OneDataAutoRollback extends AutoRollback {
+    override def fixture(implicit session :DBSession): Unit = {
+      val book = Books.ins.insert(0L, "", None, None, None, None, None, None, now, 0L, now, 0L)
+      (for {b <- Books if b.bookId === book} yield (b.bookId)).update(0L)

-      result must beSome
-      status(result.get) must beEqualTo(OK)
+      val user = UserInforms.ins.insert("", "", "", "", "", "", None, None, None, now, 0L, now, 0L)
+      (for {
+        u <- UserInforms
+        if u.userId === user
+      } yield (u.userId)).update(0L)
+    }
+  }

-      val rentalId : Long =
-        ((Json.parse(contentAsString(result.get)) \ "result")(0) \ "rental_id").as[Long]
+  "Rental" should {
+    "be able to rental book" in new WithApplication {
+      new OneDataAutoRollback {
+        val req: Map[String, Seq[String]] = Map("rental_book" -> Seq("0"))
+        val result = route(FakeRequest(POST, "/api/rental").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"), req)
+
+        result must beSome
+        status(result.get) must beEqualTo(OK)

-      val rentaled = route(FakeRequest(GET, "/api/rental/%d" format rentalId).withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"))
+        val rentalId : Long =
+          ((Json.parse(contentAsString(result.get)) \ "result")(0) \ "rental_id").as[Long]

-      rentaled must beSome
-      val info = Json.parse(contentAsString(rentaled.get))
-      (info \ "totalCount").as[Long] must be_==(1L)
-      ((info \ "result")(0) \ "rental_user_id").as[Long] must be_==(0L)
-        ((info \ "result")(0) \ "rental_book_id").as[Long] must be_==(0L)
-        ((info \ "result")(0) \ "rental_now").as[Boolean] must beTrue
+        val rentaled = route(FakeRequest(GET, "/api/rental/%d" format rentalId).withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"))

-      DB.withConnection {implicit conn =>
-        SQL("""delete from RentalInform""").executeUpdate
-        SQL("""delete from book""").executeUpdate
-        SQL("""delete from UserInform""").executeUpdate
+        rentaled must beSome
+        val info = Json.parse(contentAsString(rentaled.get))
+          (info \ "totalCount").as[Long] must be_==(1L)
+          ((info \ "result")(0) \ "rental_user_id").as[Long] must be_==(0L)
+          ((info \ "result")(0) \ "rental_book_id").as[Long] must be_==(0L)
+          ((info \ "result")(0) \ "rental_now").as[Boolean] must beTrue
       }
     }

     "be able to get rental infomation by book id" in new WithApplication {
-      DB.withConnection {implicit conn =>
-        SQL(
-          """
-          insert into book values (0, 0, '', '', '', '2012-01-01 00:00:00', '', '', '', '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val id = SQL("select last_insert_id() as lastnum from book").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update book set book_id = 0 where book_id = {id}
-          """).on('id -> id).executeUpdate
-        SQL(
-          """
-          insert into UserInform values (0, 'name', 'gid', 'guser', 'gurl', 'gphoto', 'token', 'refresh', 0, 0, '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val user = SQL("select last_insert_id() as lastnum from UserInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update UserInform set user_id = 0 where user_id = {id}
-          """).on('id -> user).executeUpdate
-
-        SQL(
-          """
-          insert into RentalInform values (0, 0, 0, '1', '2012-01-01 00:00:00', '',
-          '2012-01-01 00:00:00', '')
-          """).executeUpdate
-        val rental = SQL("select last_insert_id() as lastnum from RentalInform").apply.head[BigInteger]("lastnum")
-        SQL(
-          """
-          update RentalInform set rental_id = 0 where rental_id = {id}
-          """).on('id -> rental).executeUpdate
-      }
-
-      val result = route(FakeRequest(GET, "/api/rental/?book_id=0").withHeaders(
-        CONTENT_TYPE -> "application/x-www-form-urlencode"))

-      result must beSome
-      println(contentAsString(result.get))
-      status(result.get) must beEqualTo(OK)
+      new OneDataAutoRollback {
+        val result = route(FakeRequest(GET, "/api/rental/?book_id=0").withHeaders(
+          CONTENT_TYPE -> "application/x-www-form-urlencode"))

-      val info = Json.parse(contentAsString(result.get))
-      (info \ "totalCount").as[Long] must be_==(1L)
-      ((info \ "result")(0) \ "rental_user_id").as[Long] must be_==(0L)
-        ((info \ "result")(0) \ "rental_book_id").as[Long] must be_==(0L)
-        ((info \ "result")(0) \ "rental_now").as[Boolean] must beTrue
+        result must beSome
+        println(contentAsString(result.get))
+        status(result.get) must beEqualTo(OK)

-      DB.withConnection {implicit conn =>
-        SQL("""delete from RentalInform""").executeUpdate
-        SQL("""delete from book""").executeUpdate
-        SQL("""delete from UserInform""").executeUpdate
+        val info = Json.parse(contentAsString(result.get))
+          (info \ "totalCount").as[Long] must be_==(1L)
+          ((info \ "result")(0) \ "rental_user_id").as[Long] must be_==(0L)
+          ((info \ "result")(0) \ "rental_book_id").as[Long] must be_==(0L)
+          ((info \ "result")(0) \ "rental_now").as[Boolean] must beTrue
       }
     }
   }
diff --git a/test/db/wrapper/spec2/AutoRollback.scala b/test/db/wrapper/spec2/AutoRollback.scala
new file mode 100644
index 0000000..3dcae13
--- /dev/null
+++ b/test/db/wrapper/spec2/AutoRollback.scala
@@ -0,0 +1,30 @@
+package db.wrapper.specs2
+
+import java.sql.Connection
+import org.specs2.mutable.After
+import models.DBWrap.DBEnable
+import scala.slick.driver.MySQLDriver.simple._
+
+// traitの範囲を終了した時点で、行われたものをrollbackする。
+trait AutoRollback extends After with DBEnable {
+  implicit val session : Session = db.createSession()
+  session.conn.setAutoCommit(false)
+
+  fixture
+
+  // 事前にデータの登録などを行いたい場合、このtraitを継承したtraitで
+  // この関数をオーバーライドする。
+  def fixture(implicit conn : Session) :Unit = {}
+
+  // afterの処理は書き換え不可とする
+  final override def after = {
+    session.rollback()
+    session.close()
+  }
+}
+
+
+
+
+
+