Add ResultSet#sort
[yaz4j-moved-to-github.git] / src / main / java / org / yaz4j / ResultSet.java
1 package org.yaz4j;
2
3 import java.util.Iterator;
4 import java.util.NoSuchElementException;
5 import org.yaz4j.exception.ZoomException;
6 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_record_p;
7 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p;
8 import org.yaz4j.jni.yaz4jlib;
9
10 /**
11  * This class represents a "buffered handle" to the result set created on the
12  * server and thus retrieving records may invlove a request to the server if
13  * those records are not locally cached. Details on how to configure the retrieval
14  * (present) process are available in the YAZ manual
15  *
16  * @see <a href="http://www.indexdata.com/yaz/doc/zoom.resultsets.html">YAZ ZOOM result sets</a>
17  *
18  * Becacuse of the server misbehaviour or errors during retrieval the
19  * "getRecord" method may either return null or throw exceptions, even when the
20  * index of retrieved records lies within the bounds of the set. Client
21  * code should be prepared for such situations.
22  *
23  * This class implements the iterable interface and as such can be used within
24  * foreach loops, it's important to note however that in this case the errors
25  * during retrieval will be masked with standard NoSuchElementExceptions
26  *
27  * @author jakub
28  */
29 public class ResultSet implements Iterable<Record> {
30   //for GC refcount
31
32   private Connection conn;
33   private SWIGTYPE_p_ZOOM_resultset_p resultSet;
34   private long size = 0;
35   private boolean disposed = false;
36
37   ResultSet(SWIGTYPE_p_ZOOM_resultset_p resultSet, Connection conn) {
38     this.resultSet = resultSet;
39     size = yaz4jlib.ZOOM_resultset_size(this.resultSet);
40     this.conn = conn;
41   }
42
43   @Override
44   public void finalize() {
45     this._dispose();
46   }
47
48   /**
49    * Read option by name.
50    * @param name option name
51    * @return option value
52    */
53   public String option(String name) {
54     return yaz4jlib.ZOOM_resultset_option_get(resultSet, name);
55   }
56
57   /**
58    * Write option with a given name.
59    * @param name option name
60    * @param value option value
61    * @return result set (self) for chainability
62    */
63   public ResultSet option(String name, String value) {
64     yaz4jlib.ZOOM_resultset_option_set(resultSet, name, value);
65     return this;
66   }
67
68   public Record getRecord(long index) throws ZoomException {
69     SWIGTYPE_p_ZOOM_record_p record =
70       yaz4jlib.ZOOM_resultset_record(resultSet, index);
71     //may be out of range or unsupported syntax
72     if (record == null) {
73       return null;
74     }
75     int errorCode = yaz4jlib.ZOOM_record_error(record, null, null, null);
76     if (errorCode != 0) {
77       throw new ZoomException("Record excpetion, code " + errorCode);
78     }
79     return new Record(record, this);
80   }
81
82   @Override
83   public Iterator<Record> iterator() {
84     return new Iterator<Record>() {
85       private long cur;
86       @Override
87       public boolean hasNext() {
88         return cur < size;
89       }
90
91       @Override
92       public Record next() {
93         try {
94           return getRecord(cur++);
95         } catch (ZoomException ze) {
96           throw new NoSuchElementException(ze.getMessage());
97         }
98       }
99
100       @Override
101       public void remove() {
102         throw new UnsupportedOperationException("remove operation not supported");
103       }
104     };
105   }
106
107   public ResultSet sort(String type, String spec) throws ZoomException {
108     int ret = yaz4jlib.ZOOM_resultset_sort1(resultSet, type, spec);
109     if (ret != 0) throw new ZoomException("Sorting resultset failed");
110     return this;
111   }
112
113   public long getHitCount() {
114     return size;
115   }
116
117   void _dispose() {
118     if (!disposed) {
119       yaz4jlib.ZOOM_resultset_destroy(resultSet);
120       resultSet = null;
121       conn = null;
122       disposed = true;
123     }
124   }
125 }