1 | /* ============================================================= |
2 | * SmallSQL : a free Java DBMS library for the Java(tm) platform |
3 | * ============================================================= |
4 | * |
5 | * (C) Copyright 2004-2006, by Volker Berlin. |
6 | * |
7 | * Project Info: http://www.smallsql.de/ |
8 | * |
9 | * This library is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU Lesser General Public License as published by |
11 | * the Free Software Foundation; either version 2.1 of the License, or |
12 | * (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
17 | * License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Lesser General Public |
20 | * License along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
22 | * USA. |
23 | * |
24 | * [Java is a trademark or registered trademark of Sun Microsystems, Inc. |
25 | * in the United States and other countries.] |
26 | * |
27 | * --------------- |
28 | * Scrollable.java |
29 | * --------------- |
30 | * Author: Volker Berlin |
31 | * |
32 | * Created on 05.07.2004 |
33 | */ |
34 | package smallsql.database; |
35 | |
36 | /** |
37 | * Scrollable is a RowSource wrapper to add the feature of scrollable to any RowSource. |
38 | * @author Volker Berlin |
39 | */ |
40 | class Scrollable extends RowSource { |
41 | |
42 | /** The internal not scrollable RowSource */ |
43 | private final RowSource rowSource; |
44 | |
45 | /** The current row number */ |
46 | private int rowIdx; |
47 | |
48 | /** A map of row number to the RowPositions of the internal RowSource */ |
49 | private final LongList rowList = new LongList(); |
50 | |
51 | /** Detect if on any previous scrolling the last row was recheched. */ |
52 | //private boolean lastIsFound; |
53 | |
54 | |
55 | Scrollable(RowSource rowSource){ |
56 | this.rowSource = rowSource; |
57 | } |
58 | |
59 | |
60 | final boolean isScrollable(){ |
61 | return true; |
62 | } |
63 | |
64 | |
65 | void beforeFirst() throws Exception { |
66 | rowIdx = -1; |
67 | rowSource.beforeFirst(); |
68 | } |
69 | |
70 | |
71 | boolean isBeforeFirst(){ |
72 | return rowIdx == -1; |
73 | } |
74 | |
75 | |
76 | boolean isFirst(){ |
77 | return rowIdx == 0; |
78 | } |
79 | |
80 | |
81 | boolean first() throws Exception { |
82 | rowIdx = -1; |
83 | return next(); |
84 | } |
85 | |
86 | |
87 | boolean previous() throws Exception{ |
88 | if(rowIdx > -1){ |
89 | rowIdx--; |
90 | if(rowIdx > -1 && rowIdx < rowList.size()){ |
91 | rowSource.setRowPosition( rowList.get(rowIdx) ); |
92 | return true; |
93 | } |
94 | } |
95 | rowSource.beforeFirst(); |
96 | return false; |
97 | } |
98 | |
99 | |
100 | boolean next() throws Exception { |
101 | if(++rowIdx < rowList.size()){ |
102 | rowSource.setRowPosition( rowList.get(rowIdx) ); |
103 | return true; |
104 | } |
105 | final boolean result = rowSource.next(); |
106 | if(result){ |
107 | rowList.add( rowSource.getRowPosition()); |
108 | return true; |
109 | } |
110 | return false; |
111 | } |
112 | |
113 | |
114 | boolean last() throws Exception{ |
115 | afterLast(); |
116 | return previous(); |
117 | } |
118 | |
119 | |
120 | boolean isLast() throws Exception{ |
121 | if(rowIdx+1 != rowList.size()) return false; |
122 | if(next()){ |
123 | previous(); |
124 | return false; |
125 | } |
126 | return true; |
127 | } |
128 | |
129 | boolean isAfterLast() throws Exception{ |
130 | if(rowIdx >= rowList.size()) return true; |
131 | if(isBeforeFirst() && rowList.size() == 0){ |
132 | next(); |
133 | previous(); |
134 | if(rowList.size() == 0) return true; |
135 | } |
136 | return false; |
137 | } |
138 | |
139 | |
140 | void afterLast() throws Exception { |
141 | if(rowIdx+1 < rowList.size()){ |
142 | rowIdx = rowList.size()-1; |
143 | rowSource.setRowPosition( rowList.get(rowIdx) ); |
144 | } |
145 | while(next()); |
146 | } |
147 | |
148 | |
149 | boolean absolute(int row) throws Exception{ |
150 | if(row == 0) |
151 | throw Utils.createSQLException("The call absolute(0) is invalid."); |
152 | if(row < 0){ |
153 | afterLast(); |
154 | rowIdx = rowList.size() + row; |
155 | if(rowIdx < 0){ |
156 | beforeFirst(); |
157 | return false; |
158 | }else{ |
159 | rowSource.setRowPosition( rowList.get(rowIdx) ); |
160 | return true; |
161 | } |
162 | } |
163 | if(row <= rowList.size()){ |
164 | rowIdx = row-1; |
165 | rowSource.setRowPosition( rowList.get(rowIdx) ); |
166 | return true; |
167 | } |
168 | |
169 | rowIdx = rowList.size()-1; |
170 | if(rowIdx >= 0) |
171 | rowSource.setRowPosition( rowList.get(rowIdx) ); |
172 | boolean result; |
173 | while((result = next()) && row-1 > rowIdx); |
174 | return result; |
175 | } |
176 | |
177 | |
178 | boolean relative(int rows) throws Exception{ |
179 | int newRow = rows + rowIdx + 1; |
180 | if(newRow <= 0){ |
181 | beforeFirst(); |
182 | return false; |
183 | }else{ |
184 | return absolute(newRow); |
185 | } |
186 | } |
187 | |
188 | |
189 | int getRow() throws Exception { |
190 | if(rowIdx >= rowList.size()) return 0; |
191 | return rowIdx + 1; |
192 | } |
193 | |
194 | |
195 | long getRowPosition() { |
196 | return rowIdx; |
197 | } |
198 | |
199 | |
200 | void setRowPosition(long rowPosition) throws Exception { |
201 | rowIdx = (int)rowPosition; |
202 | } |
203 | |
204 | |
205 | final boolean rowInserted(){ |
206 | return rowSource.rowInserted(); |
207 | } |
208 | |
209 | |
210 | final boolean rowDeleted(){ |
211 | return rowSource.rowDeleted(); |
212 | } |
213 | |
214 | |
215 | void nullRow() { |
216 | rowSource.nullRow(); |
217 | rowIdx = -1; |
218 | } |
219 | |
220 | |
221 | void noRow() { |
222 | rowSource.noRow(); |
223 | rowIdx = -1; |
224 | } |
225 | |
226 | |
227 | void execute() throws Exception{ |
228 | rowSource.execute(); |
229 | rowList.clear(); |
230 | rowIdx = -1; |
231 | } |
232 | } |