001/*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.client;
021
022import java.io.IOException;
023import java.util.List;
024import java.util.Map;
025import java.util.NavigableMap;
026import java.util.UUID;
027import org.apache.hadoop.hbase.Cell;
028import org.apache.hadoop.hbase.HConstants;
029import org.apache.hadoop.hbase.KeyValue;
030import org.apache.hadoop.hbase.security.access.Permission;
031import org.apache.hadoop.hbase.security.visibility.CellVisibility;
032import org.apache.hadoop.hbase.util.Bytes;
033import org.apache.yetus.audience.InterfaceAudience;
034
035/**
036 * Used to perform Delete operations on a single row.
037 * <p>
038 * To delete an entire row, instantiate a Delete object with the row
039 * to delete.  To further define the scope of what to delete, perform
040 * additional methods as outlined below.
041 * <p>
042 * To delete specific families, execute {@link #addFamily(byte[]) deleteFamily}
043 * for each family to delete.
044 * <p>
045 * To delete multiple versions of specific columns, execute
046 * {@link #addColumns(byte[], byte[]) deleteColumns}
047 * for each column to delete.
048 * <p>
049 * To delete specific versions of specific columns, execute
050 * {@link #addColumn(byte[], byte[], long) deleteColumn}
051 * for each column version to delete.
052 * <p>
053 * Specifying timestamps, deleteFamily and deleteColumns will delete all
054 * versions with a timestamp less than or equal to that passed.  If no
055 * timestamp is specified, an entry is added with a timestamp of 'now'
056 * where 'now' is the servers's System.currentTimeMillis().
057 * Specifying a timestamp to the deleteColumn method will
058 * delete versions only with a timestamp equal to that specified.
059 * If no timestamp is passed to deleteColumn, internally, it figures the
060 * most recent cell's timestamp and adds a delete at that timestamp; i.e.
061 * it deletes the most recently added cell.
062 * <p>The timestamp passed to the constructor is used ONLY for delete of
063 * rows.  For anything less -- a deleteColumn, deleteColumns or
064 * deleteFamily -- then you need to use the method overrides that take a
065 * timestamp.  The constructor timestamp is not referenced.
066 */
067@InterfaceAudience.Public
068public class Delete extends Mutation {
069  /**
070   * Create a Delete operation for the specified row.
071   * <p>
072   * If no further operations are done, this will delete everything
073   * associated with the specified row (all versions of all columns in all
074   * families), with timestamp from current point in time to the past.
075   * Cells defining timestamp for a future point in time
076   * (timestamp > current time) will not be deleted.
077   * @param row row key
078   */
079  public Delete(byte [] row) {
080    this(row, HConstants.LATEST_TIMESTAMP);
081  }
082
083  /**
084   * Create a Delete operation for the specified row and timestamp.<p>
085   *
086   * If no further operations are done, this will delete all columns in all
087   * families of the specified row with a timestamp less than or equal to the
088   * specified timestamp.<p>
089   *
090   * This timestamp is ONLY used for a delete row operation.  If specifying
091   * families or columns, you must specify each timestamp individually.
092   * @param row row key
093   * @param timestamp maximum version timestamp (only for delete row)
094   */
095  public Delete(byte [] row, long timestamp) {
096    this(row, 0, row.length, timestamp);
097  }
098
099  /**
100   * Create a Delete operation for the specified row and timestamp.<p>
101   *
102   * If no further operations are done, this will delete all columns in all
103   * families of the specified row with a timestamp less than or equal to the
104   * specified timestamp.<p>
105   *
106   * This timestamp is ONLY used for a delete row operation.  If specifying
107   * families or columns, you must specify each timestamp individually.
108   * @param row We make a local copy of this passed in row.
109   * @param rowOffset
110   * @param rowLength
111   */
112  public Delete(final byte[] row, final int rowOffset, final int rowLength) {
113    this(row, rowOffset, rowLength, HConstants.LATEST_TIMESTAMP);
114  }
115
116  /**
117   * Create a Delete operation for the specified row and timestamp.<p>
118   *
119   * If no further operations are done, this will delete all columns in all
120   * families of the specified row with a timestamp less than or equal to the
121   * specified timestamp.<p>
122   *
123   * This timestamp is ONLY used for a delete row operation.  If specifying
124   * families or columns, you must specify each timestamp individually.
125   * @param row We make a local copy of this passed in row.
126   * @param rowOffset
127   * @param rowLength
128   * @param timestamp maximum version timestamp (only for delete row)
129   */
130  public Delete(final byte[] row, final int rowOffset, final int rowLength, long timestamp) {
131    checkRow(row, rowOffset, rowLength);
132    this.row = Bytes.copy(row, rowOffset, rowLength);
133    setTimestamp(timestamp);
134  }
135
136  /**
137   * @param deleteToCopy delete to copy
138   */
139  public Delete(final Delete deleteToCopy) {
140    super(deleteToCopy);
141  }
142
143  /**
144   * Construct the Delete with user defined data. NOTED:
145   * 1) all cells in the familyMap must have the delete type.
146   * see {@link org.apache.hadoop.hbase.Cell.Type}
147   * 2) the row of each cell must be same with passed row.
148   * @param row row. CAN'T be null
149   * @param ts timestamp
150   * @param familyMap the map to collect all cells internally. CAN'T be null
151   */
152  public Delete(byte[] row, long ts, NavigableMap<byte [], List<Cell>> familyMap) {
153    super(row, ts, familyMap);
154  }
155
156  /**
157   * Advanced use only. Add an existing delete marker to this Delete object.
158   * @param kv An existing KeyValue of type "delete".
159   * @return this for invocation chaining
160   * @throws IOException
161   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link #add(Cell)}
162   *             instead
163   */
164  @SuppressWarnings("unchecked")
165  @Deprecated
166  public Delete addDeleteMarker(Cell kv) throws IOException {
167    return this.add(kv);
168  }
169
170  /**
171   * Add an existing delete marker to this Delete object.
172   * @param cell An existing cell of type "delete".
173   * @return this for invocation chaining
174   * @throws IOException
175   */
176  public Delete add(Cell cell) throws IOException {
177    super.add(cell);
178    return this;
179  }
180
181  /**
182   * Delete all versions of all columns of the specified family.
183   * <p>
184   * Overrides previous calls to deleteColumn and deleteColumns for the
185   * specified family.
186   * @param family family name
187   * @return this for invocation chaining
188   */
189  public Delete addFamily(final byte [] family) {
190    this.addFamily(family, this.ts);
191    return this;
192  }
193
194  /**
195   * Delete all columns of the specified family with a timestamp less than
196   * or equal to the specified timestamp.
197   * <p>
198   * Overrides previous calls to deleteColumn and deleteColumns for the
199   * specified family.
200   * @param family family name
201   * @param timestamp maximum version timestamp
202   * @return this for invocation chaining
203   */
204  public Delete addFamily(final byte [] family, final long timestamp) {
205    if (timestamp < 0) {
206      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
207    }
208    List<Cell> list = getCellList(family);
209    if(!list.isEmpty()) {
210      list.clear();
211    }
212    KeyValue kv = new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamily);
213    list.add(kv);
214    return this;
215  }
216
217  /**
218   * Delete all columns of the specified family with a timestamp equal to
219   * the specified timestamp.
220   * @param family family name
221   * @param timestamp version timestamp
222   * @return this for invocation chaining
223   */
224  public Delete addFamilyVersion(final byte [] family, final long timestamp) {
225    List<Cell> list = getCellList(family);
226    list.add(new KeyValue(row, family, null, timestamp,
227          KeyValue.Type.DeleteFamilyVersion));
228    return this;
229  }
230
231  /**
232   * Delete all versions of the specified column.
233   * @param family family name
234   * @param qualifier column qualifier
235   * @return this for invocation chaining
236   */
237  public Delete addColumns(final byte [] family, final byte [] qualifier) {
238    addColumns(family, qualifier, this.ts);
239    return this;
240  }
241
242  /**
243   * Delete all versions of the specified column with a timestamp less than
244   * or equal to the specified timestamp.
245   * @param family family name
246   * @param qualifier column qualifier
247   * @param timestamp maximum version timestamp
248   * @return this for invocation chaining
249   */
250  public Delete addColumns(final byte [] family, final byte [] qualifier, final long timestamp) {
251    if (timestamp < 0) {
252      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
253    }
254    List<Cell> list = getCellList(family);
255    list.add(new KeyValue(this.row, family, qualifier, timestamp,
256        KeyValue.Type.DeleteColumn));
257    return this;
258  }
259
260  /**
261   * Delete the latest version of the specified column.
262   * This is an expensive call in that on the server-side, it first does a
263   * get to find the latest versions timestamp.  Then it adds a delete using
264   * the fetched cells timestamp.
265   * @param family family name
266   * @param qualifier column qualifier
267   * @return this for invocation chaining
268   */
269  public Delete addColumn(final byte [] family, final byte [] qualifier) {
270    this.addColumn(family, qualifier, this.ts);
271    return this;
272  }
273
274  /**
275   * Delete the specified version of the specified column.
276   * @param family family name
277   * @param qualifier column qualifier
278   * @param timestamp version timestamp
279   * @return this for invocation chaining
280   */
281  public Delete addColumn(byte [] family, byte [] qualifier, long timestamp) {
282    if (timestamp < 0) {
283      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
284    }
285    List<Cell> list = getCellList(family);
286    KeyValue kv = new KeyValue(this.row, family, qualifier, timestamp, KeyValue.Type.Delete);
287    list.add(kv);
288    return this;
289  }
290
291  @Override
292  public Delete setTimestamp(long timestamp) {
293    super.setTimestamp(timestamp);
294    return this;
295  }
296
297  @Override
298  public Delete setAttribute(String name, byte[] value) {
299    return (Delete) super.setAttribute(name, value);
300  }
301
302  @Override
303  public Delete setId(String id) {
304    return (Delete) super.setId(id);
305  }
306
307  @Override
308  public Delete setDurability(Durability d) {
309    return (Delete) super.setDurability(d);
310  }
311
312  /**
313   * Method for setting the Delete's familyMap
314   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
315   *             Use {@link Delete#Delete(byte[], long, NavigableMap)} instead
316   */
317  @Deprecated
318  @Override
319  public Delete setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
320    return (Delete) super.setFamilyCellMap(map);
321  }
322
323  @Override
324  public Delete setClusterIds(List<UUID> clusterIds) {
325    return (Delete) super.setClusterIds(clusterIds);
326  }
327
328  @Override
329  public Delete setCellVisibility(CellVisibility expression) {
330    return (Delete) super.setCellVisibility(expression);
331  }
332
333  @Override
334  public Delete setACL(String user, Permission perms) {
335    return (Delete) super.setACL(user, perms);
336  }
337
338  @Override
339  public Delete setACL(Map<String, Permission> perms) {
340    return (Delete) super.setACL(perms);
341  }
342
343  @Override
344  public Delete setTTL(long ttl) {
345    throw new UnsupportedOperationException("Setting TTLs on Deletes is not supported");
346  }
347
348  @Override
349  public Delete setPriority(int priority) {
350    return (Delete) super.setPriority(priority);
351  }
352}