h2backup.BackupFileService.java Source code

Java tutorial

Introduction

Here is the source code for h2backup.BackupFileService.java

Source

/*
 * Copyright 2017 Evgeniy Khyst.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package h2backup;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.sql.DataSource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Clock;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 *
 * @author Evgeniy Khyst
 */
@Singleton
@Slf4j
public class BackupFileService {

    private static final String ZIP_EXTENSION = ".zip";
    private static final String TMP_SUFFIX = "_tmp";

    private final DataSource dataSource;

    private Clock clock = Clock.systemDefaultZone();

    @Inject
    public BackupFileService(@H2Backup DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Path backupDatabase(BackupMethod method, String directory, String filePrefix,
            String dateTimeFormatPattern) {
        try {
            String fileNameWithoutExt = filePrefix + "_"
                    + DateTimeFormatter.ofPattern(dateTimeFormatPattern).format(LocalDateTime.now(clock)) + "_"
                    + method.getFileSuffix();
            final Path path = Paths.get(directory, fileNameWithoutExt + ZIP_EXTENSION);
            final Path tmpPath = Paths.get(directory, fileNameWithoutExt + TMP_SUFFIX + ZIP_EXTENSION);

            log.info("Starting backup to file {} using {} method", tmpPath, method);
            method.getStrategy().backupDatabase(dataSource, tmpPath.toString());

            if (Files.exists(path) && FileUtils.contentEquals(tmpPath.toFile(), path.toFile())) {
                log.info("Deleting backup {} because it is identical to previous backup {}", tmpPath, path);
                Files.delete(tmpPath);
                return null;
            }

            int maxIndex = 0;
            do {
                maxIndex++;
            } while (Files.exists(Paths.get(directory, fileNameWithoutExt + "_" + maxIndex + ZIP_EXTENSION)));

            for (int index = maxIndex; index >= 1; index--) {
                Path oldPath = Paths.get(directory,
                        fileNameWithoutExt + (index > 1 ? "_" + (index - 1) : "") + ZIP_EXTENSION);
                Path newPath = Paths.get(directory, fileNameWithoutExt + "_" + index + ZIP_EXTENSION);
                if (Files.exists(oldPath)) {
                    log.debug("Moving file {} to {}", oldPath, newPath);
                    Files.move(oldPath, newPath);
                }
            }

            Files.move(tmpPath, path);

            return path;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public Clock getClock() {
        return clock;
    }

    public void setClock(Clock clock) {
        this.clock = clock;
    }
}