Java tutorial
/* * Copyright 2009-2014 Jagornet Technologies, LLC. All Rights Reserved. * * This software is the proprietary information of Jagornet Technologies, LLC. * Use is subject to license terms. * */ /* * This file DbSchemaManager.java is part of Jagornet DHCP. * * Jagornet DHCP is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Jagornet DHCP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jagornet DHCP. If not, see <http://www.gnu.org/licenses/>. * */ package com.jagornet.dhcp.db; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.JdbcTemplate; import com.jagornet.dhcp.server.JagornetDhcpServer; import com.jagornet.dhcp.util.DhcpConstants; /** * The Class DbSchemaManager. * * @author A. Gregory Rabil */ public class DbSchemaManager { private static Logger log = LoggerFactory.getLogger(DbSchemaManager.class); public static String SCHEMATYPE_JDBC_DERBY = "jdbc-derby"; public static String SCHEMATYPE_JDBC_H2 = "jdbc-h2"; public static String SCHEMATYPE_JDBC_SQLITE = "jdbc-sqlite"; public static String SCHEMATYPE_SQLITE = "sqlite"; public static String SCHEMATYPE_MONGO = "mongo"; public static String DB_HOME = DhcpConstants.JAGORNET_DHCP_HOME != null ? (DhcpConstants.JAGORNET_DHCP_HOME + "/db/") : "db/"; public static String SCHEMA_FILENAME = DB_HOME + "jagornet-dhcpv6-schema.sql"; public static String SCHEMA_DERBY_FILENAME = DB_HOME + "jagornet-dhcpv6-schema-derby.sql"; public static String[] TABLE_NAMES = { "DHCPOPTION", "IAADDRESS", "IAPREFIX", "IDENTITYASSOC" }; public static String SCHEMA_V2_FILENAME = DB_HOME + "jagornet-dhcpv6-schema-v2.sql"; public static String SCHEMA_DERBY_V2_FILENAME = DB_HOME + "jagornet-dhcpv6-schema-derby-v2.sql"; public static String[] TABLE_NAMES_V2 = { "DHCPLEASE" }; /** * Validate schema. * * @param dataSource the data source * * @throws SQLException if there is a problem with the database * @throws IOExcpetion if there is a problem reading the schema file * * returns true if database was created, false otherwise */ public static boolean validateSchema(DataSource dataSource, String schemaFilename, int schemaVersion) throws SQLException, IOException { boolean schemaCreated = false; List<String> tableNames = new ArrayList<String>(); Connection conn = dataSource.getConnection(); DatabaseMetaData dbMetaData = conn.getMetaData(); log.info("JDBC Connection Info:\n" + "url = " + dbMetaData.getURL() + "\n" + "database = " + dbMetaData.getDatabaseProductName() + " " + dbMetaData.getDatabaseProductVersion() + "\n" + "driver = " + dbMetaData.getDriverName() + " " + dbMetaData.getDriverVersion()); String[] types = { "TABLE" }; ResultSet rs = dbMetaData.getTables(null, null, "%", types); if (rs.next()) { tableNames.add(rs.getString("TABLE_NAME")); } else { createSchema(dataSource, schemaFilename); dbMetaData = conn.getMetaData(); rs = dbMetaData.getTables(null, null, "%", types); schemaCreated = true; } while (rs.next()) { tableNames.add(rs.getString("TABLE_NAME")); } String[] schemaTableNames; if (schemaVersion <= 1) { schemaTableNames = TABLE_NAMES; } else { schemaTableNames = TABLE_NAMES_V2; } if (tableNames.size() == schemaTableNames.length) { for (int i = 0; i < schemaTableNames.length; i++) { if (!tableNames.contains(schemaTableNames[i])) { throw new IllegalStateException("Invalid database schema: unknown tables"); } } } else { throw new IllegalStateException("Invalid database schema: wrong number of tables"); } return schemaCreated; } public static List<String> getSchemaDDL(String schemaFilename) throws IOException { List<String> schema = new ArrayList<String>(); FileReader fr = null; BufferedReader br = null; try { StringBuilder ddl = new StringBuilder(); if (JagornetDhcpServer.springBootStrategy) { String cpFileName = schemaFilename.substring(schemaFilename.lastIndexOf("/") + 1, schemaFilename.length()); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream res = classLoader.getResourceAsStream(cpFileName); br = new BufferedReader(new InputStreamReader(res, "UTF-8")); } else { fr = new FileReader(schemaFilename); br = new BufferedReader(fr); } String line = br.readLine(); while (line != null) { if (!line.startsWith("-- ")) { ddl.append(line); } if (ddl.toString().endsWith(";")) { ddl.setLength(ddl.length() - 1); schema.add(ddl.toString()); ddl.setLength(0); } line = br.readLine(); } } finally { if (br != null) { br.close(); } if (fr != null) { fr.close(); } } return schema; } /** * Creates the schema. * * @param dataSource the data source * * @throws SQLException if there is a problem with the database * @throws IOExcpetion if there is a problem reading the schema file */ public static void createSchema(DataSource dataSource, String schemaFilename) throws SQLException, IOException { log.info("Creating new JDBC schema from file: " + schemaFilename); JdbcTemplate jdbc = new JdbcTemplate(dataSource); List<String> schemaDDL = getSchemaDDL(schemaFilename); for (String ddl : schemaDDL) { jdbc.execute(ddl); } } }