001/*
002 * #%L
003 * Netarchivesuite - archive
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.archive.arcrepositoryadmin;
025
026import java.io.File;
027import java.io.IOException;
028import java.sql.CallableStatement;
029import java.sql.Connection;
030import java.sql.DriverManager;
031import java.sql.SQLException;
032
033import dk.netarkivet.common.exceptions.ArgumentNotValid;
034import dk.netarkivet.common.exceptions.IOFailure;
035import dk.netarkivet.common.exceptions.PermissionDenied;
036import dk.netarkivet.common.utils.ExceptionUtils;
037import dk.netarkivet.common.utils.FileUtils;
038
039/**
040 * A class that implement functionality specific to the embedded Derby system.
041 */
042public class DerbyEmbeddedSpecifics extends DerbySpecifics {
043    /**
044     * Get an instance of the Embedded Derby specifics.
045     *
046     * @return Instance of the Derby specifics implementation
047     */
048    public static DBSpecifics getInstance() {
049        return new DerbyEmbeddedSpecifics();
050    }
051
052    /**
053     * Shutdown the database system, if running in embedded mode. Otherwise, this is ignored.
054     * <p>
055     * Will log a warning on errors, but otherwise ignore them.
056     */
057    public void shutdownDatabase() {
058        try {
059            // This call throws an exception, see
060            // http://db.apache.org/derby/docs/10.2/ref/rrefattrib16471.html
061            DriverManager.getConnection("jdbc:derby:;shutdown=true");
062            log.warn("Shut down Derby embedded database w/o expected warning");
063        } catch (SQLException e) {
064            log.info("Embedded Derby database has been shut down");
065            log.debug(
066                    "Shutdown down derby gave (as expected) an exception" + "\n"
067                            + ExceptionUtils.getSQLExceptionCause(e), e);
068        }
069    }
070
071    /**
072     * Backup the database. For server-based databases, where the administrator is expected to perform the backups, this
073     * method should do nothing. This method gets called within one hour of the hour-of-day indicated by the
074     * DB_BACKUP_INIT_HOUR settings.
075     *
076     * @param backupDir Directory to which the database should be backed up
077     * @param c The connection to the database.
078     * @throws PermissionDenied if the directory cannot be created.
079     * @throws IOFailure If we cannot connect to the database
080     * @throws ArgumentNotValid If the connection or the backupDir if null.
081     */
082    public void backupDatabase(Connection c, File backupDir) throws PermissionDenied, ArgumentNotValid, IOFailure {
083        ArgumentNotValid.checkNotNull(c, "Connection c");
084        ArgumentNotValid.checkNotNull(backupDir, "backupDir");
085
086        FileUtils.createDir(backupDir);
087        CallableStatement cs = null;
088        try {
089            cs = c.prepareCall("CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE(?)");
090            cs.setString(1, backupDir.getCanonicalPath());
091            cs.execute();
092            cs.close();
093            log.info("Backed up database to " + backupDir.getCanonicalPath());
094        } catch (IOException e) {
095            throw new IOFailure("Couldn't back up database to " + backupDir, e);
096        } catch (SQLException e) {
097            throw new IOFailure("Could not execute sql statememt.", e);
098        }
099    }
100
101    /**
102     * Get the name of the JDBC driver class that handles interfacing to this server.
103     *
104     * @return The name of a JDBC driver class
105     */
106    public String getDriverClassName() {
107        return "org.apache.derby.jdbc.EmbeddedDriver";
108    }
109}