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.CellBuilder;
027import org.apache.hadoop.hbase.CellBuilderType;
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 to delete. To further define
039 * the scope of what to delete, perform additional methods as outlined below.
040 * <p>
041 * To delete specific families, execute {@link #addFamily(byte[]) deleteFamily} for each family to
042 * delete.
043 * <p>
044 * To delete multiple versions of specific columns, execute {@link #addColumns(byte[], byte[])
045 * deleteColumns} for each column to delete.
046 * <p>
047 * To delete specific versions of specific columns, execute {@link #addColumn(byte[], byte[], long)
048 * deleteColumn} for each column version to delete.
049 * <p>
050 * Specifying timestamps, deleteFamily and deleteColumns will delete all versions with a timestamp
051 * less than or equal to that passed. If no timestamp is specified, an entry is added with a
052 * timestamp of 'now' where 'now' is the servers's EnvironmentEdgeManager.currentTime(). Specifying
053 * a timestamp to the deleteColumn method will delete versions only with a timestamp equal to that
054 * specified. If no timestamp is passed to deleteColumn, internally, it figures the most recent
055 * cell's timestamp and adds a delete at that timestamp; i.e. it deletes the most recently added
056 * cell.
057 * <p>
058 * The timestamp passed to the constructor is used ONLY for delete of rows. For anything less -- a
059 * deleteColumn, deleteColumns or deleteFamily -- then you need to use the method overrides that
060 * take a timestamp. The constructor timestamp is not referenced.
061 */
062@InterfaceAudience.Public
063public class Delete extends Mutation {
064  /**
065   * Create a Delete operation for the specified row.
066   * <p>
067   * If no further operations are done, this will delete everything associated with the specified
068   * row (all versions of all columns in all families), with timestamp from current point in time to
069   * the past. Cells defining timestamp for a future point in time (timestamp > current time) will
070   * not be deleted.
071   * @param row row key
072   */
073  public Delete(byte[] row) {
074    this(row, HConstants.LATEST_TIMESTAMP);
075  }
076
077  /**
078   * Create a Delete operation for the specified row and timestamp.
079   * <p>
080   * If no further operations are done, this will delete all columns in all families of the
081   * specified row with a timestamp less than or equal to the specified timestamp.
082   * <p>
083   * This timestamp is ONLY used for a delete row operation. If specifying families or columns, you
084   * must specify each timestamp individually.
085   * @param row       row key
086   * @param timestamp maximum version timestamp (only for delete row)
087   */
088  public Delete(byte[] row, long timestamp) {
089    this(row, 0, row.length, timestamp);
090  }
091
092  /**
093   * Create a Delete operation for the specified row and timestamp.
094   * <p>
095   * If no further operations are done, this will delete all columns in all families of the
096   * specified row with a timestamp less than or equal to the specified timestamp.
097   * <p>
098   * This timestamp is ONLY used for a delete row operation. If specifying families or columns, you
099   * must specify each timestamp individually.
100   * @param row We make a local copy of this passed in row.
101   */
102  public Delete(final byte[] row, final int rowOffset, final int rowLength) {
103    this(row, rowOffset, rowLength, HConstants.LATEST_TIMESTAMP);
104  }
105
106  /**
107   * Create a Delete operation for the specified row and timestamp.
108   * <p>
109   * If no further operations are done, this will delete all columns in all families of the
110   * specified row with a timestamp less than or equal to the specified timestamp.
111   * <p>
112   * This timestamp is ONLY used for a delete row operation. If specifying families or columns, you
113   * must specify each timestamp individually.
114   */
115  public Delete(final byte[] row, final int rowOffset, final int rowLength, long timestamp) {
116    checkRow(row, rowOffset, rowLength);
117    this.row = Bytes.copy(row, rowOffset, rowLength);
118    setTimestamp(timestamp);
119  }
120
121  /**
122   * Create a Delete operation using another Delete as template.
123   * @param deleteToCopy delete to copy
124   */
125  public Delete(final Delete deleteToCopy) {
126    super(deleteToCopy);
127  }
128
129  /**
130   * Construct the Delete with user defined data. NOTED: 1) all cells in the familyMap must have the
131   * delete type. see {@link org.apache.hadoop.hbase.Cell.Type} 2) the row of each cell must be same
132   * with passed row.
133   * @param row       row. CAN'T be null
134   * @param ts        timestamp
135   * @param familyMap the map to collect all cells internally. CAN'T be null
136   */
137  public Delete(byte[] row, long ts, NavigableMap<byte[], List<Cell>> familyMap) {
138    super(row, ts, familyMap);
139  }
140
141  /**
142   * Add an existing delete marker to this Delete object.
143   * @param cell An existing cell of type "delete".
144   * @return this for invocation chaining
145   */
146  @Override
147  public Delete add(Cell cell) throws IOException {
148    super.add(cell);
149    return this;
150  }
151
152  /**
153   * Delete all versions of all columns of the specified family.
154   * <p>
155   * Overrides previous calls to deleteColumn and deleteColumns for the specified family.
156   * @param family family name
157   * @return this for invocation chaining
158   */
159  public Delete addFamily(final byte[] family) {
160    this.addFamily(family, this.ts);
161    return this;
162  }
163
164  /**
165   * Delete all columns of the specified family with a timestamp less than or equal to the specified
166   * timestamp.
167   * <p>
168   * Overrides previous calls to deleteColumn and deleteColumns for the specified family.
169   * @param family    family name
170   * @param timestamp maximum version timestamp
171   * @return this for invocation chaining
172   */
173  public Delete addFamily(final byte[] family, final long timestamp) {
174    if (timestamp < 0) {
175      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
176    }
177    List<Cell> list = getCellList(family);
178    if (!list.isEmpty()) {
179      list.clear();
180    }
181    KeyValue kv = new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamily);
182    list.add(kv);
183    return this;
184  }
185
186  /**
187   * Delete all columns of the specified family with a timestamp equal to the specified timestamp.
188   * @param family    family name
189   * @param timestamp version timestamp
190   * @return this for invocation chaining
191   */
192  public Delete addFamilyVersion(final byte[] family, final long timestamp) {
193    if (timestamp < 0) {
194      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
195    }
196    List<Cell> list = getCellList(family);
197    list.add(new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamilyVersion));
198    return this;
199  }
200
201  /**
202   * Delete all versions of the specified column.
203   * @param family    family name
204   * @param qualifier column qualifier
205   * @return this for invocation chaining
206   */
207  public Delete addColumns(final byte[] family, final byte[] qualifier) {
208    addColumns(family, qualifier, this.ts);
209    return this;
210  }
211
212  /**
213   * Delete all versions of the specified column with a timestamp less than or equal to the
214   * specified timestamp.
215   * @param family    family name
216   * @param qualifier column qualifier
217   * @param timestamp maximum version timestamp
218   * @return this for invocation chaining
219   */
220  public Delete addColumns(final byte[] family, final byte[] qualifier, final long timestamp) {
221    if (timestamp < 0) {
222      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
223    }
224    List<Cell> list = getCellList(family);
225    list.add(new KeyValue(this.row, family, qualifier, timestamp, KeyValue.Type.DeleteColumn));
226    return this;
227  }
228
229  /**
230   * Delete the latest version of the specified column. This is an expensive call in that on the
231   * server-side, it first does a get to find the latest versions timestamp. Then it adds a delete
232   * using the fetched cells timestamp.
233   * @param family    family name
234   * @param qualifier column qualifier
235   * @return this for invocation chaining
236   */
237  public Delete addColumn(final byte[] family, final byte[] qualifier) {
238    this.addColumn(family, qualifier, this.ts);
239    return this;
240  }
241
242  /**
243   * Delete the specified version of the specified column.
244   * @param family    family name
245   * @param qualifier column qualifier
246   * @param timestamp version timestamp
247   * @return this for invocation chaining
248   */
249  public Delete addColumn(byte[] family, byte[] qualifier, long timestamp) {
250    if (timestamp < 0) {
251      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp);
252    }
253    List<Cell> list = getCellList(family);
254    KeyValue kv = new KeyValue(this.row, family, qualifier, timestamp, KeyValue.Type.Delete);
255    list.add(kv);
256    return this;
257  }
258
259  @Override
260  public Delete setTimestamp(long timestamp) {
261    super.setTimestamp(timestamp);
262    return this;
263  }
264
265  @Override
266  public Delete setAttribute(String name, byte[] value) {
267    return (Delete) super.setAttribute(name, value);
268  }
269
270  @Override
271  public Delete setId(String id) {
272    return (Delete) super.setId(id);
273  }
274
275  @Override
276  public Delete setDurability(Durability d) {
277    return (Delete) super.setDurability(d);
278  }
279
280  @Override
281  public Delete setClusterIds(List<UUID> clusterIds) {
282    return (Delete) super.setClusterIds(clusterIds);
283  }
284
285  @Override
286  public Delete setCellVisibility(CellVisibility expression) {
287    return (Delete) super.setCellVisibility(expression);
288  }
289
290  @Override
291  public Delete setACL(String user, Permission perms) {
292    return (Delete) super.setACL(user, perms);
293  }
294
295  @Override
296  public Delete setACL(Map<String, Permission> perms) {
297    return (Delete) super.setACL(perms);
298  }
299
300  @Override
301  public Delete setTTL(long ttl) {
302    throw new UnsupportedOperationException("Setting TTLs on Deletes is not supported");
303  }
304
305  @Override
306  public Delete setPriority(int priority) {
307    return (Delete) super.setPriority(priority);
308  }
309
310  @Override
311  public CellBuilder getCellBuilder(CellBuilderType type) {
312    return getCellBuilder(type, Cell.Type.Delete);
313  }
314}