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