X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fyaz4j%2FResultSet.java;h=b2fd11958beb65d303f0ceef91cf1afcf7cfa3e3;hb=8c7413fbaf0870975229e8e101f79096b5dfe6f0;hp=fad095c019f0836f70575f46bc5639fded42f990;hpb=2def7bc64faa1dfb9f3393f2c2ef0bca0c6265e1;p=yaz4j-moved-to-github.git diff --git a/src/main/java/org/yaz4j/ResultSet.java b/src/main/java/org/yaz4j/ResultSet.java index fad095c..b2fd119 100644 --- a/src/main/java/org/yaz4j/ResultSet.java +++ b/src/main/java/org/yaz4j/ResultSet.java @@ -1,57 +1,166 @@ package org.yaz4j; -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import org.yaz4j.exception.ZoomException; import org.yaz4j.jni.SWIGTYPE_p_ZOOM_record_p; import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p; +import org.yaz4j.jni.SWIGTYPE_p_p_ZOOM_record_p; import org.yaz4j.jni.yaz4jlib; -public class ResultSet { +/** + * This class represents a "buffered handle" to the result set created on the + * server and thus retrieving records may involve a request to the server if + * those records are not locally cached. Details on how to configure the retrieval + * (present) process are available in the YAZ manual + * + * @see YAZ ZOOM result sets + * + * Because of server misbehavior or errors during retrieval the + * "getRecord" method may either return null or throw exceptions, even when the + * index of retrieved records lies within the bounds of the set. Client + * code should be prepared for such situations. + * + * This class implements the iterable interface and as such can be used within + * foreach loops, it's important to note, however, that in this case the errors + * during retrieval will be masked with standard NoSuchElementExceptions. + * + * @author jakub + */ +public class ResultSet implements Iterable { + //for GC refcount - private SWIGTYPE_p_ZOOM_resultset_p resultSet; - private SWIGTYPE_p_ZOOM_connection_p connection; - private long size = 0; - private Record[] records = null; - private boolean disposed = false; + private Connection conn; + private SWIGTYPE_p_ZOOM_resultset_p resultSet; + private long size = 0; + private boolean disposed = false; - ResultSet(SWIGTYPE_p_ZOOM_resultset_p resultSet, SWIGTYPE_p_ZOOM_connection_p connection) { - this.resultSet = resultSet; - this.connection = connection; - size = yaz4jlib.ZOOM_resultset_size(this.resultSet); - records = new Record[(int) size]; - } + ResultSet(SWIGTYPE_p_ZOOM_resultset_p resultSet, Connection conn) { + this.resultSet = resultSet; + size = yaz4jlib.ZOOM_resultset_size(this.resultSet); + this.conn = conn; + } - public void finalize() { - this.dispose(); - } + @Override + public void finalize() { + this._dispose(); + } - ResultSetOptionsCollection getResultSetOptions() { - return new ResultSetOptionsCollection(resultSet); - } + /** + * Read option by name. + * @param name option name + * @return option value + */ + public String option(String name) { + return yaz4jlib.ZOOM_resultset_option_get(resultSet, name); + } - public Record getRecord(int index) { - if (records[index] == null) { - SWIGTYPE_p_ZOOM_record_p recordTemp = yaz4jlib.ZOOM_resultset_record(resultSet, index); - records[index] = new Record(recordTemp, this); - } + /** + * Write option with a given name. + * @param name option name + * @param value option value + * @return result set (self) for chainability + */ + public ResultSet option(String name, String value) { + yaz4jlib.ZOOM_resultset_option_set(resultSet, name, value); + return this; + } - return this.records[index]; + public Record getRecord(long index) throws ZoomException { + SWIGTYPE_p_ZOOM_record_p record = + yaz4jlib.ZOOM_resultset_record(resultSet, index); + //may be out of range or unsupported syntax + if (record == null) { + return null; } - - public int getSize() { - return (int) size; + int errorCode = yaz4jlib.ZOOM_record_error(record, null, null, null); + if (errorCode != 0) { + throw new ZoomException("Record excpetion, code " + errorCode); + } + return new Record(record, this); + } + + /** + * Retrieve a collection of records at once. If a record cannot be retrieved, + * it is omitted from the list (thus the list size may be smaller than 'count'). + * @param start start index within the result set + * @param count number of records to retrieve + * @return + * @throws ZoomException raised in case of protocol errors + */ + public List getRecords(long start, int count) throws ZoomException { + List out = new ArrayList(count); + SWIGTYPE_p_p_ZOOM_record_p recs = yaz4jlib.new_zoomRecordArray(count); + yaz4jlib.ZOOM_resultset_records(resultSet, recs, start, count); + ZoomException err = this.conn.getZoomException(); + if (err != null) { + throw err; } + for (int i = 0; i < count; i++) { + SWIGTYPE_p_ZOOM_record_p record = + yaz4jlib.zoomRecordArray_getitem(recs, i); + if (record == null) { + continue; + } + int errorCode = yaz4jlib.ZOOM_record_error(record, null, null, null); + if (errorCode != 0) { + throw new ZoomException("Record excpetion, code " + errorCode); + } + out.add(new Record(record, this)); + } + return out; + } + + @Override + public Iterator iterator() { + return new Iterator() { + private long cur; + @Override + public boolean hasNext() { + return cur < size; + } - public void dispose() { - if (!disposed) { - for (int i = 0; i < records.length; i++) { - if (records[i] != null) { - records[i].dispose(); - } - } - yaz4jlib.ZOOM_resultset_destroy(resultSet); - connection = null; - resultSet = null; - disposed = true; + @Override + public Record next() { + try { + return getRecord(cur++); + } catch (ZoomException ze) { + throw new NoSuchElementException(ze.getMessage()); } + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove operation not supported"); + } + }; + } + + /** + * + * @param type + * @param spec + * @return + * @throws ZoomException + */ + public ResultSet sort(String type, String spec) throws ZoomException { + int ret = yaz4jlib.ZOOM_resultset_sort1(resultSet, type, spec); + if (ret != 0) throw new ZoomException("Sorting resultset failed"); + return this; + } + + public long getHitCount() { + return size; + } + + void _dispose() { + if (!disposed) { + yaz4jlib.ZOOM_resultset_destroy(resultSet); + resultSet = null; + conn = null; + disposed = true; } + } }