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