KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > result > LocalResult


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.result;
6
7 import java.sql.ResultSet JavaDoc;
8 import java.sql.ResultSetMetaData JavaDoc;
9 import java.sql.SQLException JavaDoc;
10
11 import org.h2.engine.Database;
12 import org.h2.engine.Session;
13 import org.h2.expression.Expression;
14 import org.h2.expression.ExpressionColumn;
15 import org.h2.message.Message;
16 import org.h2.table.Column;
17 import org.h2.util.ObjectArray;
18 import org.h2.util.ValueHashMap;
19 import org.h2.value.DataType;
20 import org.h2.value.Value;
21 import org.h2.value.ValueArray;
22
23 /**
24  */

25 public class LocalResult implements ResultInterface {
26
27     private int maxMemoryRows;
28     private Session session;
29     private int visibleColumnCount;
30     private Expression[] expressions;
31     private int rowId, rowCount;
32     private ObjectArray rows;
33     private SortOrder sort;
34     private ValueHashMap distinctRows;
35     private Value[] currentRow;
36     private int[] displaySizes;
37     private int offset, limit;
38     private ResultDiskBuffer disk;
39     private int diskOffset;
40     private boolean isUpdateCount;
41     private int updateCount;
42     
43     public static LocalResult read(Session session, ResultSet JavaDoc rs) throws SQLException JavaDoc {
44         ResultSetMetaData JavaDoc meta = rs.getMetaData();
45         int columnCount = meta.getColumnCount();
46         ObjectArray cols = new ObjectArray();
47         int[] types = new int[columnCount];
48         Database db = session == null ? null : session.getDatabase();
49         for (int i = 0; i < columnCount; i++) {
50             String JavaDoc name = meta.getColumnLabel(i + 1);
51             int type = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
52             types[i] = type;
53             int precision = meta.getPrecision(i + 1);
54             int scale = meta.getScale(i + 1);
55             Column col = new Column(name, type, precision, scale);
56             Expression expr = new ExpressionColumn(db, null, col);
57             cols.add(expr);
58         }
59         LocalResult result = new LocalResult(session, cols, columnCount);
60         while (rs.next()) {
61             Value[] list = new Value[columnCount];
62             for (int j = 0; j < columnCount; j++) {
63                 list[j] = DataType.readValue(session, rs, j + 1, types[j]);
64             }
65             result.addRow(list);
66         }
67         result.done();
68         return result;
69     }
70     
71     public LocalResult(int updateCount) {
72         this.isUpdateCount = true;
73         this.updateCount = updateCount;
74     }
75     
76     public LocalResult createShallowCopy(Session session) {
77         LocalResult copy = new LocalResult(0);
78         copy.maxMemoryRows = this.maxMemoryRows;
79         copy.session = session;
80         copy.visibleColumnCount = this.visibleColumnCount;
81         copy.expressions = this.expressions;
82         copy.rowId = -1;
83         copy.rowCount = this.rowCount;
84         copy.rows = this.rows;
85         copy.sort = this.sort;
86         copy.distinctRows = this.distinctRows;
87         copy.currentRow = null;
88         copy.displaySizes = this.displaySizes;
89         copy.offset = 0;
90         copy.limit = 0;
91         copy.disk = this.disk;
92         copy.diskOffset = this.diskOffset;
93         copy.isUpdateCount = this.isUpdateCount;
94         copy.updateCount = this.updateCount;
95         return copy;
96     }
97     
98     public boolean isUpdateCount() {
99         return isUpdateCount;
100     }
101     
102     public int getUpdateCount() {
103         return updateCount;
104     }
105
106     public LocalResult(Session session, ObjectArray cols, int visibleColumnCount) {
107         this.session = session;
108         if(session == null) {
109             this.maxMemoryRows = Integer.MAX_VALUE;
110         } else {
111             this.maxMemoryRows = session.getDatabase().getMaxMemoryRows();
112         }
113         this.expressions = new Expression[cols.size()];
114         cols.toArray(expressions);
115         this.displaySizes = new int[cols.size()];
116         rows = new ObjectArray();
117         this.visibleColumnCount = visibleColumnCount;
118         rowId = -1;
119     }
120
121     public void setSortOrder(SortOrder sort) {
122         this.sort = sort;
123     }
124
125     public void setDistinct() {
126         // TODO big result sets: how to buffer distinct result sets? maybe do the
127
// distinct when sorting each block, and final merging
128
distinctRows = new ValueHashMap(session.getDatabase());
129     }
130     
131     public void removeDistinct(Value[] values) throws SQLException JavaDoc {
132         if(distinctRows == null) {
133             throw Message.getInternalError();
134         }
135         ValueArray array = ValueArray.get(values);
136         distinctRows.remove(array);
137         rowCount = distinctRows.size();
138     }
139     
140     public boolean containsDistinct(Value[] values) throws SQLException JavaDoc {
141         if(distinctRows == null) {
142             throw Message.getInternalError();
143         }
144         ValueArray array = ValueArray.get(values);
145         return distinctRows.get(array) != null;
146     }
147
148     public void reset() throws SQLException JavaDoc {
149         rowId = -1;
150         if (disk != null) {
151             disk.reset();
152             if(diskOffset > 0) {
153                 for(int i=0; i<diskOffset; i++) {
154                     disk.next();
155                 }
156             }
157         }
158     }
159
160     public Value[] currentRow() {
161         return currentRow;
162     }
163
164     public boolean next() throws SQLException JavaDoc {
165         if (rowId < rowCount) {
166             rowId++;
167             if (rowId < rowCount) {
168                 if (disk != null) {
169                     currentRow = disk.next();
170                 } else {
171                     currentRow = (Value[]) rows.get(rowId);
172                 }
173                 return true;
174             }
175             currentRow = null;
176         }
177         return false;
178     }
179
180     public int getRowId() {
181         return rowId;
182     }
183
184     public void addRow(Value[] values) throws SQLException JavaDoc {
185         for(int i=0; i<values.length; i++) {
186             // TODO display sizes: check if this is a performance problem, maybe provide a setting to not do it
187
Value v = values[i];
188             int size = v.getDisplaySize();
189             displaySizes[i] = Math.max(displaySizes[i], size);
190         }
191         if (distinctRows != null) {
192             ValueArray array = ValueArray.get(values);
193             distinctRows.put(array, values);
194             rowCount = distinctRows.size();
195             return;
196         }
197         rows.add(values);
198         rowCount++;
199         if (rows.size() > maxMemoryRows && session.getDatabase().isPersistent()) {
200             if (disk == null) {
201                 disk = new ResultDiskBuffer(session, sort, values.length);
202             }
203             addRowsToDisk();
204         }
205     }
206
207     private void addRowsToDisk() throws SQLException JavaDoc {
208         disk.addRows(rows);
209         rows.clear();
210     }
211
212     public int getVisibleColumnCount() {
213         return visibleColumnCount;
214     }
215
216     public void done() throws SQLException JavaDoc {
217         if (distinctRows != null) {
218             rows = distinctRows.values();
219             distinctRows = null;
220         }
221         if (disk != null) {
222             addRowsToDisk();
223             disk.done();
224         } else {
225             if (sort != null) {
226                 sort.sort(rows);
227             }
228         }
229         applyOffset();
230         applyLimit();
231         reset();
232     }
233
234     public int getRowCount() {
235         return rowCount;
236     }
237
238     public void setLimit(int limit) {
239         this.limit = limit;
240     }
241     
242     private void applyLimit() {
243         if(limit <=0 ) {
244             return;
245         }
246         if(disk == null) {
247             if(rows.size() > limit) {
248                 rows.removeRange(limit, rows.size());
249                 rowCount = limit;
250             }
251         } else {
252             if(limit < rowCount) {
253                 rowCount = limit;
254             }
255         }
256     }
257
258     public void close() {
259         if (disk != null) {
260             disk.close();
261             disk = null;
262         }
263     }
264
265     public String JavaDoc getAlias(int i) {
266         return expressions[i].getAlias();
267     }
268
269     public String JavaDoc getTableName(int i) {
270         return expressions[i].getTableName();
271     }
272     
273     public String JavaDoc getSchemaName(int i) {
274         return expressions[i].getSchemaName();
275     }
276     
277     public int getDisplaySize(int i) {
278         return displaySizes[i];
279     }
280
281     public String JavaDoc getColumnName(int i) {
282         return expressions[i].getColumnName();
283     }
284
285     public int getColumnType(int i) {
286         return expressions[i].getType();
287     }
288
289     public long getColumnPrecision(int i) {
290         return expressions[i].getPrecision();
291     }
292
293     public int getNullable(int i) {
294         return expressions[i].getNullable();
295     }
296
297     public boolean isAutoIncrement(int i) {
298         return expressions[i].isAutoIncrement();
299     }
300
301     public int getColumnScale(int i) {
302         return expressions[i].getScale();
303     }
304
305     public void setOffset(int offset) {
306         this.offset = offset;
307     }
308     
309     private void applyOffset() {
310         if(offset <=0) {
311             return;
312         }
313         if(disk == null) {
314             if(offset >= rows.size()) {
315                 rows.clear();
316                 rowCount = 0;
317             } else {
318                 // avoid copying the whole array for each row
319
int remove = Math.min(offset, rows.size());
320                 rows.removeRange(0, remove);
321                 rowCount -= remove;
322             }
323         } else {
324             if(offset >= rowCount) {
325                 rowCount = 0;
326             } else {
327                 diskOffset = offset;
328                 rowCount -= offset;
329             }
330         }
331     }
332
333 }
334
Popular Tags