2017-03-29 1 views
0
scripts SQL

d'évolution doivent être nommésEst-il possible de nommer les scripts d'évolution de sql de jeu?

  • 1.SQL,
  • 2.sql,
  • XXX.sql

selon la documentation. https://www.playframework.com/documentation/2.5.x/Evolutions#Running-evolutions-using-compile-time-DI

Est-il possible de changer convention de dénomination pour

  • 1_create__customers.sql
  • 2_create__orders.sql
  • 3_alter__customers__add__home_address.sql

comme il RoR: http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration

Oui, j'ai évalué https://github.com/flyway/flyway-play et nous pouvons passer à elle.

En ce moment je cherche la fonctionnalité de jeu par défaut.

Répondre

2

Oui, c'est possible.

Créer un nouveau fichier dans ce chemin: your/modules/folder/EvolutionsModule.scala

Ensuite, ajoutez ce qui suit:

package your.modules.folder 

import javax.inject._ 

import play.api.db.evolutions._ 
import play.api.inject.{ Module } 
import play.api.libs.Collections 
import play.api.{ Configuration, Environment } 
import org.apache.commons.io.FileUtils 

class EvolutionsModule extends Module { 
    def bindings(environment: Environment, configuration: Configuration) = { 
    Seq(
     bind[EvolutionsConfig].toProvider[DefaultEvolutionsConfigParser], 
     bind[EvolutionsReader].to[YourEvolutionsReader], 
     bind[EvolutionsApi].to[DefaultEvolutionsApi], 
     bind[ApplicationEvolutions].toProvider[ApplicationEvolutionsProvider].eagerly 
    ) 
    } 
} 

@Singleton 
class YourEvolutionsReader @Inject()(environment: Environment) extends EvolutionsReader { 

    def evolutions(db: String): Seq[Evolution] = { 

    val upsMarker = """^#.*!Ups.*$""".r 
    val downsMarker = """^#.*!Downs.*$""".r 

    val UPS = "UPS" 
    val DOWNS = "DOWNS" 
    val UNKNOWN = "UNKNOWN" 

    val mapUpsAndDowns: PartialFunction[String, String] = { 
     case upsMarker() => UPS 
     case downsMarker() => DOWNS 
     case _ => UNKNOWN 
    } 

    val isMarker: PartialFunction[String, Boolean] = { 
     case upsMarker() => true 
     case downsMarker() => true 
     case _ => false 
    } 

    val folder = environment.getFile(Evolutions.directoryName(db)) 
    val sqlFiles = folder.listFiles() 
     .filter(file => file.getName.indexOf(".sql") > -1) 
     .sortBy(file => { 
     val fileName = file.getName 
     val nameAfterSqlNumber = fileName.split("\\.")(0).split("_").drop(1).mkString("") + ".sql" 
     val sqlNumber = fileName.split("\\.")(0).split("_")(0).toInt 
     val newPrefix = "%07d".format(sqlNumber) 
     newPrefix + nameAfterSqlNumber 
     }) 
     .toSeq 
    sqlFiles.zip(1 to sqlFiles.size) 
     .map { 
     case (file, revision) => { 
      val script = FileUtils.readFileToString(file) 
      val parsed = Collections.unfoldLeft(("", script.split('\n').toList.map(_.trim))) { 
      case (_, Nil) => None 
      case (context, lines) => { 
       val (some, next) = lines.span(l => !isMarker(l)) 
       Some((next.headOption.map(c => (mapUpsAndDowns(c), next.tail)).getOrElse("" -> Nil), 
       context -> some.mkString("\n"))) 
      } 
      }.reverse.drop(1).groupBy(i => i._1).mapValues { _.map(_._2).mkString("\n").trim } 
      Evolution(
      revision, 
      parsed.getOrElse(UPS, ""), 
      parsed.getOrElse(DOWNS, "") 
     ) 
     } 
     } 
    } 
} 

Accédez à votre applications.conf, puis ajouter ces lignes. Ceci est pour remplacer le EvolutionsModule par défaut avec notre très propre.

play.modules { 
    enabled += "your.modules.folder.EvolutionsModule" 
    disabled += "play.api.db.evolutions.EvolutionsModule" 
} 

Explication pour le premier bloc de texte:

  • Selon le code source, les évolutions sont ajoutés uniquement basée sur une seule classe et de méthode - la EvolutionsReader et la méthode evolutions.
  • Après l'exécution de la méthode evolutions, le module d'évolutions s'appuiera sur les entrées de la base de données générées. Donc, nous avons seulement besoin de remplacer cette méthode par la nôtre.
  • Malgré l'énorme bloc de code, il s'agit en fait d'une modification mineure du code source. J'ai remplacé la fonctionnalité de la fonction loadResource par la liste des fichiers dans le dossier evolutions sql files. Le reste est une copie straight-up de la méthode evolutions dans EvolutionsApi.scala

Les codes sources citées by this answer sont des fonctions utilitaires les plus probables - le module Evolutions ne repose pas vraiment sur elle. Je n'ai pas trouvé d'utilisation significative de fileName et resourceName pour exécuter le evolutions. Au lieu de cela, ils référencent tous le tableau play_evolutions.

Référence: https://github.com/playframework/playframework/issues/6919

+0

Wow, merci ... mais nous sommes passés à https://flywaydb.org déjà. – Sergey

+0

@Sergey Tout va bien. IMO, abandonner complètement les évolutions et changer de décision est la bonne décision (et laisser tomber, mais c'est une autre histoire). mais je ne pouvais pas parce que je hérite d'un projet. Pourtant, je voulais que cette question ait la bonne réponse pour référence future pour moi et les autres mainteneurs de code, et surtout parce que j'utiliserai Scala pendant très, très longtemps. – blindbox

1

Non, il est impossible, le code source:

def fileName(db: String, revision: Int): String = s"${directoryName(db)}/${revision}.sql" 

https://github.com/playframework/playframework/blob/2.5.x/framework/src/play-jdbc-evolutions/src/main/scala/play/api/db/evolutions/Evolutions.scala#L103

def resourceName(db: String, revision: Int): String = s"evolutions/${db}/${revision}.sql" 

https://github.com/playframework/playframework/blob/2.5.x/framework/src/play-jdbc-evolutions/src/main/scala/play/api/db/evolutions/Evolutions.scala#L108

@Singleton 
class EnvironmentEvolutionsReader @Inject() (environment: Environment) extends ResourceEvolutionsReader { 

    def loadResource(db: String, revision: Int) = { 
    environment.getExistingFile(Evolutions.fileName(db, revision)).map(new FileInputStream(_)).orElse { 
     environment.resourceAsStream(Evolutions.resourceName(db, revision)) 
    } 
    } 
} 

https://github.com/playframework/playframework/blob/2.5.x/framework/src/play-jdbc-evolutions/src/main/scala/play/api/db/evolutions/EvolutionsApi.scala#L471-L479

Ainsi, tel qu'il est décrit dans la documentation, vous ne pouvez utiliser que le numéro {revision}.sql