package de.is24.infrastructure.gridfs.http.metadata.generation; import de.is24.infrastructure.gridfs.http.domain.YumEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.Map; import static java.sql.DriverManager.getConnection; import static org.apache.commons.io.IOUtils.closeQuietly; import static org.apache.commons.io.IOUtils.readLines; import static org.apache.commons.lang.StringUtils.defaultIfBlank; import static org.apache.commons.lang.StringUtils.isNotBlank; public abstract class DbGenerator { private static final Logger LOG = LoggerFactory.getLogger(DbGenerator.class); public static final int DB_VERSION = 10; protected static final String SQL_DIR = "/sql/"; protected static final String PACKAGES = "packages"; protected static final String CHANGELOG = "changelog"; protected static final String FILES = "files"; protected static final String FILELIST = "filelist"; private final String name; protected DbGenerator(String name) { this.name = name; initJdbC(); } public void createDb(File dbFile, List<YumEntry> entries) throws SQLException, IOException { dbFile.delete(); try(Connection connection = getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath())) { initSchema(connection, getName() + ".sql"); Map<String, PreparedStatement> preparedStatements = createPreparedStatements(connection); try { int pkgKey = 1; for (YumEntry entry : entries) { writeEntry(preparedStatements, pkgKey, entry); pkgKey++; } } finally { close(preparedStatements); } } catch (SQLException | IOException e) { LOG.error("Could not generate metadata for repository: {}", name, e); throw e; } } protected abstract void writeEntry(Map<String, PreparedStatement> preparedStatements, int pkgKey, YumEntry entry) throws SQLException; protected abstract Map<String, PreparedStatement> createPreparedStatements(Connection connection) throws SQLException; public String getName() { return name; } protected void initSchema(Connection connection, String schemaFile) throws IOException, SQLException { try(Statement statement = connection.createStatement()) { for (String command : readCommands(schemaFile)) { statement.executeUpdate(command); } insertVersion(statement); } } protected List<String> readCommands(String filename) throws IOException { InputStream inputStream = getClass().getResourceAsStream(SQL_DIR + filename); if (inputStream == null) { throw new IllegalStateException("Could not find prepared sql: " + filename); } try { return readLines(inputStream); } finally { closeQuietly(inputStream); } } protected void insertVersion(Statement statement) throws SQLException { statement.executeUpdate("insert into db_info values(" + DB_VERSION + ", 'direct_create')"); } protected void initJdbC() { try { Class.forName("org.sqlite.JDBC"); } catch (ClassNotFoundException e) { throw new IllegalStateException("SQLite JDBC driver not found", e); } } protected void close(Map<String, PreparedStatement> preparedStatements) throws SQLException { for (Map.Entry<String, PreparedStatement> entry : preparedStatements.entrySet()) { entry.getValue().close(); } } protected static String emptyIfBlank(String str) { return defaultIfBlank(str, ""); } protected static String nullIfBlank(String str) { return defaultIfBlank(str, null); } protected static String trim(String str) { if (isNotBlank(str)) { return str.trim(); } return null; } }