收集动态类型服务类的问题&对象

时间:2016-05-20 23:57:23

标签: scala reflection types playframework casting

我们正在构建数据结构迁移系统,该系统应该能够从任何版本的案例类迁移到最新版本;以及从最新版本到以前任何一个版本。 概念如下:

我们有一个案例类和迁移类的结构

v1/SchemaV1 <= Case class V1
v2/SchemaV2 <= Case class V2
v2/MigrationV2 <= Migration Class from 1->2 and back
v3/SchemaV3 <= Case class V3
v3/MigrationV3 <= Migration Class from 2->3 and back
...

其中:

  • 案例类可能是任何东西,但是它们实现了相同的接口Schema
  • 迁移类实现迁移特征,必须实现简单地将一个对象转换为另一个对象的“向上”和“向下”方法。

目前,迁移特征如下所示:

trait TypedMigration[F <: Schema, T <: Schema] {

  type FromSchema = F
  type ToSchema = T

  /**
    * This method is responsible for migrating one version of a schema 'F'(From) to another 'T' (To)
    *
    * @param from
    * @return
    */
  def up(from: FromSchema): ToSchema

  /**
    * This method is responsible for migrating one version of a schema down one level
    *
    * @param from
    * @return
    */
  def down(from: ToSchema): FromSchema
}

这里的想法是,每个迁移类的实现都会强制执行fromto类型。

举个例子:

class V2Migration extends TypedMigration[v1.SchemaV1, v2.SchemaV2] {
   ...
}

如何,有一个服务类负责管理整个迁移过程。这个类有两种处理迁移'up'的方法。分别“下来”

举个例子:

protected[versioning] def doMigrateUp(schema: Schema): ChecklistSchema = {

    // load all required migration classes
    val migrations = loadMigrationObjects[Schema, Schema](resolveSchemaVersion(schema), targetVersion)

    var migratedSchema = schema
    // apply all migrations up
    migrations.foreach { migration =>
      migratedSchema = migration.up(migratedSchema)
    }

    migratedSchema.asInstanceOf[ChecklistSchema]
  }

其中:

  • `loadMigrationObjects'方法按顺序返回迁移对象列表
  • ChecklistSchema是最新版本的类型别名。所以我最后可以安全地投入它。

直到现在都很好......

我的问题始于'doMigrateDown`方法:

protected[versioning] def doMigrateDown[S <: Schema](schema: ChecklistSchema, targetVersion: Int): S = {
    val migrations = loadMigrationObjects[Schema, ChecklistSchema](resolveSchemaVersion(schema), targetVersion)

    var migratedSchema = schema
    // apply all migrations down
    migrations.foreach { migration =>
      migratedSchema = migration.down(migratedSchema)
    }

    migratedSchema.asInstanceOf[S]
  }

这里有两个问题:

  1. 我收到编译错误: enter image description here

  2. 我不确定这个演员是否真的有效。

  3. 我这一点我完全被卡住了......

    作为参考,这是我们构建迁移对象列表的方式:

    protected[versioning] def loadMigrationObjects[F <: Schema, T <: Schema](currentVersion: Int, targetVersion: Int): List[TypedMigration[F, T]] = {
    
        val migrationsRange = if (currentVersion <= targetVersion) {
          currentVersion + 1 to targetVersion
        } else {
          currentVersion to targetVersion + 1 by -1
        }
    
        val migrations = List[TypedMigration[F, T]]()
    
        migrationsRange.foldLeft(migrations) { case (acc, versionNumber) =>
          Try {
    
            val migrationClassName = MigrationClassNameFormat.format(versionNumber, versionNumber)
            Class.forName(migrationClassName).newInstance().asInstanceOf[TypedMigration[F, T]]
    
          } match {
            case Success(m) => acc :+ m
            case Failure(e: ClassNotFoundException) =>
              logger.info("migration class was not found", e)
              acc
            case Failure(e) => throw e
          }
        }
    
      }
    

0 个答案:

没有答案