Skip to content

Instantly share code, notes, and snippets.

@diversit
Created March 1, 2018 12:37
Show Gist options
  • Save diversit/6fab43b6db96058b348e862265b10232 to your computer and use it in GitHub Desktop.
Save diversit/6fab43b6db96058b348e862265b10232 to your computer and use it in GitHub Desktop.
Slick Code Generator adding an extra sub generator
/**
* In custom Table implementation add a new `Def` or `TypeDef` implementation
* and add it to the `definitions`.
*
* The custom `Def` can conditionally be applied to tables by overriding the `enabled` function.
*
* This `InsertDef` adds some helper functions to only insert a row based on a predicate.
* See https://stackoverflow.com/a/31352126/3309859 for an example.
* Since defining the `insert` query is quite cumbersome, I created the generator to generate it.
*/
def InsertDef = new TypeDef {
// now only for shipments
override def enabled: Boolean = Seq("shipments", "orders") contains model.name.table
override def doc: String = "Helper Query functions for conditionally inserting a row."
override def code: String = {
val bindNames = columns.map(c => s"row.${c.name}.bind")
val rowClassName = name
val tableClassName = tableName(model.name.table)
s"""def ${tableClassName}InsertQuery(row: $rowClassName) = (${bindNames.mkString(", ")}) <> ($rowClassName.apply _ tupled, $rowClassName.unapply)
|def ${tableClassName}ExistsQuery(predicate: $tableClassName => Rep[Boolean]) = $tableClassName.filter(predicate).exists
|def ${tableClassName}InsertIfNotExists(row: $rowClassName)(predicate: $tableClassName => Rep[Boolean]) = $tableClassName.forceInsertQuery {
| for {
| r <- Query(${tableClassName}InsertQuery(row)) if !${tableClassName}ExistsQuery(predicate)
| } yield r
|}
|""".stripMargin
}
override def rawName: String = entityName(model.name.table)
}
override def definitions = super.definitions :+ InsertDef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment