diff --git a/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/DatabaseSubkeyLookup.java b/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/DatabaseSubkeyLookup.java new file mode 100644 index 00000000..960053a2 --- /dev/null +++ b/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/DatabaseSubkeyLookup.java @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package pgp.cert_d.jdbc.sqlite; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import pgp.certificate_store.SubkeyLookup; + +public class DatabaseSubkeyLookup implements SubkeyLookup { + + private final SubkeyLookupDao dao; + + public DatabaseSubkeyLookup(SubkeyLookupDao dao) { + this.dao = dao; + } + + @Override + public Set getCertificatesForSubkeyId(long subkeyId) throws IOException { + try { + List entries = dao.selectValues(subkeyId); + Set certificates = new HashSet<>(); + for (Entry entry : entries) { + certificates.add(entry.getCertificate()); + } + + return Collections.unmodifiableSet(certificates); + } catch (SQLException e) { + throw new IOException("Cannot query for subkey lookup entries.", e); + } + } + + @Override + public void storeCertificateSubkeyIds(String certificate, List subkeyIds) throws IOException { + try { + dao.insertValues(certificate, subkeyIds); + } catch (SQLException e) { + throw new IOException("Cannot store subkey lookup entries in database.", e); + } + } +} diff --git a/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookup.java b/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupDaoImpl.java similarity index 68% rename from pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookup.java rename to pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupDaoImpl.java index df7761b1..ecc5e662 100644 --- a/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookup.java +++ b/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupDaoImpl.java @@ -4,8 +4,10 @@ package pgp.cert_d.jdbc.sqlite; +import org.sqlite.SQLiteErrorCode; +import org.sqlite.SQLiteException; + import java.io.File; -import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -13,16 +15,9 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import org.sqlite.SQLiteErrorCode; -import org.sqlite.SQLiteException; -import pgp.certificate_store.SubkeyLookup; - -public class SqliteSubkeyLookup implements SubkeyLookup { +public class SqliteSubkeyLookupDaoImpl implements SubkeyLookupDao { private final String databaseUrl; @@ -41,7 +36,7 @@ public class SqliteSubkeyLookup implements SubkeyLookup { "SELECT * FROM subkey_lookup " + "WHERE subkey_id=?"; - public SqliteSubkeyLookup(String databaseURL) throws SQLException { + public SqliteSubkeyLookupDaoImpl(String databaseURL) throws SQLException { this.databaseUrl = databaseURL; try (Connection connection = getConnection(); Statement statement = connection.createStatement()) { statement.execute(CREATE_TABLE_STMT); @@ -52,17 +47,19 @@ public class SqliteSubkeyLookup implements SubkeyLookup { return DriverManager.getConnection(databaseUrl); } - public static SqliteSubkeyLookup forDatabaseFile(File databaseFile) throws SQLException { - return new SqliteSubkeyLookup("jdbc:sqlite:" + databaseFile.getAbsolutePath()); + public static SqliteSubkeyLookupDaoImpl forDatabaseFile(File databaseFile) throws SQLException { + return new SqliteSubkeyLookupDaoImpl("jdbc:sqlite:" + databaseFile.getAbsolutePath()); } - public void insertValues(String certificate, List subkeyIds) throws SQLException { + public int insertValues(String certificate, List subkeyIds) throws SQLException { + int inserted = 0; try (Connection connection = getConnection(); PreparedStatement statement = connection.prepareStatement(INSERT_STMT)) { for (long subkeyId : subkeyIds) { try { statement.setString(1, certificate); statement.setLong(2, subkeyId); statement.executeUpdate(); + inserted++; } catch (SQLiteException e) { // throw any exception, except: // ignore unique constraint-related exceptions if we ignoreDuplicates @@ -74,6 +71,7 @@ public class SqliteSubkeyLookup implements SubkeyLookup { } } } + return inserted; } public List selectValues(long subkeyId) throws SQLException { @@ -92,28 +90,4 @@ public class SqliteSubkeyLookup implements SubkeyLookup { } return results; } - - @Override - public Set getCertificatesForSubkeyId(long subkeyId) throws IOException { - try { - List entries = selectValues(subkeyId); - Set certificates = new HashSet<>(); - for (Entry entry : entries) { - certificates.add(entry.getCertificate()); - } - - return Collections.unmodifiableSet(certificates); - } catch (SQLException e) { - throw new IOException("Cannot query for subkey lookup entries.", e); - } - } - - @Override - public void storeCertificateSubkeyIds(String certificate, List subkeyIds) throws IOException { - try { - insertValues(certificate, subkeyIds); - } catch (SQLException e) { - throw new IOException("Cannot store subkey lookup entries in database.", e); - } - } } diff --git a/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SubkeyLookupDao.java b/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SubkeyLookupDao.java new file mode 100644 index 00000000..350751b4 --- /dev/null +++ b/pgp-cert-d-java-jdbc-sqlite-lookup/src/main/java/pgp/cert_d/jdbc/sqlite/SubkeyLookupDao.java @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package pgp.cert_d.jdbc.sqlite; + +import java.sql.SQLException; +import java.util.List; + +public interface SubkeyLookupDao { + + int insertValues(String certificate, List subkeyIds) throws SQLException; + + List selectValues(long subkeyId) throws SQLException; +} diff --git a/pgp-cert-d-java-jdbc-sqlite-lookup/src/test/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupTest.java b/pgp-cert-d-java-jdbc-sqlite-lookup/src/test/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupTest.java index 40fadb63..1b80d037 100644 --- a/pgp-cert-d-java-jdbc-sqlite-lookup/src/test/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupTest.java +++ b/pgp-cert-d-java-jdbc-sqlite-lookup/src/test/java/pgp/cert_d/jdbc/sqlite/SqliteSubkeyLookupTest.java @@ -23,14 +23,14 @@ import org.junit.jupiter.api.Test; public class SqliteSubkeyLookupTest { private File databaseFile; - private SqliteSubkeyLookup lookup; + private DatabaseSubkeyLookup lookup; @BeforeEach public void setupLookup() throws IOException, SQLException { databaseFile = Files.createTempFile("pgp.cert.d-", "lookup.db").toFile(); databaseFile.createNewFile(); databaseFile.deleteOnExit(); - lookup = SqliteSubkeyLookup.forDatabaseFile(databaseFile); + lookup = new DatabaseSubkeyLookup(SqliteSubkeyLookupDaoImpl.forDatabaseFile(databaseFile)); } @Test @@ -45,8 +45,7 @@ public class SqliteSubkeyLookupTest { } @Test - public void getNonExistingSubkeyYieldsNull() throws IOException, SQLException { - assertTrue(lookup.selectValues(6666666).isEmpty()); + public void getNonExistingSubkeyYieldsNull() throws IOException { assertTrue(lookup.getCertificatesForSubkeyId(6666666).isEmpty()); } @@ -56,7 +55,7 @@ public class SqliteSubkeyLookupTest { assertEquals(Collections.singleton("eb85bb5fa33a75e15e944e63f231550c4f47e38e"), lookup.getCertificatesForSubkeyId(1337)); // do the lookup using a second db instance on the same file - SqliteSubkeyLookup secondInstance = SqliteSubkeyLookup.forDatabaseFile(databaseFile); + DatabaseSubkeyLookup secondInstance = new DatabaseSubkeyLookup(SqliteSubkeyLookupDaoImpl.forDatabaseFile(databaseFile)); assertEquals(Collections.singleton("eb85bb5fa33a75e15e944e63f231550c4f47e38e"), secondInstance.getCertificatesForSubkeyId(1337)); } diff --git a/pgp-cert-d-java/src/test/java/pgp/cert_d/SubkeyLookupTest.java b/pgp-cert-d-java/src/test/java/pgp/cert_d/SubkeyLookupTest.java index d4821918..eab6e288 100644 --- a/pgp-cert-d-java/src/test/java/pgp/cert_d/SubkeyLookupTest.java +++ b/pgp-cert-d-java/src/test/java/pgp/cert_d/SubkeyLookupTest.java @@ -22,7 +22,8 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import pgp.cert_d.jdbc.sqlite.SqliteSubkeyLookup; +import pgp.cert_d.jdbc.sqlite.DatabaseSubkeyLookup; +import pgp.cert_d.jdbc.sqlite.SqliteSubkeyLookupDaoImpl; import pgp.certificate_store.SubkeyLookup; public class SubkeyLookupTest { @@ -37,7 +38,7 @@ public class SubkeyLookupTest { File sqliteDatabase = Files.createTempFile("subkeyLookupTest", ".db").toFile(); sqliteDatabase.createNewFile(); sqliteDatabase.deleteOnExit(); - SqliteSubkeyLookup sqliteSubkeyLookup = SqliteSubkeyLookup.forDatabaseFile(sqliteDatabase); + DatabaseSubkeyLookup sqliteSubkeyLookup = new DatabaseSubkeyLookup(SqliteSubkeyLookupDaoImpl.forDatabaseFile(sqliteDatabase)); testSubjects.add(sqliteSubkeyLookup); } diff --git a/pgpainless-cert-d-cli/src/main/java/pgp/cert_d/cli/PGPCertDCli.java b/pgpainless-cert-d-cli/src/main/java/pgp/cert_d/cli/PGPCertDCli.java index 8115caed..859dd2fb 100644 --- a/pgpainless-cert-d-cli/src/main/java/pgp/cert_d/cli/PGPCertDCli.java +++ b/pgpainless-cert-d-cli/src/main/java/pgp/cert_d/cli/PGPCertDCli.java @@ -11,7 +11,8 @@ import pgp.cert_d.SharedPGPCertificateDirectoryImpl; import pgp.cert_d.cli.commands.Get; import pgp.cert_d.cli.commands.Import; import pgp.cert_d.cli.commands.MultiImport; -import pgp.cert_d.jdbc.sqlite.SqliteSubkeyLookup; +import pgp.cert_d.jdbc.sqlite.DatabaseSubkeyLookup; +import pgp.cert_d.jdbc.sqlite.SqliteSubkeyLookupDaoImpl; import pgp.certificate_store.SubkeyLookup; import pgp.certificate_store.exception.NotAStoreException; import pgp.certificate_store.CertificateDirectory; @@ -53,7 +54,8 @@ public class PGPCertDCli { certificateDirectory = new SharedPGPCertificateDirectoryImpl( baseDirectory, new CertificateReader()); - subkeyLookup = SqliteSubkeyLookup.forDatabaseFile(new File(baseDirectory, "_pgpainless_subkey_map.db")); + subkeyLookup = new DatabaseSubkeyLookup( + SqliteSubkeyLookupDaoImpl.forDatabaseFile(new File(baseDirectory, "_pgpainless_subkey_map.db"))); PGPCertDCli.certificateDirectory = new SharedPGPCertificateDirectoryAdapter(certificateDirectory, subkeyLookup); }