All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.zarkus13.SlickGenerator.scala Maven / Gradle / Ivy

There is a newer version: 0.2.0
Show newest version
package com.github.zarkus13

import scala.slick.driver.{PostgresDriver, JdbcDriver, MySQLDriver}
import scala.slick.driver.MySQLDriver.simple._
import scala.slick.jdbc.meta._
import scala.slick.codegen.SourceCodeGenerator

/**
 * Created by Alexis on 24/02/14.
 */

sealed trait Driver {
  val jdbcDriver: String
  val slickDriver: String
  val driverClass: JdbcDriver
}
case class MySQL() extends Driver {
  val jdbcDriver: String = "com.mysql.jdbc.Driver"
  val slickDriver: String = "scala.slick.driver.MySQLDriver"
  val driverClass: JdbcDriver = MySQLDriver
}
case class PostgreSQL() extends Driver {
  val jdbcDriver: String = "org.postgresql.Driver"
  val slickDriver: String = "scala.slick.driver.PostgresDriver"
  val driverClass: JdbcDriver = PostgresDriver
}

object SlickGenerator {

  def generateTablesClasses(
      url: String,
      user: String,
      password: String,
      driver: Driver,
      genFolder: String,
      genPackage: String,
      excludeTables: List[String] = List(),
      fileCode: String => String = code => code,
      tableName: Option[String => String] = None, // If None : calls super.tableName
      entityName: Option[String => String] = None, // If None : calls super.entityName
      tableCode: (Seq[String], String) => Seq[String] = (code, entityName) => code,
      tableQueryName: String => String = pluralize,
      columnName: Option[String => String] = None, // If None : calls super.rawName
      columnType: Option[String => Option[String]] = None, // If None : calls super.rawType
      columnEnabled: String => Boolean = name => true
   ) = {

    def tName = tableName
    def eName = entityName
    
    val db = Database.forURL(
      url = url,
      user = user,
      password = password,
      driver = driver.jdbcDriver
    )

    db.withSession { implicit session =>

      driver.driverClass.getTables
        .list
        .filterNot(t => excludeTables.contains(t.name.name))
        .foreach(t => {
          val model = createModel(
            Seq(t),
            MySQLDriver
          )

          val codeGen = new SourceCodeGenerator(model) {

            override def tableName: (String) => String = tName getOrElse super.tableName

            override def entityName: (String) => String = eName getOrElse super.entityName

            override def code = fileCode(super.code)

            override def Table = new Table(_) {

              override def code = tableCode(super.code, entityName(model.name.table))

              override def TableValue = new TableValue{
                override def rawName = tableQueryName(super.rawName)
              }

              override def Column = new Column(_) {
                override def enabled: Boolean = columnEnabled(model.name)

                override def rawName: String = columnName match {
                  case None => super.rawName
                  case Some(columnName) => columnName(model.name)
                }

                override def rawType = columnType match {
                  case None => super.rawType
                  case Some(columnType) => columnType(model.tpe) getOrElse parseType(model.tpe)
                }
              }
            }
          }

          val taName = (tableName match {
            case None => codeGen.tableName
            case Some(f) => f
          })(t.name.name)

          codeGen.writeToFile(
            driver.slickDriver,
            genFolder,
            genPackage,
            taName,
            taName + ".scala"
          )
        })
    }
  }

  def camelCase(str: String): String = {

    def capitalizeParts(parts: Array[String]): String = {
      parts.map(_.capitalize).mkString("")
    }

    capitalizeParts(
      capitalizeParts(
        capitalizeParts(
          str.toLowerCase.split("_")
        ).split("-")
      ).split(" ")
    )
  }

  def pluralize(str: String) = {
    "^*(s|x|z)$".r findFirstMatchIn str match {
      case Some(_) => str
      case None => "^(.*)y$".r findFirstMatchIn str match {
        case Some(r) => r.group(1) + "ies"
        case None => str + "s"
      }
    }
  }

  def unCapitalize(str: String) = {
    val firstChar = str.charAt(0).toString
    str.replaceFirst(
      firstChar,
      firstChar.toLowerCase
    )
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy