You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2010/08/28 00:29:36 UTC
svn commit: r990290 - in /pivot/trunk:
core/src/org/apache/pivot/collections/ArrayAdapter.java
core/src/org/apache/pivot/sql/ResultList.java
tests/src/org/apache/pivot/tests/sql/ResultListTest.java
Author: gbrown
Date: Fri Aug 27 22:29:36 2010
New Revision: 990290
URL: http://svn.apache.org/viewvc?rev=990290&view=rev
Log:
Optimize ResultList performance; add org.apache.pivot.collections.ArrayAdapter class.
Added:
pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java
Modified:
pivot/trunk/core/src/org/apache/pivot/sql/ResultList.java
pivot/trunk/tests/src/org/apache/pivot/tests/sql/ResultListTest.java
Added: pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java?rev=990290&view=auto
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java (added)
+++ pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java Fri Aug 27 22:29:36 2010
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.collections;
+
+import org.apache.pivot.collections.Sequence;
+
+/**
+ * Implementation of the {@link Sequence} interface that wraps an array.
+ */
+public class ArrayAdapter<T> implements Sequence<T> {
+ private T[] array;
+
+ public ArrayAdapter(T[] array) {
+ if (array == null) {
+ throw new IllegalArgumentException();
+ }
+
+ this.array = array;
+ }
+
+ @Override
+ public int add(T item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void insert(T item, int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public T update(int index, T item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int remove(T item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Sequence<T> remove(int index, int count) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public T get(int index) {
+ return array[index];
+ }
+
+ @Override
+ public int indexOf(T item) {
+ int index = 0;
+
+ while (index < array.length) {
+ if (item == null) {
+ if (array[index] == null) {
+ break;
+ }
+ } else {
+ if (item.equals(array[index])) {
+ break;
+ }
+ }
+
+ index++;
+ }
+
+ if (index == array.length) {
+ index = -1;
+ }
+
+ return index;
+ }
+
+ @Override
+ public int getLength() {
+ return array.length;
+ }
+}
Modified: pivot/trunk/core/src/org/apache/pivot/sql/ResultList.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/sql/ResultList.java?rev=990290&r1=990289&r2=990290&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/sql/ResultList.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/sql/ResultList.java Fri Aug 27 22:29:36 2010
@@ -20,9 +20,11 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Comparator;
import java.util.Date;
+import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.ArrayAdapter;
import org.apache.pivot.collections.HashMap;
import org.apache.pivot.collections.List;
import org.apache.pivot.collections.ListListener;
@@ -31,334 +33,250 @@ import org.apache.pivot.collections.Sequ
import org.apache.pivot.util.ListenerList;
/**
- * Implementation of the {@link List} interface that is backed by a
- * instance of {@link java.sql.ResultSet}.
- * <p>
- * Note that this list is not suitable for random access and can only be
- * navigated via an iterator.
- */
+* Implementation of the {@link List} interface that is backed by a
+* instance of {@link java.sql.ResultSet}.
+* <p>
+* Note that this list is not suitable for random access and can only be
+* navigated via an iterator.
+*/
public class ResultList implements List<Map<String, Object>> {
- /**
- * Class that maps a result set column to a map key/value pair.
- */
- public static final class Field {
- /**
- * The source column name.
- */
- public final String columnName;
-
- /**
- * The name of the map key. If <tt>null</tt>, the column name will be used.
- */
- public final String key;
-
- /**
- * The type of the map value. If <tt>null</tt>, the default SQL type will be used.
- */
- public final Class<?> type;
-
- public Field(String columnName) {
- this(columnName, null, null);
- }
-
- public Field(String columnName, String key) {
- this(columnName, key, null);
- }
-
- public Field(String columnName, String key, Class<?> type) {
- this.columnName = columnName;
- this.key = key;
- this.type = type;
- }
- }
-
- private class ResultListItemIterator implements ItemIterator<Map<String, Object>> {
- @Override
- public boolean hasNext() {
- boolean hasNext;
-
- try {
- hasNext = resultSet.isBeforeFirst()
- || (resultSet.getRow() > 0 && !resultSet.isLast());
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
-
- return hasNext;
- }
-
- @Override
- public Map<String, Object> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
-
- try {
- resultSet.next();
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
-
- return current();
- }
-
- @Override
- public boolean hasPrevious() {
- boolean hasPrevious;
-
- try {
- hasPrevious = resultSet.isAfterLast()
- || (resultSet.getRow() > 0 && !resultSet.isFirst());
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
-
- return hasPrevious;
- }
-
- @Override
- public Map<String, Object> previous() {
- if (!hasPrevious()) {
- throw new NoSuchElementException();
- }
-
- try {
- resultSet.previous();
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
-
- return current();
- }
-
- private Map<String, Object> current() {
- HashMap<String, Object> current = new HashMap<String, Object>();
-
- try {
- for (Field field : fields) {
- Object value;
-
- if (field.type == Boolean.class
- || field.type == Boolean.TYPE) {
- value = resultSet.getBoolean(field.columnName);
- } else if (field.type == Byte.class
- || field.type == Byte.TYPE) {
- value = resultSet.getByte(field.columnName);
- } else if (field.type == Short.class
- || field.type == Short.TYPE) {
- value = resultSet.getShort(field.columnName);
- } else if (field.type == Integer.class
- || field.type == Integer.TYPE) {
- value = resultSet.getInt(field.columnName);
- } else if (field.type == Long.class
- || field.type == Long.TYPE) {
- value = resultSet.getLong(field.columnName);
- } else if (field.type == Float.class
- || field.type == Float.TYPE) {
- value = resultSet.getFloat(field.columnName);
- } else if (field.type == Double.class
- || field.type == Double.TYPE) {
- value = resultSet.getDouble(field.columnName);
- } else if (field.type == String.class) {
- value = resultSet.getString(field.columnName);
- } else if (field.type == Date.class) {
- value = resultSet.getDate(field.columnName);
- } else {
- value = resultSet.getObject(field.columnName);
- }
-
- if (resultSet.wasNull()) {
- value = null;
- }
-
- if (value != null || includeNullValues) {
- String key = (field.key == null) ? field.columnName : field.key;
- current.put(key, value);
- }
- }
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
-
- return current;
- }
-
- @Override
- public void toStart() {
- try {
- resultSet.beforeFirst();
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
- }
-
- @Override
- public void toEnd() {
- try {
- resultSet.afterLast();
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
- }
-
- @Override
- public void insert(Map<String, Object> item) {
- // TODO
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void update(Map<String, Object> item) {
- // TODO
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove() {
- try {
- resultSet.deleteRow();
- } catch (SQLException exception) {
- throw new RuntimeException(exception);
- }
- }
- }
-
- private ResultSet resultSet;
- private boolean includeNullValues;
- private ArrayList<Field> fields;
-
- private ListListenerList<Map<String, Object>> listListeners =
- new ListListenerList<Map<String,Object>>();
-
- public ResultList(ResultSet resultSet, Field... fields) {
- this(resultSet, false, new ArrayList<Field>(fields));
- }
-
- public ResultList(ResultSet resultSet, boolean includeNullValues, Field... fields) {
- this(resultSet, includeNullValues, new ArrayList<Field>(fields));
- }
-
- public ResultList(ResultSet resultSet, Sequence<Field> fields) {
- this(resultSet, false, new ArrayList<Field>(fields));
- }
-
- public ResultList(ResultSet resultSet, boolean includeNullValues, Sequence<Field> fields) {
- this(resultSet, includeNullValues, new ArrayList<Field>(fields));
- }
-
- private ResultList(ResultSet resultSet, boolean includeNullValues, ArrayList<Field> fields) {
- if (resultSet == null) {
- throw new IllegalArgumentException();
- }
-
- for (Field field : fields) {
- if (field.columnName == null) {
- throw new IllegalArgumentException("columnName is required.");
- }
-
- if (!(field.type == null
- || field.type == Boolean.class
- || field.type == Boolean.TYPE
- || field.type == Byte.class
- || field.type == Byte.TYPE
- || field.type == Short.class
- || field.type == Short.TYPE
- || field.type == Integer.class
- || field.type == Integer.TYPE
- || field.type == Long.class
- || field.type == Long.TYPE
- || field.type == Float.class
- || field.type == Float.TYPE
- || field.type == Double.class
- || field.type == Double.TYPE
- || field.type == Date.class
- || field.type == String.class)) {
- throw new IllegalArgumentException(field.type.getName()
- + " is not a supported type.");
- }
- }
-
- this.resultSet = resultSet;
- this.includeNullValues = includeNullValues;
- this.fields = fields;
- }
-
-
- public Field getField(int index) {
- return fields.get(index);
- }
-
- public int getFieldCount() {
- return fields.getLength();
- }
-
- @Override
- public int add(Map<String, Object> item) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void insert(Map<String, Object> item, int index) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Map<String, Object> update(int index, Map<String, Object> item) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int remove(Map<String, Object> item) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Sequence<Map<String, Object>> remove(int index, int count) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Map<String, Object> get(int index) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int indexOf(Map<String, Object> item) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isEmpty() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getLength() {
- return -1;
- }
-
- @Override
- public Comparator<Map<String, Object>> getComparator() {
- return null;
- }
-
- @Override
- public void setComparator(Comparator<Map<String, Object>> comparator) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ItemIterator<Map<String, Object>> iterator() {
- return new ResultListItemIterator();
- }
-
- @Override
- public ListenerList<ListListener<Map<String, Object>>> getListListeners() {
- return listListeners;
- }
+ /**
+ * Class that maps a result set column to a map key/value pair.
+ */
+ public static final class Field {
+ /**
+ * The source column name.
+ */
+ public final String columnName;
+
+ /**
+ * The name of the map key. If <tt>null</tt>, the column name will be used.
+ */
+ public final String key;
+
+ /**
+ * The type of the map value. If <tt>null</tt>, the default SQL type will be used.
+ */
+ public final Class<?> type;
+
+ public Field(String columnName) {
+ this(columnName, null, null);
+ }
+
+ public Field(String columnName, String key) {
+ this(columnName, key, null);
+ }
+
+ public Field(String columnName, String key, Class<?> type) {
+ if (columnName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (!(type == null
+ || type == Boolean.class
+ || type == Boolean.TYPE
+ || type == Byte.class
+ || type == Byte.TYPE
+ || type == Short.class
+ || type == Short.TYPE
+ || type == Integer.class
+ || type == Integer.TYPE
+ || type == Long.class
+ || type == Long.TYPE
+ || type == Float.class
+ || type == Float.TYPE
+ || type == Double.class
+ || type == Double.TYPE
+ || type == Date.class
+ || type == String.class)) {
+ throw new IllegalArgumentException(type.getName() + " is not a supported type.");
+ }
+
+ this.columnName = columnName;
+ this.key = key;
+ this.type = type;
+ }
+ }
+
+ private class ResultListItemIterator implements Iterator<Map<String, Object>> {
+ private boolean hasNext = true;
+ private boolean moveNext = true;
+
+ @Override
+ public boolean hasNext() {
+ if (hasNext
+ && moveNext) {
+ try {
+ hasNext = resultSet.next();
+ moveNext = false;
+ } catch (SQLException exception) {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ return hasNext;
+ }
+
+ @Override
+ public Map<String, Object> next() {
+ if (!hasNext) {
+ throw new NoSuchElementException();
+ }
+
+ HashMap<String, Object> item = new HashMap<String, Object>();
+
+ try {
+ for (Field field : fields) {
+ Object value;
+
+ if (field.type == Boolean.class
+ || field.type == Boolean.TYPE) {
+ value = resultSet.getBoolean(field.columnName);
+ } else if (field.type == Byte.class
+ || field.type == Byte.TYPE) {
+ value = resultSet.getByte(field.columnName);
+ } else if (field.type == Short.class
+ || field.type == Short.TYPE) {
+ value = resultSet.getShort(field.columnName);
+ } else if (field.type == Integer.class
+ || field.type == Integer.TYPE) {
+ value = resultSet.getInt(field.columnName);
+ } else if (field.type == Long.class
+ || field.type == Long.TYPE) {
+ value = resultSet.getLong(field.columnName);
+ } else if (field.type == Float.class
+ || field.type == Float.TYPE) {
+ value = resultSet.getFloat(field.columnName);
+ } else if (field.type == Double.class
+ || field.type == Double.TYPE) {
+ value = resultSet.getDouble(field.columnName);
+ } else if (field.type == String.class) {
+ value = resultSet.getString(field.columnName);
+ } else if (field.type == Date.class) {
+ value = resultSet.getDate(field.columnName);
+ } else {
+ value = resultSet.getObject(field.columnName);
+ }
+
+ if (resultSet.wasNull()) {
+ value = null;
+ }
+
+ item.put((field.key == null) ? field.columnName : field.key, value);
+ }
+ } catch (SQLException exception) {
+ throw new RuntimeException(exception);
+ }
+
+ moveNext = true;
+
+ return item;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private ResultSet resultSet;
+ private ArrayList<Field> fields;
+
+ private ListListenerList<Map<String, Object>> listListeners = new ListListenerList<Map<String,Object>>();
+
+ public ResultList(ResultSet resultSet, Field... fields) {
+ this(resultSet, new ArrayAdapter<Field>(fields));
+ }
+
+ public ResultList(ResultSet resultSet, Sequence<Field> fields) {
+ if (resultSet == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (fields == null) {
+ throw new IllegalArgumentException();
+ }
+
+ this.resultSet = resultSet;
+ this.fields = new ArrayList<Field>(fields);
+ }
+
+
+ public Field getField(int index) {
+ return fields.get(index);
+ }
+
+ public int getFieldCount() {
+ return fields.getLength();
+ }
+
+ @Override
+ public int add(Map<String, Object> item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void insert(Map<String, Object> item, int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, Object> update(int index, Map<String, Object> item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int remove(Map<String, Object> item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Sequence<Map<String, Object>> remove(int index, int count) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, Object> get(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int indexOf(Map<String, Object> item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getLength() {
+ return -1;
+ }
+
+ @Override
+ public Comparator<Map<String, Object>> getComparator() {
+ return null;
+ }
+
+ @Override
+ public void setComparator(Comparator<Map<String, Object>> comparator) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Iterator<Map<String, Object>> iterator() {
+ return new ResultListItemIterator();
+ }
+
+ @Override
+ public ListenerList<ListListener<Map<String, Object>>> getListListeners() {
+ return listListeners;
+ }
}
Modified: pivot/trunk/tests/src/org/apache/pivot/tests/sql/ResultListTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/sql/ResultListTest.java?rev=990290&r1=990289&r2=990290&view=diff
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/sql/ResultListTest.java (original)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/sql/ResultListTest.java Fri Aug 27 22:29:36 2010
@@ -20,8 +20,8 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
+import java.util.Iterator;
-import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Map;
import org.apache.pivot.json.JSONSerializer;
import org.apache.pivot.sql.ResultList;
@@ -73,14 +73,10 @@ public class ResultListTest {
new ResultList.Field("s"),
new ResultList.Field("b"));
- List.ItemIterator<Map<String, Object>> iterator = resultList.iterator();
+ Iterator<Map<String, Object>> iterator = resultList.iterator();
while (iterator.hasNext()) {
out.println(JSONSerializer.toString(iterator.next()));
}
-
- while(iterator.hasPrevious()) {
- out.println(JSONSerializer.toString(iterator.previous()));
- }
} finally {
if (connection != null) {
connection.close();