// Path: src/main/java/io/jvoid/database/DbUtils.java
// public class DbUtils {
// 
//     private static final QueryRunner queryRunner = new QueryRunner();
// 
//     private DbUtils() {
//         super();
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sql
//      * @param parameters
//      */
//     public static void executeUpdate(MetadataDatabase database, String sql, Object... parameters) {
//         try (Connection conn = database.getConnection()) {
//             QueryRunner query = new QueryRunner();
//             query.update(conn, sql, parameters);
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sql
//      * @param parameters
//      * @return
//      */
//     public static Long executeInsert(MetadataDatabase database, String sql, Object... parameters) {
//         try (Connection conn = database.getConnection()) {
//             ResultSetHandler<Long> rsh = new ScalarHandler<>();
//             return queryRunner.insert(conn, sql, rsh, parameters);
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sqlList
//      * @param parametersList
//      * @return
//      */
//     public static List<Long> executeMultipleInserts(MetadataDatabase database, List<String> sqlList, List<Object[]> parametersList) {
//         try (Connection conn = database.getConnection()) {
//             List<Long> results = new ArrayList<>();
//             for (int i = 0; i < sqlList.size(); i++) {
//                 Object[] parameters = parametersList.get(i);
//                 String sql = sqlList.get(i);
//                 
//                 ResultSetHandler<Long> rsh = new ScalarHandler<>();
//                 Long id = queryRunner.insert(conn, sql, rsh, parameters);
//                 results.add(id);
//             }
//             return results;
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sql
//      * @param resultSetHandler
//      * @param parameters
//      * @return
//      */
//     public static <T> T query(MetadataDatabase database, String sql, ResultSetHandler<T> resultSetHandler, Object... parameters) {
//         try (Connection conn = database.getConnection()) {
//             return queryRunner.query(conn, sql, resultSetHandler, parameters);
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// }
// 
// Path: src/main/java/io/jvoid/database/MetadataDatabase.java
// @Singleton
// public class MetadataDatabase {
// 
//     private JVoidConfiguration configuration;
// 
//     private HikariDataSource ds;
// 
//     /**
//      *
//      * @param configuration
//      */
//     @Inject
//     public MetadataDatabase(JVoidConfiguration configuration) {
//         this.configuration = configuration;
//     }
// 
//     /**
//      *
//      */
//     @Inject
//     public void startup() {
//         if (ds != null && !ds.isClosed()) {
//             return;
//         }
// 
//         HikariConfig config = new HikariConfig();
//         config.setJdbcUrl(configuration.dbUrl());
//         config.setUsername(configuration.dbUsername());
//         config.setPassword(configuration.dbPassword());
//         config.addDataSourceProperty("cachePrepStmts", "true");
//         config.addDataSourceProperty("prepStmtCacheSize", "250");
//         config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
// 
//         ds = new HikariDataSource(config);
// 
//         initializeDatabase();
//     }
// 
//     /**
//      *
//      */
//     public void shutdown() {
//         if (ds != null) {
//             ds.close();
//             ds = null;
//         }
//     }
// 
//     /**
//      *
//      */
//     private void initializeDatabase() {
//         Flyway flyway = new Flyway();
//         flyway.setDataSource(ds);
//         flyway.migrate();
//     }
// 
//     /**
//      *
//      * @return A connection from the pool
//      */
//     public Connection getConnection() {
//         try {
//             return ds.getConnection();
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// }


import java.util.List;
import org.apache.commons.dbutils.ResultSetHandler;
import io.jvoid.database.DbUtils;
import io.jvoid.database.MetadataDatabase;
package io.jvoid.metadata.repositories;




/**
 * Generic repository class extended by all the concrete JVoid repositories.
 *
 */
public abstract class AbstractRepository<T, I> implements BaseRepository<T, I> {

    protected MetadataDatabase database;

    public AbstractRepository(MetadataDatabase database) {
        this.database = database;
    }

    protected void executeUpdate(String sql, Object... parameters) {
        DbUtils.executeUpdate(database, sql, parameters);
    }

    protected Long executeInsert(String sql, Object... parameters) {
        return DbUtils.executeInsert(database, sql, parameters);
    }

    protected List<Long> executeMultipleInserts(List<String> sqlList, List<Object[]> parametersList) {
        return DbUtils.executeMultipleInserts(database, sqlList, parametersList);
    }

    protected <U> U query(String sql, ResultSetHandler<U> resultSetHandler, Object... parameters) {
        return DbUtils.query(database, sql, resultSetHandler, parameters);
    }

    protected static void assertNull(Object value) {
        if (value != null) {
// Path: src/main/java/io/jvoid/database/DbUtils.java
// public class DbUtils {
// 
//     private static final QueryRunner queryRunner = new QueryRunner();
// 
//     private DbUtils() {
//         super();
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sql
//      * @param parameters
//      */
//     public static void executeUpdate(MetadataDatabase database, String sql, Object... parameters) {
//         try (Connection conn = database.getConnection()) {
//             QueryRunner query = new QueryRunner();
//             query.update(conn, sql, parameters);
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sql
//      * @param parameters
//      * @return
//      */
//     public static Long executeInsert(MetadataDatabase database, String sql, Object... parameters) {
//         try (Connection conn = database.getConnection()) {
//             ResultSetHandler<Long> rsh = new ScalarHandler<>();
//             return queryRunner.insert(conn, sql, rsh, parameters);
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sqlList
//      * @param parametersList
//      * @return
//      */
//     public static List<Long> executeMultipleInserts(MetadataDatabase database, List<String> sqlList, List<Object[]> parametersList) {
//         try (Connection conn = database.getConnection()) {
//             List<Long> results = new ArrayList<>();
//             for (int i = 0; i < sqlList.size(); i++) {
//                 Object[] parameters = parametersList.get(i);
//                 String sql = sqlList.get(i);
//                 
//                 ResultSetHandler<Long> rsh = new ScalarHandler<>();
//                 Long id = queryRunner.insert(conn, sql, rsh, parameters);
//                 results.add(id);
//             }
//             return results;
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// 
//     /**
//      *
//      * @param database
//      * @param sql
//      * @param resultSetHandler
//      * @param parameters
//      * @return
//      */
//     public static <T> T query(MetadataDatabase database, String sql, ResultSetHandler<T> resultSetHandler, Object... parameters) {
//         try (Connection conn = database.getConnection()) {
//             return queryRunner.query(conn, sql, resultSetHandler, parameters);
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// }
// 
// Path: src/main/java/io/jvoid/database/MetadataDatabase.java
// @Singleton
// public class MetadataDatabase {
// 
//     private JVoidConfiguration configuration;
// 
//     private HikariDataSource ds;
// 
//     /**
//      *
//      * @param configuration
//      */
//     @Inject
//     public MetadataDatabase(JVoidConfiguration configuration) {
//         this.configuration = configuration;
//     }
// 
//     /**
//      *
//      */
//     @Inject
//     public void startup() {
//         if (ds != null && !ds.isClosed()) {
//             return;
//         }
// 
//         HikariConfig config = new HikariConfig();
//         config.setJdbcUrl(configuration.dbUrl());
//         config.setUsername(configuration.dbUsername());
//         config.setPassword(configuration.dbPassword());
//         config.addDataSourceProperty("cachePrepStmts", "true");
//         config.addDataSourceProperty("prepStmtCacheSize", "250");
//         config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
// 
//         ds = new HikariDataSource(config);
// 
//         initializeDatabase();
//     }
// 
//     /**
//      *
//      */
//     public void shutdown() {
//         if (ds != null) {
//             ds.close();
//             ds = null;
//         }
//     }
// 
//     /**
//      *
//      */
//     private void initializeDatabase() {
//         Flyway flyway = new Flyway();
//         flyway.setDataSource(ds);
//         flyway.migrate();
//     }
// 
//     /**
//      *
//      * @return A connection from the pool
//      */
//     public Connection getConnection() {
//         try {
//             return ds.getConnection();
//         } catch (SQLException e) {
//             throw new JVoidDataAccessException(e);
//         }
//     }
// }


// Path: src/main/java/io/jvoid/metadata/repositories/AbstractRepository.java
import java.util.List;
import org.apache.commons.dbutils.ResultSetHandler;
import io.jvoid.database.DbUtils;
import io.jvoid.database.MetadataDatabase;

package io.jvoid.metadata.repositories;




/**
 * Generic repository class extended by all the concrete JVoid repositories.
 *
 */
public abstract class AbstractRepository<T, I> implements BaseRepository<T, I> {

    protected MetadataDatabase database;

    public AbstractRepository(MetadataDatabase database) {
        this.database = database;
    }

    protected void executeUpdate(String sql, Object... parameters) {
        DbUtils.executeUpdate(database, sql, parameters);
    }

    protected Long executeInsert(String sql, Object... parameters) {
        return DbUtils.executeInsert(database, sql, parameters);
    }

    protected List<Long> executeMultipleInserts(List<String> sqlList, List<Object[]> parametersList) {
        return DbUtils.executeMultipleInserts(database, sqlList, parametersList);
    }

    protected <U> U query(String sql, ResultSetHandler<U> resultSetHandler, Object... parameters) {
        return DbUtils.query(database, sql, resultSetHandler, parameters);
    }

    protected static void assertNull(Object value) {
        if (value != null) {
            throw new RuntimeException();