Skip to content
This repository has been archived by the owner on Jul 26, 2024. It is now read-only.

Commit

Permalink
Add JPA and JDBC implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralf Ueberfuhr committed Jun 21, 2024
1 parent 2e4e274 commit 2a93333
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.schulung.sample.quarkus.persistence;

import de.schulung.sample.quarkus.domain.Customer;
import de.schulung.sample.quarkus.domain.Customer.CustomerState;
import de.schulung.sample.quarkus.domain.CustomersSink;
import io.quarkus.arc.properties.IfBuildProperty;
import jakarta.enterprise.context.ApplicationScoped;
Expand All @@ -27,66 +28,181 @@ public class CustomersSinkJdbcImpl implements CustomersSink {

private final DataSource ds;

private static LocalDate convert(Date date) {
/* ******************************************************* *
* Converter methods - could be converter objects instead *
* ******************************************************* */

private static UUID convertUuid(String uuid) {
return Optional.ofNullable(uuid)
.map(UUID::fromString)
.orElse(null);
}

private static String convertUuid(UUID uuid) {
return Optional.ofNullable(uuid)
.map(UUID::toString)
.orElse(null);
}

private static LocalDate convertDate(Date date) {
return Optional.ofNullable(date)
.map(Date::toLocalDate)
.orElse(null);
}

@Override
public Stream<Customer> findAll() {
try(Connection con = ds.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from CUSTOMERS")) {
private static Date convertDate(LocalDate date) {
return Optional.ofNullable(date)
.map(Date::valueOf)
.orElse(null);
}

Collection<Customer> result = new LinkedList<>();
private static CustomerState convertState(int value) {
return CustomerState.values()[value];
}

while(rs.next()) {
private static int convertState(CustomerState value) {
return Optional.ofNullable(value)
.map(CustomerState::ordinal)
.orElse(0);

var customer = Customer.builder()
.uuid(UUID.fromString(rs.getString("UUID")))
.birthdate(convert(rs.getDate("DATE_OF_BIRTH")))
.name(rs.getString("NAME"))
//.state(rs.?)
.build();
result.add(customer);
}

}
/* ******************************************************* *
* Row Mapping - could be a RowMapper object instead *
* ******************************************************* */

private static Customer readSingle(ResultSet rs) throws SQLException {
return Customer.builder()
.uuid(convertUuid(rs.getString("UUID")))
.birthdate(convertDate(rs.getDate("DATE_OF_BIRTH")))
.name(rs.getString("NAME"))
.state(convertState(rs.getInt("STATE")))
.build();
}

private static Stream<Customer> readAll(ResultSet rs) throws SQLException {
Collection<Customer> result = new LinkedList<>();
while (rs.next()) {
result.add(readSingle(rs));
}
return result.stream();
}

/* ******************************************************* *
* CustomersSink implementation *
* ******************************************************* */

@Override
public Stream<Customer> findAll() {
try (Connection con = ds.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
"select * from CUSTOMERS"
)) {

return result.stream();
return readAll(rs);

} catch (SQLException e) {
throw new RuntimeException(e); // eigene Exception?
throw new RuntimeException(e); // eigene Exception?
}
}

@Override
public Stream<Customer> findByState(Customer.CustomerState state) {
return CustomersSink.super.findByState(state);
public Stream<Customer> findByState(CustomerState state) {
try (Connection con = ds.getConnection();
PreparedStatement stmt = con.prepareStatement(
"select * from CUSTOMERS where STATE=?"
)) {

stmt.setInt(1, convertState(state));

try (ResultSet rs = stmt.executeQuery()) {
return readAll(rs);
}

} catch (SQLException e) {
throw new RuntimeException(e); // eigene Exception?
}
}

@Override
public Optional<Customer> findByUuid(UUID uuid) {
return CustomersSink.super.findByUuid(uuid);
try (Connection con = ds.getConnection();
PreparedStatement stmt = con.prepareStatement(
"select * from CUSTOMERS where UUID=?"
)) {

stmt.setString(1, convertUuid(uuid));

try (ResultSet rs = stmt.executeQuery()) {
if (!rs.next()) {
return Optional.empty();
}
return Optional.of(readSingle(rs));
}

} catch (SQLException e) {
throw new RuntimeException(e); // eigene Exception?
}
}

@Override
public void save(Customer customer) {
// TODO only insert, we need an update too, if the UUID is already set
try (Connection con = ds.getConnection();
PreparedStatement stmt = con.prepareStatement(
"insert into CUSTOMERS(UUID,NAME,DATE_OF_BIRTH,STATE) values(?,?,?,?)",
Statement.RETURN_GENERATED_KEYS
)) {

stmt.setString(1, convertUuid(customer.getUuid()));
stmt.setString(2, customer.getName());
stmt.setDate(3, convertDate(customer.getBirthdate()));
stmt.setInt(4, convertState(customer.getState()));
stmt.executeUpdate();

try (ResultSet rs = stmt.getGeneratedKeys()) {
if (!rs.next()) {
throw new RuntimeException("not expected"); // bessere Exception
}
customer.setUuid(convertUuid(rs.getString(1)));
}

} catch (SQLException e) {
throw new RuntimeException(e); // eigene Exception?
}
}

@Override
public boolean delete(UUID uuid) {
return false;
}
try (Connection con = ds.getConnection();
PreparedStatement stmt = con.prepareStatement(
"delete from CUSTOMERS where UUID=?"
)) {

@Override
public boolean exists(UUID uuid) {
return CustomersSink.super.exists(uuid);
stmt.setString(1, convertUuid(uuid));
return stmt.executeUpdate() > 0;

} catch (SQLException e) {
throw new RuntimeException(e); // eigene Exception?
}
}

@Override
public long count() {
return 0;
try (Connection con = ds.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
"select count(uuid) from CUSTOMERS"
)) {

if (!rs.next()) {
return 0;
}
return rs.getLong(1);

} catch (SQLException e) {
throw new RuntimeException(e); // eigene Exception?
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package de.schulung.sample.quarkus.persistence;

import de.schulung.sample.quarkus.domain.Customer;
import de.schulung.sample.quarkus.domain.CustomersSink;
import io.quarkus.test.TestTransaction;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

@QuarkusTest
@TestTransaction
@TestProfile(UseJdbcImplementation.class)
public class PersistenceJdbcCustomersSinkTests {

@Inject
CustomersSink sink;

@Test
void shouldFindByState() {
var result = sink.findByState(Customer.CustomerState.ACTIVE);
assertThat(result).isNotNull();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package de.schulung.sample.quarkus.persistence;

import de.schulung.sample.quarkus.domain.Customer;
import de.schulung.sample.quarkus.domain.CustomersSink;
import io.quarkus.test.TestTransaction;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

@QuarkusTest
@TestTransaction
@TestProfile(UseJpaImplementation.class)
public class PersistenceJpaCustomersSinkTests {

@Inject
CustomersSink sink;

@Test
void shouldFindByState() {
var result = sink.findByState(Customer.CustomerState.ACTIVE);
assertThat(result).isNotNull();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
@QuarkusTest
@TestTransaction
@TestProfile(UsePanacheImplementation.class)
public class PersistenceCustomersSinkTests {
public class PersistencePanacheCustomersSinkTests {

@Inject
CustomersSink sink;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package de.schulung.sample.quarkus.persistence;

import io.quarkus.test.junit.QuarkusTestProfile;

import java.util.Map;

public class UseJdbcImplementation implements QuarkusTestProfile {

@Override
public Map<String, String> getConfigOverrides() {
return Map.of(
"persistence.sink.implementation", "jdbc"
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package de.schulung.sample.quarkus.persistence;

import io.quarkus.test.junit.QuarkusTestProfile;

import java.util.Map;

public class UseJpaImplementation implements QuarkusTestProfile {

@Override
public Map<String, String> getConfigOverrides() {
return Map.of(
"persistence.sink.implementation", "jpa"
);
}
}

0 comments on commit 2a93333

Please sign in to comment.