【问题标题】:grails: guidance on writing scripts, esp for calling existing database-migration scriptsgrails:编写脚本的指南,尤其是调用现有数据库迁移脚本的指南
【发布时间】:2012-12-25 02:28:40
【问题描述】:

我的要求是从 Jenkins 构建服务器调用一些处理,以确定自上次构建以来域模型是否已更改。我得出的结论是,前进的方向是编写一个脚本,该脚本将从 db-migration 插件中调用一系列现有脚本。然后我可以在调用 test-app 和 war 的步骤中调用它。

我查看了 Grails 文档和一些 db-migration 脚本,但我发现自己陷入困境 - 不知道从哪里开始尝试。如果有人能指出任何合适的来源,我将不胜感激。顺便说一句,我对 Grails 有点生疏。两年前开始通过概念验证项目自学,持续了 6 个月。然后又回到了 Eclipse 富客户端工作。这可能是我的问题的一部分,尽管我从未参与过脚本。

我在 Jenkins evt 中需要做的一件事是掌握用于构建的当前 SVN 修订号。欢迎提出建议。

问候,约翰

【问题讨论】:

    标签: grails scripting database-migration


    【解决方案1】:

    通过运行grails create-script scriptname 创建一个新脚本。数据库迁移插件脚本配置为易于重用。 _DatabaseMigrationCommon.groovy 中有很多共享代码,每个脚本定义一个具有唯一名称的目标。因此,您可以导入共享脚本或任何独立脚本(或多个脚本)并像调用方法一样调用目标。

    默认情况下,create-script 生成的脚本会通过includeTargets << grailsScript("_GrailsInit")“导入”_GrailsInit 脚本,您也可以这样做,利用指向已安装插件目录的魔法变量:

    includeTargets << new File("$databaseMigrationPluginDir/scripts/DbmGenerateChangelog.groovy")
    

    如果您这样做,您可以删除 _GrailsInit 的包含,因为它已经包含在内,但如果您不这样做也没关系,因为 Grails 只包含一次文件。

    然后您可以定义您的目标并调用任何插件的目标。目标不能接受参数,但您可以将数据添加到argsMap(这是 Grails 从解析的命令行参数创建的映射)来模拟用户指定的参数。请注意,传递给脚本的任何参数都将被数据库迁移插件的脚本看到,因为它们使用相同的argsMap

    这是一个示例脚本,它与dbm-generate-changelog 执行相同的操作,但添加了前后消息:

    includeTargets << new File("$databaseMigrationPluginDir/scripts/DbmGenerateChangelog.groovy")
    
    target(foo: "Just calls dbmGenerateChangelog") {
       println 'before'
       dbmGenerateChangelog()
       println 'after'
    }
    
    setDefaultTarget foo
    

    请注意,我将目标从 main 重命名为 foo,因此它是独一无二的,以防您想从另一个脚本调用它。

    作为使用 args 的示例,以下是修改后的版本,如果没有提供,则指定默认的更改日志名称:

    println 'before'
    if (!argsMap.params) {
       argsMap.params = ['foo2.groovy']
    }
    dbmGenerateChangelog()
    println 'after'
    

    编辑:这是一个更完整的示例,它将 dbm-gorm-diff 的输出捕获为字符串:

    includeTargets << new File("$databaseMigrationPluginDir/scripts/_DatabaseMigrationCommon.groovy")
    
    target(foo: "foo") {
       depends dbmInit
    
       def configuredSchema = config.grails.plugin.databasemigration.schema
       String argSchema = argsMap.schema
       String effectiveSchema = argSchema ?: configuredSchema ?: defaultSchema
    
       def realDatabase
       boolean add = false // booleanArg('add')
       String filename = null // argsList[0]
    
       try {
          printMessage "Starting $hyphenatedScriptName"
    
          ByteArrayOutputStream baos = new ByteArrayOutputStream()
          def baosOut = new PrintStream(baos)
    
          ScriptUtils.executeAndWrite filename, add, dsName, { PrintStream out ->
             MigrationUtils.executeInSession(dsName) {
                realDatabase = MigrationUtils.getDatabase(effectiveSchema, dsName)
                def gormDatabase = ScriptUtils.createGormDatabase(dataSourceSuffix, config, appCtx, realDatabase, effectiveSchema)
                ScriptUtils.createAndPrintFixedDiff(gormDatabase, realDatabase, realDatabase, appCtx, diffTypes, baosOut)
             }
          }
    
          String xml = new String(baos.toString('UTF-8'))
          def ChangelogXml2Groovy = classLoader.loadClass('grails.plugin.databasemigration.ChangelogXml2Groovy')
          String groovy = ChangelogXml2Groovy.convert(xml)
    
          // do something with the groovy or xml here
    
          printMessage "Finished $hyphenatedScriptName"
       }
       catch (e) {
          ScriptUtils.printStackTrace e
          exit 1
       }
       finally {
          ScriptUtils.closeConnection realDatabase
       }
    }
    
    setDefaultTarget foo
    

    【讨论】:

    • 非常感谢。你能不厌其烦地为我提供这样一个有用的开胃菜真是太好了。我现在设法创建了一个“差异”文件。如果我没有向 dbmGormDiff() 提供文件名 parm,则在控制台中会看到输出(如指定的那样)。是否可以将控制台输出定向到我的脚本中的闭包中?这样我就可以搜索“
    • 感谢 Burt - 非常棒的帮助。由于我仍在使用 1.2.2,因此我将代码替换为该版本 DbmGormDiff 的副本中的“boasOut”。我创建了一个内部“utils”脚本供我的主脚本使用。大多数现在都在工作。如果有域更改,并且如果 changelog-svnRevno.xml 文件存在(= 重新运行),我将其删除并继续。我的一个问题是如何阻止 master.xml 被重复的“包含”更新。不确定我是否可以通过从 SVN 获取早期版本来解决这个问题,因为我不知道如何重新运行。认为我已经掌握了简单脚本的窍门。
    • 这超出了 SO 问题的范围 - 您可能想在用户邮件列表中讨论这个问题。
    • 明白你的意思。非常感谢您给予的帮助。约翰
    猜你喜欢
    • 2011-06-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多