2017-03-29 2 views
0

進化SQLスクリプトは、マニュアルに従ってplay evolution SQLスクリプトに名前を付けることは可能ですか?

  • 1.SQL、
  • 2.sql、
  • XXX.sql

名前を付ける必要があります。 https://www.playframework.com/documentation/2.5.x/Evolutions#Running-evolutions-using-compile-time-DI

それRoRのような

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

に命名規則を変更するには、いずれかの可能性があります: http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration

はい、私はhttps://github.com/flyway/flyway-play と評価しました。私たちはそれに切り替えることができます。

現在、私はデフォルトの再生機能を探しています。

答えて

2

はい、可能です。そして、あなたのapplications.conf

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, "") 
     ) 
     } 
     } 
    } 
} 

Go]を次の行を追加します。

your/modules/folder/EvolutionsModule.scalaが続いて、次の行を追加します。

は、このパスに新しいファイルを作成します。これはデフォルトの EvolutionsModuleを独自のものに置き換えるためのものです。テキストの最初のブロックの

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

説明:

  • ソースコードによると、進化は、単に単一のクラスおよびメソッドに基づいて追加される - EvolutionsReader及び方法evolutions
  • evolutionsメソッドを実行すると、evolutionsモジュールは生成されたデータベースエントリに依存します。したがって、このメソッドを独自のメソッドでオーバーライドするだけで済みます。
  • 膨大なコードブロックにもかかわらず、実際にはソースコードのマイナーな編集です。私はloadResource関数の機能をevolutionsのsqlファイルフォルダ内のファイルのリストに置き換えました。それの残りの部分はEvolutionsApi.scala

evolutions方法のストレートアップコピーであるby this answerを引用したソースコードは、最も可能性の高いユーティリティ関数です - エボリューションモジュールは、実際にそれに依存しません。私はevolutionsを実行するために、fileNameresourceNameの重要な使用を見つけることができませんでした。代わりに、彼らはすべてplay_evolutionsテーブルを参照しています。

参考:https://github.com/playframework/playframework/issues/6919

+0

うわー、おかげで...しかし、我々はすでにhttps://flywaydb.orgに切り替えます。 – Sergey

+0

@Sergeyそれは大丈夫です。 IMO、進化を完全に落として、切り替えは正しい決定です(また、滑り落ちますが、それは別の話です)。私はプロジェクトを継承しているのでできませんでした。それでも、私はこの質問に、私と仲間のコード管理者の将来の参照のための正しい答えを持ってほしいと思っていました。特に、私はScalaを長時間使っています。 – blindbox

1

ありませんが、それは可能ではないですが、ソースコード:

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

だから、ドキュメントに記載されているように、数字だけを使うことができます{revision}.sql

関連する問題