Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/notifications/notification_database.h" | 5 #include "content/browser/notifications/notification_database.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 24 | 24 |
| 25 // Notification LevelDB database schema (in alphabetized order) | 25 // Notification LevelDB database schema (in alphabetized order) |
| 26 // ======================= | 26 // ======================= |
| 27 // | 27 // |
| 28 // key: "DATA:" <origin identifier> '\x00' <notification_id> | 28 // key: "DATA:" <origin identifier> '\x00' <notification_id> |
| 29 // value: String containing the NotificationDatabaseDataProto protocol buffer | 29 // value: String containing the NotificationDatabaseDataProto protocol buffer |
| 30 // in serialized form. | 30 // in serialized form. |
| 31 // | 31 // |
| 32 // key: "NEXT_NOTIFICATION_ID" | 32 // key: "NEXT_NOTIFICATION_ID" |
| 33 // value: Decimal string which fits into an int64_t. | 33 // value: Decimal string which fits into an int64_t. |
|
johnme
2016/09/07 17:13:14
"Decimal string that fits into an int64_t, contain
Peter Beverloo
2016/09/08 13:18:56
Done.
| |
| 34 | 34 |
| 35 namespace content { | 35 namespace content { |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 // Keys of the fields defined in the database. | 38 // Keys of the fields defined in the database. |
| 39 const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID"; | 39 const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID"; |
|
johnme
2016/09/07 17:13:13
kNextPersistentNotificationIdKey?
Peter Beverloo
2016/09/08 13:18:56
The name ideally should match the key. We shouldn'
| |
| 40 const char kDataKeyPrefix[] = "DATA:"; | 40 const char kDataKeyPrefix[] = "DATA:"; |
| 41 | 41 |
| 42 // Separates the components of compound keys. | 42 // Separates the components of compound keys. |
| 43 const char kKeySeparator = '\x00'; | 43 const char kKeySeparator = '\x00'; |
| 44 | 44 |
| 45 // The first notification id which to be handed out by the database. | 45 // The first notification id which to be handed out by the database. |
| 46 const int64_t kFirstNotificationId = 1; | 46 const int64_t kFirstPersistentNotificationId = 1; |
| 47 | 47 |
| 48 // Converts the LevelDB |status| to one of the notification database's values. | 48 // Converts the LevelDB |status| to one of the notification database's values. |
| 49 NotificationDatabase::Status LevelDBStatusToStatus( | 49 NotificationDatabase::Status LevelDBStatusToStatus( |
| 50 const leveldb::Status& status) { | 50 const leveldb::Status& status) { |
| 51 if (status.ok()) | 51 if (status.ok()) |
| 52 return NotificationDatabase::STATUS_OK; | 52 return NotificationDatabase::STATUS_OK; |
| 53 else if (status.IsNotFound()) | 53 else if (status.IsNotFound()) |
| 54 return NotificationDatabase::STATUS_ERROR_NOT_FOUND; | 54 return NotificationDatabase::STATUS_ERROR_NOT_FOUND; |
| 55 else if (status.IsCorruption()) | 55 else if (status.IsCorruption()) |
| 56 return NotificationDatabase::STATUS_ERROR_CORRUPTED; | 56 return NotificationDatabase::STATUS_ERROR_CORRUPTED; |
| 57 else if (status.IsIOError()) | 57 else if (status.IsIOError()) |
| 58 return NotificationDatabase::STATUS_IO_ERROR; | 58 return NotificationDatabase::STATUS_IO_ERROR; |
| 59 else if (status.IsNotSupportedError()) | 59 else if (status.IsNotSupportedError()) |
| 60 return NotificationDatabase::STATUS_NOT_SUPPORTED; | 60 return NotificationDatabase::STATUS_NOT_SUPPORTED; |
| 61 else if (status.IsInvalidArgument()) | 61 else if (status.IsInvalidArgument()) |
| 62 return NotificationDatabase::STATUS_INVALID_ARGUMENT; | 62 return NotificationDatabase::STATUS_INVALID_ARGUMENT; |
| 63 | 63 |
| 64 return NotificationDatabase::STATUS_ERROR_FAILED; | 64 return NotificationDatabase::STATUS_ERROR_FAILED; |
| 65 } | 65 } |
| 66 | 66 |
| 67 // Creates a prefix for the data entries based on |origin|. | 67 // Creates a prefix for the data entries based on |origin|. |
| 68 std::string CreateDataPrefix(const GURL& origin) { | 68 std::string CreateDataPrefix(const GURL& origin) { |
| 69 if (!origin.is_valid()) | 69 if (!origin.is_valid()) |
| 70 return kDataKeyPrefix; | 70 return kDataKeyPrefix; |
| 71 | 71 |
| 72 return base::StringPrintf("%s%s%c", kDataKeyPrefix, | 72 return base::StringPrintf("%s%s%c", kDataKeyPrefix, |
| 73 storage::GetIdentifierFromOrigin(origin).c_str(), | 73 storage::GetIdentifierFromOrigin(origin).c_str(), |
|
johnme
2016/09/07 17:13:14
Drive-by: DatabaseIdentifier::CreateFromOrigin has
Peter Beverloo
2016/09/08 13:18:56
Yes.
| |
| 74 kKeySeparator); | 74 kKeySeparator); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Creates the compound data key in which notification data is stored. | 77 // Creates the compound data key in which notification data is stored. |
| 78 std::string CreateDataKey(const GURL& origin, int64_t notification_id) { | 78 std::string CreateDataKey(const GURL& origin, |
| 79 const std::string& notification_id) { | |
| 79 DCHECK(origin.is_valid()); | 80 DCHECK(origin.is_valid()); |
| 80 return CreateDataPrefix(origin) + base::Int64ToString(notification_id); | 81 DCHECK(!notification_id.empty()); |
| 82 | |
| 83 return CreateDataPrefix(origin) + notification_id; | |
| 81 } | 84 } |
| 82 | 85 |
| 83 // Deserializes data in |serialized_data| to |notification_database_data|. | 86 // Deserializes data in |serialized_data| to |notification_database_data|. |
| 84 // Will return if the deserialization was successful. | 87 // Will return if the deserialization was successful. |
| 85 NotificationDatabase::Status DeserializedNotificationData( | 88 NotificationDatabase::Status DeserializedNotificationData( |
| 86 const std::string& serialized_data, | 89 const std::string& serialized_data, |
| 87 NotificationDatabaseData* notification_database_data) { | 90 NotificationDatabaseData* notification_database_data) { |
| 88 DCHECK(notification_database_data); | 91 DCHECK(notification_database_data); |
| 89 if (DeserializeNotificationDatabaseData(serialized_data, | 92 if (DeserializeNotificationDatabaseData(serialized_data, |
| 90 notification_database_data)) { | 93 notification_database_data)) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db)); | 136 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db)); |
| 134 if (status != STATUS_OK) | 137 if (status != STATUS_OK) |
| 135 return status; | 138 return status; |
| 136 | 139 |
| 137 state_ = STATE_INITIALIZED; | 140 state_ = STATE_INITIALIZED; |
| 138 db_.reset(db); | 141 db_.reset(db); |
| 139 | 142 |
| 140 return ReadNextNotificationId(); | 143 return ReadNextNotificationId(); |
| 141 } | 144 } |
| 142 | 145 |
| 146 int64_t NotificationDatabase::GetNextNotificationId() { | |
| 147 return next_persistent_notification_id_++; | |
| 148 } | |
| 149 | |
| 143 NotificationDatabase::Status NotificationDatabase::ReadNotificationData( | 150 NotificationDatabase::Status NotificationDatabase::ReadNotificationData( |
| 144 int64_t notification_id, | 151 const std::string& notification_id, |
| 145 const GURL& origin, | 152 const GURL& origin, |
| 146 NotificationDatabaseData* notification_database_data) const { | 153 NotificationDatabaseData* notification_database_data) const { |
| 147 DCHECK(sequence_checker_.CalledOnValidSequence()); | 154 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 148 DCHECK_EQ(STATE_INITIALIZED, state_); | 155 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 149 DCHECK_GE(notification_id, kFirstNotificationId); | 156 DCHECK(!notification_id.empty()); |
| 150 DCHECK(origin.is_valid()); | 157 DCHECK(origin.is_valid()); |
| 151 DCHECK(notification_database_data); | 158 DCHECK(notification_database_data); |
| 152 | 159 |
| 153 std::string key = CreateDataKey(origin, notification_id); | 160 std::string key = CreateDataKey(origin, notification_id); |
| 154 std::string serialized_data; | 161 std::string serialized_data; |
| 155 | 162 |
| 156 Status status = LevelDBStatusToStatus( | 163 Status status = LevelDBStatusToStatus( |
| 157 db_->Get(leveldb::ReadOptions(), key, &serialized_data)); | 164 db_->Get(leveldb::ReadOptions(), key, &serialized_data)); |
| 158 if (status != STATUS_OK) | 165 if (status != STATUS_OK) |
| 159 return status; | 166 return status; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 181 NotificationDatabase::ReadAllNotificationDataForServiceWorkerRegistration( | 188 NotificationDatabase::ReadAllNotificationDataForServiceWorkerRegistration( |
| 182 const GURL& origin, | 189 const GURL& origin, |
| 183 int64_t service_worker_registration_id, | 190 int64_t service_worker_registration_id, |
| 184 std::vector<NotificationDatabaseData>* notification_data_vector) const { | 191 std::vector<NotificationDatabaseData>* notification_data_vector) const { |
| 185 return ReadAllNotificationDataInternal(origin, service_worker_registration_id, | 192 return ReadAllNotificationDataInternal(origin, service_worker_registration_id, |
| 186 notification_data_vector); | 193 notification_data_vector); |
| 187 } | 194 } |
| 188 | 195 |
| 189 NotificationDatabase::Status NotificationDatabase::WriteNotificationData( | 196 NotificationDatabase::Status NotificationDatabase::WriteNotificationData( |
| 190 const GURL& origin, | 197 const GURL& origin, |
| 191 const NotificationDatabaseData& notification_database_data, | 198 const NotificationDatabaseData& notification_data) { |
| 192 int64_t* notification_id) { | |
| 193 DCHECK(sequence_checker_.CalledOnValidSequence()); | 199 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 194 DCHECK_EQ(STATE_INITIALIZED, state_); | 200 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 195 DCHECK(notification_id); | |
| 196 DCHECK(origin.is_valid()); | 201 DCHECK(origin.is_valid()); |
| 197 | 202 |
| 198 DCHECK_GE(next_notification_id_, kFirstNotificationId); | 203 const std::string& notification_id = notification_data.notification_id; |
| 199 | 204 DCHECK(!notification_id.empty()); |
| 200 NotificationDatabaseData storage_data = notification_database_data; | |
| 201 storage_data.notification_id = next_notification_id_; | |
| 202 | 205 |
| 203 std::string serialized_data; | 206 std::string serialized_data; |
| 204 if (!SerializeNotificationDatabaseData(storage_data, &serialized_data)) { | 207 if (!SerializeNotificationDatabaseData(notification_data, &serialized_data)) { |
| 205 DLOG(ERROR) << "Unable to serialize data for a notification belonging " | 208 DLOG(ERROR) << "Unable to serialize data for a notification belonging " |
| 206 << "to: " << origin; | 209 << "to: " << origin; |
| 207 return STATUS_ERROR_FAILED; | 210 return STATUS_ERROR_FAILED; |
| 208 } | 211 } |
| 209 | 212 |
| 210 leveldb::WriteBatch batch; | 213 leveldb::WriteBatch batch; |
| 211 batch.Put(CreateDataKey(origin, next_notification_id_), serialized_data); | 214 batch.Put(CreateDataKey(origin, notification_id), serialized_data); |
| 212 batch.Put(kNextNotificationIdKey, | |
| 213 base::Int64ToString(next_notification_id_ + 1)); | |
| 214 | 215 |
| 215 Status status = | 216 if (written_persistent_notification_id_ != next_persistent_notification_id_) { |
|
johnme
2016/09/07 17:13:13
I like that if you create two and successfully wri
Peter Beverloo
2016/09/08 13:18:56
That's fine. We have space for another 9,223,372,0
| |
| 216 LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); | 217 written_persistent_notification_id_ = next_persistent_notification_id_; |
| 217 if (status != STATUS_OK) | 218 batch.Put(kNextNotificationIdKey, |
| 218 return status; | 219 base::Int64ToString(next_persistent_notification_id_)); |
| 220 } | |
| 219 | 221 |
| 220 *notification_id = next_notification_id_++; | 222 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); |
| 221 return STATUS_OK; | |
| 222 } | 223 } |
| 223 | 224 |
| 224 NotificationDatabase::Status NotificationDatabase::DeleteNotificationData( | 225 NotificationDatabase::Status NotificationDatabase::DeleteNotificationData( |
| 225 int64_t notification_id, | 226 const std::string& notification_id, |
| 226 const GURL& origin) { | 227 const GURL& origin) { |
| 227 DCHECK(sequence_checker_.CalledOnValidSequence()); | 228 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 228 DCHECK_EQ(STATE_INITIALIZED, state_); | 229 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 229 DCHECK_GE(notification_id, kFirstNotificationId); | 230 DCHECK(!notification_id.empty()); |
| 230 DCHECK(origin.is_valid()); | 231 DCHECK(origin.is_valid()); |
| 231 | 232 |
| 232 std::string key = CreateDataKey(origin, notification_id); | 233 std::string key = CreateDataKey(origin, notification_id); |
| 233 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); | 234 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); |
| 234 } | 235 } |
| 235 | 236 |
| 236 NotificationDatabase::Status | 237 NotificationDatabase::Status |
| 237 NotificationDatabase::DeleteAllNotificationDataForOrigin( | 238 NotificationDatabase::DeleteAllNotificationDataForOrigin( |
| 238 const GURL& origin, | 239 const GURL& origin, |
| 239 const std::string& tag, | 240 const std::string& tag, |
| 240 std::set<int64_t>* deleted_notification_set) { | 241 std::set<std::string>* deleted_notification_ids) { |
| 241 return DeleteAllNotificationDataInternal(origin, tag, | 242 return DeleteAllNotificationDataInternal(origin, tag, |
| 242 kInvalidServiceWorkerRegistrationId, | 243 kInvalidServiceWorkerRegistrationId, |
| 243 deleted_notification_set); | 244 deleted_notification_ids); |
| 244 } | 245 } |
| 245 | 246 |
| 246 NotificationDatabase::Status | 247 NotificationDatabase::Status |
| 247 NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration( | 248 NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration( |
| 248 const GURL& origin, | 249 const GURL& origin, |
| 249 int64_t service_worker_registration_id, | 250 int64_t service_worker_registration_id, |
| 250 std::set<int64_t>* deleted_notification_set) { | 251 std::set<std::string>* deleted_notification_ids) { |
| 251 return DeleteAllNotificationDataInternal(origin, "" /* tag */, | 252 return DeleteAllNotificationDataInternal(origin, "" /* tag */, |
| 252 service_worker_registration_id, | 253 service_worker_registration_id, |
| 253 deleted_notification_set); | 254 deleted_notification_ids); |
| 254 } | 255 } |
| 255 | 256 |
| 256 NotificationDatabase::Status NotificationDatabase::Destroy() { | 257 NotificationDatabase::Status NotificationDatabase::Destroy() { |
| 257 DCHECK(sequence_checker_.CalledOnValidSequence()); | 258 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 258 | 259 |
| 259 leveldb::Options options; | 260 leveldb::Options options; |
| 260 if (IsInMemoryDatabase()) { | 261 if (IsInMemoryDatabase()) { |
| 261 if (!env_) | 262 if (!env_) |
| 262 return STATUS_OK; // The database has not been initialized. | 263 return STATUS_OK; // The database has not been initialized. |
| 263 | 264 |
| 264 options.env = env_.get(); | 265 options.env = env_.get(); |
| 265 } | 266 } |
| 266 | 267 |
| 267 state_ = STATE_DISABLED; | 268 state_ = STATE_DISABLED; |
| 268 db_.reset(); | 269 db_.reset(); |
| 269 | 270 |
| 270 return LevelDBStatusToStatus( | 271 return LevelDBStatusToStatus( |
| 271 leveldb::DestroyDB(path_.AsUTF8Unsafe(), options)); | 272 leveldb::DestroyDB(path_.AsUTF8Unsafe(), options)); |
| 272 } | 273 } |
| 273 | 274 |
| 274 NotificationDatabase::Status NotificationDatabase::ReadNextNotificationId() { | 275 NotificationDatabase::Status NotificationDatabase::ReadNextNotificationId() { |
| 275 std::string value; | 276 std::string value; |
| 276 Status status = LevelDBStatusToStatus( | 277 Status status = LevelDBStatusToStatus( |
| 277 db_->Get(leveldb::ReadOptions(), kNextNotificationIdKey, &value)); | 278 db_->Get(leveldb::ReadOptions(), kNextNotificationIdKey, &value)); |
| 278 | 279 |
| 279 if (status == STATUS_ERROR_NOT_FOUND) { | 280 if (status == STATUS_ERROR_NOT_FOUND) { |
| 280 next_notification_id_ = kFirstNotificationId; | 281 next_persistent_notification_id_ = kFirstPersistentNotificationId; |
| 282 written_persistent_notification_id_ = kFirstPersistentNotificationId; | |
| 281 return STATUS_OK; | 283 return STATUS_OK; |
| 282 } | 284 } |
| 283 | 285 |
| 284 if (status != STATUS_OK) | 286 if (status != STATUS_OK) |
| 285 return status; | 287 return status; |
| 286 | 288 |
| 287 if (!base::StringToInt64(value, &next_notification_id_) || | 289 if (!base::StringToInt64(value, &next_persistent_notification_id_) || |
| 288 next_notification_id_ < kFirstNotificationId) { | 290 next_persistent_notification_id_ < kFirstPersistentNotificationId) { |
| 289 return STATUS_ERROR_CORRUPTED; | 291 return STATUS_ERROR_CORRUPTED; |
| 290 } | 292 } |
| 291 | 293 |
| 294 written_persistent_notification_id_ = next_persistent_notification_id_; | |
| 295 | |
| 292 return STATUS_OK; | 296 return STATUS_OK; |
| 293 } | 297 } |
| 294 | 298 |
| 295 NotificationDatabase::Status | 299 NotificationDatabase::Status |
| 296 NotificationDatabase::ReadAllNotificationDataInternal( | 300 NotificationDatabase::ReadAllNotificationDataInternal( |
| 297 const GURL& origin, | 301 const GURL& origin, |
| 298 int64_t service_worker_registration_id, | 302 int64_t service_worker_registration_id, |
| 299 std::vector<NotificationDatabaseData>* notification_data_vector) const { | 303 std::vector<NotificationDatabaseData>* notification_data_vector) const { |
| 300 DCHECK(sequence_checker_.CalledOnValidSequence()); | 304 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 301 DCHECK(notification_data_vector); | 305 DCHECK(notification_data_vector); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 326 } | 330 } |
| 327 | 331 |
| 328 return LevelDBStatusToStatus(iter->status()); | 332 return LevelDBStatusToStatus(iter->status()); |
| 329 } | 333 } |
| 330 | 334 |
| 331 NotificationDatabase::Status | 335 NotificationDatabase::Status |
| 332 NotificationDatabase::DeleteAllNotificationDataInternal( | 336 NotificationDatabase::DeleteAllNotificationDataInternal( |
| 333 const GURL& origin, | 337 const GURL& origin, |
| 334 const std::string& tag, | 338 const std::string& tag, |
| 335 int64_t service_worker_registration_id, | 339 int64_t service_worker_registration_id, |
| 336 std::set<int64_t>* deleted_notification_set) { | 340 std::set<std::string>* deleted_notification_ids) { |
| 337 DCHECK(sequence_checker_.CalledOnValidSequence()); | 341 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 338 DCHECK(deleted_notification_set); | 342 DCHECK(deleted_notification_ids); |
| 339 DCHECK(origin.is_valid()); | 343 DCHECK(origin.is_valid()); |
| 340 | 344 |
| 341 const std::string prefix = CreateDataPrefix(origin); | 345 const std::string prefix = CreateDataPrefix(origin); |
| 342 const bool should_deserialize = | |
| 343 service_worker_registration_id != kInvalidServiceWorkerRegistrationId || | |
| 344 !tag.empty(); | |
| 345 | 346 |
| 346 leveldb::Slice prefix_slice(prefix); | 347 leveldb::Slice prefix_slice(prefix); |
| 347 leveldb::WriteBatch batch; | 348 leveldb::WriteBatch batch; |
| 348 | 349 |
| 349 NotificationDatabaseData notification_database_data; | 350 NotificationDatabaseData notification_database_data; |
| 350 std::unique_ptr<leveldb::Iterator> iter( | 351 std::unique_ptr<leveldb::Iterator> iter( |
| 351 db_->NewIterator(leveldb::ReadOptions())); | 352 db_->NewIterator(leveldb::ReadOptions())); |
| 352 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { | 353 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { |
| 353 if (!iter->key().starts_with(prefix_slice)) | 354 if (!iter->key().starts_with(prefix_slice)) |
| 354 break; | 355 break; |
| 355 | 356 |
| 356 if (should_deserialize) { | 357 Status status = DeserializedNotificationData(iter->value().ToString(), |
| 357 Status status = DeserializedNotificationData(iter->value().ToString(), | 358 ¬ification_database_data); |
| 358 ¬ification_database_data); | 359 if (status != STATUS_OK) |
| 359 if (status != STATUS_OK) | 360 return status; |
| 360 return status; | |
| 361 | 361 |
| 362 if (!tag.empty() && | 362 if (!tag.empty() && |
| 363 notification_database_data.notification_data.tag != tag) { | 363 notification_database_data.notification_data.tag != tag) { |
| 364 continue; | 364 continue; |
| 365 } | |
| 366 | |
| 367 if (service_worker_registration_id != | |
| 368 kInvalidServiceWorkerRegistrationId && | |
| 369 notification_database_data.service_worker_registration_id != | |
| 370 service_worker_registration_id) { | |
| 371 continue; | |
| 372 } | |
| 373 } | 365 } |
| 374 | 366 |
| 375 leveldb::Slice notification_id_slice = iter->key(); | 367 if (service_worker_registration_id != kInvalidServiceWorkerRegistrationId && |
| 376 notification_id_slice.remove_prefix(prefix_slice.size()); | 368 notification_database_data.service_worker_registration_id != |
| 377 | 369 service_worker_registration_id) { |
| 378 int64_t notification_id = 0; | 370 continue; |
| 379 if (!base::StringToInt64(notification_id_slice.ToString(), | |
| 380 ¬ification_id)) { | |
| 381 return STATUS_ERROR_CORRUPTED; | |
| 382 } | 371 } |
| 383 | 372 |
| 384 deleted_notification_set->insert(notification_id); | |
| 385 batch.Delete(iter->key()); | 373 batch.Delete(iter->key()); |
| 374 deleted_notification_ids->insert( | |
| 375 notification_database_data.notification_id); | |
| 386 } | 376 } |
| 387 | 377 |
| 388 if (deleted_notification_set->empty()) | 378 if (deleted_notification_ids->empty()) |
| 389 return STATUS_OK; | 379 return STATUS_OK; |
| 390 | 380 |
| 391 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); | 381 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); |
| 392 } | 382 } |
| 393 | 383 |
| 394 } // namespace content | 384 } // namespace content |
| OLD | NEW |