Cache.java (2845B)
1 package fr.kevincorvisier.mtg.dd; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.File; 6 import java.io.IOException; 7 import java.io.StringReader; 8 import java.net.URL; 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.sql.PreparedStatement; 12 import java.sql.ResultSet; 13 import java.sql.SQLException; 14 15 import javax.annotation.Nullable; 16 17 import org.apache.commons.io.output.StringBuilderWriter; 18 import org.springframework.beans.factory.annotation.Value; 19 import org.springframework.stereotype.Service; 20 21 import fr.kevincorvisier.mtg.utils.mtgo.MagicOnlineDeckContent; 22 import fr.kevincorvisier.mtg.utils.mtgo.MagicOnlineFileReader; 23 import fr.kevincorvisier.mtg.utils.mtgo.MagicOnlineFileWriter; 24 import jakarta.validation.constraints.NotNull; 25 import lombok.NonNull; 26 import lombok.extern.slf4j.Slf4j; 27 28 @Slf4j 29 @Service 30 public class Cache 31 { 32 private static final String QUERY_INITIALIZE = "CREATE TABLE IF NOT EXISTS `decks` (`url` TEXT PRIMARY KEY,`content` TEXT);"; 33 34 private final Connection connection; 35 36 public Cache(@Value("${cache.database}") final String file) throws SQLException 37 { 38 if (file == null) 39 throw new NullPointerException("Property cache.database must be present and have a value"); 40 41 new File(file).getParentFile().mkdirs(); 42 43 connection = DriverManager.getConnection("jdbc:sqlite:" + file); 44 initialize(); 45 } 46 47 private void initialize() throws SQLException 48 { 49 try (PreparedStatement ps = connection.prepareStatement(QUERY_INITIALIZE)) 50 { 51 ps.executeUpdate(); 52 } 53 } 54 55 @Nullable 56 public MagicOnlineDeckContent findByUrl(@NonNull @NotNull final URL url) 57 { 58 final String content; 59 60 try (PreparedStatement ps = connection.prepareStatement("SELECT content FROM decks WHERE url = ?")) 61 { 62 ps.setString(1, url.toString()); 63 final ResultSet rs = ps.executeQuery(); 64 65 if (!rs.next()) 66 return null; 67 68 content = rs.getString("content"); 69 } 70 catch (final SQLException e) 71 { 72 log.error("findByUrl: url={}", url, e); 73 return null; 74 } 75 76 try (BufferedReader reader = new BufferedReader(new StringReader(content))) 77 { 78 return MagicOnlineFileReader.read(reader); 79 } 80 catch (final NumberFormatException | IOException e) 81 { 82 // Cached content is not valid, return null 83 return null; 84 } 85 } 86 87 public void save(@NonNull @NotNull final URL url, @NonNull @NotNull final MagicOnlineDeckContent content) throws SQLException, IOException 88 { 89 final StringBuilder builder = new StringBuilder(); 90 91 try (BufferedWriter writer = new BufferedWriter(new StringBuilderWriter(builder))) 92 { 93 MagicOnlineFileWriter.write(writer, content); 94 } 95 96 try (PreparedStatement ps = connection.prepareStatement("INSERT INTO `decks` (`url`, `content`) VALUES (?, ?);")) 97 { 98 ps.setString(1, url.toString()); 99 ps.setString(2, builder.toString()); 100 ps.executeUpdate(); 101 } 102 } 103 }