changeset 44:cd6ff38c90f4 embedded

Cleaned more code. Ready to implement the iterators internally.
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Thu, 10 Nov 2016 11:16:09 +0100 (2016-11-10)
parents 2ab2b21cf930
children 8353929359d6
files src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedConnection.java src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedDatabase.java src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractRowSet.java src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBRow.java src/main/java/nl/cwi/monetdb/embedded/resultset/EmbeddedPreparedStatement.java src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultRowSet.java src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSet.java src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetColumn.java src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetRows.java src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableIterator.java src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableRemover.java src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableUpdater.java src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java src/main/java/nl/cwi/monetdb/embedded/tables/RowRemover.java src/main/java/nl/cwi/monetdb/embedded/tables/RowUpdater.java
diffstat 16 files changed, 529 insertions(+), 433 deletions(-) [+]
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;
 }