2012-10-02 24 views
6

Tôi đã xem computer-database sample và tôi nhận thấy rằng để sử dụng lại trình phân tích Máy tính, phương pháp danh sách sử dụng trình phân tích cú pháp Computer.withCompany, trả về một bộ tuple của (Computer, Công ty)cách sử dụng lại trình phân tích cú pháp anorm trong playframework 2.0 với scala

trong trường hợp tôi phải xử lý, thay vì một tham chiếu đến id của máy tính tôi muốn có một đối tượng Computer, như

trường hợp lớp máy tính này (id: Vn [ Long] = Không được gán, tên: Chuỗi, được giới thiệu: Tùy chọn [Ngày], đã ngừng: Tùy chọn [Ngày], công ty: Công ty)

vì vậy tôi đã nghĩ ing làm thế nào tôi có thể đạt được một cái gì đó như sau (seudocode của nó, tất nhiên)

val simple = { 
    get[Pk[Long]]("computer.id") ~ 
    get[String]("computer.name") ~ 
    get[Option[Date]]("computer.introduced") ~ 
    get[Option[Date]]("computer.discontinued") ~ 
    get[Company]("company.*") map { 
    case id~name~introduced~discontinued~company => Computer(id, name, introduced, discontinued, company) 
    } 
} 

Rõ ràng, phần khó khăn sẽ là như thế nào để giải quyết phương thức getCompany

bất kỳ ý tưởng ???

Trả lời

5

Tôi có một thực thể Idea và một thực thể IdeaType (nó giống như máy tính và Công ty, trong ví dụ máy tính cơ sở dữ liệu)

case class IdeaTest(
    val id: Pk[Long]   = NotAssigned, 
    val name: String   = "unknown idea", 
    val description: String = "no description", 
    val kind: IdeaType  = IdeaType() 
) 

case class IdeaType (
    val id: Pk[Long] = NotAssigned, 
    val name: String = "unknown idea type", 
    val description: String = "no description" 
) 

tôi xác định một TypeParser

val typeParser: RowParser[IdeaType] = { 
    get[Pk[Long]]("idea_type.id") ~ 
    get[String]("idea_type.name") ~ 
    get[String]("idea_type.description") map { 
    case id~name~description => IdeaType(
     id, name, description 
    ) 
    } 
} 

Và điều đầu tiên tôi đã thử là:

val ideaParser: RowParser[IdeaTest] = { 
    get[Pk[Long]]("idea.id") ~ 
    get[String]("idea.name") ~ 
    get[String]("idea.description") ~ 
    typeParser map { 
    case id~name~description~ideaType => IdeaTest(
     id, name, description, ideaType 
    ) 
    } 
} 

Mặc dù nó biên dịch ok, luôn gặp sự cố khi tải IdeaType.

Cuối cùng, tôi phải xác định một ideaParser không có ideaType và soạn nó với một typeParser:

val typeParser: RowParser[IdeaType] = { 
    get[Pk[Long]]("idea_type.id") ~ 
    get[String]("idea_type.name") ~ 
    get[String]("idea_type.description") map { 
    case id~name~description => IdeaType(
     id, name, description 
    ) 
    } 
} 

val ideaWithTypeParser = ideaParser ~ typeParser map { 
    case idea~kind => (idea.copy(kind=kind)) 
} 

và đây là mã sử dụng nó:

def ideaById(id: Long): Option[IdeaTest] = { 
    DB.withConnection { implicit connection => 
    SQL(""" 
     select * from 
     idea inner join idea_type 
     on idea.idea_type_id = idea_type.id 
     where idea.id = {id}"""). 
     on('id -> id). 
     as(ideaParser.singleOpt) 
    } 
} 

duy nhất gặp rắc rối tôi thấy, là tôi phải tạo đối tượng IdeaTest trong trạng thái không nhất quán (không có ideaType) và sau đó sao chép nó vào một cá thể khác bằng IdeaType chính xác.

+1

Câu trả lời này thực sự hữu ích và giúp củng cố kiến ​​thức của tôi về việc soạn thảo các trình phân tích cú pháp, cảm ơn! – EdgeCaseBerg

Các vấn đề liên quan