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. nn
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 n * @deprecated As of release 2.0.0, this will be removed
143   *         in HBase 3.0.0. Use {@link #add(Cell)} instead
144   */
145  @SuppressWarnings("unchecked")
146  @Deprecated
147  public Delete addDeleteMarker(Cell kv) throws IOException {
148    return this.add(kv);
149  }
150
151  /**
152   * Add an existing delete marker to this Delete object.
153   * @param cell An existing cell of type "delete".
154   * @return this for invocation chaining n
155   */
156  @Override
157  public Delete add(Cell cell) throws IOException {
158    super.add(cell);
159    return this;
160  }
161
162  /**
163   * Delete all versions of all columns of the specified family.
164   * <p>
165   * Overrides previous calls to deleteColumn and deleteColumns for the specified family.
166   * @param family family name
167   * @return this for invocation chaining
168   */
169  public Delete addFamily(final byte[] family) {
170    this.addFamily(family, this.ts);
171    return this;
172  }
173
174  /**
175   * Delete all columns of the specified family with a timestamp less than or equal to the specified
176   * timestamp.
177   * <p>
178   * Overrides previous calls to deleteColumn and deleteColumns for the specified family.
179   * @param family    family name
180   * @param timestamp maximum version timestamp
181   * @return this for invocation chaining
182   */
183  public Delete addFamily(final byte[] family, final long timestamp) {
184    if (timestamp < 0) {
185      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
186    }
187    List<Cell> list = getCellList(family);
188    if (!list.isEmpty()) {
189      list.clear();
190    }
191    KeyValue kv = new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamily);
192    list.add(kv);
193    return this;
194  }
195
196  /**
197   * Delete all columns of the specified family with a timestamp equal to the specified timestamp.
198   * @param family    family name
199   * @param timestamp version timestamp
200   * @return this for invocation chaining
201   */
202  public Delete addFamilyVersion(final byte[] family, final long timestamp) {
203    if (timestamp < 0) {
204      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
205    }
206    List<Cell> list = getCellList(family);
207    list.add(new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamilyVersion));
208    return this;
209  }
210
211  /**
212   * Delete all versions of the specified column.
213   * @param family    family name
214   * @param qualifier column qualifier
215   * @return this for invocation chaining
216   */
217  public Delete addColumns(final byte[] family, final byte[] qualifier) {
218    addColumns(family, qualifier, this.ts);
219    return this;
220  }
221
222  /**
223   * Delete all versions of the specified column with a timestamp less than or equal to the
224   * specified timestamp.
225   * @param family    family name
226   * @param qualifier column qualifier
227   * @param timestamp maximum version timestamp
228   * @return this for invocation chaining
229   */
230  public Delete addColumns(final byte[] family, final byte[] qualifier, final long timestamp) {
231    if (timestamp < 0) {
232      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
233    }
234    List<Cell> list = getCellList(family);
235    list.add(new KeyValue(this.row, family, qualifier, timestamp, KeyValue.Type.DeleteColumn));
236    return this;
237  }
238
239  /**
240   * Delete the latest version of the specified column. This is an expensive call in that on the
241   * server-side, it first does a get to find the latest versions timestamp. Then it adds a delete
242   * using the fetched cells timestamp.
243   * @param family    family name
244   * @param qualifier column qualifier
245   * @return this for invocation chaining
246   */
247  public Delete addColumn(final byte[] family, final byte[] qualifier) {
248    this.addColumn(family, qualifier, this.ts);
249    return this;
250  }
251
252  /**
253   * Delete the specified version of the specified column.
254   * @param family    family name
255   * @param qualifier column qualifier
256   * @param timestamp version timestamp
257   * @return this for invocation chaining
258   */
259  public Delete addColumn(byte[] family, byte[] qualifier, long timestamp) {
260    if (timestamp < 0) {
261      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
262    }
263    List<Cell> list = getCellList(family);
264    KeyValue kv = new KeyValue(this.row, family, qualifier, timestamp, KeyValue.Type.Delete);
265    list.add(kv);
266    return this;
267  }
268
269  @Override
270  public Delete setTimestamp(long timestamp) {
271    super.setTimestamp(timestamp);
272    return this;
273  }
274
275  @Override
276  public Delete setAttribute(String name, byte[] value) {
277    return (Delete) super.setAttribute(name, value);
278  }
279
280  @Override
281  public Delete setId(String id) {
282    return (Delete) super.setId(id);
283  }
284
285  @Override
286  public Delete setDurability(Durability d) {
287    return (Delete) super.setDurability(d);
288  }
289
290  /**
291   * Method for setting the Delete's familyMap
292   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
293   *             {@link Delete#Delete(byte[], long, NavigableMap)} instead
294   */
295  @Deprecated
296  @Override
297  public Delete setFamilyCellMap(NavigableMap<byte[], List<Cell>> map) {
298    return (Delete) super.setFamilyCellMap(map);
299  }
300
301  @Override
302  public Delete setClusterIds(List<UUID> clusterIds) {
303    return (Delete) super.setClusterIds(clusterIds);
304  }
305
306  @Override
307  public Delete setCellVisibility(CellVisibility expression) {
308    return (Delete) super.setCellVisibility(expression);
309  }
310
311  @Override
312  public Delete setACL(String user, Permission perms) {
313    return (Delete) super.setACL(user, perms);
314  }
315
316  @Override
317  public Delete setACL(Map<String, Permission> perms) {
318    return (Delete) super.setACL(perms);
319  }
320
321  @Override
322  public Delete setTTL(long ttl) {
323    throw new UnsupportedOperationException("Setting TTLs on Deletes is not supported");
324  }
325
326  @Override
327  public Delete setPriority(int priority) {
328    return (Delete) super.setPriority(priority);
329  }
330}