0

Suppose I have a normalized database model for a generic type that comes in like this:

case class BaseModel(id: String, 
                     createdBy: String,
                     attr1: Option[String] = None,
                     attr2: Option[Int] = None, 
                     attr3: Option[LocalDate] = None)

Given a sequence of BaseModel, if all the fields of a certain Option attribute are not populated, can shapeless create a reduced model for me?

For example suppose that all the attr1 fields are empty. Without me having to specify the object before hand can shapeless create a generic object that looks like this?

case class BaseModel(id: String, 
                     createdBy: String,
                     attr2: Option[Int] = None, 
                     attr3: Option[LocalDate] = None)
franklin
  • 1,800
  • 7
  • 32
  • 59

1 Answers1

1

What Shapeless can do is, given two case classes, create an object of one of them from an object of another.

import java.time.LocalDate
import shapeless.LabelledGeneric
import shapeless.record._

case class BaseModel(id: String,
                     createdBy: String,
                     attr1: Option[String] = None,
                     attr2: Option[Int] = None,
                     attr3: Option[LocalDate] = None)

case class BaseModel1(id: String,
                      createdBy: String,
                      attr2: Option[Int] = None,
                      attr3: Option[LocalDate] = None)

val bm = BaseModel(
  id = "cff4545gvgf", 
  createdBy = "John Doe", 
  attr2 = Some(42), 
  attr3 = Some(LocalDate.parse("2018-11-03"))
)  // BaseModel(cff4545gvgf,John Doe,None,Some(42),Some(2018-11-03))
val hlist = LabelledGeneric[BaseModel].to(bm)
val hlist1 = hlist - 'attr1
val bm1 = LabelledGeneric[BaseModel1].from(hlist1)    
   // BaseModel1(cff4545gvgf,John Doe,Some(42),Some(2018-11-03))

But Shapeless can't create a new case class. If you need a new case class to be created automatically you can write a macro.

franklin
  • 1,800
  • 7
  • 32
  • 59
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • 1
    https://stackoverflow.com/questions/22850340/dynamically-creating-case-classes-with-macros Maybe this? – franklin Nov 03 '18 at 15:10
  • Does this mean that for generics, the Base Model needs to have all the fields of any possible Child Model? – franklin Nov 06 '18 at 14:26
  • Sorry I don't understand your question. I guess it doesn't. – Dmytro Mitin Nov 06 '18 at 14:34
  • No. I think it does. A `ChildModel1` with types `a, b, c, d` and a `ChildModel2` with types `a, b, c, d, e` must both extend a `BaseModel` with types `a, b, c, d, e`. The `BaseModel` must contain the product of all the types used in any child model. – franklin Nov 06 '18 at 18:08
  • Sorry I still don't understand your point. I can create arbitrary case classes ChildModel1, ChildModel2, BaseModel whatever. – Dmytro Mitin Nov 06 '18 at 19:19
  • 1
    What Shapeless does, is tranformation from case class to some generic representation (hlist) and vice versa. You can do everything what you want with hlist, add fields, remove fields, transform fields. What Shapeless can't do is defining case classes. – Dmytro Mitin Nov 06 '18 at 19:22