View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.client;
21  
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.NavigableMap;
27  import java.util.UUID;
28  
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  import org.apache.hadoop.hbase.classification.InterfaceStability;
31  import org.apache.hadoop.hbase.Cell;
32  import org.apache.hadoop.hbase.CellUtil;
33  import org.apache.hadoop.hbase.HConstants;
34  import org.apache.hadoop.hbase.KeyValue;
35  import org.apache.hadoop.hbase.security.access.Permission;
36  import org.apache.hadoop.hbase.security.visibility.CellVisibility;
37  import org.apache.hadoop.hbase.util.Bytes;
38  
39  /**
40   * Used to perform Delete operations on a single row.
41   * <p>
42   * To delete an entire row, instantiate a Delete object with the row
43   * to delete.  To further define the scope of what to delete, perform
44   * additional methods as outlined below.
45   * <p>
46   * To delete specific families, execute {@link #addFamily(byte[]) deleteFamily}
47   * for each family to delete.
48   * <p>
49   * To delete multiple versions of specific columns, execute
50   * {@link #addColumns(byte[], byte[]) deleteColumns}
51   * for each column to delete.
52   * <p>
53   * To delete specific versions of specific columns, execute
54   * {@link #addColumn(byte[], byte[], long) deleteColumn}
55   * for each column version to delete.
56   * <p>
57   * Specifying timestamps, deleteFamily and deleteColumns will delete all
58   * versions with a timestamp less than or equal to that passed.  If no
59   * timestamp is specified, an entry is added with a timestamp of 'now'
60   * where 'now' is the servers's System.currentTimeMillis().
61   * Specifying a timestamp to the deleteColumn method will
62   * delete versions only with a timestamp equal to that specified.
63   * If no timestamp is passed to deleteColumn, internally, it figures the
64   * most recent cell's timestamp and adds a delete at that timestamp; i.e.
65   * it deletes the most recently added cell.
66   * <p>The timestamp passed to the constructor is used ONLY for delete of
67   * rows.  For anything less -- a deleteColumn, deleteColumns or
68   * deleteFamily -- then you need to use the method overrides that take a
69   * timestamp.  The constructor timestamp is not referenced.
70   */
71  @InterfaceAudience.Public
72  @InterfaceStability.Stable
73  public class Delete extends Mutation implements Comparable<Row> {
74    /**
75     * Create a Delete operation for the specified row.
76     * <p>
77     * If no further operations are done, this will delete everything
78     * associated with the specified row (all versions of all columns in all
79     * families).
80     * @param row row key
81     */
82    public Delete(byte [] row) {
83      this(row, HConstants.LATEST_TIMESTAMP);
84    }
85  
86    /**
87     * Create a Delete operation for the specified row and timestamp.<p>
88     *
89     * If no further operations are done, this will delete all columns in all
90     * families of the specified row with a timestamp less than or equal to the
91     * specified timestamp.<p>
92     *
93     * This timestamp is ONLY used for a delete row operation.  If specifying
94     * families or columns, you must specify each timestamp individually.
95     * @param row row key
96     * @param timestamp maximum version timestamp (only for delete row)
97     */
98    public Delete(byte [] row, long timestamp) {
99      this(row, 0, row.length, timestamp);
100   }
101 
102   /**
103    * Create a Delete operation for the specified row and timestamp.<p>
104    *
105    * If no further operations are done, this will delete all columns in all
106    * families of the specified row with a timestamp less than or equal to the
107    * specified timestamp.<p>
108    *
109    * This timestamp is ONLY used for a delete row operation.  If specifying
110    * families or columns, you must specify each timestamp individually.
111    * @param rowArray We make a local copy of this passed in row.
112    * @param rowOffset
113    * @param rowLength
114    */
115   public Delete(final byte [] rowArray, final int rowOffset, final int rowLength) {
116     this(rowArray, rowOffset, rowLength, HConstants.LATEST_TIMESTAMP);
117   }
118 
119   /**
120    * Create a Delete operation for the specified row and timestamp.<p>
121    *
122    * If no further operations are done, this will delete all columns in all
123    * families of the specified row with a timestamp less than or equal to the
124    * specified timestamp.<p>
125    *
126    * This timestamp is ONLY used for a delete row operation.  If specifying
127    * families or columns, you must specify each timestamp individually.
128    * @param rowArray We make a local copy of this passed in row.
129    * @param rowOffset
130    * @param rowLength
131    * @param ts maximum version timestamp (only for delete row)
132    */
133   public Delete(final byte [] rowArray, final int rowOffset, final int rowLength, long ts) {
134     checkRow(rowArray, rowOffset, rowLength);
135     this.row = Bytes.copy(rowArray, rowOffset, rowLength);
136     setTimestamp(ts);
137   }
138 
139   /**
140    * @param d Delete to clone.
141    */
142   public Delete(final Delete d) {
143     this.row = d.getRow();
144     this.ts = d.getTimeStamp();
145     this.familyMap.putAll(d.getFamilyCellMap());
146     this.durability = d.durability;
147     for (Map.Entry<String, byte[]> entry : d.getAttributesMap().entrySet()) {
148       this.setAttribute(entry.getKey(), entry.getValue());
149     }
150     super.setPriority(d.getPriority());
151   }
152 
153   /**
154    * Advanced use only.
155    * Add an existing delete marker to this Delete object.
156    * @param kv An existing KeyValue of type "delete".
157    * @return this for invocation chaining
158    * @throws IOException
159    */
160   @SuppressWarnings("unchecked")
161   public Delete addDeleteMarker(Cell kv) throws IOException {
162     // TODO: Deprecate and rename 'add' so it matches how we add KVs to Puts.
163     if (!CellUtil.isDelete(kv)) {
164       throw new IOException("The recently added KeyValue is not of type "
165           + "delete. Rowkey: " + Bytes.toStringBinary(this.row));
166     }
167     if (Bytes.compareTo(this.row, 0, row.length, kv.getRowArray(),
168         kv.getRowOffset(), kv.getRowLength()) != 0) {
169       throw new WrongRowIOException("The row in " + kv.toString() +
170         " doesn't match the original one " +  Bytes.toStringBinary(this.row));
171     }
172     byte [] family = CellUtil.cloneFamily(kv);
173     List<Cell> list = getCellList(family);
174     list.add(kv);
175     return this;
176   }
177 
178   /**
179    * Delete all versions of all columns of the specified family.
180    * <p>
181    * Overrides previous calls to deleteColumn and deleteColumns for the
182    * specified family.
183    * @param family family name
184    * @return this for invocation chaining
185    * @deprecated Since 1.0.0. Use {@link #addFamily(byte[])}
186    */
187   @Deprecated
188   public Delete deleteFamily(byte [] family) {
189     return addFamily(family);
190   }
191 
192   /**
193    * Delete all versions of all columns of the specified family.
194    * <p>
195    * Overrides previous calls to deleteColumn and deleteColumns for the
196    * specified family.
197    * @param family family name
198    * @return this for invocation chaining
199    */
200   public Delete addFamily(final byte [] family) {
201     this.deleteFamily(family, this.ts);
202     return this;
203   }
204 
205   /**
206    * Delete all columns of the specified family with a timestamp less than
207    * or equal to the specified timestamp.
208    * <p>
209    * Overrides previous calls to deleteColumn and deleteColumns for the
210    * specified family.
211    * @param family family name
212    * @param timestamp maximum version timestamp
213    * @return this for invocation chaining
214    * @deprecated Since 1.0.0. Use {@link #addFamily(byte[], long)}
215    */
216   @Deprecated
217   public Delete deleteFamily(byte [] family, long timestamp) {
218     return addFamily(family, timestamp);
219   }
220 
221   /**
222    * Delete all columns of the specified family with a timestamp less than
223    * or equal to the specified timestamp.
224    * <p>
225    * Overrides previous calls to deleteColumn and deleteColumns for the
226    * specified family.
227    * @param family family name
228    * @param timestamp maximum version timestamp
229    * @return this for invocation chaining
230    */
231   public Delete addFamily(final byte [] family, final long timestamp) {
232     if (timestamp < 0) {
233       throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
234     }
235     List<Cell> list = getCellList(family);
236     if(!list.isEmpty()) {
237       list.clear();
238     }
239     KeyValue kv = new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamily);
240     list.add(kv);
241     return this;
242   }
243 
244   /**
245    * Delete all columns of the specified family with a timestamp equal to
246    * the specified timestamp.
247    * @param family family name
248    * @param timestamp version timestamp
249    * @return this for invocation chaining
250    * @deprecated Since hbase-1.0.0. Use {@link #addFamilyVersion(byte[], long)}
251    */
252   @Deprecated
253   public Delete deleteFamilyVersion(byte [] family, long timestamp) {
254     return addFamilyVersion(family, timestamp);
255   }
256 
257   /**
258    * Delete all columns of the specified family with a timestamp equal to
259    * the specified timestamp.
260    * @param family family name
261    * @param timestamp version timestamp
262    * @return this for invocation chaining
263    */
264   public Delete addFamilyVersion(final byte [] family, final long timestamp) {
265     List<Cell> list = getCellList(family);
266     list.add(new KeyValue(row, family, null, timestamp,
267           KeyValue.Type.DeleteFamilyVersion));
268     return this;
269   }
270 
271   /**
272    * Delete all versions of the specified column.
273    * @param family family name
274    * @param qualifier column qualifier
275    * @return this for invocation chaining
276    * @deprecated Since hbase-1.0.0. Use {@link #addColumns(byte[], byte[])}
277    */
278   @Deprecated
279   public Delete deleteColumns(byte [] family, byte [] qualifier) {
280     return addColumns(family, qualifier);
281   }
282 
283   /**
284    * Delete all versions of the specified column.
285    * @param family family name
286    * @param qualifier column qualifier
287    * @return this for invocation chaining
288    */
289   public Delete addColumns(final byte [] family, final byte [] qualifier) {
290     addColumns(family, qualifier, this.ts);
291     return this;
292   }
293 
294   /**
295    * Delete all versions of the specified column with a timestamp less than
296    * or equal to the specified timestamp.
297    * @param family family name
298    * @param qualifier column qualifier
299    * @param timestamp maximum version timestamp
300    * @return this for invocation chaining
301    * @deprecated Since hbase-1.0.0. Use {@link #addColumns(byte[], byte[], long)}
302    */
303   @Deprecated
304   public Delete deleteColumns(byte [] family, byte [] qualifier, long timestamp) {
305     return addColumns(family, qualifier, timestamp);
306   }
307 
308   /**
309    * Delete all versions of the specified column with a timestamp less than
310    * or equal to the specified timestamp.
311    * @param family family name
312    * @param qualifier column qualifier
313    * @param timestamp maximum version timestamp
314    * @return this for invocation chaining
315    */
316   public Delete addColumns(final byte [] family, final byte [] qualifier, final long timestamp) {
317     if (timestamp < 0) {
318       throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
319     }
320     List<Cell> list = getCellList(family);
321     list.add(new KeyValue(this.row, family, qualifier, timestamp,
322         KeyValue.Type.DeleteColumn));
323     return this;
324   }
325 
326   /**
327    * Delete the latest version of the specified column.
328    * This is an expensive call in that on the server-side, it first does a
329    * get to find the latest versions timestamp.  Then it adds a delete using
330    * the fetched cells timestamp.
331    * @param family family name
332    * @param qualifier column qualifier
333    * @return this for invocation chaining
334    * @deprecated Since hbase-1.0.0. Use {@link #addColumn(byte[], byte[])}
335    */
336   @Deprecated
337   public Delete deleteColumn(byte [] family, byte [] qualifier) {
338     return addColumn(family, qualifier);
339   }
340 
341   /**
342    * Delete the latest version of the specified column.
343    * This is an expensive call in that on the server-side, it first does a
344    * get to find the latest versions timestamp.  Then it adds a delete using
345    * the fetched cells timestamp.
346    * @param family family name
347    * @param qualifier column qualifier
348    * @return this for invocation chaining
349    */
350   public Delete addColumn(final byte [] family, final byte [] qualifier) {
351     this.deleteColumn(family, qualifier, this.ts);
352     return this;
353   }
354 
355   /**
356    * Delete the specified version of the specified column.
357    * @param family family name
358    * @param qualifier column qualifier
359    * @param timestamp version timestamp
360    * @return this for invocation chaining
361    * @deprecated Since hbase-1.0.0. Use {@link #addColumn(byte[], byte[], long)}
362    */
363   @Deprecated
364   public Delete deleteColumn(byte [] family, byte [] qualifier, long timestamp) {
365     return addColumn(family, qualifier, timestamp);
366   }
367 
368   /**
369    * Delete the specified version of the specified column.
370    * @param family family name
371    * @param qualifier column qualifier
372    * @param timestamp version timestamp
373    * @return this for invocation chaining
374    */
375   public Delete addColumn(byte [] family, byte [] qualifier, long timestamp) {
376     if (timestamp < 0) {
377       throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
378     }
379     List<Cell> list = getCellList(family);
380     KeyValue kv = new KeyValue(this.row, family, qualifier, timestamp, KeyValue.Type.Delete);
381     list.add(kv);
382     return this;
383   }
384 
385   /**
386    * Set the timestamp of the delete.
387    *
388    * @param timestamp
389    */
390   public Delete setTimestamp(long timestamp) {
391     if (timestamp < 0) {
392       throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
393     }
394     this.ts = timestamp;
395     return this;
396   }
397 
398   @Override
399   public Map<String, Object> toMap(int maxCols) {
400     // we start with the fingerprint map and build on top of it.
401     Map<String, Object> map = super.toMap(maxCols);
402     // why is put not doing this?
403     map.put("ts", this.ts);
404     return map;
405   }
406 
407   @Override
408   public Delete setAttribute(String name, byte[] value) {
409     return (Delete) super.setAttribute(name, value);
410   }
411 
412   @Override
413   public Delete setId(String id) {
414     return (Delete) super.setId(id);
415   }
416 
417   @Override
418   @Deprecated
419   public Delete setWriteToWAL(boolean write) {
420     return (Delete) super.setWriteToWAL(write);
421   }
422 
423   @Override
424   public Delete setDurability(Durability d) {
425     return (Delete) super.setDurability(d);
426   }
427 
428   @Override
429   public Delete setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
430     return (Delete) super.setFamilyCellMap(map);
431   }
432 
433   @Override
434   @Deprecated
435   public Delete setFamilyMap(NavigableMap<byte[], List<KeyValue>> map) {
436     return (Delete) super.setFamilyMap(map);
437   }
438 
439   @Override
440   public Delete setClusterIds(List<UUID> clusterIds) {
441     return (Delete) super.setClusterIds(clusterIds);
442   }
443 
444   @Override
445   public Delete setCellVisibility(CellVisibility expression) {
446     return (Delete) super.setCellVisibility(expression);
447   }
448 
449   @Override
450   public Delete setACL(String user, Permission perms) {
451     return (Delete) super.setACL(user, perms);
452   }
453 
454   @Override
455   public Delete setACL(Map<String, Permission> perms) {
456     return (Delete) super.setACL(perms);
457   }
458 
459   @Override
460   public Delete setTTL(long ttl) {
461     throw new UnsupportedOperationException("Setting TTLs on Deletes is not supported");
462   }
463 
464   @Override
465   public Delete setPriority(int priority) {
466     return (Delete) super.setPriority(priority);
467   }
468 
469 }