/* * Copyright 2013 SFB 632. * * 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 annis.administration; import com.google.common.base.Preconditions; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.JdbcTemplate; /** * A helper class that allows you to fix the database scheme. * * Currently it can * - create an corpus_alias table <br /> * - create an url_shortener table <br /> * * @author Thomas Krause <krauseto@hu-berlin.de> */ public class SchemeFixer { private final Logger log = LoggerFactory.getLogger(SchemeFixer.class); // use Spring's JDBC support private DataSource dataSource; private JdbcTemplate jdbcTemplate; private String databaseSchema; /** * Execute all fixes that are available. */ public void checkAndFix() { log.info("testing if fixing schema is necessary"); corpusAlias(); log.info("finished schema test"); } protected void corpusAlias() { try(Connection conn = dataSource.getConnection();) { DatabaseMetaData dbMeta = conn.getMetaData(); try(ResultSet result = dbMeta.getColumns(null, getDatabaseSchema(), "corpus_alias", null);) { Map<String, Integer> columnType = new HashMap<>(); while(result.next()) { columnType.put(result.getString(4), result.getInt(5)); } if(columnType.isEmpty()) { // create the table log.info("Creating corpus_alias table"); jdbcTemplate.execute( "CREATE TABLE IF NOT EXISTS corpus_alias\n" + "(\n" + " alias text COLLATE \"C\",\n" + " corpus_ref bigint references corpus(id) ON DELETE CASCADE,\n" + " PRIMARY KEY (alias, corpus_ref)\n" + ");\n" + ""); } else { // check if columns have correct type and name, if not throw an error Preconditions.checkState(Types.VARCHAR == columnType.get("alias"), "there must be an \"alias\" column of type \"text\""); Preconditions.checkState(Types.BIGINT == columnType.get("corpus_ref"), "there must be an \"corpus_ref\" column of type \"bigint\""); } } } catch (SQLException ex) { log.error("Could not get the metadata for the database", ex); } } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; this.jdbcTemplate = new JdbcTemplate(dataSource); } public String getDatabaseSchema() { return databaseSchema; } public void setDatabaseSchema(String databaseSchema) { this.databaseSchema = databaseSchema; } }