Skip to content

Commit

Permalink
exception handling improvements & javadoc API
Browse files Browse the repository at this point in the history
  • Loading branch information
NivixX committed Feb 7, 2023
1 parent 7ca2179 commit 9a1d603
Show file tree
Hide file tree
Showing 24 changed files with 305 additions and 159 deletions.
2 changes: 1 addition & 1 deletion ndatabase-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>ndatabase</artifactId>
<groupId>com.nivixx</groupId>
<version>0.1.6-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.nivixx.ndatabase.api;

import com.nivixx.ndatabase.api.exception.NDatabaseException;
import com.nivixx.ndatabase.api.model.NEntity;
import com.nivixx.ndatabase.api.repository.Repository;

/**
* NDatabase - KeyValue store database
* Report any issue or contribute here https://github.com/NivixX/NDatabase
*/
public class NDatabase {

private static NDatabaseAPI instance;

/**
*
* @return the api interface to operate NDatabase.
* The actual implementation will differ depending on what platform
* you are currently using.
*/
public static NDatabaseAPI api() {
NDatabaseAPI instance = NDatabase.instance;
if (instance == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,26 @@
import com.nivixx.ndatabase.api.model.NEntity;
import com.nivixx.ndatabase.api.repository.Repository;

/**
* NDatabase - KeyValue store database
* Report any issue or contribute here https://github.com/NivixX/NDatabase
*/
public interface NDatabaseAPI {

/**
*
* This method will return you a repository for your desired entity.
* Note that calling this method will also create your database schema
* if it doesn't exist according to your current database type configuration.
*
* @param entityType The data model class type which extends {@code NEntity}
* @param <K> The key type used for your key-value store
* @param <V> Your entity class which represent your data model
* @return A fully CRUD usable {@code Repository} with async extension using Async to Sync pipeline
*
* @throws NDatabaseException throw an exception if either
* the creation of your database schema failed or if a reflection issue occurred.
*/
<K,V extends NEntity<K>> Repository<K,V> getOrCreateRepository(Class<V> entityType) throws NDatabaseException;

}
155 changes: 154 additions & 1 deletion ndatabase-api/src/main/java/com/nivixx/ndatabase/api/Promise.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,180 @@
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
* NDatabase - KeyValue store database
* Report any issue or contribute here https://github.com/NivixX/NDatabase
*
* Promise interface to handle the Async to Sync mechanism
* You can easily do async call to generate a CompletableFuture
* and handle this future task to schedule callback in the main thread
*/
public interface Promise {

/**
* Async pipeline in the case your database operation return a result
* @param <E> Your Entity class
*/
interface AsyncResult<E> {

/**
* @return future task, handle it as your needs
*/
CompletableFuture<E> getResultFuture();

/**
* retrieve data async and consume it in the same async thread once it's available.
* This method doesn't handle exception, so if an Exception occurred during
* the data retrieving, your consumer will be ignored and won't be called.
* <pre>
* .thenAsync((entity) -> {
* // handle entity
* // will not be called if an exception occurred
* })
* </pre>
* Note that if an exception occurred NDatabase with handle and log a warning message for you
* telling that you didn't handle the exception and the code line will be specified.
*
* @param valueConsumer your entity value consumer.
* Will be called only if there is no exception.
* E will be null if no result was found
*/
void thenAsync(Consumer<E> valueConsumer);

/**
* retrieve data async and consume it in the main thread once it's available.
* This method doesn't handle exception, so if an Exception occurred during
* the data retrieving, your consumer will be ignored and won't be called.
* <pre>
* .thenSync((entity) -> {
* // handle entity
* // will not be called if an exception occurred
* })
* </pre>
* Note that if an exception occurred NDatabase with handle and log a warning message for you
* telling that you didn't handle the exception and the code line will be specified.
*
* @param valueConsumer your entity value consumer.
* Will be called only if there is no exception.
* E will be null if no result was found
*/
void thenSync(Consumer<E> valueConsumer);

/**
* retrieve data async and consume it in the same async thread once it's available.
* This method handle exception if an exception occurred.
* In case where the task ended exceptionally, E value will be null and Throwable
* will contain your exception.
* <pre>
* .thenAsync((entity, throwable) -> {
* if(throwable != null) {
* // Handle exception
* return;
* }
* // handle entity
* })
* </pre>
* @param valueConsumer your entity, exception value consumer.
* E will be null if no result was found
*/
void thenAsync(BiConsumer<E, Throwable> valueConsumer);

/**
* retrieve data async and consume it in the main thread once it's available.
* This method handle exception if an exception occurred.
* In case where the task ended exceptionally, E value will be null and Throwable
* will contain your exception.
* <pre>
* .thenSync((entity, throwable) -> {
* if(throwable != null) {
* // Handle exception
* return;
* }
* // handle entity
* })
* </pre>
* @param valueConsumer your entity, exception value consumer.
* E will be null if no result was found
*/
void thenSync(BiConsumer<E, Throwable> valueConsumer);
}

interface AsyncEmptyResult { //TODO void
/**
* Async pipeline in the case your database operation doesn't return a result
*/
interface AsyncEmptyResult {

/**
* @return future task, handle it as your needs
*/
CompletableFuture<Void> getResultFuture();

/**
* process your database operation async and run a callback in the same async thread when finished
* This method doesn't handle exception, so if an Exception occurred during
* the operation, your callback will be ignored and won't be called.
* <pre>
* .thenAsync(() -> {
* // execute callback
* // will not be called if an exception occurred
* })
* </pre>
* Note that if an exception occurred NDatabase with handle and log a warning message for you
* telling that you didn't handle the exception and the code line will be specified.
*
* @param callback that will be called only if there is no exception.
*/
void thenAsync(Runnable callback);

/**
* process your database operation async and run a callback in the main thread when finished
* This method doesn't handle exception, so if an Exception occurred during
* the operation, your callback will be ignored and won't be called.
* <pre>
* .thenAsync(() -> {
* // execute callback
* // will not be called if an exception occurred
* })
* </pre>
* Note that if an exception occurred NDatabase with handle and log a warning message for you
* telling that you didn't handle the exception and the code line will be specified.
*
* @param callback that will be called only if there is no exception.
*/
void thenSync(Runnable callback);

/**
* process your database operation async and run a callback in the same async thread when finished
* This method handle exception if an exception occurred.
* <pre>
* .thenAsync((throwable) -> {
* if(throwable != null) {
* // handle exception
* return;
* }
* // execute callback
* })
* </pre>
* @param throwableConsumer throwable consumer.
* will be null if no exception occurred
*/
void thenAsync(Consumer<Throwable> throwableConsumer);

/**
* process your database operation async and run a callback in the main thread when finished
* This method handle exception if an exception occurred.
* <pre>
* .thenSync((throwable) -> {
* if(throwable != null) {
* // handle exception
* return;
* }
* // execute callback
* })
* </pre>
* @param throwableConsumer throwable consumer.
* will be null if no exception occurred
*/
void thenSync(Consumer<Throwable> throwableConsumer);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

public abstract class NEntity<K> {

//TODO @JsonIgnore // Don't store the id twice (in the K-V value)
@JsonProperty("key")
protected /*transient*/ K key;
protected K key;

public NEntity() {
}
Expand All @@ -23,5 +22,4 @@ public void setKey(K key) {
this.key = key;
}


}
6 changes: 3 additions & 3 deletions ndatabase-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>ndatabase</artifactId>
<groupId>com.nivixx</groupId>
<version>0.1.6-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand All @@ -20,12 +20,12 @@
<dependency>
<groupId>com.nivixx</groupId>
<artifactId>ndatabase-api</artifactId>
<version>0.1.6-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.nivixx</groupId>
<artifactId>core-platform</artifactId>
<version>0.1.6-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
package com.nivixx.ndatabase.core;

import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Types;
import com.nivixx.ndatabase.api.annotation.NTable;
import com.nivixx.ndatabase.api.exception.DatabaseCreationException;
import com.nivixx.ndatabase.api.model.NEntity;
import com.nivixx.ndatabase.core.config.NDatabaseConfig;
import com.nivixx.ndatabase.core.dao.Dao;
import com.nivixx.ndatabase.core.dao.inmemory.InMemoryDao;
import com.nivixx.ndatabase.core.dao.mysql.MysqlConnectionPool;
import com.nivixx.ndatabase.core.dao.mysql.HikariConnectionPool;
import com.nivixx.ndatabase.core.dao.mysql.MysqlDao;
import com.nivixx.ndatabase.core.serialization.NEntityEncoder;
import com.nivixx.ndatabase.platforms.coreplatform.logging.DBLogger;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class DatabaseTypeResolver {

Expand All @@ -30,7 +24,7 @@ public <K,V extends NEntity<K>> Dao<K,V> getDaoForConfiguredDatabase(V nEntity,
case IN_MEMORY:
return new InMemoryDao<>(nTable.name(), nTable.schema(), keyType, dbLogger);
case MYSQL:
MysqlConnectionPool jdbcConnectionPool = Injector.resolveInstance(MysqlConnectionPool.class);
HikariConnectionPool jdbcConnectionPool = Injector.resolveInstance(HikariConnectionPool.class);
return new MysqlDao<>(
nTable.name(),
nTable.schema(),
Expand All @@ -45,7 +39,6 @@ public <K,V extends NEntity<K>> Dao<K,V> getDaoForConfiguredDatabase(V nEntity,
private <K,V extends NEntity<K>> NTable extractNTable(V nEntity) {
Annotation[] annotations = nEntity.getClass().getAnnotations();
for (Annotation annotation : annotations) {
Class<? extends Annotation> type = annotation.annotationType();
if(annotation instanceof NTable) {
return (NTable) annotation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Types;
import com.nivixx.ndatabase.api.NDatabase;
import com.nivixx.ndatabase.api.NDatabaseAPI;
import com.nivixx.ndatabase.api.exception.NDatabaseLoadException;
import com.nivixx.ndatabase.api.model.NEntity;
import com.nivixx.ndatabase.core.config.DatabaseType;
import com.nivixx.ndatabase.core.config.NDatabaseConfig;
import com.nivixx.ndatabase.core.dao.mysql.MysqlConnectionPool;
import com.nivixx.ndatabase.core.dao.mysql.HikariConnectionPool;
import com.nivixx.ndatabase.core.promise.AsyncThreadPool;
import com.nivixx.ndatabase.core.serialization.BytesNEntityEncoder;
import com.nivixx.ndatabase.core.serialization.NEntityEncoder;
import com.nivixx.ndatabase.platforms.coreplatform.executor.SyncExecutor;
import com.nivixx.ndatabase.platforms.coreplatform.logging.DBLogger;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

public abstract class PlatformLoader extends AbstractModule {

Expand All @@ -30,7 +24,7 @@ protected void configure() {
NDatabaseConfig nDatabaseConfig = supplyNDatabaseConfig();
nDatabaseConfig.verifyConfig();
if(nDatabaseConfig.getDatabaseType() == DatabaseType.MYSQL) {
bind(MysqlConnectionPool.class).toInstance(new MysqlConnectionPool(nDatabaseConfig.getMysqlConfig()));
bind(HikariConnectionPool.class).toInstance(new HikariConnectionPool(nDatabaseConfig.getMysqlConfig()));
}
bind(NDatabaseConfig.class).toInstance(nDatabaseConfig);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,16 @@ public V createEntityInstance(Class<V> entityClass) throws DatabaseCreationExcep

@SuppressWarnings("unchecked")
public Class<K> resolveKeyFromEntity(V nEntity) {
ParameterizedType genericSuperclass = (ParameterizedType) nEntity.getClass().getGenericSuperclass();
Type actualTypeArgument = genericSuperclass.getActualTypeArguments()[0];
return (Class<K>) actualTypeArgument;
try {
ParameterizedType genericSuperclass = (ParameterizedType) nEntity.getClass().getGenericSuperclass();
Type actualTypeArgument = genericSuperclass.getActualTypeArguments()[0];
return (Class<K>) actualTypeArgument;
} catch (Exception e) {
throw new DatabaseCreationException(
String.format("could not resolve the key type for NEntity class '%s'." +
" Did you properly used a supported key type ?",
nEntity.getClass().getCanonicalName()), e);
}
}

}
Loading

0 comments on commit 9a1d603

Please sign in to comment.