changeset 48:8353929359d6 embedded

Starting to test Java to BAT conversion. Let the debugging games begin!
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Fri, 11 Nov 2016 18:10:44 +0100 (2016-11-11)
parents cd6ff38c90f4
children 8217f77fcf6b
files src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBToJavaMapping.java src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableCursor.java src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableIterator.java src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTableColumn.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/jdbc/MonetConnection.java
diffstat 8 files changed, 160 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBToJavaMapping.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBToJavaMapping.java
@@ -25,6 +25,7 @@ import java.util.UUID;
  */
 public enum MonetDBToJavaMapping {
 
+    /* PLEASE Don't change these enum values order!! */
     Boolean(Boolean.class), Char(String.class), Varchar(String.class), Clob(String.class), Oid(Long.class),
     Tinyint(Byte.class), Smallint(Short.class), Int(Integer.class), Wrd(Long.class), Bigint(Long.class),
     Hugeint(BigInteger.class), Decimal(BigDecimal.class), Real(Float.class), Double(Double.class),
rename from src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableIterator.java
rename to src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableCursor.java
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableIterator.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/tables/IMonetDBTableCursor.java
@@ -5,7 +5,7 @@ package nl.cwi.monetdb.embedded.tables;
  *
  * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a>
  */
-public interface IMonetDBTableIterator extends IMonetDBTableBaseIterator {
+public interface IMonetDBTableCursor extends IMonetDBTableBaseIterator {
 
     /**
      * The business logic for the iterator.
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java
@@ -4,6 +4,7 @@ import nl.cwi.monetdb.embedded.env.Monet
 import nl.cwi.monetdb.embedded.mapping.AbstractColumn;
 import nl.cwi.monetdb.embedded.mapping.AbstractResultTable;
 import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedConnection;
+import nl.cwi.monetdb.embedded.mapping.MonetDBRow;
 import nl.cwi.monetdb.embedded.resultset.QueryResultSet;
 import nl.cwi.monetdb.embedded.resultset.QueryResultSetColumn;
 
@@ -35,6 +36,11 @@ public class MonetDBTable extends Abstra
      */
     private long connectionPointer;
 
+    private final int[] columnsJavaIndexes;
+    private final int[] columnsMonetDBIndexes;
+    private final String[] columnsNames;
+    private final Class[] columnsClasses;
+
     public MonetDBTable(MonetDBEmbeddedConnection connection, long connectionPointer, String schemaName,
                         String tableName, MonetDBTableColumn<?>[] columns) {
         super(connection);
@@ -42,6 +48,18 @@ public class MonetDBTable extends Abstra
         this.schemaName = schemaName;
         this.tableName = tableName;
         this.columns = columns;
+        this.columnsJavaIndexes = new int[columns.length];
+        this.columnsMonetDBIndexes = new int[columns.length];
+        this.columnsNames = new String[columns.length];
+        this.columnsClasses = new Class[columns.length];
+        int i = 0;
+        for(MonetDBTableColumn col : this.columns) {
+            this.columnsJavaIndexes[i] = col.getInternalMonetDBTypeIndex();
+            this.columnsMonetDBIndexes[i] = col.getMapping().ordinal();
+            this.columnsNames[i] = col.getColumnName();
+            this.columnsClasses[i] = col.getMapping().getJavaClass();
+            i++;
+        }
     }
 
     @Override
@@ -114,32 +132,69 @@ public class MonetDBTable extends Abstra
     }
 
     /**
-     * Iterate over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableIterator} instance.
+     * Private method to check the limits of iteration.
      *
-     * @param iterator The iterator with the business logic
+     * @param iterator The iterator to check
+     * @return An integer array with the limits fixed
+     */
+    private int[] checkIterator(IMonetDBTableBaseIterator iterator) {
+        int[] res = {iterator.getFirstRowToIterate(), iterator.getLastRowToIterate()};
+        if(res[0] == res[1]) {
+            throw new ArrayIndexOutOfBoundsException("Iterating over 0 rows?");
+        }
+        if(res[1] < res[0]) {
+            int aux = res[0];
+            res[0] = res[1];
+            res[0] = aux;
+        }
+        if (res[0] < 0) {
+            res[0] = 0;
+        }
+        int numberOfRows = this.getNumberOfRows();
+        if (res[1] > numberOfRows) {
+            res[1] = numberOfRows;
+        }
+        return res;
+    }
+
+    /**
+     * Iterate over the table using a {@link IMonetDBTableCursor} instance.
+     *
+     * @param cursor 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) throws MonetDBEmbeddedException {
-        int res = 0;
-        RowIterator ri = this.getRowIteratorInternal(this.connectionPointer, this.schemaName, this.tableName,
-                iterator.getFirstRowToIterate(), iterator.getLastRowToIterate());
+    public int iterateTable(IMonetDBTableCursor cursor) throws MonetDBEmbeddedException {
+        int[] limits = this.checkIterator(cursor);
+        int res = 0, total = limits[1] - limits[0];
+        String query = new StringBuffer("SELECT * FROM ").append(this.schemaName).append(".").append(this.tableName)
+                .append(" LIMIT ").append(total).append(" OFFSET ").append(limits[0]).append(";").toString();
+
+        QueryResultSet eqr = this.getConnection().sendQuery(query);
+        MonetDBRow[] array = eqr.fetchAllRowValues().getAllRows();
+        eqr.close();
+        Object[][] data = new Object[eqr.getNumberOfRows()][this.getNumberOfColumns()];
+        for(int i = 0 ; i < eqr.getNumberOfRows() ; i++) {
+            data[i] = array[i].getAllColumns();
+        }
+
+        RowIterator ri = new RowIterator(this, data, limits[0], limits[1]);
         while(ri.tryContinueIteration()) {
-            iterator.processNextRow(ri);
+            cursor.processNextRow(ri);
             res++;
         }
         return res;
     }
 
     /**
-     * Iterate over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableIterator}
+     * Iterate over the table using a {@link IMonetDBTableCursor}
      * 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 {
+    /*public CompletableFuture<Integer> iterateTable(IMonetDBTableCursor iterator) throws MonetDBEmbeddedException {
         return CompletableFuture.supplyAsync(() -> this.iterateTable(iterator));
     }*/
 
@@ -151,14 +206,15 @@ public class MonetDBTable extends Abstra
      * @return The number of rows updated
      * @throws MonetDBEmbeddedException If an error in the database occurred
      */
-    public int updateRows(IMonetDBTableUpdater updater) throws MonetDBEmbeddedException {
+    /*public int updateRows(IMonetDBTableUpdater updater) throws MonetDBEmbeddedException {
+        int[] limits = this.checkIterator(updater);
         RowUpdater ru = this.getRowUpdaterInternal(this.connectionPointer, this.schemaName, this.tableName,
-                updater.getFirstRowToIterate(), updater.getLastRowToIterate());
+                limits[0], limits[1]);
         while(ru.tryContinueIteration()) {
             updater.processNextRow(ru);
         }
         return ru.submitUpdates();
-    }
+    }*/
 
     /**
      * Perform an update iteration over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableUpdater}
@@ -180,14 +236,15 @@ public class MonetDBTable extends Abstra
      * @return The number of rows removed
      * @throws MonetDBEmbeddedException If an error in the database occurred
      */
-    public int removeRows(IMonetDBTableRemover remover) throws MonetDBEmbeddedException {
+    /*public int removeRows(IMonetDBTableRemover remover) throws MonetDBEmbeddedException {
+        int[] limits = this.checkIterator(remover);
         RowRemover rr = this.getRowRemoverInternal(this.connectionPointer, this.schemaName, this.tableName,
-                remover.getFirstRowToIterate(), remover.getLastRowToIterate());
+                limits[0], limits[1]);
         while(rr.tryContinueIteration()) {
             remover.processNextRow(rr);
         }
         return rr.submitDeletes();
-    }
+    }*/
 
     /**
      * Perform a removal iteration over the table using a {@link nl.cwi.monetdb.embedded.tables.IMonetDBTableRemover}
@@ -207,9 +264,9 @@ public class MonetDBTable extends Abstra
      * @return The number of rows removed
      * @throws MonetDBEmbeddedException If an error in the database occurred
      */
-    public int truncateTable() throws MonetDBEmbeddedException {
+    /*public int truncateTable() throws MonetDBEmbeddedException {
         return this.truncateTableInternal(this.connectionPointer, this.schemaName, this.tableName);
-    }
+    }*/
 
     /**
      * Deletes all rows in the table asynchronously.
@@ -222,21 +279,30 @@ public class MonetDBTable extends Abstra
     }*/
 
     /**
-     * Appends new rows to the table.
+     * Appends new rows to the table. As MonetDB's storage is column-wise, the method
+     * {@link nl.cwi.monetdb.embedded.tables.MonetDBTable#appendColumns(Object[][]) appendColumns} is preferable
+     * over this one.
      *
      * @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) throws MonetDBEmbeddedException {
-        int i = 0;
-        for (Object[] row : rows) {
-            if (row.length != this.getNumberOfColumns()) {
+        int numberOfRows = rows.length, numberOfColumns = this.getNumberOfColumns();
+        if(numberOfRows == 0) {
+            throw new ArrayStoreException("Appending 0 rows?");
+        }
+        Object[][] transposed = new Object[numberOfColumns][numberOfRows];
+
+        for (int i = 0; i < numberOfRows; i++) {
+            if(rows[i].length != numberOfColumns) {
                 throw new ArrayStoreException("The values array at row " + i + " differs from the number of columns!");
             }
-            i++;
+            for (int j = 0; j < numberOfColumns; j++) {
+                transposed[j][i] = rows[i][j];
+            }
         }
-        return this.appendRowsInternal(this.connectionPointer, this.schemaName, this.tableName, rows);
+        return this.appendColumns(transposed);
     }
 
     /**
@@ -251,32 +317,52 @@ public class MonetDBTable extends Abstra
     }*/
 
     /**
-     * Internal implementation to get a table iterator.
+     * Appends new rows to the table column-wise. As MonetDB's storage is column-wise, this method is preferable over
+     * {@link nl.cwi.monetdb.embedded.tables.MonetDBTable#appendRows(Object[][]) appendRows} method.
+     *
+     * @param columns An array of columns to append
+     * @return The number of rows appended
+     * @throws MonetDBEmbeddedException If an error in the database occurred
      */
-    private native RowIterator getRowIteratorInternal(long connectionPointer, String schemaName, String tableName,
-                                                     int firstRowToIterate, int lastRowToIterate) throws MonetDBEmbeddedException;
+    public int appendColumns(Object[][] columns) throws MonetDBEmbeddedException {
+        int numberOfRows = columns[0].length, numberOfColumns = this.getNumberOfColumns();
+        if(numberOfRows == 0) {
+            throw new ArrayStoreException("Appending 0 rows?");
+        }
+        if (columns.length != numberOfColumns) {
+            throw new ArrayStoreException("The number of columns differs from the table's number of columns!");
+        }
+        for (int i = 0; i < numberOfRows; i++) {
+            if(columns[i].length != numberOfRows) {
+                throw new ArrayStoreException("The number of rows in each column is not consistent!");
+            }
+        }
+        return this.appendColumnsInternal(this.connectionPointer, this.schemaName, this.tableName, this.columnsJavaIndexes,
+                this.columnsMonetDBIndexes,  this.columnsNames, this.columnsClasses, columns);
+    }
 
     /**
-     * Internal implementation to get a table updater iterator.
+     * Appends new rows to the table column-wise and asynchronously.
+     *
+     * @param columns An array of columns to append
+     * @return The number of rows appended
+     * @throws MonetDBEmbeddedException If an error in the database occurred
      */
-    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;
+    /*public CompletableFuture<Integer> appendColumnsAsync(Object[][] columns) throws MonetDBEmbeddedException {
+        return CompletableFuture.supplyAsync(() -> this.appendColumns(schemaName, tableName));
+    }*/
 
     /**
      * Internal implementation of table truncation.
      */
-    private native int truncateTableInternal(long connectionPointer, String schemaName, String tableName)
-            throws MonetDBEmbeddedException;
+    /*private native int truncateTableInternal(long connectionPointer, String schemaName, String tableName)
+            throws MonetDBEmbeddedException;*/
 
     /**
-     * Internal implementation of rows insertion.
+     * Internal implementation of columns insertion.
      */
-    private native int appendRowsInternal(long connectionPointer, String schemaName, String tableName, Object[][] rows)
+    private native int appendColumnsInternal(long connectionPointer, String schemaName, String tableName,
+                                             int[] monetDBindexes, int[] javaindexes, String[] columnsNames,
+                                             Class[] classes, Object[][] columns)
             throws MonetDBEmbeddedException;
 }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTableColumn.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTableColumn.java
@@ -19,11 +19,17 @@ public class MonetDBTableColumn<T> exten
      */
     private final boolean isNullable;
 
+    /**
+     * Internal MonetDB index of the column.
+     */
+    private final int internalMonetDBTypeIndex;
+
     public MonetDBTableColumn(int resultSetIndex, String columnName, String columnType, int columnDigits,
-                              int columnScale, String defaultValue, boolean isNullable) {
+                              int columnScale, String defaultValue, boolean isNullable, int internalMonetDBTypeIndex) {
         super(resultSetIndex, columnName, columnType, columnDigits, columnScale);
         this.defaultValue = defaultValue;
         this.isNullable = isNullable;
+        this.internalMonetDBTypeIndex = internalMonetDBTypeIndex;
     }
 
     /**
@@ -39,4 +45,6 @@ public class MonetDBTableColumn<T> exten
      * @return The indication if the column is nullable
      */
     public boolean isNullable() { return isNullable; }
+
+    protected int getInternalMonetDBTypeIndex() { return internalMonetDBTypeIndex; }
 }
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java
@@ -34,8 +34,8 @@ public class RowIterator extends Abstrac
     protected RowIterator(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) {
         super(table.getMappings(), rows);
         this.table = table;
-        this.firstIndex = firstIndex; //Math.max(firstIndex, 0);
-        this.lastIndex = lastIndex; //Math.min(Math.min(lastIndex, table.getNumberOfRows()), 0);
+        this.firstIndex = firstIndex;
+        this.lastIndex = lastIndex;
         this.currentIterationNumber = 0;
     }
 
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/RowRemover.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/tables/RowRemover.java
@@ -14,7 +14,7 @@ public class RowRemover extends RowItera
      */
     private boolean[] removeIndexes;
 
-    public RowRemover(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) {
+    protected RowRemover(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) {
         super(table, rows, firstIndex, lastIndex);
         this.removeIndexes = new boolean[lastIndex - firstIndex];
     }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -169,9 +169,9 @@ public class MonetConnection extends Mon
 		this.username = props.getProperty("user");
 		this.password = props.getProperty("password");
 		String language = props.getProperty("language");
-		boolean debug = Boolean.valueOf(props.getProperty("debug")).booleanValue();
+		boolean debug = Boolean.valueOf(props.getProperty("debug"));
 		String hash = props.getProperty("hash");
-		blobIsBinary = Boolean.valueOf(props.getProperty("treat_blob_as_binary")).booleanValue();
+		blobIsBinary = Boolean.valueOf(props.getProperty("treat_blob_as_binary"));
 		int sockTimeout = 0;
 		try {
 			sockTimeout = Integer.parseInt(props.getProperty("so_timeout"));
@@ -1548,7 +1548,7 @@ public class MonetConnection extends Mon
 		 * @return a non-null String if the line is invalid,
 		 *         or additional lines are not allowed.
 		 */
-		public abstract String addLine(String line, int linetype);
+		String addLine(String line, int linetype);
 
 		/**
 		 * Returns whether this Reponse expects more lines to be added
@@ -1556,7 +1556,7 @@ public class MonetConnection extends Mon
 		 *
 		 * @return true if a next line should be added, false otherwise
 		 */
-		public abstract boolean wantsMore();
+		boolean wantsMore();
 
 		/**
 		 * Indicates that no more header lines will be added to this
@@ -1565,14 +1565,14 @@ public class MonetConnection extends Mon
 		 * @throws SQLException if the contents of the Response is not
 		 *         consistent or sufficient.
 		 */
-		public abstract void complete() throws SQLException;
+		void complete() throws SQLException;
 
 		/**
 		 * Instructs the Response implementation to close and do the
 		 * necessary clean up procedures.
 		 *
 		 */
-		public abstract void close();
+		void close();
 	}
 	// }}}