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