Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate HOZip to Kotlin. #2169

Merged
merged 1 commit into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 0 additions & 74 deletions src/main/java/core/db/backup/BackupHelper.java

This file was deleted.

72 changes: 72 additions & 0 deletions src/main/java/core/db/backup/BackupHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package core.db.backup

import core.db.user.UserManager
import core.util.HOLogger
import java.io.File
import java.text.SimpleDateFormat
import java.util.*

/**
* HSQL DB zipper
* @author Thorsten Dietz
*/

object BackupHelper {
private val sdf = SimpleDateFormat("yyyy-MM-dd")
private val extensions = listOf("script", "data", "backup", "log", "properties")

// zip and delete db
@JvmStatic
fun backup(dbDirectory: File) {
if (!dbDirectory.exists()) {
return
}

val filesToBackup = getFilesToBackup(dbDirectory)
if (filesToBackup.isEmpty()) {
return
}

val zOut: HOZip
try {

zOut = HOZip(
"""$dbDirectory${File.separator}db_${UserManager.instance().currentUser.teamName}-${sdf.format(Date())}.${HOZip.zipExt}"""
)

for (file in filesToBackup) {
zOut.addFile(file)
}

zOut.closeArchive()
} catch (e: Exception) {
HOLogger.instance().log(BackupHelper::class.java, e)
}

deleteOldFiles(dbDirectory)
}

/**
* Deletes old zip files in the directory <code>dbDirectory</code>.
*
* @param dbDirectory Directory where to find the zip files to be deleted.
*/
private fun deleteOldFiles(dbDirectory: File) {
val files = dbDirectory.listFiles { file: File ->
file.isFile && file.extension == HOZip.zipExt

}?.toList()

if (files != null) {
files.sortedByDescending { f -> f.lastModified() }
.drop(UserManager.instance().currentUser.numberOfBackups)
.forEach { f -> f.delete() }
}
}

private fun getFilesToBackup(dbDirectory: File): Array<File> {
return dbDirectory.listFiles { file: File ->
file.isFile && extensions.any { suffix -> file.extension == suffix }
} ?: arrayOf()
}
}
92 changes: 0 additions & 92 deletions src/main/java/core/db/backup/HOZip.java

This file was deleted.

52 changes: 52 additions & 0 deletions src/main/java/core/db/backup/HOZip.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package core.db.backup

import core.util.HOLogger
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

private const val COMPRESSION_LEVEL = 5
private const val COMPRESSION_METHOD = ZipOutputStream.DEFLATED

class HOZip(filename: String) : File(filename) {
private val zOut: ZipOutputStream

var fileCount: Int = 0
private set

/**
* Creates a new HOZip object.
*/
init {
HOLogger.instance().info(javaClass, "Create Backup: $filename")
zOut = ZipOutputStream(FileOutputStream(this))
zOut.setMethod(COMPRESSION_METHOD)
zOut.setLevel(COMPRESSION_LEVEL)
}

@Throws(Exception::class)
fun addFile(file: File) {
FileInputStream(file).use { fis ->
zOut.putNextEntry(ZipEntry(file.name))
fis.copyTo(zOut)
zOut.closeEntry()
}
fileCount++
}

@Throws(Exception::class)
fun closeArchive() {
zOut.finish()
zOut.close()
}

companion object {
val zipExt = "zip"
private val sdf = SimpleDateFormat("yyyy-MM-dd")
fun createZipName(prefix: String): String = prefix + sdf.format(Date()) + ".${zipExt}"
}
}
100 changes: 100 additions & 0 deletions src/test/java/core/db/backup/BackupHelperTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package core.db.backup

import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.io.File
import java.nio.file.Files
import java.nio.file.attribute.FileTime
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.zip.ZipFile


internal class BackupHelperTest {

private val testResourcesDir = File("./src/test/resources")
private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")

private fun listZipInDir(path: String): Array<out File> {
val dir = File(path)
val output = dir.listFiles { _, fileName ->
fileName.endsWith(".zip")
}
return output ?: arrayOf<File>()
}

private fun zipFileName() = "db_user-${formatter.format(LocalDate.now())}.zip"


private fun listFilesInZip(zipPath: String): List<String> {
return ZipFile(zipPath)
.entries()
.toList().map { e -> e.name }
}

@Test
fun testBackupDbDoesNothingIfDirDoesntExist() {
val noDir = File(testResourcesDir, "none")
BackupHelper.backup(noDir)

val zips = listZipInDir(noDir.absolutePath)
Assertions.assertNotNull(zips)
listZipInDir(noDir.absolutePath).let { Assertions.assertTrue(it.isEmpty()) }
}

@Test
fun testBackupDbDoesNothingIfNoMatchingFiles() {
val exportDir = File(testResourcesDir, "export")
BackupHelper.backup(exportDir)

val zips = listZipInDir(exportDir.absolutePath)
Assertions.assertNotNull(zips)
listZipInDir(exportDir.absolutePath).let { Assertions.assertTrue(it.isEmpty()) }
}

@Test
fun testBackupIncludesRelevantFiles() {
val dbDir = File(testResourcesDir, "db")
BackupHelper.backup(dbDir)

val zips = listZipInDir(dbDir.absolutePath)
Assertions.assertNotNull(zips)
Assertions.assertEquals(1, zips.size)

val entries = listFilesInZip(zips.first().absolutePath)
Assertions.assertEquals(3, entries.size)
Assertions.assertEquals(zipFileName(), zips.first().name)
}

@Test
fun testBackupOnlyKeepsMaxNumber() {
val dbDir = File(testResourcesDir, "db")

val currentDate = LocalDateTime.now()
(1..5).forEach { i ->
val date = currentDate.minusDays(i.toLong())
val f = File(testResourcesDir, "db/db_user-${formatter.format(date)}.zip")
f.createNewFile()
Files.setLastModifiedTime(f.toPath(), FileTime.from(date.toInstant(ZoneOffset.UTC)))
}

BackupHelper.backup(dbDir)

val zips = listZipInDir(dbDir.absolutePath)
Assertions.assertNotNull(zips)
Assertions.assertEquals(3, zips.size)
}

@AfterEach
fun cleanup() {
File(testResourcesDir, "db").listFiles()
?.forEach { f ->
if (f.extension == "zip") {
f.delete()
}
}
}
}
Loading