001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.sync;
019
020import java.io.File;
021import java.sql.SQLException;
022
023import net.sf.hajdbc.Database;
024import net.sf.hajdbc.DatabaseCluster;
025import net.sf.hajdbc.DumpRestoreSupport;
026import net.sf.hajdbc.ExceptionType;
027import net.sf.hajdbc.Messages;
028import net.sf.hajdbc.SynchronizationStrategy;
029import net.sf.hajdbc.codec.Decoder;
030import net.sf.hajdbc.dialect.Dialect;
031import net.sf.hajdbc.util.Files;
032
033/**
034 * A synchronization strategy that uses dump/restore procedures.
035 * @author Paul Ferraro
036 */
037public class DumpRestoreSynchronizationStrategy implements SynchronizationStrategy
038{
039        private static final long serialVersionUID = 5743532034969216540L;
040        private static final String DUMP_FILE_SUFFIX = ".dump";
041
042        private boolean dataOnly = false;
043
044        @Override
045        public String getId()
046        {
047                return "dump-restore";
048        }
049
050        public boolean isDataOnly()
051        {
052                return this.dataOnly;
053        }
054
055        public void setDataOnly(boolean dataOnly)
056        {
057                this.dataOnly = dataOnly;
058        }
059
060        /**
061         * {@inheritDoc}
062         * @see net.sf.hajdbc.SynchronizationStrategy#init(net.sf.hajdbc.DatabaseCluster)
063         */
064        @Override
065        public <Z, D extends Database<Z>> void init(DatabaseCluster<Z, D> cluster)
066        {
067        }
068
069        /**
070         * {@inheritDoc}
071         * @see net.sf.hajdbc.SynchronizationStrategy#destroy(net.sf.hajdbc.DatabaseCluster)
072         */
073        @Override
074        public <Z, D extends Database<Z>> void destroy(DatabaseCluster<Z, D> cluster)
075        {
076        }
077        
078        /**
079         * {@inheritDoc}
080         * @see net.sf.hajdbc.SynchronizationStrategy#synchronize(net.sf.hajdbc.sync.SynchronizationContext)
081         */
082        @Override
083        public <Z, D extends Database<Z>> void synchronize(SynchronizationContext<Z, D> context) throws SQLException
084        {
085                Dialect dialect = context.getDialect();
086                Decoder decoder = context.getDecoder();
087                DumpRestoreSupport support = dialect.getDumpRestoreSupport();
088                
089                if (support == null)
090                {
091                        throw new SQLException(Messages.DUMP_RESTORE_UNSUPPORTED.getMessage(dialect));
092                }
093                
094                try
095                {
096                        File file = Files.createTempFile(DUMP_FILE_SUFFIX);
097                        
098                        try
099                        {
100                                support.dump(context.getSourceDatabase(), decoder, file, this.dataOnly);
101                                support.restore(context.getTargetDatabase(), decoder, file, this.dataOnly);
102                        }
103                        finally
104                        {
105                                Files.delete(file);
106                        }
107                }
108                catch (Exception e)
109                {
110                        throw ExceptionType.SQL.<SQLException>getExceptionFactory().createException(e);
111                }
112        }
113}