Mercurial > hg > monetdb-java
changeset 54:6617eaf808cb embedded
Intermediary commit. Added direct mapping for primitive types. Removed unused code.
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 @@ -39,7 +39,7 @@ public class MonetDBEmbeddedConnection { */ public String getCurrentSchema() throws MonetDBEmbeddedException { QueryResultSet eqr = this.sendQuery("SELECT current_schema FROM sys.var();"); - QueryResultSetColumn<String> col = eqr.getColumnByIndex(0); + QueryResultSetObjectColumn<String> col = eqr.getObjectColumnByIndex(0); String res = col.fetchFirstNColumnValues(1)[0]; eqr.close(); return res; @@ -138,31 +138,6 @@ public class MonetDBEmbeddedConnection { }*/ /** - * Creates a prepared query statement likewise the PreparedStatement in JDBC. - * - * @param query The SQL query with '?' indicating the parameters to replace in the query - * @return An instance of EmbeddedPreparedStatement - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - /*public EmbeddedPreparedStatement createPreparedStatement(String query) throws MonetDBEmbeddedException { - if (!query.endsWith(";")) { - query += ";"; - } - return this.createPreparedStatementInternal(this.connectionPointer, query); - }*/ - - /** - * Creates a prepared query statement likewise the PreparedStatement in JDBC asynchronously. - * - * @param query The SQL query with '?' indicating the parameters to replace in the query - * @return An instance of EmbeddedPreparedStatement - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - /*public CompletableFuture<EmbeddedPreparedStatement> createPreparedStatementAsync(String query) throws MonetDBEmbeddedException { - return CompletableFuture.supplyAsync(() -> this.createPreparedStatement(query)); - }*/ - - /** * Retrieves a MonetDB Table for further operations * * @param schemaName The schema of the table @@ -284,9 +259,6 @@ public class MonetDBEmbeddedConnection { private native MonetDBTable getMonetDBTableInternal(long connectionPointer, String schemaName, String tableName) throws MonetDBEmbeddedException; - /*private native EmbeddedPreparedStatement createPreparedStatementInternal(long connectionPointer, String query) - throws MonetDBEmbeddedException;*/ - /** * Internal implementation to close a connection. */
--- a/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractColumn.java +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractColumn.java @@ -16,12 +16,30 @@ package nl.cwi.monetdb.embedded.mapping; public abstract class AbstractColumn { /** - * The Mapping between MonetDB type and the Java Class. + * The mapping between MonetDB type and the Java Class. */ protected final MonetDBToJavaMapping mapping; - protected AbstractColumn(String columnType) { + /** + * The column name. + */ + private final String columnName; + + /** + * The column digits. + */ + private final int columnDigits; + + /** + * The column scale. + */ + private final int columnScale; + + protected AbstractColumn(String columnType, String columnName, int columnDigits, int columnScale) { this.mapping = MonetDBToJavaMapping.GetJavaMappingFromMonetDBString(columnType); + this.columnName = columnName; + this.columnDigits = columnDigits; + this.columnScale = columnScale; } /** @@ -43,19 +61,19 @@ public abstract class AbstractColumn { * * @return The column name */ - public abstract String getColumnName(); + public String getColumnName() { return this.columnName; } /** * Gets the number digits of the column. * * @return The number of digits */ - public abstract int getColumnDigits(); + public int getColumnDigits() { return this.columnDigits; } /** * Gets the scale of the column. * * @return The scale */ - public abstract int getColumnScale(); + public int getColumnScale() { return this.columnScale; } }
--- a/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractResultTable.java +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractResultTable.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.mapping; import nl.cwi.monetdb.embedded.env.AbstractConnectionResult;
--- a/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractRowSet.java +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/AbstractRowSet.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.mapping; /** @@ -9,6 +17,11 @@ package nl.cwi.monetdb.embedded.mapping; public abstract class AbstractRowSet { /** + * The original query result set this row set belongs. + */ + private final AbstractResultTable table; + + /** * The MonetDB-To-Java mappings of the columns. */ protected final MonetDBToJavaMapping[] mappings; @@ -18,7 +31,8 @@ public abstract class AbstractRowSet { */ protected final MonetDBRow[] rows; - protected AbstractRowSet(MonetDBToJavaMapping[] mappings, Object[][] rows) { + protected AbstractRowSet(AbstractResultTable table, MonetDBToJavaMapping[] mappings, Object[][] rows) { + this.table = table; this.mappings = mappings; this.rows = new MonetDBRow[rows.length]; for(int i = 0 ; i < rows.length ; i++) { @@ -27,9 +41,23 @@ public abstract class AbstractRowSet { } /** + * Gets the original query result set this row set belongs. + * + * @return The original query result set this row set belongs + */ + public AbstractResultTable getQueryResultTable() { return table; } + + /** * Gets the number of columns in this set. * * @return The number of columns in this set */ public int getNumberOfColumns() { return mappings.length; } + + /** + * Gets a column index in the result set by name. + * + * @return The index number + */ + public abstract int getColumnIndexByName(String columnName); }
--- a/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBEmbeddedBlob.java +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBEmbeddedBlob.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.mapping; import java.io.*;
--- a/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBRow.java +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBRow.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.mapping; import java.util.Arrays; @@ -30,7 +38,7 @@ public class MonetDBRow implements Itera * * @return The original row result set from this row */ - public AbstractRowSet getOriginalSet() { return originalSet; } + public AbstractRowSet getRowSet() { return originalSet; } /** * Gets the columns values as Java objects. @@ -40,7 +48,7 @@ public class MonetDBRow implements Itera public Object[] getAllColumns() { return columns; } /** - * Sets all columns values as Java objects. + * Sets all columns values as Java objects. Warning - this method does not override the contents in the database! * * @param values An object array of the elements to update */ @@ -80,7 +88,33 @@ public class MonetDBRow implements Itera } /** - * Sets a column value as a Java class. + * Gets a column value as a Java class. + * + * @param <T> A Java class mapped to a MonetDB data type + * @param columnName The name of the column + * @param javaClass The Java class + * @return The column value as a Java class + */ + public <T> T getColumnByName(String columnName, Class<T> javaClass) { + int index = this.getRowSet().getColumnIndexByName(columnName); + 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 columnName The name of the column + * @return The column value as a Java class + */ + public <T> T getColumnByName(String columnName) { + int index = this.getRowSet().getColumnIndexByName(columnName); + Class<T> javaClass = this.originalSet.mappings[index].getJavaClass(); + return javaClass.cast(columns[index]); + } + + /** + * Sets a column value as a Java class. Warning - this method does not override the contents in the database! * * @param <T> A Java class mapped to a MonetDB data type * @param index The index of the column @@ -91,7 +125,7 @@ public class MonetDBRow implements Itera } /** - * Sets a column value as a Java class. + * Sets a column value as a Java class. Warning - this method does not override the contents in the database! * * @param <T> A Java class mapped to a MonetDB data type * @param index The index of the column @@ -102,6 +136,31 @@ public class MonetDBRow implements Itera this.columns[index] = javaClass.cast(value); } + /** + * Sets a column value as a Java class. Warning - this method does not override the contents in the database! + * + * @param <T> A Java class mapped to a MonetDB data type + * @param columnName The name of the column + * @param value The value to set + */ + public <T> void setColumnByName(String columnName, T value) { + int index = this.getRowSet().getColumnIndexByName(columnName); + this.columns[index] = this.originalSet.mappings[index].getJavaClass().cast(value); + } + + /** + * Sets a column value as a Java class. Warning - this method does not override the contents in the database! + * + * @param <T> A Java class mapped to a MonetDB data type + * @param columnName The name of the column + * @param javaClass The Java class + * @param value The value to set + */ + public <T> void setColumnByName(String columnName, Class<T> javaClass, T value) { + int index = this.getRowSet().getColumnIndexByName(columnName); + 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/mapping/MonetDBToJavaMapping.java +++ b/src/main/java/nl/cwi/monetdb/embedded/mapping/MonetDBToJavaMapping.java @@ -74,10 +74,11 @@ public enum MonetDBToJavaMapping { /** * Get the corresponding MonetDBToJavaMapping from MonetDB internal data type. * - * @return A MonetDBToJavaMapping enum value + * @param sqlName The MonetDB's data type SQL name + * @return A MonetDBToJavaMapping enum value, or null if it has no mapping */ - public static MonetDBToJavaMapping GetJavaMappingFromMonetDBString(String sqlname) { - return MonetDBMappings.get(sqlname); + public static MonetDBToJavaMapping GetJavaMappingFromMonetDBString(String sqlName) { + return MonetDBMappings.get(sqlName); } /**
rename from src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetColumn.java rename to src/main/java/nl/cwi/monetdb/embedded/resultset/AbstractQueryResultSetColumn.java --- a/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetColumn.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/AbstractQueryResultSetColumn.java @@ -8,20 +8,18 @@ package nl.cwi.monetdb.embedded.resultset; +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; import nl.cwi.monetdb.embedded.mapping.AbstractColumn; -import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; -import java.lang.reflect.Array; -import java.util.Arrays; -import java.util.ListIterator; +import java.lang.reflect.ParameterizedType; /** * An abstract class for accessing materialised (Java-level) query result columns. * - * @param <T> A Java class mapped to a MonetDB data type + * @param <A> An array of a Java primitive mapped from a MonetDB column !! Must be a Java array !! * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> */ -public class QueryResultSetColumn<T> extends AbstractColumn implements Iterable<T> { +public abstract class AbstractQueryResultSetColumn<A> extends AbstractColumn { /** * Internal C pointer of the column, @@ -29,29 +27,9 @@ public class QueryResultSetColumn<T> ext protected long tablePointer; /** - * Array with the retrieved values. - */ - private final T[] values; - - /** * The index of the column. */ - private final int resultSetIndex; - - /** - * The column name. - */ - private final String columnName; - - /** - * The column digits. - */ - private final int columnDigits; - - /** - * The column scale. - */ - private final int columnScale; + protected final int resultSetIndex; /** * The number of rows in this column. @@ -61,56 +39,53 @@ public class QueryResultSetColumn<T> ext /** * The index of the first value mapped to a Java class. */ - private int firstRetrievedIndex; + protected int firstRetrievedIndex; /** * The index of the last value mapped to a Java class. */ - private int lastRetrievedIndex; + protected int lastRetrievedIndex; - @SuppressWarnings("unchecked") - protected QueryResultSetColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, int columnDigits, int columnScale, int numberOfRows) { - super(columnType); + protected AbstractQueryResultSetColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, columnName, columnDigits, columnScale); + Class<?> param = (Class<?>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; + if(!param.isArray()) { + throw new ClassCastException("The parameter must be of array type!!"); + } this.tablePointer = tablePointer; this.resultSetIndex = resultSetIndex; - this.columnName = columnName; - this.columnDigits = columnDigits; - this.columnScale = columnScale; this.numberOfRows = numberOfRows; this.firstRetrievedIndex = numberOfRows; this.lastRetrievedIndex = 0; - this.values = (T[]) Array.newInstance(this.mapping.getJavaClass(), numberOfRows); } - @Override - public String getColumnName() { return this.columnName; } - - @Override - public int getColumnDigits() { return this.columnDigits; } - - @Override - public int getColumnScale() { return this.columnScale; } - /** - * Get the number of rows in this column. + * Gets the number of rows in this column. * * @return The number of rows */ public int getNumberOfRows() { return this.numberOfRows; } - public int getResultSetIndex() { return resultSetIndex; } + protected abstract void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException; + + protected abstract A storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve); + + protected abstract boolean[] checkIfIndexesAreNullImplementation(A values, boolean[] res) + throws MonetDBEmbeddedException; + + protected abstract Object[] mapValuesToObjectArrayImplementation(A values) + throws MonetDBEmbeddedException; /** - * Maps columns values into the Java representation. + * Maps columns values using the provided Java representation by the query. * * @param startIndex The first column index to retrieve * @param endIndex The last column index to retrieve - * @param javaClass The Java class to map * @return The column values as a Java array * @throws MonetDBEmbeddedException If an error in the database occurred */ - @SuppressWarnings("unchecked") - public T[] fetchColumnValues(int startIndex, int endIndex, Class<T> javaClass) throws MonetDBEmbeddedException { + public A fetchColumnValues(int startIndex, int endIndex) throws MonetDBEmbeddedException { if(endIndex < startIndex) { int aux = startIndex; startIndex = endIndex; @@ -123,103 +98,25 @@ public class QueryResultSetColumn<T> ext } else if(startIndex == endIndex) { throw new ArrayIndexOutOfBoundsException("Retrieving 0 values?"); } - - boolean hasToConvert = false; + boolean hasToFetch = false; int numberOfRowsToRetrieve = endIndex - startIndex; int firstIndexToFetch = Math.min(startIndex, this.firstRetrievedIndex); int lastIndexToFetch = Math.max(endIndex, this.lastRetrievedIndex); if(startIndex < this.firstRetrievedIndex) { this.firstRetrievedIndex = startIndex; - hasToConvert = true; + hasToFetch = true; } if(endIndex > this.lastRetrievedIndex) { this.lastRetrievedIndex = endIndex; - hasToConvert = true; + hasToFetch = true; } - if(hasToConvert) { + if(hasToFetch) { if(this.tablePointer == 0) { throw new MonetDBEmbeddedException("Connection closed!"); } - T[] newvalues = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, - (Class<T>) this.mapping.getJavaClass(), this.mapping.ordinal(), firstIndexToFetch, lastIndexToFetch); - System.arraycopy(newvalues, 0, this.values, firstIndexToFetch, newvalues.length); + this.fetchMoreData(firstIndexToFetch, lastIndexToFetch); } - - T[] result = (T[]) Array.newInstance(javaClass, numberOfRowsToRetrieve); - System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); - return result; - } - - /** - * Maps columns values into the Java representation asynchronously. - * - * @param startIndex The first column index to retrieve - * @param endIndex The last column index to retrieve - * @param javaClass The Java class to map - * @return The column values as a Java array - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - /*public CompletableFuture<T[]> fetchColumnValuesAsync(int startIndex, int endIndex, Class<T> javaClass) throws MonetDBEmbeddedException { - return CompletableFuture.supplyAsync(() -> this.fetchColumnValues(startIndex, endIndex, javaClass)); - }*/ - - /** - * Maps the first N column values. - * - * @param n The last column index to map - * @param javaClass The Java class to map - * @return The column values as a Java array - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - public T[] fetchFirstNColumnValues(int n, Class<T> javaClass) throws MonetDBEmbeddedException { - return this.fetchColumnValues(0, n, javaClass); - } - - /** - * Maps the first N column values asynchronously. - * - * @param n The last column index to map - * @param javaClass The Java class to map - * @return The column values as a Java array - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - /*public CompletableFuture<T[]> fetchFirstNColumnValuesAsync(int n, Class<T> javaClass) throws MonetDBEmbeddedException { - return this.fetchColumnValuesAsync(0, n, javaClass); - }*/ - - /** - * Maps all column values. - * - * @param javaClass The Java class to map - * @return The column values as a Java array - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - public T[] fetchAllColumnValues(Class<T> javaClass) throws MonetDBEmbeddedException { - return this.fetchColumnValues(0, this.numberOfRows, javaClass); - } - - /** - * Maps all column values asynchronously. - * - * @param javaClass The Java class to map - * @return The column values as a Java array - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - /*public CompletableFuture<T[]> fetchAllColumnValuesAsync(Class<T> javaClass) throws MonetDBEmbeddedException { - return this.fetchColumnValuesAsync(0, this.numberOfRows, javaClass); - }*/ - - /** - * Maps columns values using the provided Java representation by the query. - * - * @param startIndex The first column index to retrieve - * @param endIndex The last column index to retrieve - * @return The column values as a Java array - * @throws MonetDBEmbeddedException If an error in the database occurred - */ - @SuppressWarnings("unchecked") - public T[] fetchColumnValues(int startIndex, int endIndex) throws MonetDBEmbeddedException { - return this.fetchColumnValues(startIndex, endIndex, (Class<T>) this.mapping.getJavaClass()); + return this.storeNewDataAndGetResult(startIndex, numberOfRowsToRetrieve); } /** @@ -242,7 +139,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[] fetchFirstNColumnValues(int n) throws MonetDBEmbeddedException { + public A fetchFirstNColumnValues(int n) throws MonetDBEmbeddedException { return this.fetchColumnValues(0, n); } @@ -263,7 +160,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[] fetchAllColumnValues() throws MonetDBEmbeddedException { + public A fetchAllColumnValues() throws MonetDBEmbeddedException { return this.fetchColumnValues(0, this.numberOfRows); } @@ -277,18 +174,53 @@ public class QueryResultSetColumn<T> ext return this.fetchColumnValuesAsync(0, this.numberOfRows); }*/ - @Override - public ListIterator<T> iterator() { - try { - return Arrays.asList(this.fetchAllColumnValues()).listIterator(); - } catch (Exception ex) { - return null; + /** + * Checks if column indexes are null + * + * @param startIndex The first column index to check + * @param endIndex The last column index to check + * @return If the index is null or not + */ + public boolean[] checkIfIndexesAreNull(int startIndex, int endIndex) throws MonetDBEmbeddedException { + if(endIndex < startIndex) { + int aux = startIndex; + startIndex = endIndex; + endIndex = aux; } + if (startIndex < 0) { + throw new ArrayIndexOutOfBoundsException("The start index must be larger than 0!"); + } else if (endIndex > this.numberOfRows) { + throw new ArrayIndexOutOfBoundsException("The index must be smaller than the number of elements in the columns!"); + } else if(startIndex == endIndex) { + throw new ArrayIndexOutOfBoundsException("Checking 0 values?"); + } + int numberOfRowsToRetrieve = endIndex - startIndex; + A values = this.fetchColumnValues(startIndex, endIndex); + boolean[] res = new boolean[numberOfRowsToRetrieve]; + return this.checkIfIndexesAreNullImplementation(values, res); } /** - * Internal implementation to fetch values from the column. + * Maps values to a Java Object array while mapping null values as well. + * + * @param startIndex The first column index to map + * @param endIndex The last column index to map + * @return The mapped Java array */ - private native T[] fetchValuesInternal(long tablePointer, int resultSetIndex, Class<T> jclass, int javaIndex, int first, int last) - throws MonetDBEmbeddedException; + public Object[] mapValuesToObjectArray(int startIndex, int endIndex) throws MonetDBEmbeddedException { + if(endIndex < startIndex) { + int aux = startIndex; + startIndex = endIndex; + endIndex = aux; + } + if (startIndex < 0) { + throw new ArrayIndexOutOfBoundsException("The start index must be larger than 0!"); + } else if (endIndex > this.numberOfRows) { + throw new ArrayIndexOutOfBoundsException("The index must be smaller than the number of elements in the columns!"); + } else if(startIndex == endIndex) { + throw new ArrayIndexOutOfBoundsException("Retrieving 0 values?"); + } + A values = this.fetchColumnValues(startIndex, endIndex); + return this.mapValuesToObjectArrayImplementation(values); + } }
--- a/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultRowSet.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultRowSet.java @@ -23,24 +23,11 @@ import java.util.ListIterator; */ public class QueryResultRowSet extends AbstractRowSet implements Iterable { - /** - * The original query result set this row set belongs. - */ - private final QueryResultSet queryResultSet; - - protected QueryResultRowSet(MonetDBToJavaMapping[] mappings, Object[][] rows, QueryResultSet queryResultSet) { - super(mappings, rows); - this.queryResultSet = queryResultSet; + protected QueryResultRowSet(QueryResultSet queryResultSet, MonetDBToJavaMapping[] mappings, Object[][] rows) { + super(queryResultSet, mappings, rows); } /** - * Gets the original query result set this row set belongs. - * - * @return The original query result set this row set belongs - */ - public QueryResultSet getQueryResultSet() { return queryResultSet; } - - /** * Gets all rows of this set. * * @return All rows of this set @@ -62,6 +49,11 @@ public class QueryResultRowSet extends A */ public MonetDBRow getSingleRow(int row) { return rows[row]; } + @Override + public int getColumnIndexByName(String columnName) { + return ((QueryResultSet) this.getQueryResultTable()).getColumnIndexByName(columnName); + } + /** * Gets a single value in this set as a Java class. * @@ -98,15 +90,8 @@ public class QueryResultRowSet extends A * @return The value mapped to a instance of the provided class */ public <T> T getSingleValueByName(int row, String columnName, Class<T> javaClass) { - String[] colNames = this.getQueryResultSet().getColumnNames(); - int index = 0; - for (String colName : colNames) { - if (columnName.equals(colName)) { - return this.getSingleValueByIndex(row, index, javaClass); - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + int index = this.getColumnIndexByName(columnName); + return this.getSingleValueByIndex(row, index, javaClass); } /** @@ -118,15 +103,8 @@ public class QueryResultRowSet extends A * @return The value mapped to a instance of the provided class */ public <T> T getSingleValueByName(int row, String columnName) { - String[] colNames = this.getQueryResultSet().getColumnNames(); - int index = 0; - for (String colName : colNames) { - if (columnName.equals(colName)) { - return this.getSingleValueByIndex(row, index); - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + int index = this.getColumnIndexByName(columnName); + return this.getSingleValueByIndex(row, index); } /** @@ -166,39 +144,25 @@ public class QueryResultRowSet extends A * Gets a column in this set as a Java class. * * @param <T> A Java class mapped to a MonetDB data type - * @param name The name of the column to retrieve + * @param columnName The name of the column to retrieve * @param javaClass The Java class * @return The value mapped to a instance of the provided class */ - public <T> T[] getColumnByName(String name, Class<T> javaClass) { - String[] colNames = this.getQueryResultSet().getColumnNames(); - int index = 0; - for (String colName : colNames) { - if (name.equals(colName)) { - return this.getColumnByIndex(index, javaClass); - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + public <T> T[] getColumnByName(String columnName, Class<T> javaClass) { + int index = this.getColumnIndexByName(columnName); + return this.getColumnByIndex(index, javaClass); } /** * Gets a column in this set as a Java class using the default mapping. * * @param <T> A Java class mapped to a MonetDB data type - * @param name The name of the column to retrieve + * @param columnName The name of the column to retrieve * @return The value mapped to a instance of the provided class */ - public <T> T[] getColumnByName(String name) { - String[] colNames = this.getQueryResultSet().getColumnNames(); - int index = 0; - for (String colName : colNames) { - if (name.equals(colName)) { - return this.getColumnByIndex(index); - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + public <T> T[] getColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return this.getColumnByIndex(index); } @Override
--- a/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSet.java +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSet.java @@ -35,15 +35,15 @@ public class QueryResultSet extends Abst /** * The query result set columns listing. */ - private final QueryResultSetColumn<?>[] columns; + private final AbstractQueryResultSetColumn<?>[] columns; /** * The number of rows in the query result. */ protected final int numberOfRows; - protected QueryResultSet(MonetDBEmbeddedConnection connection, long tablePointer, QueryResultSetColumn<?>[] columns, - int numberOfRows) { + protected QueryResultSet(MonetDBEmbeddedConnection connection, long tablePointer, + AbstractQueryResultSetColumn<?>[] columns, int numberOfRows) { super(connection); this.tablePointer = tablePointer; this.numberOfRows = numberOfRows; @@ -63,7 +63,7 @@ public class QueryResultSet extends Abst public String[] getColumnNames() { int i = 0; String[] result = new String[this.getNumberOfColumns()]; - for(QueryResultSetColumn col : this.columns) { + for(AbstractQueryResultSetColumn col : this.columns) { result[i] = col.getColumnName(); } return result; @@ -73,7 +73,7 @@ public class QueryResultSet extends Abst public String[] getColumnTypes() { int i = 0; String[] result = new String[this.getNumberOfColumns()]; - for(QueryResultSetColumn col : this.columns) { + for(AbstractQueryResultSetColumn col : this.columns) { result[i] = col.getColumnInternalTypeName(); } return result; @@ -83,7 +83,7 @@ public class QueryResultSet extends Abst public MonetDBToJavaMapping[] getMappings() { int i = 0; MonetDBToJavaMapping[] result = new MonetDBToJavaMapping[this.getNumberOfColumns()]; - for(QueryResultSetColumn col : this.columns) { + for(AbstractQueryResultSetColumn col : this.columns) { result[i] = col.getMapping(); } return result; @@ -93,7 +93,7 @@ public class QueryResultSet extends Abst public int[] getColumnDigits() { int i = 0; int[] result = new int[this.getNumberOfColumns()]; - for(QueryResultSetColumn col : this.columns) { + for(AbstractQueryResultSetColumn col : this.columns) { result[i] = col.getColumnDigits(); } return result; @@ -103,7 +103,7 @@ public class QueryResultSet extends Abst public int[] getColumnScales() { int i = 0; int[] result = new int[this.getNumberOfColumns()]; - for(QueryResultSetColumn col : this.columns) { + for(AbstractQueryResultSetColumn col : this.columns) { result[i] = col.getColumnScale(); } return result; @@ -117,30 +117,213 @@ public class QueryResultSet extends Abst public boolean isStatementClosed() { return this.tablePointer == 0; } /** + * Gets a column index from the result set by name + * + * @param columnName AbstractQueryResultSetColumn name + * @return The index number + */ + public int getColumnIndexByName(String columnName) { + int index = 0; + for (AbstractQueryResultSetColumn col : this.columns) { + if (col.getColumnName().equals(columnName)) { + return index; + } + index++; + } + throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + } + + /** * Gets a column from the result set by index. * - * @param index QueryResultSetColumn index (starting from 0) + * @param index AbstractQueryResultSetColumn index (starting from 0) * @return The column */ - @SuppressWarnings("unchecked") - public <T> QueryResultSetColumn<T> getColumnByIndex(int index) { return (QueryResultSetColumn<T>) columns[index]; } + protected AbstractQueryResultSetColumn<?> getColumnByIndex(int index) { + return this.columns[index]; + } /** * Gets a column from the result set by name. * - * @param name QueryResultSetColumn name + * @param columnName AbstractQueryResultSetColumn name * @return The column */ + protected AbstractQueryResultSetColumn<?> getColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return this.columns[index]; + } + + /** + * Gets a boolean column from the result set by index. + * + * @param index QueryResultSetBooleanColumn index (starting from 0) + * @return The boolean column + */ + public QueryResultSetBooleanColumn getBooleanColumnByIndex(int index) { + return (QueryResultSetBooleanColumn) this.columns[index]; + } + + /** + * Gets a boolean column from the result set by name. + * + * @param columnName QueryResultSetBooleanColumn name + * @return The boolean column + */ + public QueryResultSetBooleanColumn getBooleanColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetBooleanColumn) this.columns[index]; + } + + /** + * Gets a byte column from the result set by index. + * + * @param index QueryResultSetByteColumn index (starting from 0) + * @return The byte column + */ + public QueryResultSetByteColumn getByteColumnByIndex(int index) { + return (QueryResultSetByteColumn) this.columns[index]; + } + + /** + * Gets a byte column from the result set by name. + * + * @param columnName QueryResultSetByteColumn name + * @return The byte column + */ + public QueryResultSetByteColumn getByteColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetByteColumn) this.columns[index]; + } + + /** + * Gets a short column from the result set by index. + * + * @param index QueryResultSetShortColumn index (starting from 0) + * @return The short column + */ + public QueryResultSetShortColumn getShortColumnByIndex(int index) { + return (QueryResultSetShortColumn) this.columns[index]; + } + + /** + * Gets a short column from the result set by name. + * + * @param columnName QueryResultSetShortColumn name + * @return The short column + */ + public QueryResultSetShortColumn getShortColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetShortColumn) this.columns[index]; + } + + /** + * Gets a int column from the result set by index. + * + * @param index QueryResultSetIntColumn index (starting from 0) + * @return The int column + */ + public QueryResultSetIntColumn getIntColumnByIndex(int index) { + return (QueryResultSetIntColumn) this.columns[index]; + } + + /** + * Gets a int column from the result set by name. + * + * @param columnName QueryResultSetIntColumn name + * @return The int column + */ + public QueryResultSetIntColumn getIntColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetIntColumn) this.columns[index]; + } + + /** + * Gets a long column from the result set by index. + * + * @param index QueryResultSetLongColumn index (starting from 0) + * @return The long column + */ + public QueryResultSetLongColumn getLongColumnByIndex(int index) { + return (QueryResultSetLongColumn) this.columns[index]; + } + + /** + * Gets a long column from the result set by name. + * + * @param columnName QueryResultSetLongColumn name + * @return The long column + */ + public QueryResultSetLongColumn getLongColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetLongColumn) this.columns[index]; + } + + /** + * Gets a float column from the result set by index. + * + * @param index QueryResultSetFloatColumn index (starting from 0) + * @return The float column + */ + public QueryResultSetFloatColumn getFloatColumnByIndex(int index) { + return (QueryResultSetFloatColumn) this.columns[index]; + } + + /** + * Gets a float column from the result set by name. + * + * @param columnName QueryResultSetFloatColumn name + * @return The float column + */ + public QueryResultSetFloatColumn getFloatColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetFloatColumn) this.columns[index]; + } + + /** + * Gets a double column from the result set by index. + * + * @param index QueryResultSetDoubleColumn index (starting from 0) + * @return The double column + */ + public QueryResultSetDoubleColumn getDoubleColumnByIndex(int index) { + return (QueryResultSetDoubleColumn) this.columns[index]; + } + + /** + * Gets a double column from the result set by name. + * + * @param columnName QueryResultSetDoubleColumn name + * @return The double column + */ + public QueryResultSetDoubleColumn getDoubleColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetDoubleColumn) this.columns[index]; + } + + /** + * Gets an object column from the result set by index. + * + * @param <T> The Java class of the mapped MonetDB column + * @param index QueryResultSetObjectColumn index (starting from 0) + * @return The object column + */ @SuppressWarnings("unchecked") - public <T> QueryResultSetColumn<T> getColumnByName(String name) { - int index = 0; - for (QueryResultSetColumn col : this.columns) { - if (col.getColumnName().equals(name)) { - return (QueryResultSetColumn<T>) this.columns[index]; - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + public <T> QueryResultSetObjectColumn<T> getObjectColumnByIndex(int index) { + return (QueryResultSetObjectColumn<T>) this.columns[index]; + } + + /** + * Gets an object column from the result set by name. + * + * @param <T> The Java class of the mapped MonetDB column + * @param columnName QueryResultSetObjectColumn name + * @return The object column + */ + @SuppressWarnings("unchecked") + public <T> QueryResultSetObjectColumn<T> getObjectColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return (QueryResultSetObjectColumn<T>) this.columns[index]; } /** @@ -167,12 +350,12 @@ public class QueryResultSet extends Abst int numberOfRowsToRetrieve = endIndex - startIndex; Object[][] temp = new Object[numberOfRowsToRetrieve][this.getNumberOfColumns()]; for (int i = 0 ; i < this.getNumberOfColumns(); i++) { - Object[] nextColumn = this.columns[i].fetchColumnValues(startIndex, endIndex); - for(int j = 0; j < numberOfRowsToRetrieve ; j++) { + Object[] nextColumn = this.columns[i].mapValuesToObjectArray(startIndex, endIndex); + for(int j = 0; j < numberOfRowsToRetrieve; j++) { temp[j][i] = nextColumn[j]; } } - return new QueryResultRowSet(this.getMappings(), temp, this); + return new QueryResultRowSet(this, this.getMappings(), temp); } /**
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetBooleanColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java boolean values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetBooleanColumn extends AbstractQueryResultSetColumn<boolean[]> { + + /** + * MonetDB's boolean null constant. + */ + private static boolean BooleanNullConstant; + + /** + * Gets MonetDB's boolean null constant + * + * @return MonetDB's boolean null constant + */ + public static boolean GetBooleanNullConstant() { return BooleanNullConstant; } + + /** + * Array with the retrieved values. + */ + private final boolean[] values; + + protected QueryResultSetBooleanColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Boolean.class)) { + throw new ClassCastException("The parameter must be of boolean type!!"); + } + this.values = new boolean[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + boolean[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected boolean[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + boolean[] result = new boolean[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(boolean[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == BooleanNullConstant); + } + return res; + } + + @Override + protected Boolean[] mapValuesToObjectArrayImplementation(boolean[] values) throws MonetDBEmbeddedException { + Boolean[] res = new Boolean[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == BooleanNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native boolean[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetByteColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java byte values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetByteColumn extends AbstractQueryResultSetColumn<byte[]> { + + /** + * MonetDB's byte null constant. + */ + private static byte ByteNullConstant; + + /** + * Gets MonetDB's byte null constant + * + * @return MonetDB's byte null constant + */ + public static byte GetByteNullConstant() { return ByteNullConstant; } + + /** + * Array with the retrieved values. + */ + private final byte[] values; + + protected QueryResultSetByteColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Byte.class)) { + throw new ClassCastException("The parameter must be of byte type!!"); + } + this.values = new byte[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + byte[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected byte[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + byte[] result = new byte[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(byte[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == ByteNullConstant); + } + return res; + } + + @Override + protected Byte[] mapValuesToObjectArrayImplementation(byte[] values) throws MonetDBEmbeddedException { + Byte[] res = new Byte[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == ByteNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native byte[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetDoubleColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java double values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetDoubleColumn extends AbstractQueryResultSetColumn<double[]> { + + /** + * MonetDB's double null constant. + */ + private static double DoubleNullConstant; + + /** + * Gets MonetDB's double null constant + * + * @return MonetDB's double null constant + */ + public static double GetDoubleNullConstant() { return DoubleNullConstant; } + + /** + * Array with the retrieved values. + */ + private final double[] values; + + protected QueryResultSetDoubleColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Double.class)) { + throw new ClassCastException("The parameter must be of boolean type!!"); + } + this.values = new double[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + double[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected double[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + double[] result = new double[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(double[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == DoubleNullConstant); + } + return res; + } + + @Override + protected Double[] mapValuesToObjectArrayImplementation(double[] values) throws MonetDBEmbeddedException { + Double[] res = new Double[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == DoubleNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native double[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetFloatColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java float values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetFloatColumn extends AbstractQueryResultSetColumn<float[]> { + + /** + * MonetDB's float null constant. + */ + private static float FloatNullConstant; + + /** + * Gets MonetDB's float null constant + * + * @return MonetDB's float null constant + */ + public static float GetFloatNullConstant() { return FloatNullConstant; } + + /** + * Array with the retrieved values. + */ + private final float[] values; + + protected QueryResultSetFloatColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Float.class)) { + throw new ClassCastException("The parameter must be of boolean type!!"); + } + this.values = new float[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + float[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected float[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + float[] result = new float[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(float[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == FloatNullConstant); + } + return res; + } + + @Override + protected Float[] mapValuesToObjectArrayImplementation(float[] values) throws MonetDBEmbeddedException { + Float[] res = new Float[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == FloatNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native float[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetIntColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java integer values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetIntColumn extends AbstractQueryResultSetColumn<int[]> { + + /** + * MonetDB's int null constant. + */ + private static int IntNullConstant; + + /** + * Gets MonetDB's int null constant + * + * @return MonetDB's int null constant + */ + public static int GetIntNullConstant() { return IntNullConstant; } + + /** + * Array with the retrieved values. + */ + private final int[] values; + + protected QueryResultSetIntColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Integer.class)) { + throw new ClassCastException("The parameter must be of integer type!!"); + } + this.values = new int[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + int[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected int[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + int[] result = new int[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(int[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == IntNullConstant); + } + return res; + } + + @Override + protected Integer[] mapValuesToObjectArrayImplementation(int[] values) throws MonetDBEmbeddedException { + Integer[] res = new Integer[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == IntNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native int[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetLongColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java long values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetLongColumn extends AbstractQueryResultSetColumn<long[]> { + + /** + * MonetDB's long null constant. + */ + private static long LongNullConstant; + + /** + * Gets MonetDB's long null constant + * + * @return MonetDB's long null constant + */ + public static long GetIntegerNullConstant() { return LongNullConstant; } + + /** + * Array with the retrieved values. + */ + private final long[] values; + + protected QueryResultSetLongColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Long.class)) { + throw new ClassCastException("The parameter must be of boolean type!!"); + } + this.values = new long[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + long[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected long[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + long[] result = new long[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(long[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == LongNullConstant); + } + return res; + } + + @Override + protected Long[] mapValuesToObjectArrayImplementation(long[] values) throws MonetDBEmbeddedException { + Long[] res = new Long[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == LongNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native long[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetObjectColumn.java @@ -0,0 +1,80 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.ListIterator; + +/** + * A MonetDB column converted to an array of Java objects. + * + * @param <T> The Java class of the mapped MonetDB column + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetObjectColumn<T> extends AbstractQueryResultSetColumn<T[]> implements Iterable<T> { + + /** + * Array with the retrieved values. + */ + private final T[] values; + + @SuppressWarnings("unchecked") + public QueryResultSetObjectColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + this.values = (T[]) Array.newInstance(this.mapping.getJavaClass(), numberOfRows); + } + + @Override + @SuppressWarnings("unchecked") + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + T[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, + (Class<T>) this.mapping.getJavaClass(), this.mapping.ordinal(), startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + @SuppressWarnings("unchecked") + protected T[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + T[] result = (T[]) Array.newInstance(this.mapping.getJavaClass(), numberOfRowsToRetrieve); + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(T[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == null); + } + return res; + } + + @Override + protected T[] mapValuesToObjectArrayImplementation(T[] values) throws MonetDBEmbeddedException { + return values; + } + + @Override + public ListIterator<T> iterator() { + try { + return Arrays.asList(this.fetchAllColumnValues()).listIterator(); + } catch (Exception ex) { + return null; + } + } + + /** + * Internal implementation to fetch values from the column. + */ + private native T[] fetchValuesInternal(long tablePointer, int resultSetIndex, Class<T> jClass, int javaIndex, + int startIndex, int endIndex) throws MonetDBEmbeddedException; +}
new file mode 100644 --- /dev/null +++ b/src/main/java/nl/cwi/monetdb/embedded/resultset/QueryResultSetShortColumn.java @@ -0,0 +1,81 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + +package nl.cwi.monetdb.embedded.resultset; + +import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; + +/** + * A MonetDB column converted to an array of Java short values. + * + * @author <a href="mailto:pedro.ferreira@monetdbsolutions.com">Pedro Ferreira</a> + */ +public class QueryResultSetShortColumn extends AbstractQueryResultSetColumn<short[]> { + + /** + * MonetDB's short null constant. + */ + private static long ShortNullConstant; + + /** + * Gets MonetDB's short null constant + * + * @return MonetDB's short null constant + */ + public static long GetShortNullConstant() { return ShortNullConstant; } + + /** + * Array with the retrieved values. + */ + private final short[] values; + + protected QueryResultSetShortColumn(String columnType, long tablePointer, int resultSetIndex, String columnName, + int columnDigits, int columnScale, int numberOfRows) { + super(columnType, tablePointer, resultSetIndex, columnName, columnDigits, columnScale, numberOfRows); + if(!this.getMapping().getJavaClass().equals(Short.class)) { + throw new ClassCastException("The parameter must be of boolean type!!"); + } + this.values = new short[numberOfRows]; + } + + @Override + protected void fetchMoreData(int startIndex, int endIndex) throws MonetDBEmbeddedException { + short[] values = this.fetchValuesInternal(this.tablePointer, this.resultSetIndex, startIndex, endIndex); + System.arraycopy(values, 0, this.values, startIndex, values.length); + } + + @Override + protected short[] storeNewDataAndGetResult(int startIndex, int numberOfRowsToRetrieve) { + short[] result = new short[numberOfRowsToRetrieve]; + System.arraycopy(this.values, startIndex, result, 0, numberOfRowsToRetrieve); + return result; + } + + @Override + protected boolean[] checkIfIndexesAreNullImplementation(short[] values, boolean[] res) throws MonetDBEmbeddedException { + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == ShortNullConstant); + } + return res; + } + + @Override + protected Short[] mapValuesToObjectArrayImplementation(short[] values) throws MonetDBEmbeddedException { + Short[] res = new Short[values.length]; + for(int i = 0 ; i < values.length ; i++) { + res[i] = (values[i] == ShortNullConstant) ? null : values[i]; + } + return res; + } + + /** + * Internal implementation to fetch values from the column. + */ + private native short[] fetchValuesInternal(long tablePointer, int resultSetIndex, int startIndex, int endIndex) + throws MonetDBEmbeddedException; +}
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTable.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.tables; import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException; @@ -6,7 +14,7 @@ import nl.cwi.monetdb.embedded.env.Monet import nl.cwi.monetdb.embedded.mapping.MonetDBRow; import nl.cwi.monetdb.embedded.mapping.MonetDBToJavaMapping; import nl.cwi.monetdb.embedded.resultset.QueryResultSet; -import nl.cwi.monetdb.embedded.resultset.QueryResultSetColumn; +import nl.cwi.monetdb.embedded.resultset.QueryResultSetLongColumn; /** * Java representation of a MonetDB table. It's possible to perform several CRUD operations using the respective @@ -40,8 +48,8 @@ public class MonetDBTable extends Abstra try { String query = "SELECT COUNT(*) FROM " + this.getTableSchema() + "." + this.getTableName() + ";"; QueryResultSet eqr = this.getConnection().sendQuery(query); - QueryResultSetColumn<Long> eqc = eqr.getColumnByIndex(0); - res = eqc.fetchFirstNColumnValues(1)[0].intValue(); + QueryResultSetLongColumn eqc = eqr.getLongColumnByIndex(0); + res = (int) eqc.fetchFirstNColumnValues(1)[0]; eqr.close(); } catch (MonetDBEmbeddedException ex) { res = -1;
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTableColumn.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/MonetDBTableColumn.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.tables; import nl.cwi.monetdb.embedded.mapping.AbstractColumn; @@ -9,35 +17,23 @@ import nl.cwi.monetdb.embedded.mapping.A */ public class MonetDBTableColumn extends AbstractColumn { - private final String columnName; - - private final int columnDigits; - - private final int columnScale; - + /** + * If the column has a default value. + */ private final String defaultValue; + /** + * If the column is Nullable. + */ private final boolean isNullable; protected MonetDBTableColumn(String columnType, String columnName, int columnDigits, int columnScale, String defaultValue, boolean isNullable) { - super(columnType); - this.columnName = columnName; - this.columnDigits = columnDigits; - this.columnScale = columnScale; + super(columnType, columnName, columnDigits, columnScale); this.defaultValue = defaultValue; this.isNullable = isNullable; } - @Override - public String getColumnName() { return this.columnName; } - - @Override - public int getColumnDigits() { return this.columnDigits; } - - @Override - public int getColumnScale() { return this.columnScale; } - /** * Get the default value if there is one, or null if none. *
--- a/src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java +++ b/src/main/java/nl/cwi/monetdb/embedded/tables/RowIterator.java @@ -1,3 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016 MonetDB B.V. + */ + package nl.cwi.monetdb.embedded.tables; import nl.cwi.monetdb.embedded.mapping.AbstractRowSet; @@ -12,11 +20,6 @@ import nl.cwi.monetdb.embedded.mapping.M public class RowIterator extends AbstractRowSet { /** - * The original table of this iterator. - */ - protected final MonetDBTable table; - - /** * The current table row number on the fetched set. */ protected int currentIterationNumber; @@ -32,19 +35,31 @@ public class RowIterator extends Abstrac protected final int lastIndex; protected RowIterator(MonetDBTable table, Object[][] rows, int firstIndex, int lastIndex) { - super(table.getMappings(), rows); - this.table = table; + super(table, table.getMappings(), rows); this.firstIndex = firstIndex; this.lastIndex = lastIndex; this.currentIterationNumber = -1; } + @Override + public int getColumnIndexByName(String columnName) { + String[] columnNames = this.getTable().getColumnNames(); + int index = 0; + for (String colName : columnNames) { + if (columnName.equals(colName)) { + return this.getColumnByIndex(index); + } + index++; + } + throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + } + /** * Gets the original table of this iterator. * * @return The original table of this iterator */ - public MonetDBTable getTable() { return table; } + public MonetDBTable getTable() { return (MonetDBTable) this.getQueryResultTable(); } /** * Gets the first index used on this iteration. @@ -116,39 +131,25 @@ public class RowIterator extends Abstrac * Gets a column value as a Java class. * * @param <T> A Java class mapped to a MonetDB data type - * @param name The name of the column + * @param columnName The name of the column * @param javaClass The Java class * @return The column value as a Java class */ - public <T> T getColumnByName(String name, Class<T> javaClass) { - String[] colNames = this.getTable().getColumnNames(); - int index = 0; - for (String colName : colNames) { - if (name.equals(colName)) { - return this.getColumnByIndex(index, javaClass); - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + public <T> T getColumnByName(String columnName, Class<T> javaClass) { + int index = this.getColumnIndexByName(columnName); + return this.getColumnByIndex(index, javaClass); } /** * Gets a column value as a Java class using the default mapping. * * @param <T> A Java class mapped to a MonetDB data type - * @param name The name of the column + * @param columnName The name of the column * @return The column value as a Java class */ - public <T> T getColumnByName(String name) { - String[] colNames = this.getTable().getColumnNames(); - int index = 0; - for (String colName : colNames) { - if (name.equals(colName)) { - return this.getColumnByIndex(index); - } - index++; - } - throw new ArrayIndexOutOfBoundsException("The column is not present in the result set!"); + public <T> T getColumnByName(String columnName) { + int index = this.getColumnIndexByName(columnName); + return this.getColumnByIndex(index); } /**