scala - Using the Parser API with nullable columns in Anorm 2.4 -
i'm struggling rid of deprecation warnings i've upgraded anorm 2.4. i've had @ how handle null in anorm didn't me enough.
let's take simple example: account
database table:
id
(bigint not null)email_address
(varchar not null)first_name
(varchar)last_name
(varchar)
i have 2 functions in scala code: getaccountofid
, getaccountsoflastname
.
getaccountofid
returns 0 or 1 account, thereforeoption[(long, string, option[string], option[string])]
keep our example simplegetaccountsoflastname
returns list of accounts (which potentially have size of 0), thereforelist[(long, string, option[string], string)]
keep our example simple
part of code of these 2 functions:
def getaccountofid(id: long): option[(long, string, option[string], option[string])] = { db.withconnection { implicit c => val query = """select email_address, first_name, last_name account id = {id};""" /* rest of code struggle unless use deprecated functions */ } } def getaccountsoflastname(lastname: string): list[(long, string, option[string], string)] = { db.withconnection { implicit c => val query = """select id, email_address, first_name account last_name = {lastname};""" /* rest of code struggle unless use deprecated functions */ } }
i want "rest of code" in these 2 functions based on anorm's parser api.
not sure if helps, using anorm 2.4, have case class looks this:
final case class role(id: int, label: string, roletype: int, lid: option[int], aid: option[int], created: datetime, modified: datetime)
and have parser combinator looks this:
val roleoptionrowparser = int("id") ~ str("label") ~ int("roletype") ~ (int("lid")?) ~ (int("vid")?) ~ get[datetime]("created") ~ get[datetime]("modified") map { case id~label~roletype~lid~vid~created~modified ⇒ some(role(id, label, roletype, lid, vid, created, modified)) case _ ⇒ none }
so parse out using ? combinator optional fields, match based on extract sql result row. can apply queries in following way:
sql(s""" | select * $source | $clause """.stripmargin).on(params : _*).as(rowparser.single).get
where 'rowparser' in case reference roleoptionrowparser defined in last lump of code.
if have multiple rows returned query (or expect have multiple rows) can apply same combinators (such ? or *) before passing them through 'as' function this:
sql(s""" | select * $source | $clause """.stripmargin).on(params : _*).as(rowparser *).flatten
or
sql(s""" | select * $source | $clause """.stripmargin).on(params : _*).as(rowparser ?).flatten
ah - forgot mention 'flatten' on end there because parser in example returns option[role], depending on whether necessary column values present in returned row (this bit):
case id~label~roletype~lid~vid~created~modified ⇒ some(role(id, label, roletype, lid, vid, created, modified))
so, when multiple rows returned, apply 'flatten' uplift out of option type end list of actual 'role' instances.
cheers,
hth.
Comments
Post a Comment