/* * 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.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import cn.edu.zju.acm.onlinejudge.bean.enumeration.Language; import cn.edu.zju.acm.onlinejudge.persistence.LanguagePersistence; import cn.edu.zju.acm.onlinejudge.persistence.PersistenceCreationException; import cn.edu.zju.acm.onlinejudge.persistence.PersistenceException; public class LanguagePersistenceImpl implements LanguagePersistence { /** * The statement to create a language. */ private static final String INSERT_LANGUAGE = MessageFormat .format( "INSERT INTO {0} ({1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", new Object[] {DatabaseConstants.LANGUAGE_TABLE, DatabaseConstants.LANGUAGE_LANGUAGE_ID, DatabaseConstants.LANGUAGE_NAME, DatabaseConstants.LANGUAGE_DESCRIPTION, DatabaseConstants.LANGUAGE_OPTIONS, DatabaseConstants.LANGUAGE_COMPILER, DatabaseConstants.CREATE_USER, DatabaseConstants.CREATE_DATE, DatabaseConstants.LAST_UPDATE_USER, DatabaseConstants.LAST_UPDATE_DATE}); /** * The statement to update a language. */ private static final String UPDATE_LANGUAGE = MessageFormat.format("UPDATE {0} SET {1}=?, {2}=?, {3}=?, {4}=?, {5}=?, {6}=? WHERE {7}=?", new Object[] {DatabaseConstants.LANGUAGE_TABLE, DatabaseConstants.LANGUAGE_NAME, DatabaseConstants.LANGUAGE_DESCRIPTION, DatabaseConstants.LANGUAGE_OPTIONS, DatabaseConstants.LANGUAGE_COMPILER, DatabaseConstants.LAST_UPDATE_USER, DatabaseConstants.LAST_UPDATE_DATE, DatabaseConstants.LANGUAGE_LANGUAGE_ID}); /** * The statement to delete a language. */ private static final String DELETE_LANGUAGE = MessageFormat.format("DELETE FROM {0} WHERE {1}=?", new Object[] {DatabaseConstants.LANGUAGE_TABLE, DatabaseConstants.LANGUAGE_LANGUAGE_ID}); /** * The statement to delete a language. */ private static final String DELETE_SUBMISSION = MessageFormat .format("DELETE FROM {0} WHERE {1}=?", new Object[] {DatabaseConstants.SUBMISSION_TABLE, DatabaseConstants.SUBMISSION_LANGUAGE_ID}); /** * The query to get all languages. */ private static final String GET_ALL_LANGUAGES = MessageFormat.format("SELECT {0}, {1}, {2}, {3}, {4} FROM {5}", new Object[] {DatabaseConstants.LANGUAGE_LANGUAGE_ID, DatabaseConstants.LANGUAGE_NAME, DatabaseConstants.LANGUAGE_DESCRIPTION, DatabaseConstants.LANGUAGE_OPTIONS, DatabaseConstants.LANGUAGE_COMPILER, DatabaseConstants.LANGUAGE_TABLE}); /** * The statement to delete a language. */ private static final String DELETE_LANGUAGE_CONTEST = MessageFormat.format("DELETE FROM {0} WHERE {1}=?", new Object[] {DatabaseConstants.CONTEST_LANGUAGE_TABLE, DatabaseConstants.CONTEST_LANGUAGE_LANGUAGE_ID}); /** * The languages cache. */ private Map<Long, Language> allLanguages = new HashMap<Long, Language>(); public LanguagePersistenceImpl() throws PersistenceCreationException { Connection conn = null; try { conn = Database.createConnection(); PreparedStatement ps = null; try { ps = conn.prepareStatement(LanguagePersistenceImpl.GET_ALL_LANGUAGES); ResultSet rs = ps.executeQuery(); while (rs.next()) { Language language = new Language(rs.getLong(DatabaseConstants.LANGUAGE_LANGUAGE_ID), rs.getString(DatabaseConstants.LANGUAGE_NAME), rs.getString(DatabaseConstants.LANGUAGE_DESCRIPTION), rs.getString(DatabaseConstants.LANGUAGE_COMPILER), rs.getString(DatabaseConstants.LANGUAGE_OPTIONS)); this.allLanguages.put(language.getId(), language); } } finally { Database.dispose(ps); } } catch (Exception e) { throw new PersistenceCreationException("Fail to get all languages", e); } finally { Database.dispose(conn); } } /* * (non-Javadoc) * * @see * cn.edu.zju.acm.onlinejudge.persistence.sql.LanguagePersistence#createLanguage(cn.edu.zju.acm.onlinejudge.bean * .enumeration.Language, long) */ public void createLanguage(Language language, long user) throws PersistenceException { Connection conn = null; try { conn = Database.createConnection(); PreparedStatement ps = null; synchronized (this.allLanguages) { try { ps = conn.prepareStatement(LanguagePersistenceImpl.INSERT_LANGUAGE); ps.setLong(1, language.getId()); ps.setString(2, language.getName()); ps.setString(3, language.getDescription()); ps.setString(4, language.getOptions()); ps.setString(5, language.getCompiler()); ps.setLong(6, user); ps.setTimestamp(7, new Timestamp(new Date().getTime())); ps.setLong(8, user); ps.setTimestamp(9, new Timestamp(new Date().getTime())); ps.executeUpdate(); } finally { Database.dispose(ps); } this.allLanguages.put(language.getId(), language); } } catch (SQLException e) { throw new PersistenceException("Failed to create language.", e); } finally { Database.dispose(conn); } } /* * (non-Javadoc) * * @see * cn.edu.zju.acm.onlinejudge.persistence.sql.LanguagePersistence#updateLanguage(cn.edu.zju.acm.onlinejudge.bean * .enumeration.Language, long) */ public void updateLanguage(Language language, long user) throws PersistenceException { Connection conn = null; try { conn = Database.createConnection(); PreparedStatement ps = null; synchronized (this.allLanguages) { try { ps = conn.prepareStatement(LanguagePersistenceImpl.UPDATE_LANGUAGE); ps.setString(1, language.getName()); ps.setString(2, language.getDescription()); ps.setString(3, language.getOptions()); ps.setString(4, language.getCompiler()); ps.setLong(5, user); ps.setTimestamp(6, new Timestamp(new Date().getTime())); ps.setLong(7, language.getId()); if (ps.executeUpdate() == 0) { throw new PersistenceException("no such language"); } } finally { Database.dispose(ps); } this.allLanguages.put(language.getId(), language); } } catch (PersistenceException pe) { throw pe; } catch (Exception e) { throw new PersistenceException("Failed to update language.", e); } finally { Database.dispose(conn); } } /* * (non-Javadoc) * * @see cn.edu.zju.acm.onlinejudge.persistence.sql.LanguagePersistence#deleteLanguage(long, long) */ // TODO(xuchuan): this is a very dangerous operation. Check if necessary. public void deleteLanguage(long id, long user) throws PersistenceException { Connection conn = null; try { conn = Database.createConnection(); conn.setAutoCommit(false); synchronized (this.allLanguages) { PreparedStatement ps = null; ps = conn.prepareStatement(LanguagePersistenceImpl.DELETE_SUBMISSION); try { ps.setLong(1, id); ps.executeUpdate(); } finally { Database.dispose(ps); } try { ps = conn.prepareStatement(LanguagePersistenceImpl.DELETE_LANGUAGE_CONTEST); ps.setLong(1, id); ps.executeUpdate(); } finally { Database.dispose(ps); } try { ps = conn.prepareStatement(LanguagePersistenceImpl.DELETE_LANGUAGE); ps.setLong(1, id); ps.executeUpdate(); } finally { Database.dispose(ps); } conn.commit(); this.allLanguages.remove(id); } } catch (Exception e) { Database.rollback(conn); throw new PersistenceException("Failed to delete language.", e); } finally { Database.dispose(conn); } } /* * (non-Javadoc) * * @see cn.edu.zju.acm.onlinejudge.persistence.sql.LanguagePersistence#getLanguage(long) */ public Language getLanguage(long id) throws PersistenceException { synchronized (this.allLanguages) { return this.allLanguages.get(id); } } /* * (non-Javadoc) * * @see cn.edu.zju.acm.onlinejudge.persistence.sql.LanguagePersistence#getAllLanguages() */ public List<Language> getAllLanguages() throws PersistenceException { synchronized (this.allLanguages) { return new ArrayList<Language>(this.allLanguages.values()); } } /* * (non-Javadoc) * * @see cn.edu.zju.acm.onlinejudge.persistence.sql.LanguagePersistence#getLanguageMap() */ public Map<Long, Language> getLanguageMap() { synchronized (this.allLanguages) { return new HashMap<Long, Language>(this.allLanguages); } } }