/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.extension.jdbc.gen.internal.version; import java.io.File; import java.util.List; import org.seasar.extension.jdbc.gen.internal.exception.IllegalVersionRuntimeException; import org.seasar.extension.jdbc.gen.sql.SqlExecutionContext; import org.seasar.extension.jdbc.gen.sql.SqlUnitExecutor; import org.seasar.extension.jdbc.gen.version.DdlVersionDirectory; import org.seasar.extension.jdbc.gen.version.DdlVersionDirectoryTree; import org.seasar.extension.jdbc.gen.version.Migrater; import org.seasar.extension.jdbc.gen.version.SchemaInfoTable; import org.seasar.framework.log.Logger; /** * {@link Migrater}の実装クラスです。 * * @author taedium */ public class MigraterImpl implements Migrater { /** 最新バージョンを表す文字列 */ protected static String LATEST_VERSION = "latest"; /** 1つ次のバージョンを表す文字列 */ protected static String NEXT_VERSION = "next"; /** 1つ前のバージョンを表す文字列 */ protected static String PREVIOUS_VERSION = "previous"; /** ロガー */ protected static Logger logger = Logger.getLogger(MigraterImpl.class); /** SQLのひとまとまりの実行者 */ protected SqlUnitExecutor sqlUnitExecutor; /** スキーマのバージョン */ protected SchemaInfoTable schemaInfoTable; /** DDLのバージョンを管理するディレクトリ */ protected DdlVersionDirectoryTree ddlVersionDirectoryTree; /** 環境名 */ protected String env; /** バージョン */ protected String version; /** * インスタンスを構築します。 * * @param sqlUnitExecutor * SQLのひとまとまりの実行者 * @param schemaInfoTable * スキーマのバージョン * @param ddlVersionDirectoryTree * DDLをバージョン管理するディレクトリ * @param version * バージョン * @param env * 環境名 */ public MigraterImpl(SqlUnitExecutor sqlUnitExecutor, SchemaInfoTable schemaInfoTable, DdlVersionDirectoryTree ddlVersionDirectoryTree, String version, String env) { if (sqlUnitExecutor == null) { throw new NullPointerException("sqlUnitExecutor"); } if (schemaInfoTable == null) { throw new NullPointerException("schemaInfoTable"); } if (ddlVersionDirectoryTree == null) { throw new NullPointerException("ddlVersionDirectoryTree"); } if (version == null) { throw new NullPointerException("version"); } if (env == null) { throw new NullPointerException("env"); } this.sqlUnitExecutor = sqlUnitExecutor; this.schemaInfoTable = schemaInfoTable; this.ddlVersionDirectoryTree = ddlVersionDirectoryTree; this.version = version; this.env = env; } public void migrate(Callback callback) { int from = schemaInfoTable.getVersionNo(); int to = getDestVersion(from); logger.log("IS2JDBCGen0005", new Object[] { from, to }); migrateInternal(callback, from, to); logger.log("IS2JDBCGen0006", new Object[] { from, to }); } /** * マイグレーション先のバージョン番号を返します。 * * @param from * マイグレーション元のバージョン番号 * @return マイグレーション先のバージョン番号 */ protected int getDestVersion(int from) { int latest = ddlVersionDirectoryTree.getDdlInfoFile() .getCurrentVersionNo(); if (LATEST_VERSION.equalsIgnoreCase(version)) { return latest; } else if (NEXT_VERSION.equalsIgnoreCase(version)) { long next = from + 1; if (next > latest) { return latest; } checkVersionRange(next); return (int) next; } else if (PREVIOUS_VERSION.equalsIgnoreCase(version)) { long previous = from - 1; if (previous < 0) { return 0; } checkVersionRange(previous); return (int) previous; } return convertToInt(version); } /** * 文字列としてのバージョン番号をint型に変換します。 * * @param value * 文字列としてのバージョン番号 * @return intとしてのバージョン番号 */ protected int convertToInt(String value) { int versionNo; try { versionNo = Integer.valueOf(value); } catch (NumberFormatException e) { throw new IllegalVersionRuntimeException(version, value); } if (versionNo < 0) { throw new IllegalVersionRuntimeException(version, value); } return versionNo; } /** * バージョン番号の範囲をチェックします。 * * @param value * バージョン番号 */ protected void checkVersionRange(long value) { if (value < 0 || Integer.MAX_VALUE < value) { new IllegalVersionRuntimeException(version, value); } } /** * マイグレーション処理を実行します。 * * @param callback * コールバック * @param from * マイグレーション元のバージョン番号 * @param to * マイグレーション先のバージョン番号 */ protected void migrateInternal(final Callback callback, final int from, final int to) { DdlVersionDirectory fromVersionDir = ddlVersionDirectoryTree .getVersionDirectory(from); final List<File> dropFileList = fromVersionDir.getDropDirectory() .listAllFiles(); DdlVersionDirectory toVersionDir = ddlVersionDirectoryTree .getVersionDirectory(to); final List<File> createFileList = toVersionDir.getCreateDirectory() .listAllFiles(); sqlUnitExecutor.execute(new SqlUnitExecutor.Callback() { public void execute(SqlExecutionContext context) { for (File file : dropFileList) { callback.drop(context, file); } schemaInfoTable.setVersionNo(to); for (File file : createFileList) { callback.create(context, file); } } }); } }