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}