1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.hbql.impl;
22
23 import org.apache.expreval.client.InternalErrorException;
24 import org.apache.hadoop.hbase.hbql.client.HBqlException;
25 import org.apache.hadoop.hbase.hbql.client.HRecord;
26 import org.apache.hadoop.hbase.hbql.client.UnMappedValueMap;
27 import org.apache.hadoop.hbase.hbql.mapping.ColumnAttrib;
28 import org.apache.hadoop.hbase.hbql.mapping.FieldType;
29 import org.apache.hadoop.hbase.hbql.mapping.MappingContext;
30 import org.apache.hadoop.hbase.hbql.mapping.ResultAccessor;
31 import org.apache.hadoop.hbase.hbql.mapping.TableMapping;
32 import org.apache.hadoop.hbase.hbql.util.AtomicReferences;
33 import org.apache.hadoop.hbase.hbql.util.Lists;
34 import org.apache.hadoop.hbase.hbql.util.Maps;
35
36 import java.util.Date;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.NavigableMap;
40 import java.util.Set;
41 import java.util.concurrent.atomic.AtomicReference;
42
43 public class HRecordImpl implements HRecord {
44
45 private MappingContext mappingContext;
46 private long timestamp = System.currentTimeMillis();
47
48 private List<String> namePositionList = Lists.newArrayList();
49
50 private AtomicReference<ElementMap<ColumnValue>> atomicColumnValuesMap = AtomicReferences.newAtomicReference();
51 private AtomicReference<ElementMap<UnMappedValueMap>> atomicUnMappedValuesMap = AtomicReferences.newAtomicReference();
52
53 public HRecordImpl() {
54 }
55
56 public HRecordImpl(final MappingContext mappingContext) {
57 this.setMappingContext(mappingContext);
58 }
59
60 public MappingContext getMappingContext() {
61 return mappingContext;
62 }
63
64 public void setMappingContext(final MappingContext mappingContext) {
65 this.mappingContext = mappingContext;
66 }
67
68 public long getTimestamp() {
69 return this.timestamp;
70 }
71
72 private AtomicReference<ElementMap<UnMappedValueMap>> getAtomicUnMappedValuesMap() {
73 return this.atomicUnMappedValuesMap;
74 }
75
76 private AtomicReference<ElementMap<ColumnValue>> getAtomicColumnValuesMap() {
77 return this.atomicColumnValuesMap;
78 }
79
80 private List<String> getNamePositionList() {
81 return this.namePositionList;
82 }
83
84 public String getAttribName(final int i) throws HBqlException {
85 try {
86 return this.getNamePositionList().get(i - 1);
87 }
88 catch (ArrayIndexOutOfBoundsException e) {
89 throw new HBqlException("Invalid column number " + i);
90 }
91 }
92
93 public void addNameToPositionList(final String name) {
94 this.getNamePositionList().add(name);
95 }
96
97 public TableMapping getTableMapping() throws HBqlException {
98 return this.getMappingContext().getTableMapping();
99 }
100
101 public ResultAccessor getResultAccessor() throws HBqlException {
102 return this.getMappingContext().getResultAccessor();
103 }
104
105 protected ElementMap<ColumnValue> getColumnValuesMap() {
106 if (this.getAtomicColumnValuesMap().get() == null)
107 synchronized (this) {
108 if (this.getAtomicColumnValuesMap().get() == null)
109 this.getAtomicColumnValuesMap().set(new ElementMap<ColumnValue>(this));
110 }
111 return this.getAtomicColumnValuesMap().get();
112 }
113
114 private ElementMap<UnMappedValueMap> getUnMappedValuesMap() {
115 if (this.getAtomicUnMappedValuesMap().get() == null)
116 synchronized (this) {
117 if (this.getAtomicUnMappedValuesMap().get() == null)
118 this.getAtomicUnMappedValuesMap().set(new ElementMap<UnMappedValueMap>(this));
119 }
120 return this.getAtomicUnMappedValuesMap().get();
121 }
122
123 public void addElement(final Value value) throws HBqlException {
124
125 if (value instanceof ColumnValue)
126 this.getColumnValuesMap().addElement((ColumnValue)value);
127 else if (value instanceof UnMappedValueMap)
128 this.getUnMappedValuesMap().addElement((UnMappedValueMap)value);
129 else
130 throw new InternalErrorException(value.getClass().getName());
131 }
132
133 public void clearValues() {
134 this.getColumnValuesMap().clear();
135 this.getUnMappedValuesMap().clear();
136 }
137
138
139 public ColumnValue getColumnValue(final String name, final boolean inMapping) throws HBqlException {
140 final ColumnValue value = this.getColumnValuesMap().findElement(name);
141 if (value != null) {
142 return value;
143 }
144 else {
145 if (inMapping && !this.getTableMapping().containsVariableName(name))
146 throw new HBqlException("Invalid variable name "
147 + this.getTableMapping().getMappingName() + "." + name);
148 final ColumnValue columnValue = new ColumnValue(name);
149 this.addElement(columnValue);
150 return columnValue;
151 }
152 }
153
154 private UnMappedValueMap getUnMappedValueMap(final String name,
155 final boolean createNewIfMissing) throws HBqlException {
156 final UnMappedValueMap value = this.getUnMappedValuesMap().findElement(name);
157 if (value != null) {
158 return value;
159 }
160 else {
161 if (createNewIfMissing) {
162 final UnMappedValueMap val = new UnMappedValueMap(name);
163 this.addElement(val);
164 return val;
165 }
166 else {
167 return null;
168 }
169 }
170 }
171
172
173 public void setCurrentValue(final String family,
174 final String column,
175 final long timestamp,
176 final Object val) throws HBqlException {
177 final ColumnAttrib attrib = this.getTableMapping().getAttribFromFamilyQualifiedName(family, column);
178 if (attrib == null)
179 throw new HBqlException("Invalid column name " + family + ":" + column);
180 this.setCurrentValue(attrib.getAliasName(), timestamp, val, true);
181 }
182
183 public boolean isCurrentValueSet(final ColumnAttrib attrib) throws HBqlException {
184 final ColumnValue columnValue = this.getColumnValuesMap().findElement(attrib.getAliasName());
185 return columnValue != null && columnValue.isValueSet();
186 }
187
188 public void setCurrentValue(final String name,
189 final long timestamp,
190 final Object val,
191 final boolean inMapping) throws HBqlException {
192 this.getColumnValue(name, inMapping).setCurrentValue(timestamp, val);
193 }
194
195 public void setVersionValue(final String familyName,
196 final String columnName,
197 final long timestamp,
198 final Object val,
199 final boolean inMapping) throws HBqlException {
200 final ColumnAttrib attrib = this.getTableMapping().getAttribFromFamilyQualifiedName(familyName, columnName);
201 if (attrib == null)
202 throw new HBqlException("Invalid column name " + familyName + ":" + columnName);
203
204 this.getColumnValue(attrib.getColumnName(), inMapping).getVersionMap().put(timestamp, val);
205 }
206
207 public void setUnMappedCurrentValue(final String familyName,
208 final String columnName,
209 final long timestamp,
210 final byte[] val) throws HBqlException {
211 this.getUnMappedValueMap(familyName, true).setCurrentValueMap(timestamp, columnName, val);
212 }
213
214 public void setUnMappedVersionMap(final String familyName,
215 final String columnName,
216 final NavigableMap<Long, byte[]> val) throws HBqlException {
217 this.getUnMappedValueMap(familyName, true).setVersionMap(columnName, val);
218 }
219
220 public void reset() {
221 this.atomicColumnValuesMap = null;
222 this.atomicUnMappedValuesMap = null;
223 }
224
225 public void setTimestamp(final long timestamp) {
226 this.timestamp = timestamp;
227 }
228
229 public void setCurrentValue(final String name, final Object val) throws HBqlException {
230 this.setCurrentValue(name, this.getTimestamp(), val, true);
231 }
232
233 public boolean isColumnDefined(final String name) throws HBqlException {
234 return this.getColumnValuesMap().findElement(name) != null;
235 }
236
237 public Object getCurrentValue(final String name) throws HBqlException {
238
239 final ColumnValue columnValue = this.getColumnValuesMap().findElement(name);
240 if (columnValue != null) {
241 final Object retval = columnValue.getCurrentValue();
242 if (retval != null) {
243
244 if (retval instanceof Long) {
245 final ColumnAttrib att = this.getMappingContext().getResultAccessor().getColumnAttribByName(name);
246 if (att != null && att.getFieldType() == FieldType.DateType)
247 return new Date((Long)retval);
248 }
249 return retval;
250 }
251 }
252
253
254 final ColumnAttrib attrib = this.getMappingContext().getResultAccessor().getColumnAttribByName(name);
255 return (attrib != null) ? attrib.getDefaultValue() : null;
256 }
257
258 public Set<String> getColumnNameList() throws HBqlException {
259 return this.getColumnValuesMap().keySet();
260 }
261
262 public Map<Long, Object> getVersionMap(final String name) throws HBqlException {
263 final ColumnValue value = this.getColumnValuesMap().findElement(name);
264 return (value != null) ? value.getVersionMap() : null;
265 }
266
267 public Map<String, byte[]> getUnMappedValueMap(final String name) throws HBqlException {
268
269 final UnMappedValueMap value = this.getUnMappedValueMap(name, false);
270 if (value == null)
271 return null;
272
273 final Map<String, byte[]> retval = Maps.newHashMap();
274 for (final String key : value.getCurrentAndVersionMap().keySet())
275 retval.put(key, value.getCurrentAndVersionMap().get(key).getCurrentValue());
276 return retval;
277 }
278
279 public Map<String, NavigableMap<Long, byte[]>> getUnMappedVersionMap(final String name) throws HBqlException {
280
281 final UnMappedValueMap value = this.getUnMappedValueMap(name, false);
282 if (value == null)
283 return null;
284
285 final Map<String, NavigableMap<Long, byte[]>> retval = Maps.newHashMap();
286 for (final String key : value.getCurrentAndVersionMap().keySet())
287 retval.put(key, value.getCurrentAndVersionMap().get(key).getVersionMap());
288 return retval;
289 }
290 }