Permalink
Browse files

Adding option to wrap exposedType in an Option even though the column…

… is not. Fixes #1598

  * Add exposeOption to ColumnDef
  * Split autoIncLastAsOption in TableDef into autoIncAsOption and autoIncLast
  * Add exposeOption test
  * Replace autoIncLastAsOption in existing tests
  • Loading branch information...
1 parent 5bcef7f commit e29c0914c719bd957907ef98241b400045370f6a @rfuerst87 rfuerst87 committed Aug 30, 2016
@@ -50,7 +50,7 @@ abstract class AbstractGenerator[Code,TermName,TypeName](model: m.Model)
/** Database column positions in the desired user-facing order. Currently just moves the positions of AutoInc columns to the end if autoIncLastAsOption is enabled. */
lazy val desiredColumnOrder: Seq[Int] = {
val withIndex = columnsPositional.zipWithIndex
- if(autoIncLastAsOption)
+ if(autoIncLast)
// put auto inc column last
(withIndex.filterNot( _._1.autoInc ) ++ withIndex.filter( _._1.autoInc )).map(_._2)
else
@@ -88,10 +88,13 @@ abstract class AbstractGenerator[Code,TermName,TypeName](model: m.Model)
/** If HList should be used as a compound type instead of tuples. Default to true for > 22 columns.
@group Basic customization overrides */
def hlistEnabled = columns.size > 22
- /** Indicates whether auto increment columns should be put last and made an Option with a None default.
+ /** Indicates whether auto increment columns should be put last.
Please set to !hlistEnabled for switching this on.
@group Basic customization overrides */
- def autoIncLastAsOption = false
+ def autoIncLast = false
+ /** Indicates whether auto increment columns should be made an Option with a None default.
+ @group Basic customization overrides */
+ def autoIncAsOption = false
/** Indicates if this table should be mapped using factory and extractor or not, in which case tuples are used. (Consider overriding EntityType.enabled instead, which affects this, too.) Disabled by default when using hlists.
@group Basic customization overrides */
def mappingEnabled = !hlistEnabled
@@ -211,16 +214,20 @@ abstract class AbstractGenerator[Code,TermName,TypeName](model: m.Model)
/**
* Underlying Scala type of this column.
* Override this to just affect the data type but preserve potential Option-wrapping.
- * Override GeneratorHelpers#mapJdbcTypeString for generic adjustments.
* @group Basic customization overrides
*/
def rawType: Code = parseType(model.tpe)
+ /**
+ * Indicates whether the exposed type of this column should be wrapped in an Option. Useful for automatically created columns.
+ * @group Basic customization overrides
+ */
+ def exposeOption = false
/** Possibly Option-wrapped Scala type of this column. @see rawType and @see exposedType */
final def actualType: Code = if(model.nullable) optionType(rawType) else rawType
- /** Option of actualType if fakeNullable else actualType. Useful to expose autoInc columns as nullable. */
+ /** Option of actualType if fakeNullable else actualType. */
final def exposedType: Code = if(fakeNullable) optionType(actualType) else actualType
- /** Indicates whether this column should be user facing as a nullable column with default None even though it is not. Useful for autoInc columns. */
- final def fakeNullable = autoIncLastAsOption && autoInc
+ /** Indicates whether this column should be user facing as a nullable column with default None even though it is not. Useful for autoInc and automatically created columns. */
+ final def fakeNullable = exposeOption || (autoIncAsOption && autoInc)
assert(!(model.nullable && fakeNullable),s"Cannot enable 'fakeNullable' for a 'nullable' column. $model")
@@ -98,7 +98,7 @@ def $name($args): $name = {
val rearranged = compoundValue(desiredColumnOrder.map(i => if(hlistEnabled) s"r($i)" else tuple(i)))
def result(args: String) = if(mappingEnabled) s"$factory($args)" else args
val body =
- if(autoIncLastAsOption && columns.size > 1){
+ if(autoIncLast && columns.size > 1){
s"""
val r = $positional
import r._
@@ -75,11 +75,21 @@ val SimpleA = CustomTyping.SimpleA
new Config("CG9", StandardTestDBs.H2Mem, "H2Mem", Seq("/dbs/h2.sql")) {
override def generator = tdb.profile.createModel(ignoreInvalidDefaults=false).map(new MyGen(_) {
override def Table = new Table(_){
- override def autoIncLastAsOption = true
+ override def autoIncLast = true
+ override def autoIncAsOption = true
}
})
},
new UUIDConfig("CG10", StandardTestDBs.H2Mem, "H2Mem", Seq("/dbs/uuid-h2.sql")),
+ new Config("CG11", StandardTestDBs.H2Mem, "H2Mem", Seq("/dbs/h2-simple.sql")) {
+ override def generator = tdb.profile.createModel(ignoreInvalidDefaults=false).map(new MyGen(_) {
+ override def Table = new Table(_){
+ override def Column = new Column(_){
+ override def exposeOption = true
+ }
+ }
+ })
+ },
new Config("Postgres1", StandardTestDBs.Postgres, "Postgres", Nil) {
import tdb.profile.api._
class A(tag: Tag) extends Table[(Int, Array[Byte], Blob)](tag, "a") {
@@ -29,7 +29,8 @@ object GenerateRoundtripSources {
})
val a2 = profile.createModel(ignoreInvalidDefaults=false).map(m => new SourceCodeGenerator(m) {
override def Table = new Table(_){
- override def autoIncLastAsOption = true
+ override def autoIncLast = true
+ override def autoIncAsOption = true
}
})
val db = Database.forURL(url=url, driver=jdbcDriver, keepAliveConnection=true)
@@ -134,6 +134,23 @@ object GeneratedCodeTest {
)
}
+ def testCG11 = {
+ import CG11._
+ import profile.api._
+ def assertAll(all: Seq[SimpleA]) = {
+ assertEquals( 1, all.size )
+ assertEquals(List(SimpleA(Some(1), Some("foo"))), all)
+ }
+ DBIO.seq(
+ schema.create,
+ SimpleAs.length.result.map(assertEquals(0, _)),
+ SimpleAs += SimpleA(Some(1), Some("foo")),
+ SimpleAs.length.result.map(assertEquals(1, _)),
+ SimpleAs.result.map(assertEquals(List(SimpleA(Some(1), Some("foo"))), _)),
+ sql"select a1, a2 from SIMPLE_AS".as[SimpleA].map(assertAll)
+ )
+ }
+
def testEmptyDB = slick.dbio.DBIO.successful(())
def tableName( node:Node ) : String = {

0 comments on commit e29c091

Please sign in to comment.