Mercurial > hg > monetdb-java
changeset 44:cd6ff38c90f4 embedded
Cleaned more code. Ready to implement the iterators internally.
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedConnection.java +++ b/src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedConnection.java @@ -111,9 +111,8 @@ public class MonetDBEmbeddedConnection { * @return The update result object * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public UpdateResultSet sendUpdateAsync(String query) throws MonetDBEmbeddedException { - /CompletableFuture.supplyAsync(() -> this.sendUpdate(query)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<UpdateResultSet> sendUpdateAsync(String query) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.sendUpdate(query)); }*/ /** @@ -139,9 +138,8 @@ public class MonetDBEmbeddedConnection { * @return The query result object * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public QueryResultSet sendQueryAsync(String query) throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.sendQuery(query)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<QueryResultSet> sendQueryAsync(String query) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.sendQuery(query)); }*/ /** @@ -165,9 +163,8 @@ public class MonetDBEmbeddedConnection { * @return An instance of EmbeddedPreparedStatement * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public EmbeddedPreparedStatement createPreparedStatementAsync(String query) throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.createPreparedStatement(query)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<EmbeddedPreparedStatement> createPreparedStatementAsync(String query) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.createPreparedStatement(query)); }*/ /** @@ -192,9 +189,8 @@ public class MonetDBEmbeddedConnection { * @return A MonetDBTable instance with column details * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public MonetDBTable getMonetDBTableAsync(String schemaName, String tableName) throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.getMonetDBTable(schemaName, tableName)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<MonetDBTable> getMonetDBTableAsync(String schemaName, String tableName) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.getMonetDBTable(schemaName, tableName)); }*/ /** @@ -266,9 +262,8 @@ public class MonetDBEmbeddedConnection { /** * Shuts down this connection asynchronously. Any pending queries connections will be immediately closed as well. */ - /*public void closeConnectionAsync() { - CompletableFuture.supplyAsync(() -> this.closeConnection()); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<Void> closeConnectionAsync() { + return CompletableFuture.runAsync(() -> this.closeConnection()); }*/ /**
--- a/src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedDatabase.java +++ b/src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedDatabase.java @@ -48,10 +48,9 @@ public class MonetDBEmbeddedDatabase { * @return A MonetDBEmbeddedDatabase instance * @throws MonetDBEmbeddedException If the JNI library has not been loaded yet or an error in the database occurred */ - /*public static MonetDBEmbeddedDatabase StartDatabaseAsync(String dbDirectory, boolean silentFlag, + /*public static CompletableFuture<MonetDBEmbeddedDatabase> StartDatabaseAsync(String dbDirectory, boolean silentFlag, boolean sequentialFlag) throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> StartDatabase(dbDirectory, silentFlag, sequentialFlag)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + return CompletableFuture.supplyAsync(() -> StartDatabase(dbDirectory, silentFlag, sequentialFlag)); }*/ private final String databaseDirectory; @@ -127,9 +126,8 @@ public class MonetDBEmbeddedDatabase { * * @throws MonetDBEmbeddedException If the database is not running or an error in the database occurred */ - /*public void stopDatabaseAsync() throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.stopDatabase()); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<Void> stopDatabaseAsync() throws MonetDBEmbeddedException { + return CompletableFuture.runAsync(() -> this.stopDatabase()); }*/ /** @@ -148,9 +146,8 @@ public class MonetDBEmbeddedDatabase { * @return A MonetDBEmbeddedConnection instance * @throws MonetDBEmbeddedException If the database is not running or an error in the database occurred */ - /*public MonetDBEmbeddedConnection createConnectionAsync() throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.createConnectionInternal()); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<MonetDBEmbeddedConnection> createConnectionAsync() throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.createConnectionInternal()); }*/ /**
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractRowSet.java @@ -0,0 +1,35 @@ +package nl.cwi.monetdb.embedded.mapping; + +/** + * A row set retrieved from an embedded MonetDB query result. All the values in this set are already mapped + * to Java classes a priori. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public abstract class AbstractRowSet { + + /** + * The MonetDB-To-Java mappings of the columns. + */ + protected final MonetDBToJavaMapping[] mappings; + + /** + * The rows of this set. + */ + protected final MonetDBRow[] rows; + + protected AbstractRowSet(MonetDBToJavaMapping[] mappings, Object[][] rows) { + this.mappings = mappings; + this.rows = new MonetDBRow[mappings.length]; + for(int i = 0 ; i < mappings.length ; i++) { + this.rows[i] = new MonetDBRow(this, rows[i]); + } + } + + /** + * Gets the number of columns in this set. + * + * @return The number of columns in this set + */ + public int getNumberOfColumns() { return mappings.length; } +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBRow.java @@ -0,0 +1,107 @@ +package nl.cwi.monetdb.embedded.mapping; + +import java.util.Arrays; +import java.util.ListIterator; + +/** + * A single MonetDB row in a result set. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class MonetDBRow implements Iterable { + + /** + * The original row result set from this row. + */ + private final AbstractRowSet originalSet; + + /** + * The columns values as Java objects. + */ + private Object[] columns; + + protected MonetDBRow(AbstractRowSet originalSet, Object[] columns) { + this.originalSet = originalSet; + this.columns = columns; + } + + /** + * Gets the original row result set from this row. + * + * @return The original row result set from this row + */ + public AbstractRowSet getOriginalSet() { return originalSet; } + + /** + * Gets the columns values as Java objects. + * + * @return The columns values as Java objects + */ + public Object[] getAllColumns() { return columns; } + + /** + * Sets all columns values as Java objects. + * + * @param values An object array of the elements to update + */ + public void setAllColumns(Object[] values) { + if(values.length != this.columns.length) + throw new ArrayStoreException("The values array and the columns length differ!"); + this.columns = values; + } + + /** + * Gets the number of columns. + * + * @return The number of columns + */ + public int getNumberOfColumns() { return columns.length; } + + /** + * Gets a column value as a Java class. + * + * @param <T> A Java class mapped to a MonetDB data type + * @param index The index of the column + * @param javaClass The Java class + * @return The column value as a Java class + */ + public <T> T getColumn(int index, Class<T> javaClass) { return javaClass.cast(columns[index]); } + + /** + * Gets a column value as a Java class using the default mapping. + * + * @param <T> A Java class mapped to a MonetDB data type + * @param index The index of the column + * @return The column value as a Java class + */ + public <T> T getColumn(int index) { + Class<T> javaClass = this.originalSet.mappings[index].getJavaClass(); + return javaClass.cast(columns[index]); + } + + /** + * Sets a column value as a Java class. + * + * @param <T> A Java class mapped to a MonetDB data type + * @param index The index of the column + * @param value The value to set + */ + public <T> void setColumn(int index, T value) { + this.columns[index] = this.originalSet.mappings[index].getJavaClass().cast(value); + } + + /** + * Sets a column value as a Java class. + * + * @param <T> A Java class mapped to a MonetDB data type + * @param index The index of the column + * @param javaClass The Java class + * @param value The value to set + */ + public <T> void setColumn(int index, Class<T> javaClass, T value) { + this.columns[index] = javaClass.cast(value); + } + + @Override + public ListIterator<Object> iterator() { return Arrays.asList(this.columns).listIterator(); } +}
--- a/src/main/java/nl/cwi/monetdb/embedded/resultset/EmbeddedPreparedStatement.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/EmbeddedPreparedStatement.java @@ -414,7 +414,7 @@ public class EmbeddedPreparedStatement { * @return The update result object * @throws MonetDBEmbeddedException If an error in the database occurred or if a parameter has not been set yet */ - /*public UpdateResultSet sendUpdateAsync() throws MonetDBEmbeddedException { + /*public CompletableFuture<UpdateResultSet> sendUpdateAsync() throws MonetDBEmbeddedException { return this.connection.sendUpdateAsync(this.applyParameters()); }*/ @@ -424,7 +424,7 @@ public class EmbeddedPreparedStatement { * @return The query result object * @throws MonetDBEmbeddedException If an error in the database occurred or if a parameter has not been set yet */ - /*public QueryResultSet sendQueryAsync() throws MonetDBEmbeddedException { + /*public CompletableFuture<QueryResultSet> sendQueryAsync() throws MonetDBEmbeddedException { return this.connection.sendQueryAsync(this.applyParameters()); }*/ }
rename from src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetRows.java rename to src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultRowSet.java --- a/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetRows.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultRowSet.java @@ -8,6 +8,8 @@ package nl.cwi.monetdb.embedded.resultset; +import nl.cwi.monetdb.embedded.mapping.AbstractRowSet; +import nl.cwi.monetdb.embedded.mapping.MonetDBRow; import nl.cwi.monetdb.embedded.mapping.MonetDBToJavaMapping; import java.lang.reflect.Array; @@ -15,106 +17,20 @@ import java.util.Arrays; import java.util.ListIterator; /** - * A row set retrieved from an embedded MonetDB query result. All the values in this set are already mapped - * to Java classes a priori. + * The row result set from a sendQuery. * * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> */ -public class QueryResultSetRows implements Iterable { - - /** - * A single row in a result set. - * - * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> - */ - static public class QueryResulSetRow implements Iterable { - - /** - * The original row result set from this row. - */ - private final QueryResultSetRows resultSet; - - /** - * The columns values as Java objects. - */ - private final Object[] columns; - - protected QueryResulSetRow(QueryResultSetRows resultSet, Object[] columns) { - this.resultSet = resultSet; - this.columns = columns; - } - - /** - * Gets the original row result set from this row. - * - * @return The original row result set from this row - */ - public QueryResultSetRows getRowResultSet() { return resultSet; } - - /** - * Gets the columns values as Java objects. - * - * @return The columns values as Java objects - */ - public Object[] getAllColumns() { - return columns; - } - - /** - * Gets the number of columns. - * - * @return The number of columns - */ - public int getNumberOfColumns() { return columns.length; } - - /** - * Gets a column value as a Java class. - * - * @param <T> A Java class mapped to a MonetDB data type - * @param index The index of the column - * @param javaClass The Java class - * @return The column value as a Java class - */ - public <T> T getColumn(int index, Class<T> javaClass) { return javaClass.cast(columns[index]); } - - /** - * Gets a column value as a Java class using the default mapping. - * - * @param <T> A Java class mapped to a MonetDB data type - * @param index The index of the column - * @return The column value as a Java class - */ - public <T> T getColumn(int index) { - Class<T> javaClass = this.resultSet.mappings[index].getJavaClass(); - return javaClass.cast(columns[index]); - } - - @Override - public ListIterator<Object> iterator() { return Arrays.asList(this.columns).listIterator(); } - } +public class QueryResultRowSet extends AbstractRowSet implements Iterable { /** * The original query result set this row set belongs. */ private final QueryResultSet queryResultSet; - /** - * The MonetDB-To-Java mappings of the columns. - */ - private final MonetDBToJavaMapping[] mappings; - - /** - * The rows of this set. - */ - private final QueryResulSetRow[] rows; - - protected QueryResultSetRows(QueryResultSet queryResultSet, MonetDBToJavaMapping[] mappings, Object[][] rows) { + protected QueryResultRowSet(MonetDBToJavaMapping[] mappings, Object[][] rows, QueryResultSet queryResultSet) { + super(mappings, rows); this.queryResultSet = queryResultSet; - this.mappings = mappings; - this.rows = new QueryResulSetRow[mappings.length]; - for(int i = 0 ; i < mappings.length ; i++) { - this.rows[i] = new QueryResulSetRow(this, rows[i]); - } } /** @@ -129,7 +45,7 @@ public class QueryResultSetRows implemen * * @return All rows of this set */ - public QueryResulSetRow[] getAllRows() { return rows; } + public MonetDBRow[] getAllRows() { return rows; } /** * Gets the number of rows in this set. @@ -139,19 +55,12 @@ public class QueryResultSetRows implemen public int getNumberOfRows() { return rows.length; } /** - * Gets the number of columns in this set. - * - * @return The number of columns in this set - */ - public int getNumberOfColumns() { return mappings.length; } - - /** * Gets a single row in this set. * * @param row The index of the row to retrieve * @return A single row in this set */ - public QueryResulSetRow getSingleRow(int row) { return rows[row]; } + public MonetDBRow getSingleRow(int row) { return rows[row]; } /** * Gets a single value in this set as a Java class. @@ -213,5 +122,5 @@ public class QueryResultSetRows implemen } @Override - public ListIterator<QueryResulSetRow> iterator() { return Arrays.asList(this.rows).listIterator(); } + public ListIterator<MonetDBRow> iterator() { return Arrays.asList(this.rows).listIterator(); } }
--- a/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSet.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSet.java @@ -12,6 +12,7 @@ import nl.cwi.monetdb.embedded.mapping.A import nl.cwi.monetdb.embedded.mapping.AbstractResultTable; import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedConnection; import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; +import nl.cwi.monetdb.embedded.mapping.MonetDBRow; import java.util.Arrays; import java.util.ListIterator; @@ -83,9 +84,7 @@ public class QueryResultSet extends Abst * @return The columns, {@code null} if index not in bounds */ @SuppressWarnings("unchecked") - public <T> QueryResultSetColumn<T> getColumn(int index) { - return (QueryResultSetColumn<T>) columns[index]; - } + public <T> QueryResultSetColumn<T> getColumn(int index) { return (QueryResultSetColumn<T>) columns[index]; } /** * Gets a column from the result set by name. @@ -109,10 +108,10 @@ public class QueryResultSet extends Abst * * @param startIndex The first row index to retrieve * @param endIndex The last row index to retrieve - * @return The rows as {@code QueryResultSetRows} + * @return The rows as {@code AbstractRowSet} * @throws MonetDBEmbeddedException If an error in the database occurred */ - public QueryResultSetRows fetchResultSetRows(int startIndex, int endIndex) throws MonetDBEmbeddedException { + public QueryResultRowSet fetchResultSetRows(int startIndex, int endIndex) throws MonetDBEmbeddedException { if(endIndex < startIndex) { int aux = startIndex; startIndex = endIndex; @@ -133,7 +132,7 @@ public class QueryResultSet extends Abst temp[j][i] = nextColumn[j]; } } - return new QueryResultSetRows(this, this.getMappings(), temp); + return new QueryResultRowSet(this.getMappings(), temp, this); } /** @@ -141,22 +140,21 @@ public class QueryResultSet extends Abst * * @param startIndex The first row index to retrieve * @param endIndex The last row index to retrieve - * @return The rows as {@code QueryResultSetRows} + * @return The rows as {@code AbstractRowSet} * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public QueryResultSetRows fetchResultSetRowsAsync(int startIndex, int endIndex) throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.fetchResultSetRows(startIndex, endIndex)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<AbstractRowSet> fetchResultSetRowsAsync(int startIndex, int endIndex) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.fetchResultSetRows(startIndex, endIndex)); }*/ /** * Fetches the first N rows from the result set. * * @param n The last row index to retrieve - * @return The rows as {@code QueryResultSetRows} + * @return The rows as {@code AbstractRowSet} * @throws MonetDBEmbeddedException If an error in the database occurred */ - public QueryResultSetRows fetchFirstNRowValues(int n) throws MonetDBEmbeddedException { + public QueryResultRowSet fetchFirstNRowValues(int n) throws MonetDBEmbeddedException { return this.fetchResultSetRows(0, n); } @@ -164,35 +162,35 @@ public class QueryResultSet extends Abst * Fetches the first N rows from the result set asynchronously. * * @param n The last row index to retrieve - * @return The rows as {@code QueryResultSetRows} + * @return The rows as {@code AbstractRowSet} * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public QueryResultSetRows fetchFirstNRowValuesAsync(int n) throws MonetDBEmbeddedException { + /*public CompletableFuture<AbstractRowSet> fetchFirstNRowValuesAsync(int n) throws MonetDBEmbeddedException { return this.fetchResultSetRowsAsync(0, n); }*/ /** * Fetches all rows from the result set. * - * @return The rows as {@code QueryResultSetRows} + * @return The rows as {@code AbstractRowSet} * @throws MonetDBEmbeddedException If an error in the database occurred */ - public QueryResultSetRows fetchAllRowValues() throws MonetDBEmbeddedException { + public QueryResultRowSet fetchAllRowValues() throws MonetDBEmbeddedException { return this.fetchResultSetRows(0, this.numberOfRows); } /** * Fetches all rows from the result set asynchronously. * - * @return The rows as {@code QueryResultSetRows} + * @return The rows as {@code AbstractRowSet} * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public QueryResultSetRows fetchAllRowValuesAsync() throws MonetDBEmbeddedException { + /*public CompletableFuture<AbstractRowSet> fetchAllRowValuesAsync() throws MonetDBEmbeddedException { return this.fetchResultSetRowsAsync(0, this.numberOfRows); }*/ @Override - public ListIterator<QueryResultSetRows.QueryResulSetRow> iterator() { + public ListIterator<MonetDBRow> iterator() { try { return Arrays.asList(this.fetchAllRowValues().getAllRows()).listIterator(); } catch (MonetDBEmbeddedException ex) {
--- a/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetColumn.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetColumn.java @@ -125,9 +125,8 @@ public class QueryResultSetColumn<T> ext * @return The column values as a Java array * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public T[] fetchColumnValuesAsync(int startIndex, int endIndex, Class<T> javaClass) throws MonetDBEmbeddedException { - CompletableFuture.supplyAsync(() -> this.fetchColumnValues(startIndex, endIndex, javaClass)); - throw new UnsupportedOperationException("Must wait for Java 8 :("); + /*public CompletableFuture<T[]> fetchColumnValuesAsync(int startIndex, int endIndex, Class<T> javaClass) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.fetchColumnValues(startIndex, endIndex, javaClass)); }*/ /** @@ -150,7 +149,7 @@ public class QueryResultSetColumn<T> ext * @return The column values as a Java array * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public T[] fetchFirstNColumnValuesAsync(int n, Class<T> javaClass) throws MonetDBEmbeddedException { + /*public CompletableFuture<T[]> fetchFirstNColumnValuesAsync(int n, Class<T> javaClass) throws MonetDBEmbeddedException { return this.fetchColumnValuesAsync(0, n, javaClass); }*/ @@ -172,7 +171,7 @@ public class QueryResultSetColumn<T> ext * @return The column values as a Java array * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public T[] fetchAllColumnValuesAsync(Class<T> javaClass) throws MonetDBEmbeddedException { + /*public CompletableFuture<T[]> fetchAllColumnValuesAsync(Class<T> javaClass) throws MonetDBEmbeddedException { return this.fetchColumnValuesAsync(0, this.numberOfRows, javaClass); }*/ @@ -198,7 +197,7 @@ public class QueryResultSetColumn<T> ext * @throws MonetDBEmbeddedException If an error in the database occurred */ /*@SuppressWarnings("unchecked") - public T[] fetchColumnValuesAsync(int startIndex, int endIndex) throws MonetDBEmbeddedException { + public CompletableFuture<T[]> fetchColumnValuesAsync(int startIndex, int endIndex) throws MonetDBEmbeddedException { return this.fetchColumnValuesAsync(startIndex, endIndex, (Class<T>) this.mapping.getJavaClass()); }*/ @@ -220,7 +219,7 @@ public class QueryResultSetColumn<T> ext * @return The column values as a Java array * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public T[] fetchFirstNColumnValuesAsync(int n) throws MonetDBEmbeddedException { + /*public CompletableFuture<T[]> fetchFirstNColumnValuesAsync(int n) throws MonetDBEmbeddedException { return this.fetchColumnValuesAsync(0, n); }*/ @@ -240,7 +239,7 @@ public class QueryResultSetColumn<T> ext * @return The column values as a Java array * @throws MonetDBEmbeddedException If an error in the database occurred */ - /*public T[] fetchAllColumnValuesAsync() throws MonetDBEmbeddedException { + /*public CompletableFuture<T[]> fetchAllColumnValuesAsync() throws MonetDBEmbeddedException { return this.fetchColumnValuesAsync(0, this.numberOfRows); }*/
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableIterator.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableIterator.java @@ -12,5 +12,5 @@ public interface IMonetDBTableIterator e * * @param nextRow The next row in the iteration. */ - void nextRow(RowIterator nextRow); + void processNextRow(RowIterator nextRow); }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableRemover.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableRemover.java @@ -9,10 +9,10 @@ public interface IMonetDBTableRemover ex /** * The business logic for the iterator. Use the - * {@link nl.cwi.monetdb.embedded.tables.RowRemover#setToRemove(boolean) setToRemove} - * method in <code>nextRow</code> to set the current row to remove. + * {@link nl.cwi.monetdb.embedded.tables.RowRemover#setCurrentRowToRemove(boolean) setToRemove} + * method in <code>processNextRow</code> to set the current row to remove. * * @param nextRow The next row in the iteration. */ - void nextRow(RowRemover nextRow); + void processNextRow(RowRemover nextRow); }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableUpdater.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableUpdater.java @@ -9,10 +9,10 @@ public interface IMonetDBTableUpdater ex /** * The business logic for the iterator. Use the - * {@link nl.cwi.monetdb.embedded.tables.RowUpdater#setColumn(int, Object) setColumn} - * method in <code>nextRow</code> to update the current row. + * {@link nl.cwi.monetdb.embedded.tables.RowUpdater#updateColumn(int, Object) setColumn} + * method in <code>processNextRow</code> to update the current row. * * @param nextRow The next row in the iteration. */ - void nextRow(RowUpdater nextRow); + void processNextRow(RowUpdater nextRow); }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java @@ -6,7 +6,6 @@ import nl.cwi.monetdb.embedded.mapping.A import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedConnection; import nl.cwi.monetdb.embedded.resultset.QueryResultSet; import nl.cwi.monetdb.embedded.resultset.QueryResultSetColumn; -import nl.cwi.monetdb.embedded.utils.StringEscaper; /** * Java representation of a MonetDB table. It's possible to perform several CRUD operations using the respective @@ -31,30 +30,39 @@ public class MonetDBTable extends Abstra */ private final MonetDBTableColumn<?>[] columns; - public MonetDBTable(MonetDBEmbeddedConnection connection, String schemaName, String tableName, - MonetDBTableColumn<?>[] columns) { + /** + * The connection's C pointer. + */ + private long connectionPointer; + + public MonetDBTable(MonetDBEmbeddedConnection connection, long connectionPointer, String schemaName, + String tableName, MonetDBTableColumn<?>[] columns) { super(connection); + this.connectionPointer = connectionPointer; this.schemaName = schemaName; this.tableName = tableName; this.columns = columns; } @Override - protected void closeImplementation() {} + protected void closeImplementation() { this.connectionPointer = 0; } + + @Override + protected AbstractColumn<?>[] getColumns() { return this.columns; } @Override - protected AbstractColumn<?>[] getColumns() { return columns; } + public int getNumberOfColumns() { return this.columns.length; } - @Override - public int getNumberOfColumns() { return columns.length; } - + /** + * Gets the current number of rows in the table, or -1 if an error in the database has ocurred. + * + * @return The number of rows in the table. + */ @Override public int getNumberOfRows() { int res = -1; try { - String qschemaName = StringEscaper.SQLStringEscape(this.schemaName); - String qtableName = StringEscaper.SQLStringEscape(this.tableName); - String query = "SELECT COUNT(*) FROM " + qschemaName + "." + qtableName + ";"; + String query = "SELECT COUNT(*) FROM " + this.schemaName + "." + this.tableName + ";"; QueryResultSet eqr = this.getConnection().sendQuery(query); QueryResultSetColumn<Integer> eqc = eqr.getColumn(0); res = eqc.fetchFirstNColumnValues(1)[0]; @@ -110,69 +118,117 @@ public class MonetDBTable extends Abstra * * @param iterator The iterator with the business logic * @return The number of rows iterated + * @throws MonetDBEmbeddedException If an error in the database occurred */ - public int iterateTable(IMonetDBTableIterator iterator) { + public int iterateTable(IMonetDBTableIterator iterator) throws MonetDBEmbeddedException { int res = 0; - RowIterator ri = new RowIterator(this, iterator.getFirstRowToIterate(), iterator.getLastRowToIterate()); - while(ri.getNextTableRow()) { - iterator.nextRow(ri); + RowIterator ri = this.getRowIteratorInternal(this.connectionPointer, this.schemaName, this.tableName, + iterator.getFirstRowToIterate(), iterator.getLastRowToIterate()); + while(ri.tryContinueIteration()) { + iterator.processNextRow(ri); res++; } return res; } /** + * Iterate over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableIterator} + * instance asynchronously. + * + * @param iterator The iterator with the business logic + * @return The number of rows iterated + * @throws MonetDBEmbeddedException If an error in the database occurred + */ + /*public CompletableFuture<Integer> iterateTable(IMonetDBTableIterator iterator) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.iterateTable(iterator)); + }*/ + + /** * Perform an update iteration over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableUpdater} * instance. * * @param updater The iterator with the business logic * @return The number of rows updated + * @throws MonetDBEmbeddedException If an error in the database occurred */ - public int updateRows(IMonetDBTableUpdater updater) { - int res = 0; - RowUpdater ru = new RowUpdater(this, updater.getFirstRowToIterate(), updater.getLastRowToIterate()); - while(ru.getNextTableRow()) { - updater.nextRow(ru); - if(ru.tryUpdate()) { - res++; - } + public int updateRows(IMonetDBTableUpdater updater) throws MonetDBEmbeddedException { + RowUpdater ru = this.getRowUpdaterInternal(this.connectionPointer, this.schemaName, this.tableName, + updater.getFirstRowToIterate(), updater.getLastRowToIterate()); + while(ru.tryContinueIteration()) { + updater.processNextRow(ru); } - return res; + return ru.submitUpdates(); } /** + * Perform an update iteration over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableUpdater} + * instance asynchronously. + * + * @param updater The iterator with the business logic + * @return The number of rows updated + * @throws MonetDBEmbeddedException If an error in the database occurred + */ + /*public CompletableFuture<Integer> updateRowsAsync(IMonetDBTableUpdater updater) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.updateRows(updater)); + }*/ + + /** * Perform a removal iteration over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableRemover} * instance. * * @param remover The iterator with the business logic * @return The number of rows removed + * @throws MonetDBEmbeddedException If an error in the database occurred */ - public int removeRows(IMonetDBTableRemover remover) { - int res = 0; - RowRemover rr = new RowRemover(this, remover.getFirstRowToIterate(), remover.getLastRowToIterate()); - while(rr.getNextTableRow()) { - remover.nextRow(rr); - if(rr.tryRemove()) { - res++; - } + public int removeRows(IMonetDBTableRemover remover) throws MonetDBEmbeddedException { + RowRemover rr = this.getRowRemoverInternal(this.connectionPointer, this.schemaName, this.tableName, + remover.getFirstRowToIterate(), remover.getLastRowToIterate()); + while(rr.tryContinueIteration()) { + remover.processNextRow(rr); } - return res; + return rr.submitDeletes(); } /** + * Perform a removal iteration over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableRemover} + * instance asynchronously. + * + * @param remover The iterator with the business logic + * @return The number of rows removed + * @throws MonetDBEmbeddedException If an error in the database occurred + */ + /*public CompletableFuture<Integer> removeRowsAsync(IMonetDBTableRemover remover) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.removeRows(remover)); + }*/ + + /** * Deletes all rows in the table. * * @return The number of rows removed + * @throws MonetDBEmbeddedException If an error in the database occurred */ - public native int truncateTable(); + public int truncateTable() throws MonetDBEmbeddedException { + return this.truncateTableInternal(this.connectionPointer, this.schemaName, this.tableName); + } + + /** + * Deletes all rows in the table asynchronously. + * + * @return The number of rows removed + * @throws MonetDBEmbeddedException If an error in the database occurred + */ + /*public CompletableFuture<Integer> truncateTableAsync() throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.truncateTable()); + }*/ /** * Appends new rows to the table. * * @param rows An array of rows to append * @return The number of rows appended + * @throws MonetDBEmbeddedException If an error in the database occurred */ - public int appendRows(Object[][] rows) { + public int appendRows(Object[][] rows) throws MonetDBEmbeddedException { int i = 0; for (Object[] row : rows) { if (row.length != this.getNumberOfColumns()) { @@ -180,11 +236,47 @@ public class MonetDBTable extends Abstra } i++; } - return this.appendRowsInternal(rows); + return this.appendRowsInternal(this.connectionPointer, this.schemaName, this.tableName, rows); } /** + * Appends new rows to the table asynchronously. + * + * @param rows An array of rows to append + * @return The number of rows appended + * @throws MonetDBEmbeddedException If an error in the database occurred + */ + /*public CompletableFuture<Integer> appendRowsAsync(Object[][] rows) throws MonetDBEmbeddedException { + return CompletableFuture.supplyAsync(() -> this.appendRows(schemaName, tableName)); + }*/ + + /** + * Internal implementation to get a table iterator. + */ + private native RowIterator getRowIteratorInternal(long connectionPointer, String schemaName, String tableName, + int firstRowToIterate, int lastRowToIterate) throws MonetDBEmbeddedException; + + /** + * Internal implementation to get a table updater iterator. + */ + private native RowUpdater getRowUpdaterInternal(long connectionPointer, String schemaName, String tableName, + int firstRowToIterate, int lastRowToIterate) throws MonetDBEmbeddedException; + + /** + * Internal implementation to get a table remover iterator. + */ + private native RowRemover getRowRemoverInternal(long connectionPointer, String schemaName, String tableName, + int firstRowToIterate, int lastRowToIterate) throws MonetDBEmbeddedException; + + /** + * Internal implementation of table truncation. + */ + private native int truncateTableInternal(long connectionPointer, String schemaName, String tableName) + throws MonetDBEmbeddedException; + + /** * Internal implementation of rows insertion. */ - private native int appendRowsInternal(Object[][] rows); + private native int appendRowsInternal(long connectionPointer, String schemaName, String tableName, Object[][] rows) + throws MonetDBEmbeddedException; }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java @@ -1,6 +1,7 @@ package nl.cwi.monetdb.embedded.tables; -import nl.cwi.monetdb.embedded.mapping.MonetDBToJavaMapping; +import nl.cwi.monetdb.embedded.mapping.AbstractRowSet; +import nl.cwi.monetdb.embedded.mapping.MonetDBRow; /** * The iterator class for a MonetDB table. It's possible to inspect the current currentColumns in the row as well @@ -8,7 +9,7 @@ import nl.cwi.monetdb.embedded.mapping.M * * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> */ -public class RowIterator { +public class RowIterator extends AbstractRowSet { /** * The original table of this iterator. @@ -16,19 +17,9 @@ public class RowIterator { protected final MonetDBTable table; /** - * The mappings of the currentColumns. - */ - protected final MonetDBToJavaMapping[] mappings; - - /** - * The currentColumns values as Java objects. + * The current table row number on the fetched set. */ - protected Object[] currentColumns; - - /** - * The current row number. - */ - protected int currentRowNumber; + protected int currentIterationNumber; /** * The first row in the table to iterate. @@ -40,12 +31,12 @@ public class RowIterator { */ protected final int lastIndex; - public RowIterator(MonetDBTable table, int firstIndex, int lastIndex) { + protected RowIterator(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) { + super(table.getMappings(), rows); this.table = table; - this.mappings = table.getMappings(); - this.firstIndex = Math.max(firstIndex, 0); - this.lastIndex = Math.min(Math.min(lastIndex, table.getNumberOfRows()), 0); - this.currentRowNumber = this.firstIndex - 1; //starting on the row before the first index + this.firstIndex = firstIndex; //Math.max(firstIndex, 0); + this.lastIndex = lastIndex; //Math.min(Math.min(lastIndex, table.getNumberOfRows()), 0); + this.currentIterationNumber = 0; } /** @@ -56,20 +47,6 @@ public class RowIterator { public MonetDBTable getTable() { return table; } /** - * Gets the current row currentColumns values as Java objects. - * - * @return The current row currentColumns values as Java objects - */ - public Object[] getCurrentColumns() { return currentColumns; } - - /** - * Gets the current row number in the iteration. - * - * @return The current row number in the iteration - */ - public int getCurrentRowNumber() { return currentRowNumber; } - - /** * Gets the first index used on this iteration. * * @return The first index used on this iteration @@ -84,11 +61,32 @@ public class RowIterator { public int getLastIndex() { return lastIndex; } /** + * Gets the current iteration number. + * + * @return The current iteration number + */ + public int getCurrentIterationNumber() { return currentIterationNumber; } + + /** + * Gets the current row number of the table in the iteration. + * + * @return The current row number of the table in the iteration + */ + public int getCurrentTableRowNumber() { return this.currentIterationNumber + this.firstIndex; } + + /** + * Gets the current row currentColumns values as Java objects. + * + * @return The current row currentColumns values as Java objects + */ + public MonetDBRow getCurrentRow() { return this.rows[this.currentIterationNumber]; } + + /** * Checks if there are more rows to iterate after the current one. * * @return There are more rows to iterate */ - public boolean hasMore() { return currentRowNumber < lastIndex; } + public boolean hasMore() { return this.currentIterationNumber < this.lastIndex; } /** * Gets a column value as a Java class. @@ -98,7 +96,9 @@ public class RowIterator { * @param javaClass The Java class * @return The column value as a Java class */ - public <T> T getColumn(int index, Class<T> javaClass) { return javaClass.cast(this.currentColumns[index]); } + public <T> T getColumn(int index, Class<T> javaClass) { + return javaClass.cast(this.getCurrentRow().getColumn(index, javaClass)); + } /** * Gets a column value as a Java class using the default mapping. @@ -109,23 +109,19 @@ public class RowIterator { */ public <T> T getColumn(int index) { Class<T> javaClass = this.mappings[index].getJavaClass(); - return javaClass.cast(this.currentColumns[index]); + return javaClass.cast(this.getCurrentRow().getColumn(index)); } /** - * Method used by JNI to set the next columns and increment the current row number. + * Get the next row in the table if there are more. * - * @param columns The next retrieved columns + * @return A boolean indicating if there are more rows to fetch */ - protected void setNextIteration(Object[] columns) { - this.currentColumns = columns; - this.currentRowNumber++; + protected boolean tryContinueIteration() { + if(this.hasMore()) { + this.currentIterationNumber++; + return true; + } + return false; } - - /** - * Gets the next row in the iteration if there are more. - * - * @return A boolean indicating if a row was fetched - */ - protected native boolean getNextTableRow(); }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/RowRemover.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/RowRemover.java @@ -1,5 +1,7 @@ package nl.cwi.monetdb.embedded.tables; +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + /** * The removal iterator for a MonetDB table. * @@ -10,11 +12,11 @@ public class RowRemover extends RowItera /** * If the next row is going to be removed. */ - private boolean toRemove; + private boolean[] removeIndexes; - public RowRemover(MonetDBTable table, int firstIndex, int lastIndex) { - super(table, firstIndex, lastIndex); - this.toRemove = false; + public RowRemover(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) { + super(table, rows, firstIndex, lastIndex); + this.removeIndexes = new boolean[lastIndex - firstIndex]; } /** @@ -22,37 +24,19 @@ public class RowRemover extends RowItera * * @return If the next row is going to be removed */ - public boolean isToRemove() { return toRemove; } + public boolean isCurrentRowSetToRemove() { return this.removeIndexes[this.getCurrentIterationNumber()]; } /** * Sets the current row to remove or not. * * @param toRemove A boolean indicating if the next row will be removed */ - public void setToRemove(boolean toRemove) { this.toRemove = toRemove; } - - /** - * To be called by the JNI interface in every iteration. - * - * @param columns The next row's columns - */ - @Override - protected void setNextIteration(Object[] columns) { - super.setNextIteration(columns); - this.toRemove = false; - } + public void setCurrentRowToRemove(boolean toRemove) { this.removeIndexes[this.getCurrentIterationNumber()] = toRemove; } /** - * Remove the current row if it was set for so. + * Removes the rows. * - * @return If the row was removed internally + * @return The number of rows deleted */ - protected boolean tryRemove() { return this.isToRemove() && this.removeNextTableRow(); } - - /** - * Removes the next row. - * - * @return If the row was removed internally - */ - private native boolean removeNextTableRow(); + protected native int submitDeletes() throws MonetDBEmbeddedException; }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/RowUpdater.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/RowUpdater.java @@ -1,5 +1,7 @@ package nl.cwi.monetdb.embedded.tables; +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + import java.util.Arrays; /** @@ -12,64 +14,64 @@ public class RowUpdater extends RowItera /** * A boolean array to check the columns to be updated. */ - private final boolean[] updatedIndexes; + private final boolean[][] updatedIndexes; - public RowUpdater(MonetDBTable table, int firstIndex, int lastIndex) { - super(table, firstIndex, lastIndex); - this.updatedIndexes = new boolean[table.getNumberOfColumns()]; + protected RowUpdater(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) { + super(table, rows, firstIndex, lastIndex); + this.updatedIndexes = new boolean[lastIndex - firstIndex][table.getNumberOfColumns()]; } /** - * Sets a column value as a Java class. + * Updates a column value. * * @param <T> A Java class mapped to a MonetDB data type * @param index The index of the column * @param value The value to set */ - public <T> void setColumn(int index, T value) { - this.currentColumns[index] = this.mappings[index].getJavaClass().cast(value); - this.updatedIndexes[index] = true; + public <T> void updateColumn(int index, T value) { + this.getCurrentRow().setColumn(index, value); + this.updatedIndexes[this.getCurrentIterationNumber()][index] = true; } /** - * Sets a column value as a Java class. + * Updates a column value. * * @param <T> A Java class mapped to a MonetDB data type * @param index The index of the column * @param javaClass The Java class * @param value The value to set */ - public <T> void setColumn(int index, Class<T> javaClass, T value) { - this.currentColumns[index] = javaClass.cast(value); - this.updatedIndexes[index] = true; + public <T> void updateColumn(int index, Class<T> javaClass, T value) { + this.getCurrentRow().setColumn(index, javaClass, value); + this.updatedIndexes[this.getCurrentIterationNumber()][index] = true; } /** - * Sets all column values as Java classes. + * Updates all column values. * * @param values The values to set */ - public void setAllColumns(Object[] values) { - if(values.length != this.currentColumns.length) - throw new ArrayStoreException("The values array and the columns length differ!"); - this.currentColumns = values; - Arrays.fill(this.updatedIndexes, true); + public void updateAllColumns(Object[] values) { + this.getCurrentRow().setAllColumns(values); + Arrays.fill(this.updatedIndexes[this.getCurrentIterationNumber()], true); } /** - * Gets a boolean array of the columns indexes to be updated. + * Gets a boolean array of the column indexes to be updated in the current iteration. * - * @return A boolean array of the columns indexes to be updated + * @return A boolean array of the column indexes to be updated in the current iteration */ - public boolean[] getUpdatedIndexes() { return Arrays.copyOf(this.updatedIndexes, this.updatedIndexes.length); } + public boolean[] getCurrentUpdatedIndexes() { + return Arrays.copyOf(this.updatedIndexes[this.getCurrentIterationNumber()], this.updatedIndexes.length); + } /** - * Check if the current row is to be updated. + * Check if the current row is set to be updated. * * @return A boolean indicating if the current row is to be updated */ public boolean toUpdate() { - for (boolean bol : this.updatedIndexes) { + for (boolean bol : this.updatedIndexes[this.getCurrentIterationNumber()]) { if(bol) { return true; } @@ -78,27 +80,9 @@ public class RowUpdater extends RowItera } /** - * To be called by the JNI interface in every iteration. + * Updates the row set. * - * @param columns The next row's columns + * @return The number of rows updated */ - @Override - protected void setNextIteration(Object[] columns) { - super.setNextIteration(columns); - Arrays.fill(this.updatedIndexes, false); - } - - /** - * Update the current row if there are changes. - * - * @return If the row was updated internally - */ - protected boolean tryUpdate() { return this.toUpdate() && this.updateNextTableRow(); } - - /** - * Updates the next row. - * - * @return If the row was updated internally - */ - private native boolean updateNextTableRow(); + protected native int submitUpdates() throws MonetDBEmbeddedException; }