Skip to content

Instantly share code, notes, and snippets.

@yadavan88
Forked from skinner/NamespacedCodegen.scala
Last active August 29, 2015 14:07
Show Gist options
  • Save yadavan88/719aca4ef76b8abb6f9d to your computer and use it in GitHub Desktop.
Save yadavan88/719aca4ef76b8abb6f9d to your computer and use it in GitHub Desktop.
The available code from @skinner was for Slick 2.0(not using scala 2.11). From scala 2.11, some of the core libraries were moved out. So the code will not work with 2.11 scala. Also, added column name customization and case class/mapping class name customization as well.
package demo
import scala.slick.jdbc.meta.{MTable, createModel}
import scala.reflect.runtime.currentMirror
import java.io.File
import java.io.FileWriter
import scala.slick.codegen.SourceCodeGenerator
import scala.slick.driver.JdbcProfile
// NamespacedCodegen handles tables within schemas by namespacing them
// within objects here
// (e.g., table a.foo and table b.foo can co-exist, because this code
// generator places the relevant generated classes into separate
// objects--a "a" object, and a "b" object)
object NamespacedCodegen {
val outputDir = new java.io.File( "." ).getCanonicalPath+"\\myproj\\src\\main\\scala\\com\\myproj\\entity"
val pkg="base"
val schemaList = "hr,finance,science"
val url = "jdbc:postgresql://localhost:5432/myDB"
val slickDriver="scala.slick.driver.PostgresDriver"
val jdbcDriver = "org.postgresql.Driver"
val fname="PGTables.scala"
def main(args: Array[String]) = {
args.toList match {
case _ => {
val driver: JdbcProfile = {
val module = currentMirror.staticModule(slickDriver)
val reflectedModule = currentMirror.reflectModule(module)
val driver = reflectedModule.instance.asInstanceOf[JdbcProfile]
driver
}
val schemas = schemaList.split(",").map({
case "" => None
case (name: String) => Some(name)
}).toSet
var model = driver.simple.Database
.forURL(url,user="postgres", password="mypassword@123", driver = jdbcDriver)
.withSession { implicit session =>
val filteredTables = driver.getTables.list.filter(
(t: MTable) => schemas.contains(t.name.schema)
)
createModel(filteredTables, driver)
}
val codegen = new SourceCodeGenerator(model){
// customize Scala table name (table class, table values, ...)
//End all the mapping classes to end with 'Mapping'
override def tableName = dbTableName => dbTableName match {
case _ => dbTableName+"Mapping"
}
override def code = {
//imports is copied right out of
//scala.slick.model.codegen.AbstractSourceCodeGenerator
var imports =
"import scala.slick.model.ForeignKeyAction\n" +
( if(tables.exists(_.hlistEnabled)){
"import scala.slick.collection.heterogenous._\n"+
"import scala.slick.collection.heterogenous.syntax._\n"
} else ""
) +
( if(tables.exists(_.PlainSqlMapper.enabled)){
"import scala.slick.jdbc.{GetResult => GR}\n"+
"// NOTE: GetResult mappers for plain SQL are only generated for tables where Slick knows how to map the types of all columns.\n"
} else ""
) + "\n\n"
val bySchema = tables.groupBy(t => {
t.model.name.schema
})
val schemaFor = (schema: Option[String]) => {
bySchema(schema).sortBy(_.model.name.table).map(
_.code.mkString("\n")
).mkString("\n\n")
}
val schemata = schemas.toArray.sorted.map(
schema => schema match {
case Some(schemaName) => {
indent(
"object " + schemaName + " {\n" + schemaFor(schema)
) + "\n}\n"
}
case None => {
schemaFor(schema)
}
}
).mkString("\n\n")
imports + schemata
}
override def entityName = dbTableName => dbTableName match {
case _ => dbTableName
}
override def Table = new Table(_) {
table =>
// customize table value (TableQuery) name (uses tableName as a basis)
override def TableValue = new TableValue {
override def rawName = super.rawName.uncapitalize
}
// override generator responsible for columns
override def Column = new Column(_){
// customize Scala column names
//In the case class, i want to use the primary key field as 'id' instead of the column name
override def rawName = (table.model.name.table,this.model.name) match {
case tbl:(_,_) if(tbl._2.toLowerCase == (tbl._1+"id").toLowerCase ) => "id"
case _ => super.rawName
}
}
}
}
println(outputDir+"\\"+fname)
(new File(outputDir)).mkdirs()
val fw = new FileWriter(outputDir+"\\"+fname)
fw.write(codegen.packageCode(slickDriver, pkg))
fw.close()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment