Skip to content

Commit

Permalink
Add AutoName trait
Browse files Browse the repository at this point in the history
for columns, foreign keys, and indexes that are named based on the scala identifier
  • Loading branch information
nafg committed Mar 12, 2020
1 parent a8a035a commit b38ada8
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 6 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ lazy val `slick-additions` =
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided",
"com.typesafe.slick" %% "slick" % "3.3.2",
"com.lihaoyi" %% "sourcecode" % "0.2.1",
"org.scalatest" %% "scalatest" % "3.1.1" % "test",
"com.h2database" % "h2" % "1.4.200" % "test",
"ch.qos.logback" % "logback-classic" % "1.2.3" % "test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import scala.language.{higherKinds, implicitConversions}
import slick.additions.entity._
import slick.ast._
import slick.jdbc.JdbcProfile
import slick.lifted.{MappedProjection, RepShape}
import slick.lifted.{AbstractTable, ForeignKeyQuery, MappedProjection, RepShape}

import sourcecode.Name

trait KeyedTableProfile { this: JdbcProfile =>
trait KeyedTableApi { this: API =>

trait AdditionsProfile { this: JdbcProfile =>
trait AdditionsApi { this: API =>
implicit def lookupBaseColumnType[K: BaseColumnType, A]: BaseColumnType[Lookup[K, A]] =
MappedColumnType.base[Lookup[K, A], K](_.key, EntityKey(_))

Expand Down Expand Up @@ -109,5 +111,35 @@ trait KeyedTableProfile { this: JdbcProfile =>
def delete(ke: KEnt)(implicit ec: ExecutionContext) =
lookupQuery(ke).delete
}

trait AutoName { this: Table[_] =>
def col[A: TypedType](options: ColumnOption[A]*)(implicit name: Name, dbNameStyle: NameStyle) =
column[A](dbNameStyle.identToDb(name.value), options: _*)

def col[A: TypedType](implicit name: Name, dbNameStyle: NameStyle) =
column[A](dbNameStyle.columnName(name.value))

def foreign[P, PU, TT <: AbstractTable[_], U](sourceColumns: P, targetTableQuery: TableQuery[TT])
(targetColumns: TT => P,
onUpdate: ForeignKeyAction = ForeignKeyAction.NoAction,
onDelete: ForeignKeyAction = ForeignKeyAction.NoAction)
(implicit unpackT: Shape[_ <: FlatShapeLevel, TT, U, _],
unpackP: Shape[_ <: FlatShapeLevel, P, PU, _],
name: Name,
dbNameStyle: NameStyle): ForeignKeyQuery[TT, U] =
foreignKey(dbNameStyle.foreignKeyName(tableName, name.value), sourceColumns, targetTableQuery)(
targetColumns,
onUpdate,
onDelete
)

def idx[A](on: A, unique: Boolean = false)
(implicit shape: Shape[_ <: FlatShapeLevel, A, _, _], name: Name, dbNameStyle: NameStyle) =
index(dbNameStyle.indexName(tableName, name.value), on, unique = unique)
}

trait AutoNameSnakify extends AutoName { this: Table[_] =>
protected implicit def nameStyle: NameStyle = NameStyle.Snakify
}
}
}
28 changes: 28 additions & 0 deletions src/main/scala/slick/additions/NameStyle.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package slick.additions


class NameStyle(val identToDb: String => String) {
def columnName(name: String): String = identToDb(name)
def foreignKeyName(tableName: String, name: String) =
tableName + "__" + identToDb(name)
def indexName(tableName: String, name: String) =
tableName + "__" + identToDb(name)
}

object NameStyle {
private def snakify(s: String) = s.toList match {
case Nil => ""
case char :: chars =>
chars
.foldLeft(char :: Nil) {
case (x :: xs, c) if x.isLower && c.isUpper =>
c.toLower :: '_' :: x :: xs
case (xs, c) =>
c :: xs
}
.reverse
.mkString
}
val Exact = new NameStyle(identity)
val Snakify = new NameStyle(snakify)
}
6 changes: 3 additions & 3 deletions src/test/scala/slick/additions/test/TestProfile.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package slick.additions.test

import slick.additions.KeyedTableProfile
import slick.additions.AdditionsProfile
import slick.jdbc.H2Profile


trait TestProfile extends H2Profile with KeyedTableProfile {
object _api extends KeyedTableApi with API
trait TestProfile extends H2Profile with AdditionsProfile {
object _api extends AdditionsApi with API
override val api = _api
}

Expand Down

0 comments on commit b38ada8

Please sign in to comment.