Java tutorial
/* * 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; } }