RB_
RB_

Reputation: 1192

variable columns amount Anorm result set parser

I'm experimenting with scala, here is my stack:

I want to create a result set parser with Anorm that will be able to parse any amount of columns that I select from a given table. Here is my code:

case class Campaign(id: Int, campaign_mode_id: Int, name: String)

class Application @Inject()(db: Database) extends Controller {

  val campaign = {
    get[Int]("campaign.id") ~
    get[Int]("campaign.campaign_mode_id") ~
    get[String]("campaign.name") map {
      case id ~ campaign_mode_id ~ name  => Campaign(id, campaign_mode_id, name)
    }
  }

  def index = Action {
    val data : List[Campaign] = db.withConnection { implicit connection =>
      SQL("SELECT id, campaign_mode_id, name FROM campaign").as(campaign.*)
    }

    Ok(views.html.index(data))
  }
} 

I want to be able to run following Sqls and still use the same case class Campaign:

SELECT id, name FROM campaign
SELECT name FROM campaign

How can I achieve this functionality ?

UPDATE:

I updated my code changing type of some fields to Option:

case class Campaign(id: Int, campaign_mode_id: Option[Int], name: Option[String])

class Application @Inject()(db: Database) extends Controller {

  val campaign = {
    get[Int]("campaign.id") ~
    get[Option[Int]]("campaign.campaign_mode_id") ~
    get[Option[String]]("campaign.name") map {
      case id ~ campaign_mode_id ~ name  => Campaign(id, campaign_mode_id, name)
    }
  }

  def index = Action {
    val data : List[Campaign] = db.withConnection { implicit connection =>
      SQL("SELECT id, name FROM campaign").as(campaign.*)
    }

    Ok(views.html.index(data))
  }
}

This code produces following error:

[RuntimeException: campaign.campaign_mode_id not found, available columns : campaign.id, id, campaign.name, name]

Upvotes: 0

Views: 639

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

If the column campaign_mode_id is nullable, parses to Option[Int] and is always present in the result set, use:

get[Option[Int]]("campaign.campaign_mode_id")

If the column campaign_mode_id is not nullable, may not appear in the result set, and parses to Option[Int], use:

get[Int]("campaign.campaign_mode_id").?

In your case, it seems like you want:

val campaign = {
  get[Int]("campaign.id") ~
  get[Int]("campaign.campaign_mode_id").? ~
  get[String]("campaign.name").? map {
     case id ~ campaign_mode_id ~ name  => Campaign(id, campaign_mode_id, name)
  }
}

This assumes that campaign.campaign_mode_id and compaign.name are both non-nullable, but are optional in the result set.

Upvotes: 2

Related Questions