EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.result]

COVERAGE SUMMARY FOR SOURCE FILE [ResultRemote.java]

nameclass, %method, %block, %line, %
ResultRemote.java100% (1/1)92%  (23/25)81%  (385/478)83%  (89.6/108)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ResultRemote100% (1/1)92%  (23/25)81%  (385/478)83%  (89.6/108)
needToClose (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
toString (): String 0%   (0/1)0%   (0/21)0%   (0/1)
reset (): void 100% (1/1)21%  (10/47)31%  (4/13)
sendClose (): void 100% (1/1)56%  (34/61)64%  (7.6/12)
remapIfOld (): void 100% (1/1)89%  (39/44)82%  (9/11)
fetchRows (boolean): void 100% (1/1)99%  (117/118)96%  (25/26)
ResultRemote (SessionRemote, Transfer, int, int, int): void 100% (1/1)100% (51/51)100% (14/14)
close (): void 100% (1/1)100% (6/6)100% (3/3)
currentRow (): Value [] 100% (1/1)100% (3/3)100% (1/1)
getAlias (int): String 100% (1/1)100% (6/6)100% (1/1)
getColumnName (int): String 100% (1/1)100% (6/6)100% (1/1)
getColumnPrecision (int): long 100% (1/1)100% (6/6)100% (1/1)
getColumnScale (int): int 100% (1/1)100% (6/6)100% (1/1)
getColumnType (int): int 100% (1/1)100% (6/6)100% (1/1)
getDisplaySize (int): int 100% (1/1)100% (6/6)100% (1/1)
getFetchSize (): int 100% (1/1)100% (3/3)100% (1/1)
getNullable (int): int 100% (1/1)100% (6/6)100% (1/1)
getRowCount (): int 100% (1/1)100% (3/3)100% (1/1)
getRowId (): int 100% (1/1)100% (3/3)100% (1/1)
getSchemaName (int): String 100% (1/1)100% (6/6)100% (1/1)
getTableName (int): String 100% (1/1)100% (6/6)100% (1/1)
getVisibleColumnCount (): int 100% (1/1)100% (4/4)100% (1/1)
isAutoIncrement (int): boolean 100% (1/1)100% (6/6)100% (1/1)
next (): boolean 100% (1/1)100% (48/48)100% (10/10)
setFetchSize (int): void 100% (1/1)100% (4/4)100% (2/2)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.result;
7 
8import java.io.IOException;
9import java.util.ArrayList;
10import org.h2.engine.SessionRemote;
11import org.h2.engine.SysProperties;
12import org.h2.message.DbException;
13import org.h2.message.Trace;
14import org.h2.util.New;
15import org.h2.value.Transfer;
16import org.h2.value.Value;
17 
18/**
19 * The client side part of a result set that is kept on the server.
20 * In many cases, the complete data is kept on the client side,
21 * but for large results only a subset is in-memory.
22 */
23public class ResultRemote implements ResultInterface {
24 
25    private int fetchSize;
26    private SessionRemote session;
27    private Transfer transfer;
28    private int id;
29    private final ResultColumn[] columns;
30    private Value[] currentRow;
31    private final int rowCount;
32    private int rowId, rowOffset;
33    private ArrayList<Value[]> result;
34    private final Trace trace;
35 
36    public ResultRemote(SessionRemote session, Transfer transfer, int id,
37            int columnCount, int fetchSize) throws IOException {
38        this.session = session;
39        trace = session.getTrace();
40        this.transfer = transfer;
41        this.id = id;
42        this.columns = new ResultColumn[columnCount];
43        rowCount = transfer.readInt();
44        for (int i = 0; i < columnCount; i++) {
45            columns[i] = new ResultColumn(transfer);
46        }
47        rowId = -1;
48        result = New.arrayList();
49        this.fetchSize = fetchSize;
50        fetchRows(false);
51    }
52 
53    @Override
54    public String getAlias(int i) {
55        return columns[i].alias;
56    }
57 
58    @Override
59    public String getSchemaName(int i) {
60        return columns[i].schemaName;
61    }
62 
63    @Override
64    public String getTableName(int i) {
65        return columns[i].tableName;
66    }
67 
68    @Override
69    public String getColumnName(int i) {
70        return columns[i].columnName;
71    }
72 
73    @Override
74    public int getColumnType(int i) {
75        return columns[i].columnType;
76    }
77 
78    @Override
79    public long getColumnPrecision(int i) {
80        return columns[i].precision;
81    }
82 
83    @Override
84    public int getColumnScale(int i) {
85        return columns[i].scale;
86    }
87 
88    @Override
89    public int getDisplaySize(int i) {
90        return columns[i].displaySize;
91    }
92 
93    @Override
94    public boolean isAutoIncrement(int i) {
95        return columns[i].autoIncrement;
96    }
97 
98    @Override
99    public int getNullable(int i) {
100        return columns[i].nullable;
101    }
102 
103    @Override
104    public void reset() {
105        rowId = -1;
106        currentRow = null;
107        if (session == null) {
108            return;
109        }
110        synchronized (session) {
111            session.checkClosed();
112            try {
113                session.traceOperation("RESULT_RESET", id);
114                transfer.writeInt(SessionRemote.RESULT_RESET).writeInt(id).flush();
115            } catch (IOException e) {
116                throw DbException.convertIOException(e, null);
117            }
118        }
119    }
120 
121    @Override
122    public Value[] currentRow() {
123        return currentRow;
124    }
125 
126    @Override
127    public boolean next() {
128        if (rowId < rowCount) {
129            rowId++;
130            remapIfOld();
131            if (rowId < rowCount) {
132                if (rowId - rowOffset >= result.size()) {
133                    fetchRows(true);
134                }
135                currentRow = result.get(rowId - rowOffset);
136                return true;
137            }
138            currentRow = null;
139        }
140        return false;
141    }
142 
143    @Override
144    public int getRowId() {
145        return rowId;
146    }
147 
148    @Override
149    public int getVisibleColumnCount() {
150        return columns.length;
151    }
152 
153    @Override
154    public int getRowCount() {
155        return rowCount;
156    }
157 
158    private void sendClose() {
159        if (session == null) {
160            return;
161        }
162        // TODO result sets: no reset possible for larger remote result sets
163        try {
164            synchronized (session) {
165                session.traceOperation("RESULT_CLOSE", id);
166                transfer.writeInt(SessionRemote.RESULT_CLOSE).writeInt(id);
167            }
168        } catch (IOException e) {
169            trace.error(e, "close");
170        } finally {
171            transfer = null;
172            session = null;
173        }
174    }
175 
176    @Override
177    public void close() {
178        result = null;
179        sendClose();
180    }
181 
182    private void remapIfOld() {
183        if (session == null) {
184            return;
185        }
186        try {
187            if (id <= session.getCurrentId() - SysProperties.SERVER_CACHED_OBJECTS / 2) {
188                // object is too old - we need to map it to a new id
189                int newId = session.getNextId();
190                session.traceOperation("CHANGE_ID", id);
191                transfer.writeInt(SessionRemote.CHANGE_ID).writeInt(id).writeInt(newId);
192                id = newId;
193                // TODO remote result set: very old result sets may be
194                // already removed on the server (theoretically) - how to
195                // solve this?
196            }
197        } catch (IOException e) {
198            throw DbException.convertIOException(e, null);
199        }
200    }
201 
202    private void fetchRows(boolean sendFetch) {
203        synchronized (session) {
204            session.checkClosed();
205            try {
206                rowOffset += result.size();
207                result.clear();
208                int fetch = Math.min(fetchSize, rowCount - rowOffset);
209                if (sendFetch) {
210                    session.traceOperation("RESULT_FETCH_ROWS", id);
211                    transfer.writeInt(SessionRemote.RESULT_FETCH_ROWS).
212                            writeInt(id).writeInt(fetch);
213                    session.done(transfer);
214                }
215                for (int r = 0; r < fetch; r++) {
216                    boolean row = transfer.readBoolean();
217                    if (!row) {
218                        break;
219                    }
220                    int len = columns.length;
221                    Value[] values = new Value[len];
222                    for (int i = 0; i < len; i++) {
223                        Value v = transfer.readValue();
224                        values[i] = v;
225                    }
226                    result.add(values);
227                }
228                if (rowOffset + result.size() >= rowCount) {
229                    sendClose();
230                }
231            } catch (IOException e) {
232                throw DbException.convertIOException(e, null);
233            }
234        }
235    }
236 
237    @Override
238    public String toString() {
239        return "columns: " + columns.length + " rows: " + rowCount + " pos: " + rowId;
240    }
241 
242    @Override
243    public int getFetchSize() {
244        return fetchSize;
245    }
246 
247    @Override
248    public void setFetchSize(int fetchSize) {
249        this.fetchSize = fetchSize;
250    }
251 
252    @Override
253    public boolean needToClose() {
254        return true;
255    }
256 
257}

[all classes][org.h2.result]
EMMA 2.0.5312 (C) Vladimir Roubtsov