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

com.ebiznext.comet.extractor.ExtractScriptGen.scala Maven / Gradle / Ivy

There is a newer version: 0.2.6
Show newest version
package com.ebiznext.comet.extractor

import better.files.File
import com.ebiznext.comet.config.{DatasetArea, Settings}
import com.ebiznext.comet.extractor.config.{Settings => ExtractorSettings}
import com.ebiznext.comet.schema.handlers.SchemaHandler
import com.ebiznext.comet.schema.model.Domain
import com.typesafe.config.ConfigFactory
import com.typesafe.scalalogging.StrictLogging
import org.fusesource.scalate._

object ScriptGen extends StrictLogging {

  implicit val settings: Settings = Settings(ConfigFactory.load())
  val engine: TemplateEngine = new TemplateEngine

  /** Generate an extraction script payload based on a template and its params
    * @param template The extraction script template
    * @param templateParams Its params
    * @return The produced script payload
    */
  def templatize(template: File, templateParams: TemplateParams): String =
    engine.layout(
      template.pathAsString,
      templateParams.paramMap
    )

  /** Generate all extraction scripts based on the given domain
    * @param domain The domain extracted from the Excel referential file
    * @param scriptTemplateFile The script template
    * @param scriptsOutputPath Where the scripts are produced
    * @param defaultDeltaColumn Defaut delta column
    * @param deltaColumns Mapping table name -> delta column, has precedence over `defaultDeltaColumn`
    * @return The list of produced files
    */
  def generate(
    domain: Domain,
    scriptTemplateFile: File,
    scriptsOutputPath: File,
    defaultDeltaColumn: Option[String],
    deltaColumns: Map[String, String]
  ): List[File] = {
    val templateSettings =
      TemplateParams.fromDomain(domain, scriptsOutputPath, defaultDeltaColumn, deltaColumns)
    templateSettings.map { ts =>
      val scriptPayload = templatize(scriptTemplateFile, ts)
      val scriptFile =
        ts.scriptOutputFile.createFileIfNotExists().overwrite(scriptPayload)
      logger.info(s"Successfully generated script $scriptFile")
      scriptFile
    }
  }

  /** Fills a Mustache templated file based on a given domain.
    * The following documentation considers that we use the script to generate SQL export files.
    *
    * The schemas should at least, specify :
    *    - a table name (schemas.name)
    *    - a file pattern (schemas.pattern) which is used as the export file base name
    *    - a write mode (schemas.metadata.write): APPEND or OVERWRITE
    *    - the columns to extract (schemas.attributes.name*)
    *
    * You also have to provide a Mustache (http://mustache.github.io/mustache.5.html) template file.
    *
    * Here you'll write your extraction export process (sqlplus for Oracle, pgsql for PostgreSQL as an example).
    * In that template you can use the following parameters:
    *
    * table_name  -> the table to export
    * delimiter   -> the resulting dsv file delimiter
    * columns     -> the columns to export
    * columns is a Mustache map, it gives you access, for each column, to:
    *  - name               -> the column name
    *  - trailing_col_char  -> the separator to append to the column (, if there are more columns to come, "" otherwise)
    *                          Here is an example how to use it in a template:
    *                            SELECT
    *                            {{#columns}}
    *                            TO_CHAR({{name}}){{trailing_col_char}}
    *                            {{/columns}}
    *                            FROM
    *                            {{table_name}};
    * export_file -> the export file name
    * delta_column -> a delta date column (passed as a Main arg or as a config element), the column which is used to determine new rows for each exports in APPEND mode
    * full_export -> if the export is a full or delta export (the logic is to be implemented in your script)
    *
    * Usage: comet [script-gen] [options]
    *
    * Command: script-gen
    *   --domain             The domain for which to generate extract scripts
    *   --templateFile       Script template file
    *   --scriptsOutputDir   Scripts output folder
    *   --deltaColumn        The date column which is used to determine new rows for each exports (can be passed table by table as config element)
    */
  def run(args: Array[String]): Boolean = {
    import settings.metadataStorageHandler
    DatasetArea.initMetadata(metadataStorageHandler)
    val schemaHandler = new SchemaHandler(metadataStorageHandler)
    val domains: List[Domain] = schemaHandler.domains

    val arglist = args.toList
    logger.info(s"Running Comet $arglist")

    ExtractScriptGenConfig.parse(args) match {
      case Some(config) =>
        // Extracting the domain from the Excel referential file
        domains.find(_.name == config.domain) match {
          case Some(domain) =>
            ScriptGen.generate(
              domain,
              config.scriptTemplateFile,
              config.scriptOutputDir,
              config.deltaColumn.orElse(ExtractorSettings.deltaColumns.defaultColumn),
              ExtractorSettings.deltaColumns.deltaColumns
            )
            true
          case None =>
            logger.error(s"No domain found for domain name ${config.domain}")
            false
        }
      case _ =>
        logger.error("Program execution or parameters are wrong, please check usage")
        false
    }
  }
}

object Main {

  def main(args: Array[String]): Unit = {
    val result = ScriptGen.run(args)
    System.exit(if (result) 0 else 1)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy