Groovyでテーブルのデータを取得したい(6)

取るに足らないことなんですが、同じようなことで未来も躓きそうなので。


SafeArrayを作成して、for文でぐるぐる回すところなのですが、

  for(r in rows){
      if(1==rowNumber){
          r.each{ safeArray.putAt([rowNumber,colNumber++],it.key) }
          rowNumber++
      }
      colNumber = 1
      r.each{
          if( it.value instanceof oracle.sql.TIMESTAMP )
              it.value = sdf.format(it.value.dateValue())
           safeArray.putAt([rowNumber,colNumber++],it.value)
      }
      rowNumber++
  }

の、

    if( it.value instanceof oracle.sql.TIMESTAMP )
        it.value = sdf.format(it.value.dateValue())

がどうしても綺麗にしたくて。。。
かと言ってOracleのTimeStamp型をやめるわけにもいかず。。。


でmetaClassにメソッドを動的に追加して、for文の中では追加したメソッドを実行すれば良いのではという
発想で書き直したのが以下のコードです。

import java.text.SimpleDateFormat
import org.codehaus.groovy.scriptom.ActiveXObject
import org.codehaus.groovy.scriptom.SafeArray
def sql = groovy.sql.Sql.newInstance('jdbc:oracle:thin:@localhost:1521:ORCL','userid','password','oracle.jdbc.driver.OracleDriver')
def xlApp = new ActiveXObject('Excel.Application')
def username = "INIT"
def workbook = xlApp.workbooks.Add
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
oracle.sql.TIMESTAMP.metaClass.toString = {sdf.format(delegate.dateValue())}
sql.eachRow("SELECT table_name FROM user_tables WHERE table_name LIKE 'BIZ_AB_%'"){ rs->
    def rows = sql.rows("SELECT * FROM " + rs.table_name +" WHERE create_user_cd ='" + username + "'")
    if( rows.size() > 0 ){
        def worksheet = workbook.worksheets.Add
        worksheet.name = rs.table_name
        def (long rowNumber, long colNumber) = [1,1]
        SafeArray safeArray = new SafeArray(org.codehaus.groovy.scriptom.SafeArray.VARIANT,1..rows.size()+1,1..rows[0].size())
        for(r in rows){
            if(1==rowNumber){
                r.each{ safeArray.putAt([rowNumber,colNumber++],it.key) }
                rowNumber++
            }
            colNumber = 1
            r.each{ safeArray.putAt([rowNumber,colNumber++],it.value.toString())}
            rowNumber++
        }
        worksheet.Range(worksheet.cells(1,1),worksheet.cells(rows.size()+1,rows[0].size())).Value = safeArray
    }
}
xlApp.visible = true


思ったとおり、速度的には早くなってませんが「綺麗」にはなっています^^;
Groovyで実装したクラスだけでなく、ライブラリのクラス(ここではoracle.sql.TIMESTAMP)に
対しても拡張できるところがすごいですね。(バージョン1.6以降らしいですけど)