doobie icon indicating copy to clipboard operation
doobie copied to clipboard

Create a column name based result set mapper

Open Daenyth opened this issue 6 years ago • 8 comments

As opposed to doobie's existing positional-only mapper.

@tpolecat If someone wanted to write and contribute this, what should they start looking at?

Daenyth avatar Jun 15 '18 17:06 Daenyth

In terms of the 0.6 API Get and Put will need methods that take column names (easy) and Read and Write will need derivations based on NamedGeneric to make them aware of field names. You'll also probably need a strategy for dealing with renames … camelcase to snake case, etc. And we'll need a way to deal with prioritization of structural vs. name-based derivations, possibly by switching to a semi-automatic strategy like Circe has.

tpolecat avatar Jun 15 '18 17:06 tpolecat

I'd rather have ability to define column name based instances manually. Much easier to implement and harder for something to break.

wedens avatar Jun 15 '18 17:06 wedens

I was working on schema support for doobie concept, which I was planning to evolve into some slick like DSL for doobie. Maybe you'll find interesting the idea. https://gist.github.com/YulawOne/736764054a5e9dfda03e7ffb398f8efd

YulawOne avatar Jun 20 '18 18:06 YulawOne

For me a manual mapping would be already useful. Currently I'm using ScalikeJDBC with mapping defined like this:

  private def authorityFromRs(rs: WrappedResultSet): Authority =
    Authority(
      rs.long("id"),
      rs.string("name"),
      rs.string("description")
    )

where Authority is my model case class.

That's boilerplate of course, but it's easy to understand and implement. An ability to have such a simple manual mapping for cases where automatic derivation is not convenient would make doobie more approachable in my opinion.

antonyshchenko avatar Jun 26 '18 14:06 antonyshchenko

Is there really still no way to set mapping based on column names? That's a deal breaker. I have to resort to scalikejdbc now :'(

vasily802 avatar May 22 '20 00:05 vasily802

@vasily802 It's possible to do it, it just isn't built into the library. Ask on gitter, I don't know who has the code but it's also possible to write on your own

For one example of name-based derivation (for another library), one could consult Cormorant's LabelledRead, which performs the equivalent row decode operation for CSV inputs. https://github.com/ChristopherDavenport/cormorant/blob/master/modules/generic/src/main/scala/io/chrisdavenport/cormorant/generic/semiauto.scala#L40

Daenyth avatar May 22 '20 14:05 Daenyth

You might look at the Quill integration, which works based on name.

tpolecat avatar May 22 '20 15:05 tpolecat

For whoever needs this, there is workaround using low-level api. You can do it by referring to https://github.com/tpolecat/doobie/blob/dc960d95654c6580725b6b2146df3389dcae5a2d/modules/example/src/main/scala/example/FreeUsage.scala#L45

You can implement it like

 
   l <- FPS.executeQuery.bracket {  rs =>
       FPS.embed(rs, FRS.raw {resultSetToRecords})
   } (FPS.embed(_, FRS.close))
  
   ...

  def resultSetToRecords(rs: ResultSet): List[YourRecord] = { 
     while (rs. next()) {
         val yourRecord =  ...
     }
    ...
  }
  

chenjianjx avatar Mar 15 '24 06:03 chenjianjx