cn.edu.zju.acm.onlinejudge.persistence.sql.Database.java Source code

Java tutorial

Introduction

Here is the source code for cn.edu.zju.acm.onlinejudge.persistence.sql.Database.java

Source

/*
 * Copyright 2007 Zhang, Zheng <oldbig@gmail.com> Xu, Chuan <xuchuan@gmail.com>
 * 
 * This file is part of ZOJ.
 * 
 * ZOJ 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 revision 3 of the License, or (at your option) any later revision.
 * 
 * ZOJ 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 ZOJ. if not, see
 * <http://www.gnu.org/licenses/>.
 */

package cn.edu.zju.acm.onlinejudge.persistence.sql;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;

import cn.edu.zju.acm.onlinejudge.persistence.PersistenceException;

/**
 * <p>
 * Dateabase.
 * </p>
 * 
 * @version 2.0
 * @author Zhang, Zheng
 * @author Xu, Chuan
 */
public class Database {

    /**
     * The query to get last id.
     */
    private static final String GET_LAST_ID = "SELECT LAST_INSERT_ID()";

    /**
     * The data source config file.
     */
    public static String CONFIG_FILE = "data_source.properties";

    /**
     * A BasicDataSource instance used to create connection.
     */
    private static BasicDataSource ds = null;

    /**
     * Private constructor.
     */
    private Database() {
        // empty
    }

    static {
        try {
            Properties properties = new Properties();
            try {
                properties.load(Database.class.getClassLoader().getResourceAsStream(Database.CONFIG_FILE));
            } catch (IOException ioe) {
                throw new PersistenceException("IO error occurs when load " + Database.CONFIG_FILE + ".", ioe);
            }

            Database.ds = new BasicDataSource();
            Database.ds.setDefaultAutoCommit(
                    "true".equalsIgnoreCase(Database.getStringProperty(properties, "DefaultAutoCommit")));
            Database.ds.setDefaultCatalog(Database.getStringProperty(properties, "DefaultCatalog"));
            Database.ds.setDriverClassName(Database.getStringProperty(properties, "DriverClassName"));
            Database.ds.setMaxActive(Database.getIntegerProperty(properties, "MaxActive"));
            Database.ds.setMaxIdle(Database.getIntegerProperty(properties, "MaxIdle"));
            Database.ds.setMaxWait(Database.getLongProperty(properties, "MaxWait"));
            Database.ds.setUrl(Database.getStringProperty(properties, "Url"));
            Database.ds.setPassword(Database.getStringProperty(properties, "Password"));
            Database.ds.setUsername(Database.getStringProperty(properties, "Username"));
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * Gets a connection. This method is synchronized.
     * 
     * @return a connection
     * @throws PersistenceException
     *             if any error occurs.
     */
    public static Connection createConnection() throws PersistenceException {
        try {
            return Database.ds.getConnection();
        } catch (SQLException e) {
            throw new PersistenceException("Failed to create connection", e);
        }
    }

    public static void dispose(PreparedStatement ps) {
        if (ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
            }
        }
    }

    public static void dispose(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
            }
        }
    }

    /**
     * Create a string containing given values. The string is like '(value1, value2, value3)'
     * 
     * @param values
     *            the values
     * @return a string like '(value1, value2, value3)'
     */
    public static String createValues(Collection<String> values) {
        StringBuilder ret = new StringBuilder();
        ret.append('(');
        for (String value : values) {
            if (ret.length() > 1) {
                ret.append(',');
            }
            ret.append('\'').append(value.replaceAll("'", "''")).append('\'');
        }
        ret.append(')');
        return ret.toString();
    }

    /**
     * Create a string containing given number values. The string is like '(value1, value2, value3)'
     * 
     * @param values
     *            the values
     * @return a string like '(value1, value2, value3)'
     */
    public static String createNumberValues(Collection<Long> values) {
        StringBuilder ret = new StringBuilder();
        ret.append('(');
        for (Long value : values) {
            if (ret.length() > 1) {
                ret.append(',');
            }
            ret.append(value);
        }
        ret.append(')');
        return ret.toString();
    }

    /**
     * Rollback given connection.
     * 
     * @param conn
     *            the connection
     */
    public static void rollback(Connection conn) {
        try {
            if (conn != null) {
                conn.rollback();
            }
        } catch (SQLException e) {
            // ignore
        }
    }

    /**
     * Gets the last id.
     * 
     * @param conn
     * @param ps
     * @param rs
     * @return the last id
     * @throws SQLException
     */
    public static long getLastId(Connection conn) throws SQLException {
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(Database.GET_LAST_ID);
            ResultSet rs = ps.executeQuery();
            rs.next();
            return rs.getLong(1);
        } finally {
            Database.dispose(ps);
        }
    }

    /**
     * Gets a date value from given ResultSet.
     * 
     * @param rs
     *            the ResultSet
     * @param column
     *            the column name
     * @return a date value from given ResultSet.
     * @throws SQLException
     */
    public static Date getDate(ResultSet rs, String column) throws SQLException {
        Timestamp date = rs.getTimestamp(column);
        if (date == null) {
            return null;
        }
        return new Date(date.getTime());
    }

    /**
     * Convert given Date to Timestamp.
     * 
     * @param date
     *            the date
     * @return a Timestamp instance.
     */
    public static Timestamp toTimestamp(Date date) {
        if (date == null) {
            return null;
        }
        return new Timestamp(date.getTime());
    }

    /**
     * Gets the given string property
     * 
     * @param properties
     *            properties
     * @param key
     *            property key
     * @return the property value in string
     */
    private static String getStringProperty(Properties properties, String key) throws PersistenceException {
        String value = properties.getProperty(key);
        if (value == null) {
            throw new PersistenceException(key + " property is missing in " + Database.CONFIG_FILE);
        }
        return value;
    }

    /**
     * Gets the given int property
     * 
     * @param properties
     *            properties
     * @param key
     *            property key
     * @return the property value in int
     */
    private static int getIntegerProperty(Properties properties, String key) throws PersistenceException {
        String value = Database.getStringProperty(properties, key);
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException nfe) {
            throw new PersistenceException(key + " property is an invalid integer");
        }
    }

    /**
     * Gets the given long property
     * 
     * @param properties
     *            properties
     * @param key
     *            property key
     * @return the property value in long
     */
    private static long getLongProperty(Properties properties, String key) throws PersistenceException {
        String value = Database.getStringProperty(properties, key);
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException nfe) {
            throw new PersistenceException(key + " property is an invalid long");
        }
    }
}