Skip to content

Commit

Permalink
Aggressively statically type query providers.
Browse files Browse the repository at this point in the history
  • Loading branch information
io7m committed May 27, 2024
1 parent 8e64d81 commit c3b489b
Show file tree
Hide file tree
Showing 29 changed files with 150 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public abstract class DDatabaseAbstract<
C extends DDatabaseConfigurationType,
N extends DDatabaseConnectionType<T>,
T extends DDatabaseTransactionType,
Q extends DDatabaseQueryProviderType<T>>
Q extends DDatabaseQueryProviderType<T, ?, ?, ?>>
implements DDatabaseType<C, N, T, Q>
{
private final C configuration;
Expand All @@ -69,7 +69,7 @@ protected DDatabaseAbstract(

private static <
T extends DDatabaseTransactionType,
Q extends DDatabaseQueryProviderType<T>>
Q extends DDatabaseQueryProviderType<T, ?, ?, ?>>
Map<Class<?>, Q> collectQueryProviders(
final Collection<Q> inQueryProviders)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
public abstract class DDatabaseConnectionAbstract<
C extends DDatabaseConfigurationType,
T extends DDatabaseTransactionType,
Q extends DDatabaseQueryProviderType<T>>
Q extends DDatabaseQueryProviderType<T, ?, ?, ?>>
implements DDatabaseConnectionType<T>
{
private final Connection connection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public interface DDatabaseFactoryType<
C extends DDatabaseConfigurationType,
N extends DDatabaseConnectionType<T>,
T extends DDatabaseTransactionType,
Q extends DDatabaseQueryProviderType<T>,
Q extends DDatabaseQueryProviderType<T, ?, ?, ?>,
D extends DDatabaseType<C, N, T, Q>>
{
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,24 @@
* A convenient abstract query provider.
*
* @param <T> The precise type of database transactions
* @param <P> The type of query parameters
* @param <R> The type of query results
* @param <Q> The precise type of query
*/

public abstract class DDatabaseQueryProviderAbstract<T extends DDatabaseTransactionType>
implements DDatabaseQueryProviderType<T>
public abstract class DDatabaseQueryProviderAbstract<
T extends DDatabaseTransactionType,
P,
R,
Q extends DDatabaseQueryType<P, R>>
implements DDatabaseQueryProviderType<T, P, R, Q>
{
private final Class<?> queryClass;
private final Function<T, DDatabaseQueryType<?, ?>> constructor;
private final Class<? extends Q> queryClass;
private final Function<T, DDatabaseQueryType<P, R>> constructor;

protected DDatabaseQueryProviderAbstract(
final Class<?> inQueryClass,
final Function<T, DDatabaseQueryType<?, ?>> inConstructor)
final Class<? extends Q> inQueryClass,
final Function<T, DDatabaseQueryType<P, R>> inConstructor)
{
this.queryClass =
Objects.requireNonNull(inQueryClass, "queryClass");
Expand All @@ -43,13 +50,13 @@ protected DDatabaseQueryProviderAbstract(
}

@Override
public final Class<?> queryClass()
public final Class<? extends Q> queryClass()
{
return this.queryClass;
}

@Override
public final DDatabaseQueryType<?, ?> create(
public final DDatabaseQueryType<P, R> create(
final T transaction)
{
return this.constructor.apply(transaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,22 @@
* The type of database query providers.
*
* @param <T> The type of database transactions
* @param <P> The type of query parameters
* @param <R> The type of query results
* @param <Q> The precise type of query
*/

public interface DDatabaseQueryProviderType<T extends DDatabaseTransactionType>
public interface DDatabaseQueryProviderType<
T extends DDatabaseTransactionType,
P,
R,
Q extends DDatabaseQueryType<P, R>>
{
/**
* @return The class that will be used to fetch this query provider
*/

Class<?> queryClass();
Class<? extends Q> queryClass();

/**
* Create a query for the given transaction.
Expand All @@ -39,5 +46,5 @@ public interface DDatabaseQueryProviderType<T extends DDatabaseTransactionType>
* @return A new query
*/

DDatabaseQueryType<?, ?> create(T transaction);
DDatabaseQueryType<P, R> create(T transaction);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public abstract class DDatabaseTransactionAbstract<
C extends DDatabaseConfigurationType,
N extends DDatabaseConnectionType<T>,
T extends DDatabaseTransactionType,
Q extends DDatabaseQueryProviderType<T>>
Q extends DDatabaseQueryProviderType<T, ?, ?, ?>>
implements DDatabaseTransactionType
{
private final DDatabaseTransactionCloseBehavior closeBehavior;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface DDatabaseType<
C extends DDatabaseConfigurationType,
N extends DDatabaseConnectionType<T>,
T extends DDatabaseTransactionType,
Q extends DDatabaseQueryProviderType<T>>
Q extends DDatabaseQueryProviderType<T, ?, ?, ?>>
extends AutoCloseable
{
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ final class EPQDatabase
EPQDatabaseConfiguration,
EPQDatabaseConnectionType,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType>
EPQDatabaseQueryProviderType<?, ?, ?>>
implements EPQDatabaseType
{
EPQDatabase(
final EPQDatabaseConfiguration inConfiguration,
final DataSource inDataSource,
final Collection<EPQDatabaseQueryProviderType> queryProviders,
final Collection<EPQDatabaseQueryProviderType<?, ?, ?>> queryProviders,
final CloseableCollectionType<DDatabaseException> resources)
{
super(inConfiguration, inDataSource, queryProviders, resources);
Expand All @@ -48,7 +48,7 @@ final class EPQDatabase
protected EPQDatabaseConnectionType createConnection(
final Span span,
final Connection connection,
final Map<Class<?>, EPQDatabaseQueryProviderType> queries)
final Map<Class<?>, EPQDatabaseQueryProviderType<?, ?, ?>> queries)
{
return new EPQDatabaseConnection(this, span, connection, queries);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@

final class EPQDatabaseConnection
extends DDatabaseConnectionAbstract<
EPQDatabaseConfiguration,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType>
EPQDatabaseConfiguration,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType<?, ?, ?>>
implements EPQDatabaseConnectionType
{
EPQDatabaseConnection(
final EPQDatabaseType database,
final Span span,
final Connection connection,
final Map<Class<?>, EPQDatabaseQueryProviderType> queries)
final Map<Class<?>, EPQDatabaseQueryProviderType<?, ?, ?>> queries)
{
super(database.configuration(), span, connection, queries);
}
Expand All @@ -44,7 +44,7 @@ final class EPQDatabaseConnection
protected EPQDatabaseTransactionType createTransaction(
final DDatabaseTransactionCloseBehavior closeBehavior,
final Span transactionSpan,
final Map<Class<?>, EPQDatabaseQueryProviderType> queries)
final Map<Class<?>, EPQDatabaseQueryProviderType<?, ?, ?>> queries)
{
return new EPQDatabaseTransaction(
closeBehavior,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

public final class EPQDatabaseFactory
extends DPQDatabaseFactory<
EPQDatabaseConfiguration,
EPQDatabaseConnectionType,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType,
EPQDatabaseType>
EPQDatabaseConfiguration,
EPQDatabaseConnectionType,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType<?, ?, ?>,
EPQDatabaseType>
implements EPQDatabaseFactoryType
{
private static final Logger LOG =
Expand Down Expand Up @@ -72,7 +72,7 @@ protected Logger logger()
protected EPQDatabaseType onCreateDatabase(
final EPQDatabaseConfiguration configuration,
final DataSource source,
final List<EPQDatabaseQueryProviderType> queryProviders,
final List<EPQDatabaseQueryProviderType<?, ?, ?>> queryProviders,
final CloseableCollectionType<DDatabaseException> resources)
{
return new EPQDatabase(
Expand Down Expand Up @@ -121,11 +121,12 @@ protected void onPostUpgrade(
}

@Override
protected List<EPQDatabaseQueryProviderType> onRequireDatabaseQueryProviders()
protected List<EPQDatabaseQueryProviderType<?, ?, ?>> onRequireDatabaseQueryProviders()
{
return ServiceLoader.load(EPQDatabaseQueryProviderType.class)
.stream()
.map(ServiceLoader.Provider::get)
.map(x -> (EPQDatabaseQueryProviderType<?, ?, ?>) x)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface EPQDatabaseFactoryType
EPQDatabaseConfiguration,
EPQDatabaseConnectionType,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType,
EPQDatabaseQueryProviderType<?, ?, ?>,
EPQDatabaseType>
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,23 @@

import java.util.function.Function;

final class EPQDatabaseQueryProvider
extends DDatabaseQueryProviderAbstract<EPQDatabaseTransactionType>
implements EPQDatabaseQueryProviderType
final class EPQDatabaseQueryProvider<P, R, Q extends DDatabaseQueryType<P, R>>
extends DDatabaseQueryProviderAbstract<EPQDatabaseTransactionType, P, R, Q>
implements EPQDatabaseQueryProviderType<P, R, Q>
{
private EPQDatabaseQueryProvider(
final Class<?> inQueryClass,
final Function<EPQDatabaseTransactionType, DDatabaseQueryType<?, ?>> inConstructor)
final Class<? extends Q> inQueryClass,
final Function<EPQDatabaseTransactionType, DDatabaseQueryType<P, R>> inConstructor)
{
super(inQueryClass, inConstructor);
}

static EPQDatabaseQueryProviderType provide(
final Class<?> inQueryClass,
final Function<EPQDatabaseTransactionType, DDatabaseQueryType<?, ?>> inConstructor)
static <P, R, Q extends DDatabaseQueryType<P, R>>
EPQDatabaseQueryProviderType<P, R, Q>
provide(
final Class<? extends Q> inQueryClass,
final Function<EPQDatabaseTransactionType, DDatabaseQueryType<P, R>> inConstructor)
{
return new EPQDatabaseQueryProvider(inQueryClass, inConstructor);
return new EPQDatabaseQueryProvider<>(inQueryClass, inConstructor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@
package com.io7m.darco.examples.postgresql;

import com.io7m.darco.api.DDatabaseQueryProviderType;
import com.io7m.darco.api.DDatabaseQueryType;

/**
* The type of example PostgreSQL database query providers.
*
* @param <P> The type of query parameters
* @param <R> The type of query results
* @param <Q> The precise type of query
*/

public interface EPQDatabaseQueryProviderType
extends DDatabaseQueryProviderType<EPQDatabaseTransactionType>
public interface EPQDatabaseQueryProviderType<P, R, Q extends DDatabaseQueryType<P, R>>
extends DDatabaseQueryProviderType<EPQDatabaseTransactionType, P, R, Q>
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ final class EPQDatabaseTransaction
EPQDatabaseConfiguration,
EPQDatabaseConnectionType,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType>
EPQDatabaseQueryProviderType<?, ?, ?>>
implements EPQDatabaseTransactionType
{
EPQDatabaseTransaction(
final DDatabaseTransactionCloseBehavior closeBehavior,
final EPQDatabaseConfiguration inConfiguration,
final EPQDatabaseConnectionType inConnection,
final Span inTransactionScope,
final Map<Class<?>, EPQDatabaseQueryProviderType> queries)
final Map<Class<?>, EPQDatabaseQueryProviderType<?, ?, ?>> queries)
{
super(
closeBehavior,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface EPQDatabaseType
EPQDatabaseConfiguration,
EPQDatabaseConnectionType,
EPQDatabaseTransactionType,
EPQDatabaseQueryProviderType>
EPQDatabaseQueryProviderType<?, ?, ?>>
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ public final class EPQWordGet
* @return The query provider
*/

public static EPQDatabaseQueryProviderType provider()
public static EPQDatabaseQueryProviderType<
DDatabaseUnit, Optional<String>, ESWordGetType>
provider()
{
return EPQDatabaseQueryProvider.provide(ESWordGetType.class, EPQWordGet::new);
return EPQDatabaseQueryProvider.provide(
ESWordGetType.class,
EPQWordGet::new
);
}

@Override
Expand All @@ -53,7 +58,8 @@ protected Optional<String> onExecute(
{
final var c = transaction.connection();

try (var s = c.prepareStatement("SELECT * FROM words ORDER BY RANDOM() LIMIT 1")) {
try (var s = c.prepareStatement(
"SELECT * FROM words ORDER BY RANDOM() LIMIT 1")) {
try (var r = s.executeQuery()) {
if (r.next()) {
return Optional.of(r.getString(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ public final class EPQWordPut
* @return The query provider
*/

public static EPQDatabaseQueryProviderType provider()
public static EPQDatabaseQueryProviderType<
String, DDatabaseUnit, ESWordPutType>
provider()
{
return EPQDatabaseQueryProvider.provide(ESWordPutType.class, EPQWordPut::new);
return EPQDatabaseQueryProvider.provide(
ESWordPutType.class,
EPQWordPut::new
);
}

@Override
Expand Down
Loading

0 comments on commit c3b489b

Please sign in to comment.