22
33import java .io .IOException ;
44import java .nio .file .Files ;
5+ import java .nio .file .Path ;
56import java .nio .file .Paths ;
67import java .nio .file .StandardCopyOption ;
78import java .sql .SQLException ;
89import java .util .concurrent .TimeUnit ;
910import java .util .concurrent .atomic .AtomicBoolean ;
1011
11- import jakarta .enterprise . context . ApplicationScoped ;
12+ import jakarta .annotation . PostConstruct ;
1213import jakarta .enterprise .event .Observes ;
1314import jakarta .inject .Inject ;
15+ import jakarta .inject .Singleton ;
1416import jakarta .persistence .EntityManager ;
1517
1618import org .eclipse .microprofile .config .inject .ConfigProperty ;
1719import org .hibernate .engine .jdbc .connections .spi .JdbcConnectionAccess ;
1820import org .hibernate .internal .SessionImpl ;
19- import org .jboss .logging .Logger ;
2021
22+ import io .quarkus .logging .Log ;
2123import io .quarkus .runtime .ShutdownEvent ;
2224import io .quarkus .scheduler .Scheduled ;
2325
24- @ ApplicationScoped
26+ @ Singleton
2527public class SQLiteFilePersister {
28+ private final AtomicBoolean executing = new AtomicBoolean (false );
2629 @ ConfigProperty (name = "quarkus.datasource.jdbc.url" )
2730 String jdbcUrl ;
28-
29- private static final Logger LOGGER = Logger .getLogger (SQLiteFilePersister .class .getName ());
30-
3131 @ Inject
3232 EntityManager entityManager ;
33+ private Path dbFile ;
34+ private Path backupDBFile ;
35+ private JdbcConnectionAccess access ;
3336
34- private final AtomicBoolean executing = new AtomicBoolean (false );
37+ @ PostConstruct
38+ void init () {
39+ int prefixLength = "jdbc:sqlite:" .length ();
40+ int queryParamsIdx = jdbcUrl .indexOf ('?' );
41+ int length = (queryParamsIdx != -1 ) ? queryParamsIdx : jdbcUrl .length ();
42+ var dbFileName = jdbcUrl .substring (prefixLength , length );
43+ dbFile = Paths .get (dbFileName );
44+ backupDBFile = dbFile .toAbsolutePath ().getParent ().resolve (dbFile .getFileName () + "_backup" );
45+ access = entityManager .unwrap (SessionImpl .class ).getJdbcConnectionAccess ();
46+ }
3547
3648 // Execute a backup every 10 seconds
3749 @ Scheduled (delay = 10 , delayUnit = TimeUnit .SECONDS , every = "10s" )
@@ -47,37 +59,24 @@ public void onShutdown(@Observes ShutdownEvent event) {
4759 void backup () {
4860 if (executing .compareAndSet (false , true )) {
4961 try {
50- int prefixLength = "jdbc:sqlite:" .length ();
51- int queryParamsIdx = jdbcUrl .indexOf ('?' );
52- int length = (queryParamsIdx != -1 ) ? queryParamsIdx : jdbcUrl .length ();
53- String dbFile = jdbcUrl .substring (prefixLength , length );
54-
55- var originalDbFilePath = Paths .get (dbFile );
56- LOGGER .info ("Starting DB backup for file: " + dbFile );
57- var backupDbFilePath = originalDbFilePath .toAbsolutePath ().getParent ()
58- .resolve (originalDbFilePath .getFileName () + "_backup" );
59-
60- JdbcConnectionAccess access = entityManager
61- .unwrap (SessionImpl .class )
62- .getJdbcConnectionAccess ();
62+ Log .trace ("Starting DB backup for file: " + dbFile );
6363 try (var conn = access .obtainConnection ();
6464 var stmt = conn .createStatement ()) {
6565 // Execute the backup
66- stmt .executeUpdate ("backup to " + backupDbFilePath );
66+ stmt .executeUpdate ("backup to " + backupDBFile );
6767 // Atomically substitute the DB file with its backup
68- Files .move (backupDbFilePath , originalDbFilePath , StandardCopyOption .ATOMIC_MOVE ,
69- StandardCopyOption .REPLACE_EXISTING );
68+ Files .move (backupDBFile , dbFile , StandardCopyOption .ATOMIC_MOVE , StandardCopyOption .REPLACE_EXISTING );
7069 } catch (SQLException e ) {
7170 throw new RuntimeException ("Failed to backup the database" , e );
7271 } catch (IOException e ) {
7372 throw new RuntimeException ("Failed to create backup files or folders" , e );
7473 }
75- LOGGER .info ("Backup of " + dbFile + " completed. " );
74+ Log .info ("Backup of " + dbFile + " completed" );
7675 } finally {
7776 executing .set (false );
7877 }
7978 } else {
80- LOGGER . info ( "Backup in progress. " );
79+ Log . trace ( "Skipping backup as one is already in progress" );
8180 }
8281 }
8382
0 commit comments