PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Génération de code astucieux pour un seul schéma

Utilisez ce code avec les valeurs et le nom de schéma appropriés,

object CodeGenerator {

  def outputDir :String =""
  def pkg:String =""
  def schemaList:String = "schema1, schema2"
  def url:String  = "dburl"
  def fileName:String =""
  val user = "dbUsername"
  val password = "dbPassword"
  val slickDriver="scala.slick.driver.PostgresDriver"
  val JdbcDriver = "org.postgresql.Driver"
  val container = "Tables"


  def generate() = {    

    val driver: JdbcProfile = buildJdbcProfile

    val schemas = createSchemaList

    var model = createModel(driver,schemas)

    val codegen = new SourceCodeGenerator(model){
      // customize Scala table name (table class, table values, ...)
      override def tableName = dbTableName => dbTableName match {
        case _ => dbTableName+"Table"
      }
      override def code = {
        //imports is copied right out of
        //scala.slick.model.codegen.AbstractSourceCodeGenerator
        val 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" //+ tables.map(t => s"implicit val ${t.model.name.table}Format = Json.format[${t.model.name.table}]").mkString("\n")+"\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 joins =   tables.flatMap( _.foreignKeys.map{  foreignKey  =>
        import foreignKey._
        val fkt =   referencingTable.TableClass.name
        val pkt =   referencedTable.TableClass.name
        val columns =   referencingColumns.map(_.name)  zip
          referencedColumns.map(_.name)
        s"implicit def autojoin${fkt + name.toString} = (left:${fkt} ,right:${pkt}) =>  "   +
          columns.map{
            case    (lcol,rcol) =>
              "left."+lcol  +   "   === "   +   "right."+rcol
          }.mkString("  &&  ")
      })

      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
          override def rawName = (table.model.name.table,this.model.name) match {

            case _ => super.rawName
          }
        }
      }

    }

    println(outputDir+"\\"+fileName)
    (new File(outputDir)).mkdirs()
    val fw = new FileWriter(outputDir+File.separator+fileName)
    fw.write(codegen.packageCode(slickDriver, pkg, container))
    fw.close()

  }

  def createModel(driver: JdbcProfile, schemas:Set[Option[String]]): Model = {
    driver.simple.Database
      .forURL(url, user = user, password = password, driver = JdbcDriver)
      .withSession { implicit session =>
      val filteredTables = driver.defaultTables.filter(
        (t: MTable) => schemas.contains(t.name.schema)
      )
      PostgresDriver.createModel(Some(filteredTables))
    }
  }

  def createSchemaList: Set[Option[String]] = {
    schemaList.split(",").map({
      case "" => None
      case (name: String) => Some(name)
    }).toSet
  }

  def buildJdbcProfile: JdbcProfile = {

    val module = currentMirror.staticModule(slickDriver)
    val reflectedModule = currentMirror.reflectModule(module)
    val driver = reflectedModule.instance.asInstanceOf[JdbcProfile]
    driver

  }
}