A Play Framework Evolutions reader that reads a single revision from the class path.
import play.api.db.evolutions.{ClassLoaderEvolutionsReader, Evolution} | |
import play.api.libs.Collections | |
/*** | |
* Evolutions reader that reads a single revision from the class path. | |
* | |
* @param revision the revision number to load | |
* @param prefix A prefix that gets added to the resource file names | |
*/ | |
class SingleRevisionClassLoaderEvolutionsReader(val revision: Int, val prefix: String) extends ClassLoaderEvolutionsReader(prefix = prefix) { | |
override 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 | |
} | |
loadResource(db, revision).map { stream => | |
val script = scala.io.Source.fromInputStream(stream).mkString | |
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, "")) | |
}.toList | |
} | |
} | |
object SingleRevisionClassLoaderEvolutionsReader { | |
def apply(revision: Int, prefix: String = "") = new SingleRevisionClassLoaderEvolutionsReader(revision, prefix) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment