com.jagornet.dhcp.db.DbSchemaManager.java Source code

Java tutorial

Introduction

Here is the source code for com.jagornet.dhcp.db.DbSchemaManager.java

Source

/*
 * 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);
        }
    }
}