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 | */ |
6 | package org.h2.result; |
7 | |
8 | import org.h2.engine.Constants; |
9 | import org.h2.store.Data; |
10 | import org.h2.util.StatementBuilder; |
11 | import org.h2.value.Value; |
12 | import org.h2.value.ValueLong; |
13 | |
14 | /** |
15 | * Represents a row in a table. |
16 | */ |
17 | public class Row implements SearchRow { |
18 | |
19 | public static final int MEMORY_CALCULATE = -1; |
20 | public static final Row[] EMPTY_ARRAY = {}; |
21 | |
22 | private long key; |
23 | private final Value[] data; |
24 | private int memory; |
25 | private int version; |
26 | private boolean deleted; |
27 | private int sessionId; |
28 | |
29 | public Row(Value[] data, int memory) { |
30 | this.data = data; |
31 | this.memory = memory; |
32 | } |
33 | |
34 | /** |
35 | * Get a copy of the row that is distinct from (not equal to) this row. |
36 | * This is used for FOR UPDATE to allow pseudo-updating a row. |
37 | * |
38 | * @return a new row with the same data |
39 | */ |
40 | public Row getCopy() { |
41 | Value[] d2 = new Value[data.length]; |
42 | System.arraycopy(data, 0, d2, 0, data.length); |
43 | Row r2 = new Row(d2, memory); |
44 | r2.key = key; |
45 | r2.version = version + 1; |
46 | r2.sessionId = sessionId; |
47 | return r2; |
48 | } |
49 | |
50 | @Override |
51 | public void setKeyAndVersion(SearchRow row) { |
52 | setKey(row.getKey()); |
53 | setVersion(row.getVersion()); |
54 | } |
55 | |
56 | @Override |
57 | public int getVersion() { |
58 | return version; |
59 | } |
60 | |
61 | public void setVersion(int version) { |
62 | this.version = version; |
63 | } |
64 | |
65 | @Override |
66 | public long getKey() { |
67 | return key; |
68 | } |
69 | |
70 | @Override |
71 | public void setKey(long key) { |
72 | this.key = key; |
73 | } |
74 | |
75 | @Override |
76 | public Value getValue(int i) { |
77 | return i == -1 ? ValueLong.get(key) : data[i]; |
78 | } |
79 | |
80 | /** |
81 | * Get the number of bytes required for the data. |
82 | * |
83 | * @param dummy the template buffer |
84 | * @return the number of bytes |
85 | */ |
86 | public int getByteCount(Data dummy) { |
87 | int size = 0; |
88 | for (Value v : data) { |
89 | size += dummy.getValueLen(v); |
90 | } |
91 | return size; |
92 | } |
93 | |
94 | @Override |
95 | public void setValue(int i, Value v) { |
96 | if (i == -1) { |
97 | this.key = v.getLong(); |
98 | } else { |
99 | data[i] = v; |
100 | } |
101 | } |
102 | |
103 | public boolean isEmpty() { |
104 | return data == null; |
105 | } |
106 | |
107 | @Override |
108 | public int getColumnCount() { |
109 | return data.length; |
110 | } |
111 | |
112 | @Override |
113 | public int getMemory() { |
114 | if (memory != MEMORY_CALCULATE) { |
115 | return memory; |
116 | } |
117 | int m = Constants.MEMORY_ROW; |
118 | if (data != null) { |
119 | int len = data.length; |
120 | m += Constants.MEMORY_OBJECT + len * Constants.MEMORY_POINTER; |
121 | for (int i = 0; i < len; i++) { |
122 | Value v = data[i]; |
123 | if (v != null) { |
124 | m += v.getMemory(); |
125 | } |
126 | } |
127 | } |
128 | this.memory = m; |
129 | return m; |
130 | } |
131 | |
132 | @Override |
133 | public String toString() { |
134 | StatementBuilder buff = new StatementBuilder("( /* key:"); |
135 | buff.append(getKey()); |
136 | if (version != 0) { |
137 | buff.append(" v:" + version); |
138 | } |
139 | if (isDeleted()) { |
140 | buff.append(" deleted"); |
141 | } |
142 | buff.append(" */ "); |
143 | if (data != null) { |
144 | for (Value v : data) { |
145 | buff.appendExceptFirst(", "); |
146 | buff.append(v == null ? "null" : v.getTraceSQL()); |
147 | } |
148 | } |
149 | return buff.append(')').toString(); |
150 | } |
151 | |
152 | public void setDeleted(boolean deleted) { |
153 | this.deleted = deleted; |
154 | } |
155 | |
156 | public void setSessionId(int sessionId) { |
157 | this.sessionId = sessionId; |
158 | } |
159 | |
160 | public int getSessionId() { |
161 | return sessionId; |
162 | } |
163 | |
164 | /** |
165 | * This record has been committed. The session id is reset. |
166 | */ |
167 | public void commit() { |
168 | this.sessionId = 0; |
169 | } |
170 | |
171 | public boolean isDeleted() { |
172 | return deleted; |
173 | } |
174 | |
175 | public Value[] getValueList() { |
176 | return data; |
177 | } |
178 | |
179 | } |