| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
| 12 #include "base/json/json_reader.h" | 12 #include "base/json/json_reader.h" |
| 13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/macros.h" |
| 15 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 17 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "build/build_config.h" |
| 19 #include "content/browser/child_process_security_policy_impl.h" | 21 #include "content/browser/child_process_security_policy_impl.h" |
| 20 #include "content/browser/indexed_db/indexed_db_blob_info.h" | 22 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
| 21 #include "content/browser/indexed_db/indexed_db_class_factory.h" | 23 #include "content/browser/indexed_db/indexed_db_class_factory.h" |
| 22 #include "content/browser/indexed_db/indexed_db_database_error.h" | 24 #include "content/browser/indexed_db/indexed_db_database_error.h" |
| 23 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" | 25 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" |
| 24 #include "content/browser/indexed_db/indexed_db_metadata.h" | 26 #include "content/browser/indexed_db/indexed_db_metadata.h" |
| 25 #include "content/browser/indexed_db/indexed_db_tracing.h" | 27 #include "content/browser/indexed_db/indexed_db_tracing.h" |
| 26 #include "content/browser/indexed_db/indexed_db_value.h" | 28 #include "content/browser/indexed_db/indexed_db_value.h" |
| 27 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" | 29 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" |
| 28 #include "content/browser/indexed_db/leveldb/leveldb_database.h" | 30 #include "content/browser/indexed_db/leveldb/leveldb_database.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 46 | 48 |
| 47 using base::FilePath; | 49 using base::FilePath; |
| 48 using base::StringPiece; | 50 using base::StringPiece; |
| 49 using std::string; | 51 using std::string; |
| 50 using storage::FileWriterDelegate; | 52 using storage::FileWriterDelegate; |
| 51 | 53 |
| 52 namespace content { | 54 namespace content { |
| 53 | 55 |
| 54 namespace { | 56 namespace { |
| 55 | 57 |
| 56 FilePath GetBlobDirectoryName(const FilePath& path_base, int64 database_id) { | 58 FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) { |
| 57 return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id)); | 59 return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id)); |
| 58 } | 60 } |
| 59 | 61 |
| 60 FilePath GetBlobDirectoryNameForKey(const FilePath& path_base, | 62 FilePath GetBlobDirectoryNameForKey(const FilePath& path_base, |
| 61 int64 database_id, | 63 int64_t database_id, |
| 62 int64 key) { | 64 int64_t key) { |
| 63 FilePath path = GetBlobDirectoryName(path_base, database_id); | 65 FilePath path = GetBlobDirectoryName(path_base, database_id); |
| 64 path = path.AppendASCII(base::StringPrintf( | 66 path = path.AppendASCII(base::StringPrintf( |
| 65 "%02x", static_cast<int>(key & 0x000000000000ff00) >> 8)); | 67 "%02x", static_cast<int>(key & 0x000000000000ff00) >> 8)); |
| 66 return path; | 68 return path; |
| 67 } | 69 } |
| 68 | 70 |
| 69 FilePath GetBlobFileNameForKey(const FilePath& path_base, | 71 FilePath GetBlobFileNameForKey(const FilePath& path_base, |
| 70 int64 database_id, | 72 int64_t database_id, |
| 71 int64 key) { | 73 int64_t key) { |
| 72 FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key); | 74 FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key); |
| 73 path = path.AppendASCII(base::StringPrintf("%" PRIx64, key)); | 75 path = path.AppendASCII(base::StringPrintf("%" PRIx64, key)); |
| 74 return path; | 76 return path; |
| 75 } | 77 } |
| 76 | 78 |
| 77 bool MakeIDBBlobDirectory(const FilePath& path_base, | 79 bool MakeIDBBlobDirectory(const FilePath& path_base, |
| 78 int64 database_id, | 80 int64_t database_id, |
| 79 int64 key) { | 81 int64_t key) { |
| 80 FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key); | 82 FilePath path = GetBlobDirectoryNameForKey(path_base, database_id, key); |
| 81 return base::CreateDirectory(path); | 83 return base::CreateDirectory(path); |
| 82 } | 84 } |
| 83 | 85 |
| 84 static std::string ComputeOriginIdentifier(const GURL& origin_url) { | 86 static std::string ComputeOriginIdentifier(const GURL& origin_url) { |
| 85 return storage::GetIdentifierFromOrigin(origin_url) + "@1"; | 87 return storage::GetIdentifierFromOrigin(origin_url) + "@1"; |
| 86 } | 88 } |
| 87 | 89 |
| 88 static base::FilePath ComputeFileName(const GURL& origin_url) { | 90 static base::FilePath ComputeFileName(const GURL& origin_url) { |
| 89 return base::FilePath() | 91 return base::FilePath() |
| 90 .AppendASCII(storage::GetIdentifierFromOrigin(origin_url)) | 92 .AppendASCII(storage::GetIdentifierFromOrigin(origin_url)) |
| 91 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); | 93 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); |
| 92 } | 94 } |
| 93 | 95 |
| 94 static base::FilePath ComputeBlobPath(const GURL& origin_url) { | 96 static base::FilePath ComputeBlobPath(const GURL& origin_url) { |
| 95 return base::FilePath() | 97 return base::FilePath() |
| 96 .AppendASCII(storage::GetIdentifierFromOrigin(origin_url)) | 98 .AppendASCII(storage::GetIdentifierFromOrigin(origin_url)) |
| 97 .AddExtension(FILE_PATH_LITERAL(".indexeddb.blob")); | 99 .AddExtension(FILE_PATH_LITERAL(".indexeddb.blob")); |
| 98 } | 100 } |
| 99 | 101 |
| 100 static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) { | 102 static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) { |
| 101 return ComputeFileName(origin_url) | 103 return ComputeFileName(origin_url) |
| 102 .Append(FILE_PATH_LITERAL("corruption_info.json")); | 104 .Append(FILE_PATH_LITERAL("corruption_info.json")); |
| 103 } | 105 } |
| 104 | 106 |
| 105 } // namespace | 107 } // namespace |
| 106 | 108 |
| 107 static const int64 kKeyGeneratorInitialNumber = | 109 static const int64_t kKeyGeneratorInitialNumber = |
| 108 1; // From the IndexedDB specification. | 110 1; // From the IndexedDB specification. |
| 109 | 111 |
| 110 enum IndexedDBBackingStoreErrorSource { | 112 enum IndexedDBBackingStoreErrorSource { |
| 111 // 0 - 2 are no longer used. | 113 // 0 - 2 are no longer used. |
| 112 FIND_KEY_IN_INDEX = 3, | 114 FIND_KEY_IN_INDEX = 3, |
| 113 GET_IDBDATABASE_METADATA, | 115 GET_IDBDATABASE_METADATA, |
| 114 GET_INDEXES, | 116 GET_INDEXES, |
| 115 GET_KEY_GENERATOR_CURRENT_NUMBER, | 117 GET_KEY_GENERATOR_CURRENT_NUMBER, |
| 116 GET_OBJECT_STORES, | 118 GET_OBJECT_STORES, |
| 117 GET_RECORD, | 119 GET_RECORD, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 return leveldb::Status::InvalidArgument("Invalid database key ID"); | 204 return leveldb::Status::InvalidArgument("Invalid database key ID"); |
| 203 } | 205 } |
| 204 | 206 |
| 205 static leveldb::Status IOErrorStatus() { | 207 static leveldb::Status IOErrorStatus() { |
| 206 return leveldb::Status::IOError("IO Error"); | 208 return leveldb::Status::IOError("IO Error"); |
| 207 } | 209 } |
| 208 | 210 |
| 209 template <typename DBOrTransaction> | 211 template <typename DBOrTransaction> |
| 210 static leveldb::Status GetInt(DBOrTransaction* db, | 212 static leveldb::Status GetInt(DBOrTransaction* db, |
| 211 const StringPiece& key, | 213 const StringPiece& key, |
| 212 int64* found_int, | 214 int64_t* found_int, |
| 213 bool* found) { | 215 bool* found) { |
| 214 std::string result; | 216 std::string result; |
| 215 leveldb::Status s = db->Get(key, &result, found); | 217 leveldb::Status s = db->Get(key, &result, found); |
| 216 if (!s.ok()) | 218 if (!s.ok()) |
| 217 return s; | 219 return s; |
| 218 if (!*found) | 220 if (!*found) |
| 219 return leveldb::Status::OK(); | 221 return leveldb::Status::OK(); |
| 220 StringPiece slice(result); | 222 StringPiece slice(result); |
| 221 if (DecodeInt(&slice, found_int) && slice.empty()) | 223 if (DecodeInt(&slice, found_int) && slice.empty()) |
| 222 return s; | 224 return s; |
| 223 return InternalInconsistencyStatus(); | 225 return InternalInconsistencyStatus(); |
| 224 } | 226 } |
| 225 | 227 |
| 226 static void PutInt(LevelDBTransaction* transaction, | 228 static void PutInt(LevelDBTransaction* transaction, |
| 227 const StringPiece& key, | 229 const StringPiece& key, |
| 228 int64 value) { | 230 int64_t value) { |
| 229 DCHECK_GE(value, 0); | 231 DCHECK_GE(value, 0); |
| 230 std::string buffer; | 232 std::string buffer; |
| 231 EncodeInt(value, &buffer); | 233 EncodeInt(value, &buffer); |
| 232 transaction->Put(key, &buffer); | 234 transaction->Put(key, &buffer); |
| 233 } | 235 } |
| 234 | 236 |
| 235 template <typename DBOrTransaction> | 237 template <typename DBOrTransaction> |
| 236 WARN_UNUSED_RESULT static leveldb::Status GetVarInt(DBOrTransaction* db, | 238 WARN_UNUSED_RESULT static leveldb::Status GetVarInt(DBOrTransaction* db, |
| 237 const StringPiece& key, | 239 const StringPiece& key, |
| 238 int64* found_int, | 240 int64_t* found_int, |
| 239 bool* found) { | 241 bool* found) { |
| 240 std::string result; | 242 std::string result; |
| 241 leveldb::Status s = db->Get(key, &result, found); | 243 leveldb::Status s = db->Get(key, &result, found); |
| 242 if (!s.ok()) | 244 if (!s.ok()) |
| 243 return s; | 245 return s; |
| 244 if (!*found) | 246 if (!*found) |
| 245 return leveldb::Status::OK(); | 247 return leveldb::Status::OK(); |
| 246 StringPiece slice(result); | 248 StringPiece slice(result); |
| 247 if (DecodeVarInt(&slice, found_int) && slice.empty()) | 249 if (DecodeVarInt(&slice, found_int) && slice.empty()) |
| 248 return s; | 250 return s; |
| 249 return InternalInconsistencyStatus(); | 251 return InternalInconsistencyStatus(); |
| 250 } | 252 } |
| 251 | 253 |
| 252 static void PutVarInt(LevelDBTransaction* transaction, | 254 static void PutVarInt(LevelDBTransaction* transaction, |
| 253 const StringPiece& key, | 255 const StringPiece& key, |
| 254 int64 value) { | 256 int64_t value) { |
| 255 std::string buffer; | 257 std::string buffer; |
| 256 EncodeVarInt(value, &buffer); | 258 EncodeVarInt(value, &buffer); |
| 257 transaction->Put(key, &buffer); | 259 transaction->Put(key, &buffer); |
| 258 } | 260 } |
| 259 | 261 |
| 260 template <typename DBOrTransaction> | 262 template <typename DBOrTransaction> |
| 261 WARN_UNUSED_RESULT static leveldb::Status GetString( | 263 WARN_UNUSED_RESULT static leveldb::Status GetString( |
| 262 DBOrTransaction* db, | 264 DBOrTransaction* db, |
| 263 const StringPiece& key, | 265 const StringPiece& key, |
| 264 base::string16* found_string, | 266 base::string16* found_string, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 } | 308 } |
| 307 | 309 |
| 308 const char* IndexedDBBackingStore::Comparator::Name() const { | 310 const char* IndexedDBBackingStore::Comparator::Name() const { |
| 309 return "idb_cmp1"; | 311 return "idb_cmp1"; |
| 310 } | 312 } |
| 311 | 313 |
| 312 // 0 - Initial version. | 314 // 0 - Initial version. |
| 313 // 1 - Adds UserIntVersion to DatabaseMetaData. | 315 // 1 - Adds UserIntVersion to DatabaseMetaData. |
| 314 // 2 - Adds DataVersion to to global metadata. | 316 // 2 - Adds DataVersion to to global metadata. |
| 315 // 3 - Adds metadata needed for blob support. | 317 // 3 - Adds metadata needed for blob support. |
| 316 static const int64 kLatestKnownSchemaVersion = 3; | 318 static const int64_t kLatestKnownSchemaVersion = 3; |
| 317 WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) { | 319 WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) { |
| 318 int64 db_schema_version = 0; | 320 int64_t db_schema_version = 0; |
| 319 bool found = false; | 321 bool found = false; |
| 320 leveldb::Status s = | 322 leveldb::Status s = |
| 321 GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found); | 323 GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found); |
| 322 if (!s.ok()) | 324 if (!s.ok()) |
| 323 return false; | 325 return false; |
| 324 if (!found) { | 326 if (!found) { |
| 325 *known = true; | 327 *known = true; |
| 326 return true; | 328 return true; |
| 327 } | 329 } |
| 328 if (db_schema_version < 0) | 330 if (db_schema_version < 0) |
| 329 return false; // Only corruption should cause this. | 331 return false; // Only corruption should cause this. |
| 330 if (db_schema_version > kLatestKnownSchemaVersion) { | 332 if (db_schema_version > kLatestKnownSchemaVersion) { |
| 331 *known = false; | 333 *known = false; |
| 332 return true; | 334 return true; |
| 333 } | 335 } |
| 334 | 336 |
| 335 const uint32 latest_known_data_version = | 337 const uint32_t latest_known_data_version = |
| 336 blink::kSerializedScriptValueVersion; | 338 blink::kSerializedScriptValueVersion; |
| 337 int64 db_data_version = 0; | 339 int64_t db_data_version = 0; |
| 338 s = GetInt(db, DataVersionKey::Encode(), &db_data_version, &found); | 340 s = GetInt(db, DataVersionKey::Encode(), &db_data_version, &found); |
| 339 if (!s.ok()) | 341 if (!s.ok()) |
| 340 return false; | 342 return false; |
| 341 if (!found) { | 343 if (!found) { |
| 342 *known = true; | 344 *known = true; |
| 343 return true; | 345 return true; |
| 344 } | 346 } |
| 345 if (db_data_version < 0) | 347 if (db_data_version < 0) |
| 346 return false; // Only corruption should cause this. | 348 return false; // Only corruption should cause this. |
| 347 if (db_data_version > latest_known_data_version) { | 349 if (db_data_version > latest_known_data_version) { |
| 348 *known = false; | 350 *known = false; |
| 349 return true; | 351 return true; |
| 350 } | 352 } |
| 351 | 353 |
| 352 *known = true; | 354 *known = true; |
| 353 return true; | 355 return true; |
| 354 } | 356 } |
| 355 | 357 |
| 356 // TODO(ericu): Move this down into the member section of this file. I'm | 358 // TODO(ericu): Move this down into the member section of this file. I'm |
| 357 // leaving it here for this CL as it's easier to see the diffs in place. | 359 // leaving it here for this CL as it's easier to see the diffs in place. |
| 358 WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() { | 360 WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() { |
| 359 const uint32 latest_known_data_version = | 361 const uint32_t latest_known_data_version = |
| 360 blink::kSerializedScriptValueVersion; | 362 blink::kSerializedScriptValueVersion; |
| 361 const std::string schema_version_key = SchemaVersionKey::Encode(); | 363 const std::string schema_version_key = SchemaVersionKey::Encode(); |
| 362 const std::string data_version_key = DataVersionKey::Encode(); | 364 const std::string data_version_key = DataVersionKey::Encode(); |
| 363 | 365 |
| 364 scoped_refptr<LevelDBTransaction> transaction = | 366 scoped_refptr<LevelDBTransaction> transaction = |
| 365 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); | 367 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); |
| 366 | 368 |
| 367 int64 db_schema_version = 0; | 369 int64_t db_schema_version = 0; |
| 368 int64 db_data_version = 0; | 370 int64_t db_data_version = 0; |
| 369 bool found = false; | 371 bool found = false; |
| 370 leveldb::Status s = | 372 leveldb::Status s = |
| 371 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found); | 373 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found); |
| 372 if (!s.ok()) { | 374 if (!s.ok()) { |
| 373 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); | 375 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); |
| 374 return s; | 376 return s; |
| 375 } | 377 } |
| 376 if (!found) { | 378 if (!found) { |
| 377 // Initialize new backing store. | 379 // Initialize new backing store. |
| 378 db_schema_version = kLatestKnownSchemaVersion; | 380 db_schema_version = kLatestKnownSchemaVersion; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 392 db_schema_version = 1; | 394 db_schema_version = 1; |
| 393 PutInt(transaction.get(), schema_version_key, db_schema_version); | 395 PutInt(transaction.get(), schema_version_key, db_schema_version); |
| 394 const std::string start_key = | 396 const std::string start_key = |
| 395 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); | 397 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); |
| 396 const std::string stop_key = | 398 const std::string stop_key = |
| 397 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); | 399 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); |
| 398 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); | 400 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| 399 for (s = it->Seek(start_key); | 401 for (s = it->Seek(start_key); |
| 400 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; | 402 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| 401 s = it->Next()) { | 403 s = it->Next()) { |
| 402 int64 database_id = 0; | 404 int64_t database_id = 0; |
| 403 found = false; | 405 found = false; |
| 404 s = GetInt(transaction.get(), it->Key(), &database_id, &found); | 406 s = GetInt(transaction.get(), it->Key(), &database_id, &found); |
| 405 if (!s.ok()) { | 407 if (!s.ok()) { |
| 406 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); | 408 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); |
| 407 return s; | 409 return s; |
| 408 } | 410 } |
| 409 if (!found) { | 411 if (!found) { |
| 410 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA); | 412 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA); |
| 411 return InternalInconsistencyStatus(); | 413 return InternalInconsistencyStatus(); |
| 412 } | 414 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 | 460 |
| 459 s = transaction->Commit(); | 461 s = transaction->Commit(); |
| 460 if (!s.ok()) | 462 if (!s.ok()) |
| 461 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); | 463 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); |
| 462 return s; | 464 return s; |
| 463 } | 465 } |
| 464 | 466 |
| 465 template <typename DBOrTransaction> | 467 template <typename DBOrTransaction> |
| 466 WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId( | 468 WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId( |
| 467 DBOrTransaction* db, | 469 DBOrTransaction* db, |
| 468 int64 database_id, | 470 int64_t database_id, |
| 469 int64* max_object_store_id) { | 471 int64_t* max_object_store_id) { |
| 470 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( | 472 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( |
| 471 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); | 473 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); |
| 472 return GetMaxObjectStoreId(db, max_object_store_id_key, max_object_store_id); | 474 return GetMaxObjectStoreId(db, max_object_store_id_key, max_object_store_id); |
| 473 } | 475 } |
| 474 | 476 |
| 475 template <typename DBOrTransaction> | 477 template <typename DBOrTransaction> |
| 476 WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId( | 478 WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId( |
| 477 DBOrTransaction* db, | 479 DBOrTransaction* db, |
| 478 const std::string& max_object_store_id_key, | 480 const std::string& max_object_store_id_key, |
| 479 int64* max_object_store_id) { | 481 int64_t* max_object_store_id) { |
| 480 *max_object_store_id = -1; | 482 *max_object_store_id = -1; |
| 481 bool found = false; | 483 bool found = false; |
| 482 leveldb::Status s = | 484 leveldb::Status s = |
| 483 GetInt(db, max_object_store_id_key, max_object_store_id, &found); | 485 GetInt(db, max_object_store_id_key, max_object_store_id, &found); |
| 484 if (!s.ok()) | 486 if (!s.ok()) |
| 485 return s; | 487 return s; |
| 486 if (!found) | 488 if (!found) |
| 487 *max_object_store_id = 0; | 489 *max_object_store_id = 0; |
| 488 | 490 |
| 489 DCHECK_GE(*max_object_store_id, 0); | 491 DCHECK_GE(*max_object_store_id, 0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 502 leveldb::Status DestroyLevelDB(const base::FilePath& file_name) override { | 504 leveldb::Status DestroyLevelDB(const base::FilePath& file_name) override { |
| 503 return LevelDBDatabase::Destroy(file_name); | 505 return LevelDBDatabase::Destroy(file_name); |
| 504 } | 506 } |
| 505 | 507 |
| 506 private: | 508 private: |
| 507 DISALLOW_COPY_AND_ASSIGN(DefaultLevelDBFactory); | 509 DISALLOW_COPY_AND_ASSIGN(DefaultLevelDBFactory); |
| 508 }; | 510 }; |
| 509 | 511 |
| 510 static bool GetBlobKeyGeneratorCurrentNumber( | 512 static bool GetBlobKeyGeneratorCurrentNumber( |
| 511 LevelDBTransaction* leveldb_transaction, | 513 LevelDBTransaction* leveldb_transaction, |
| 512 int64 database_id, | 514 int64_t database_id, |
| 513 int64* blob_key_generator_current_number) { | 515 int64_t* blob_key_generator_current_number) { |
| 514 const std::string key_gen_key = DatabaseMetaDataKey::Encode( | 516 const std::string key_gen_key = DatabaseMetaDataKey::Encode( |
| 515 database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER); | 517 database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER); |
| 516 | 518 |
| 517 // Default to initial number if not found. | 519 // Default to initial number if not found. |
| 518 int64 cur_number = DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber; | 520 int64_t cur_number = DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber; |
| 519 std::string data; | 521 std::string data; |
| 520 | 522 |
| 521 bool found = false; | 523 bool found = false; |
| 522 bool ok = leveldb_transaction->Get(key_gen_key, &data, &found).ok(); | 524 bool ok = leveldb_transaction->Get(key_gen_key, &data, &found).ok(); |
| 523 if (!ok) { | 525 if (!ok) { |
| 524 INTERNAL_READ_ERROR_UNTESTED(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER); | 526 INTERNAL_READ_ERROR_UNTESTED(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER); |
| 525 return false; | 527 return false; |
| 526 } | 528 } |
| 527 if (found) { | 529 if (found) { |
| 528 StringPiece slice(data); | 530 StringPiece slice(data); |
| 529 if (!DecodeVarInt(&slice, &cur_number) || !slice.empty() || | 531 if (!DecodeVarInt(&slice, &cur_number) || !slice.empty() || |
| 530 !DatabaseMetaDataKey::IsValidBlobKey(cur_number)) { | 532 !DatabaseMetaDataKey::IsValidBlobKey(cur_number)) { |
| 531 INTERNAL_READ_ERROR_UNTESTED(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER); | 533 INTERNAL_READ_ERROR_UNTESTED(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER); |
| 532 return false; | 534 return false; |
| 533 } | 535 } |
| 534 } | 536 } |
| 535 *blob_key_generator_current_number = cur_number; | 537 *blob_key_generator_current_number = cur_number; |
| 536 return true; | 538 return true; |
| 537 } | 539 } |
| 538 | 540 |
| 539 static bool UpdateBlobKeyGeneratorCurrentNumber( | 541 static bool UpdateBlobKeyGeneratorCurrentNumber( |
| 540 LevelDBTransaction* leveldb_transaction, | 542 LevelDBTransaction* leveldb_transaction, |
| 541 int64 database_id, | 543 int64_t database_id, |
| 542 int64 blob_key_generator_current_number) { | 544 int64_t blob_key_generator_current_number) { |
| 543 #ifndef NDEBUG | 545 #ifndef NDEBUG |
| 544 int64 old_number; | 546 int64_t old_number; |
| 545 if (!GetBlobKeyGeneratorCurrentNumber( | 547 if (!GetBlobKeyGeneratorCurrentNumber( |
| 546 leveldb_transaction, database_id, &old_number)) | 548 leveldb_transaction, database_id, &old_number)) |
| 547 return false; | 549 return false; |
| 548 DCHECK_LT(old_number, blob_key_generator_current_number); | 550 DCHECK_LT(old_number, blob_key_generator_current_number); |
| 549 #endif | 551 #endif |
| 550 DCHECK( | 552 DCHECK( |
| 551 DatabaseMetaDataKey::IsValidBlobKey(blob_key_generator_current_number)); | 553 DatabaseMetaDataKey::IsValidBlobKey(blob_key_generator_current_number)); |
| 552 const std::string key = DatabaseMetaDataKey::Encode( | 554 const std::string key = DatabaseMetaDataKey::Encode( |
| 553 database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER); | 555 database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER); |
| 554 | 556 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 const BlobJournalType& journal) { | 664 const BlobJournalType& journal) { |
| 663 return AppendBlobsToBlobJournal(transaction, LiveBlobJournalKey::Encode(), | 665 return AppendBlobsToBlobJournal(transaction, LiveBlobJournalKey::Encode(), |
| 664 journal); | 666 journal); |
| 665 } | 667 } |
| 666 | 668 |
| 667 // Append a database to the specified blob journal via the supplied transaction. | 669 // Append a database to the specified blob journal via the supplied transaction. |
| 668 // The key must be either the primary journal key or live journal key. | 670 // The key must be either the primary journal key or live journal key. |
| 669 static leveldb::Status MergeDatabaseIntoBlobJournal( | 671 static leveldb::Status MergeDatabaseIntoBlobJournal( |
| 670 LevelDBDirectTransaction* transaction, | 672 LevelDBDirectTransaction* transaction, |
| 671 const std::string& key, | 673 const std::string& key, |
| 672 int64 database_id) { | 674 int64_t database_id) { |
| 673 IDB_TRACE("IndexedDBBackingStore::MergeDatabaseIntoBlobJournal"); | 675 IDB_TRACE("IndexedDBBackingStore::MergeDatabaseIntoBlobJournal"); |
| 674 BlobJournalType journal; | 676 BlobJournalType journal; |
| 675 leveldb::Status s = GetBlobJournal(key, transaction, &journal); | 677 leveldb::Status s = GetBlobJournal(key, transaction, &journal); |
| 676 if (!s.ok()) | 678 if (!s.ok()) |
| 677 return s; | 679 return s; |
| 678 journal.push_back( | 680 journal.push_back( |
| 679 std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey)); | 681 std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey)); |
| 680 UpdateBlobJournal(transaction, key, journal); | 682 UpdateBlobJournal(transaction, key, journal); |
| 681 return leveldb::Status::OK(); | 683 return leveldb::Status::OK(); |
| 682 } | 684 } |
| 683 | 685 |
| 684 static leveldb::Status MergeDatabaseIntoPrimaryBlobJournal( | 686 static leveldb::Status MergeDatabaseIntoPrimaryBlobJournal( |
| 685 LevelDBDirectTransaction* leveldb_transaction, | 687 LevelDBDirectTransaction* leveldb_transaction, |
| 686 int64 database_id) { | 688 int64_t database_id) { |
| 687 return MergeDatabaseIntoBlobJournal(leveldb_transaction, | 689 return MergeDatabaseIntoBlobJournal(leveldb_transaction, |
| 688 BlobJournalKey::Encode(), database_id); | 690 BlobJournalKey::Encode(), database_id); |
| 689 } | 691 } |
| 690 | 692 |
| 691 static leveldb::Status MergeDatabaseIntoLiveBlobJournal( | 693 static leveldb::Status MergeDatabaseIntoLiveBlobJournal( |
| 692 LevelDBDirectTransaction* leveldb_transaction, | 694 LevelDBDirectTransaction* leveldb_transaction, |
| 693 int64 database_id) { | 695 int64_t database_id) { |
| 694 return MergeDatabaseIntoBlobJournal( | 696 return MergeDatabaseIntoBlobJournal( |
| 695 leveldb_transaction, LiveBlobJournalKey::Encode(), database_id); | 697 leveldb_transaction, LiveBlobJournalKey::Encode(), database_id); |
| 696 } | 698 } |
| 697 | 699 |
| 698 // Blob Data is encoded as a series of: | 700 // Blob Data is encoded as a series of: |
| 699 // { is_file [bool], key [int64 as varInt], | 701 // { is_file [bool], key [int64_t as varInt], |
| 700 // type [string-with-length, may be empty], | 702 // type [string-with-length, may be empty], |
| 701 // (for Blobs only) size [int64 as varInt] | 703 // (for Blobs only) size [int64_t as varInt] |
| 702 // (for Files only) fileName [string-with-length] | 704 // (for Files only) fileName [string-with-length] |
| 703 // } | 705 // } |
| 704 // There is no length field; just read until you run out of data. | 706 // There is no length field; just read until you run out of data. |
| 705 static std::string EncodeBlobData( | 707 static std::string EncodeBlobData( |
| 706 const std::vector<IndexedDBBlobInfo*>& blob_info) { | 708 const std::vector<IndexedDBBlobInfo*>& blob_info) { |
| 707 std::string ret; | 709 std::string ret; |
| 708 for (const auto* info : blob_info) { | 710 for (const auto* info : blob_info) { |
| 709 EncodeBool(info->is_file(), &ret); | 711 EncodeBool(info->is_file(), &ret); |
| 710 EncodeVarInt(info->key(), &ret); | 712 EncodeVarInt(info->key(), &ret); |
| 711 EncodeStringWithLength(info->type(), &ret); | 713 EncodeStringWithLength(info->type(), &ret); |
| 712 if (info->is_file()) | 714 if (info->is_file()) |
| 713 EncodeStringWithLength(info->file_name(), &ret); | 715 EncodeStringWithLength(info->file_name(), &ret); |
| 714 else | 716 else |
| 715 EncodeVarInt(info->size(), &ret); | 717 EncodeVarInt(info->size(), &ret); |
| 716 } | 718 } |
| 717 return ret; | 719 return ret; |
| 718 } | 720 } |
| 719 | 721 |
| 720 static bool DecodeBlobData(const std::string& data, | 722 static bool DecodeBlobData(const std::string& data, |
| 721 std::vector<IndexedDBBlobInfo>* output) { | 723 std::vector<IndexedDBBlobInfo>* output) { |
| 722 std::vector<IndexedDBBlobInfo> ret; | 724 std::vector<IndexedDBBlobInfo> ret; |
| 723 output->clear(); | 725 output->clear(); |
| 724 StringPiece slice(data); | 726 StringPiece slice(data); |
| 725 while (!slice.empty()) { | 727 while (!slice.empty()) { |
| 726 bool is_file; | 728 bool is_file; |
| 727 int64 key; | 729 int64_t key; |
| 728 base::string16 type; | 730 base::string16 type; |
| 729 int64 size; | 731 int64_t size; |
| 730 base::string16 file_name; | 732 base::string16 file_name; |
| 731 | 733 |
| 732 if (!DecodeBool(&slice, &is_file)) | 734 if (!DecodeBool(&slice, &is_file)) |
| 733 return false; | 735 return false; |
| 734 if (!DecodeVarInt(&slice, &key) || | 736 if (!DecodeVarInt(&slice, &key) || |
| 735 !DatabaseMetaDataKey::IsValidBlobKey(key)) | 737 !DatabaseMetaDataKey::IsValidBlobKey(key)) |
| 736 return false; | 738 return false; |
| 737 if (!DecodeStringWithLength(&slice, &type)) | 739 if (!DecodeStringWithLength(&slice, &type)) |
| 738 return false; | 740 return false; |
| 739 if (is_file) { | 741 if (is_file) { |
| 740 if (!DecodeStringWithLength(&slice, &file_name)) | 742 if (!DecodeStringWithLength(&slice, &file_name)) |
| 741 return false; | 743 return false; |
| 742 ret.push_back(IndexedDBBlobInfo(key, type, file_name)); | 744 ret.push_back(IndexedDBBlobInfo(key, type, file_name)); |
| 743 } else { | 745 } else { |
| 744 if (!DecodeVarInt(&slice, &size) || size < 0) | 746 if (!DecodeVarInt(&slice, &size) || size < 0) |
| 745 return false; | 747 return false; |
| 746 ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64>(size), key)); | 748 ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64_t>(size), key)); |
| 747 } | 749 } |
| 748 } | 750 } |
| 749 output->swap(ret); | 751 output->swap(ret); |
| 750 | 752 |
| 751 return true; | 753 return true; |
| 752 } | 754 } |
| 753 | 755 |
| 754 IndexedDBBackingStore::IndexedDBBackingStore( | 756 IndexedDBBackingStore::IndexedDBBackingStore( |
| 755 IndexedDBFactory* indexed_db_factory, | 757 IndexedDBFactory* indexed_db_factory, |
| 756 const GURL& origin_url, | 758 const GURL& origin_url, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 780 } | 782 } |
| 781 STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), | 783 STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), |
| 782 incognito_blob_map_.end()); | 784 incognito_blob_map_.end()); |
| 783 // db_'s destructor uses comparator_. The order of destruction is important. | 785 // db_'s destructor uses comparator_. The order of destruction is important. |
| 784 db_.reset(); | 786 db_.reset(); |
| 785 comparator_.reset(); | 787 comparator_.reset(); |
| 786 } | 788 } |
| 787 | 789 |
| 788 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( | 790 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( |
| 789 const std::string& primary_key, | 791 const std::string& primary_key, |
| 790 int64 version) | 792 int64_t version) |
| 791 : primary_key_(primary_key), version_(version) { | 793 : primary_key_(primary_key), version_(version) { |
| 792 DCHECK(!primary_key.empty()); | 794 DCHECK(!primary_key.empty()); |
| 793 } | 795 } |
| 794 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier() | 796 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier() |
| 795 : primary_key_(), version_(-1) {} | 797 : primary_key_(), version_(-1) {} |
| 796 IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() {} | 798 IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() {} |
| 797 | 799 |
| 798 IndexedDBBackingStore::Cursor::CursorOptions::CursorOptions() {} | 800 IndexedDBBackingStore::Cursor::CursorOptions::CursorOptions() {} |
| 799 IndexedDBBackingStore::Cursor::CursorOptions::~CursorOptions() {} | 801 IndexedDBBackingStore::Cursor::CursorOptions::~CursorOptions() {} |
| 800 | 802 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 | 915 |
| 914 bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base, | 916 bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base, |
| 915 const GURL& origin_url, | 917 const GURL& origin_url, |
| 916 std::string* message) { | 918 std::string* message) { |
| 917 const base::FilePath info_path = | 919 const base::FilePath info_path = |
| 918 path_base.Append(ComputeCorruptionFileName(origin_url)); | 920 path_base.Append(ComputeCorruptionFileName(origin_url)); |
| 919 | 921 |
| 920 if (IsPathTooLong(info_path)) | 922 if (IsPathTooLong(info_path)) |
| 921 return false; | 923 return false; |
| 922 | 924 |
| 923 const int64 max_json_len = 4096; | 925 const int64_t max_json_len = 4096; |
| 924 int64 file_size(0); | 926 int64_t file_size(0); |
| 925 if (!GetFileSize(info_path, &file_size) || file_size > max_json_len) | 927 if (!GetFileSize(info_path, &file_size) || file_size > max_json_len) |
| 926 return false; | 928 return false; |
| 927 if (!file_size) { | 929 if (!file_size) { |
| 928 NOTREACHED(); | 930 NOTREACHED(); |
| 929 return false; | 931 return false; |
| 930 } | 932 } |
| 931 | 933 |
| 932 base::File file(info_path, base::File::FLAG_OPEN | base::File::FLAG_READ); | 934 base::File file(info_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 933 bool success = false; | 935 bool success = false; |
| 934 if (file.IsValid()) { | 936 if (file.IsValid()) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 // Decode database name (in iterator key). | 1218 // Decode database name (in iterator key). |
| 1217 StringPiece slice(it->Key()); | 1219 StringPiece slice(it->Key()); |
| 1218 DatabaseNameKey database_name_key; | 1220 DatabaseNameKey database_name_key; |
| 1219 if (!DatabaseNameKey::Decode(&slice, &database_name_key) || | 1221 if (!DatabaseNameKey::Decode(&slice, &database_name_key) || |
| 1220 !slice.empty()) { | 1222 !slice.empty()) { |
| 1221 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); | 1223 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); |
| 1222 continue; | 1224 continue; |
| 1223 } | 1225 } |
| 1224 | 1226 |
| 1225 // Decode database id (in iterator value). | 1227 // Decode database id (in iterator value). |
| 1226 int64 database_id = 0; | 1228 int64_t database_id = 0; |
| 1227 StringPiece value_slice(it->Value()); | 1229 StringPiece value_slice(it->Value()); |
| 1228 if (!DecodeInt(&value_slice, &database_id) || !value_slice.empty()) { | 1230 if (!DecodeInt(&value_slice, &database_id) || !value_slice.empty()) { |
| 1229 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); | 1231 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); |
| 1230 continue; | 1232 continue; |
| 1231 } | 1233 } |
| 1232 | 1234 |
| 1233 // Look up version by id. | 1235 // Look up version by id. |
| 1234 bool found = false; | 1236 bool found = false; |
| 1235 int64 database_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; | 1237 int64_t database_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; |
| 1236 *s = GetVarInt(db_.get(), | 1238 *s = GetVarInt(db_.get(), |
| 1237 DatabaseMetaDataKey::Encode( | 1239 DatabaseMetaDataKey::Encode( |
| 1238 database_id, DatabaseMetaDataKey::USER_INT_VERSION), | 1240 database_id, DatabaseMetaDataKey::USER_INT_VERSION), |
| 1239 &database_version, | 1241 &database_version, |
| 1240 &found); | 1242 &found); |
| 1241 if (!s->ok() || !found) { | 1243 if (!s->ok() || !found) { |
| 1242 INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES); | 1244 INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES); |
| 1243 continue; | 1245 continue; |
| 1244 } | 1246 } |
| 1245 | 1247 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) | 1302 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) |
| 1301 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; | 1303 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; |
| 1302 | 1304 |
| 1303 s = GetMaxObjectStoreId( | 1305 s = GetMaxObjectStoreId( |
| 1304 db_.get(), metadata->id, &metadata->max_object_store_id); | 1306 db_.get(), metadata->id, &metadata->max_object_store_id); |
| 1305 if (!s.ok()) { | 1307 if (!s.ok()) { |
| 1306 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); | 1308 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); |
| 1307 } | 1309 } |
| 1308 | 1310 |
| 1309 // We don't cache this, we just check it if it's there. | 1311 // We don't cache this, we just check it if it's there. |
| 1310 int64 blob_key_generator_current_number = | 1312 int64_t blob_key_generator_current_number = |
| 1311 DatabaseMetaDataKey::kInvalidBlobKey; | 1313 DatabaseMetaDataKey::kInvalidBlobKey; |
| 1312 | 1314 |
| 1313 s = GetVarInt( | 1315 s = GetVarInt( |
| 1314 db_.get(), | 1316 db_.get(), |
| 1315 DatabaseMetaDataKey::Encode( | 1317 DatabaseMetaDataKey::Encode( |
| 1316 metadata->id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER), | 1318 metadata->id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER), |
| 1317 &blob_key_generator_current_number, | 1319 &blob_key_generator_current_number, |
| 1318 found); | 1320 found); |
| 1319 if (!s.ok()) { | 1321 if (!s.ok()) { |
| 1320 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); | 1322 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); |
| 1321 return s; | 1323 return s; |
| 1322 } | 1324 } |
| 1323 if (!*found) { | 1325 if (!*found) { |
| 1324 // This database predates blob support. | 1326 // This database predates blob support. |
| 1325 *found = true; | 1327 *found = true; |
| 1326 } else if (!DatabaseMetaDataKey::IsValidBlobKey( | 1328 } else if (!DatabaseMetaDataKey::IsValidBlobKey( |
| 1327 blob_key_generator_current_number)) { | 1329 blob_key_generator_current_number)) { |
| 1328 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); | 1330 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); |
| 1329 return InternalInconsistencyStatus(); | 1331 return InternalInconsistencyStatus(); |
| 1330 } | 1332 } |
| 1331 | 1333 |
| 1332 return s; | 1334 return s; |
| 1333 } | 1335 } |
| 1334 | 1336 |
| 1335 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId( | 1337 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId( |
| 1336 LevelDBTransaction* transaction, | 1338 LevelDBTransaction* transaction, |
| 1337 int64* new_id) { | 1339 int64_t* new_id) { |
| 1338 *new_id = -1; | 1340 *new_id = -1; |
| 1339 int64 max_database_id = -1; | 1341 int64_t max_database_id = -1; |
| 1340 bool found = false; | 1342 bool found = false; |
| 1341 leveldb::Status s = | 1343 leveldb::Status s = |
| 1342 GetInt(transaction, MaxDatabaseIdKey::Encode(), &max_database_id, &found); | 1344 GetInt(transaction, MaxDatabaseIdKey::Encode(), &max_database_id, &found); |
| 1343 if (!s.ok()) { | 1345 if (!s.ok()) { |
| 1344 INTERNAL_READ_ERROR_UNTESTED(GET_NEW_DATABASE_ID); | 1346 INTERNAL_READ_ERROR_UNTESTED(GET_NEW_DATABASE_ID); |
| 1345 return s; | 1347 return s; |
| 1346 } | 1348 } |
| 1347 if (!found) | 1349 if (!found) |
| 1348 max_database_id = 0; | 1350 max_database_id = 0; |
| 1349 | 1351 |
| 1350 DCHECK_GE(max_database_id, 0); | 1352 DCHECK_GE(max_database_id, 0); |
| 1351 | 1353 |
| 1352 int64 database_id = max_database_id + 1; | 1354 int64_t database_id = max_database_id + 1; |
| 1353 PutInt(transaction, MaxDatabaseIdKey::Encode(), database_id); | 1355 PutInt(transaction, MaxDatabaseIdKey::Encode(), database_id); |
| 1354 *new_id = database_id; | 1356 *new_id = database_id; |
| 1355 return leveldb::Status::OK(); | 1357 return leveldb::Status::OK(); |
| 1356 } | 1358 } |
| 1357 | 1359 |
| 1358 leveldb::Status IndexedDBBackingStore::CreateIDBDatabaseMetaData( | 1360 leveldb::Status IndexedDBBackingStore::CreateIDBDatabaseMetaData( |
| 1359 const base::string16& name, | 1361 const base::string16& name, |
| 1360 const base::string16& version, | 1362 const base::string16& version, |
| 1361 int64 int_version, | 1363 int64_t int_version, |
| 1362 int64* row_id) { | 1364 int64_t* row_id) { |
| 1363 // TODO(jsbell): Don't persist metadata if open fails. http://crbug.com/395472 | 1365 // TODO(jsbell): Don't persist metadata if open fails. http://crbug.com/395472 |
| 1364 scoped_refptr<LevelDBTransaction> transaction = | 1366 scoped_refptr<LevelDBTransaction> transaction = |
| 1365 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); | 1367 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); |
| 1366 | 1368 |
| 1367 leveldb::Status s = GetNewDatabaseId(transaction.get(), row_id); | 1369 leveldb::Status s = GetNewDatabaseId(transaction.get(), row_id); |
| 1368 if (!s.ok()) | 1370 if (!s.ok()) |
| 1369 return s; | 1371 return s; |
| 1370 DCHECK_GE(*row_id, 0); | 1372 DCHECK_GE(*row_id, 0); |
| 1371 | 1373 |
| 1372 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) | 1374 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1390 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber); | 1392 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber); |
| 1391 | 1393 |
| 1392 s = transaction->Commit(); | 1394 s = transaction->Commit(); |
| 1393 if (!s.ok()) | 1395 if (!s.ok()) |
| 1394 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA); | 1396 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA); |
| 1395 return s; | 1397 return s; |
| 1396 } | 1398 } |
| 1397 | 1399 |
| 1398 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( | 1400 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( |
| 1399 IndexedDBBackingStore::Transaction* transaction, | 1401 IndexedDBBackingStore::Transaction* transaction, |
| 1400 int64 row_id, | 1402 int64_t row_id, |
| 1401 int64 int_version) { | 1403 int64_t int_version) { |
| 1402 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) | 1404 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) |
| 1403 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; | 1405 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; |
| 1404 DCHECK_GE(int_version, 0) << "int_version was " << int_version; | 1406 DCHECK_GE(int_version, 0) << "int_version was " << int_version; |
| 1405 PutVarInt(transaction->transaction(), | 1407 PutVarInt(transaction->transaction(), |
| 1406 DatabaseMetaDataKey::Encode(row_id, | 1408 DatabaseMetaDataKey::Encode(row_id, |
| 1407 DatabaseMetaDataKey::USER_INT_VERSION), | 1409 DatabaseMetaDataKey::USER_INT_VERSION), |
| 1408 int_version); | 1410 int_version); |
| 1409 return true; | 1411 return true; |
| 1410 } | 1412 } |
| 1411 | 1413 |
| 1412 // If you're deleting a range that contains user keys that have blob info, this | 1414 // If you're deleting a range that contains user keys that have blob info, this |
| 1413 // won't clean up the blobs. | 1415 // won't clean up the blobs. |
| 1414 static leveldb::Status DeleteRangeBasic(LevelDBTransaction* transaction, | 1416 static leveldb::Status DeleteRangeBasic(LevelDBTransaction* transaction, |
| 1415 const std::string& begin, | 1417 const std::string& begin, |
| 1416 const std::string& end, | 1418 const std::string& end, |
| 1417 bool upper_open) { | 1419 bool upper_open) { |
| 1418 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); | 1420 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); |
| 1419 leveldb::Status s; | 1421 leveldb::Status s; |
| 1420 for (s = it->Seek(begin); s.ok() && it->IsValid() && | 1422 for (s = it->Seek(begin); s.ok() && it->IsValid() && |
| 1421 (upper_open ? CompareKeys(it->Key(), end) < 0 | 1423 (upper_open ? CompareKeys(it->Key(), end) < 0 |
| 1422 : CompareKeys(it->Key(), end) <= 0); | 1424 : CompareKeys(it->Key(), end) <= 0); |
| 1423 s = it->Next()) | 1425 s = it->Next()) |
| 1424 transaction->Remove(it->Key()); | 1426 transaction->Remove(it->Key()); |
| 1425 return s; | 1427 return s; |
| 1426 } | 1428 } |
| 1427 | 1429 |
| 1428 static leveldb::Status DeleteBlobsInRange( | 1430 static leveldb::Status DeleteBlobsInRange( |
| 1429 IndexedDBBackingStore::Transaction* transaction, | 1431 IndexedDBBackingStore::Transaction* transaction, |
| 1430 int64 database_id, | 1432 int64_t database_id, |
| 1431 int64 object_store_id, | 1433 int64_t object_store_id, |
| 1432 const std::string& start_key, | 1434 const std::string& start_key, |
| 1433 const std::string& end_key, | 1435 const std::string& end_key, |
| 1434 bool upper_open) { | 1436 bool upper_open) { |
| 1435 scoped_ptr<LevelDBIterator> it = transaction->transaction()->CreateIterator(); | 1437 scoped_ptr<LevelDBIterator> it = transaction->transaction()->CreateIterator(); |
| 1436 leveldb::Status s = it->Seek(start_key); | 1438 leveldb::Status s = it->Seek(start_key); |
| 1437 for (; s.ok() && it->IsValid() && | 1439 for (; s.ok() && it->IsValid() && |
| 1438 (upper_open ? CompareKeys(it->Key(), end_key) < 0 | 1440 (upper_open ? CompareKeys(it->Key(), end_key) < 0 |
| 1439 : CompareKeys(it->Key(), end_key) <= 0); | 1441 : CompareKeys(it->Key(), end_key) <= 0); |
| 1440 s = it->Next()) { | 1442 s = it->Next()) { |
| 1441 StringPiece key_piece(it->Key()); | 1443 StringPiece key_piece(it->Key()); |
| 1442 std::string user_key = | 1444 std::string user_key = |
| 1443 BlobEntryKey::ReencodeToObjectStoreDataKey(&key_piece); | 1445 BlobEntryKey::ReencodeToObjectStoreDataKey(&key_piece); |
| 1444 if (!user_key.size()) { | 1446 if (!user_key.size()) { |
| 1445 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); | 1447 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); |
| 1446 return InternalInconsistencyStatus(); | 1448 return InternalInconsistencyStatus(); |
| 1447 } | 1449 } |
| 1448 transaction->PutBlobInfo( | 1450 transaction->PutBlobInfo( |
| 1449 database_id, object_store_id, user_key, NULL, NULL); | 1451 database_id, object_store_id, user_key, NULL, NULL); |
| 1450 } | 1452 } |
| 1451 return s; | 1453 return s; |
| 1452 } | 1454 } |
| 1453 | 1455 |
| 1454 static leveldb::Status DeleteBlobsInObjectStore( | 1456 static leveldb::Status DeleteBlobsInObjectStore( |
| 1455 IndexedDBBackingStore::Transaction* transaction, | 1457 IndexedDBBackingStore::Transaction* transaction, |
| 1456 int64 database_id, | 1458 int64_t database_id, |
| 1457 int64 object_store_id) { | 1459 int64_t object_store_id) { |
| 1458 std::string start_key, stop_key; | 1460 std::string start_key, stop_key; |
| 1459 start_key = | 1461 start_key = |
| 1460 BlobEntryKey::EncodeMinKeyForObjectStore(database_id, object_store_id); | 1462 BlobEntryKey::EncodeMinKeyForObjectStore(database_id, object_store_id); |
| 1461 stop_key = | 1463 stop_key = |
| 1462 BlobEntryKey::EncodeStopKeyForObjectStore(database_id, object_store_id); | 1464 BlobEntryKey::EncodeStopKeyForObjectStore(database_id, object_store_id); |
| 1463 return DeleteBlobsInRange( | 1465 return DeleteBlobsInRange( |
| 1464 transaction, database_id, object_store_id, start_key, stop_key, true); | 1466 transaction, database_id, object_store_id, start_key, stop_key, true); |
| 1465 } | 1467 } |
| 1466 | 1468 |
| 1467 leveldb::Status IndexedDBBackingStore::DeleteDatabase( | 1469 leveldb::Status IndexedDBBackingStore::DeleteDatabase( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 // the journal until completion. | 1525 // the journal until completion. |
| 1524 if (need_cleanup) | 1526 if (need_cleanup) |
| 1525 CleanPrimaryJournalIgnoreReturn(); | 1527 CleanPrimaryJournalIgnoreReturn(); |
| 1526 | 1528 |
| 1527 db_->Compact(start_key, stop_key); | 1529 db_->Compact(start_key, stop_key); |
| 1528 return s; | 1530 return s; |
| 1529 } | 1531 } |
| 1530 | 1532 |
| 1531 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it, | 1533 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it, |
| 1532 const std::string& stop_key, | 1534 const std::string& stop_key, |
| 1533 int64 object_store_id, | 1535 int64_t object_store_id, |
| 1534 int64 meta_data_type) { | 1536 int64_t meta_data_type) { |
| 1535 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0) | 1537 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0) |
| 1536 return false; | 1538 return false; |
| 1537 | 1539 |
| 1538 StringPiece slice(it->Key()); | 1540 StringPiece slice(it->Key()); |
| 1539 ObjectStoreMetaDataKey meta_data_key; | 1541 ObjectStoreMetaDataKey meta_data_key; |
| 1540 bool ok = | 1542 bool ok = |
| 1541 ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key) && slice.empty(); | 1543 ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key) && slice.empty(); |
| 1542 DCHECK(ok); | 1544 DCHECK(ok); |
| 1543 if (meta_data_key.ObjectStoreId() != object_store_id) | 1545 if (meta_data_key.ObjectStoreId() != object_store_id) |
| 1544 return false; | 1546 return false; |
| 1545 if (meta_data_key.MetaDataType() != meta_data_type) | 1547 if (meta_data_key.MetaDataType() != meta_data_type) |
| 1546 return false; | 1548 return false; |
| 1547 return ok; | 1549 return ok; |
| 1548 } | 1550 } |
| 1549 | 1551 |
| 1550 // TODO(jsbell): This should do some error handling rather than | 1552 // TODO(jsbell): This should do some error handling rather than |
| 1551 // plowing ahead when bad data is encountered. | 1553 // plowing ahead when bad data is encountered. |
| 1552 leveldb::Status IndexedDBBackingStore::GetObjectStores( | 1554 leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| 1553 int64 database_id, | 1555 int64_t database_id, |
| 1554 IndexedDBDatabaseMetadata::ObjectStoreMap* object_stores) { | 1556 IndexedDBDatabaseMetadata::ObjectStoreMap* object_stores) { |
| 1555 IDB_TRACE("IndexedDBBackingStore::GetObjectStores"); | 1557 IDB_TRACE("IndexedDBBackingStore::GetObjectStores"); |
| 1556 if (!KeyPrefix::IsValidDatabaseId(database_id)) | 1558 if (!KeyPrefix::IsValidDatabaseId(database_id)) |
| 1557 return InvalidDBKeyStatus(); | 1559 return InvalidDBKeyStatus(); |
| 1558 const std::string start_key = | 1560 const std::string start_key = |
| 1559 ObjectStoreMetaDataKey::Encode(database_id, 1, 0); | 1561 ObjectStoreMetaDataKey::Encode(database_id, 1, 0); |
| 1560 const std::string stop_key = | 1562 const std::string stop_key = |
| 1561 ObjectStoreMetaDataKey::EncodeMaxKey(database_id); | 1563 ObjectStoreMetaDataKey::EncodeMaxKey(database_id); |
| 1562 | 1564 |
| 1563 DCHECK(object_stores->empty()); | 1565 DCHECK(object_stores->empty()); |
| 1564 | 1566 |
| 1565 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); | 1567 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| 1566 leveldb::Status s = it->Seek(start_key); | 1568 leveldb::Status s = it->Seek(start_key); |
| 1567 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { | 1569 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { |
| 1568 StringPiece slice(it->Key()); | 1570 StringPiece slice(it->Key()); |
| 1569 ObjectStoreMetaDataKey meta_data_key; | 1571 ObjectStoreMetaDataKey meta_data_key; |
| 1570 bool ok = | 1572 bool ok = |
| 1571 ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key) && slice.empty(); | 1573 ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key) && slice.empty(); |
| 1572 DCHECK(ok); | 1574 DCHECK(ok); |
| 1573 if (!ok || meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { | 1575 if (!ok || meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { |
| 1574 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1576 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1575 // Possible stale metadata, but don't fail the load. | 1577 // Possible stale metadata, but don't fail the load. |
| 1576 s = it->Next(); | 1578 s = it->Next(); |
| 1577 if (!s.ok()) | 1579 if (!s.ok()) |
| 1578 break; | 1580 break; |
| 1579 continue; | 1581 continue; |
| 1580 } | 1582 } |
| 1581 | 1583 |
| 1582 int64 object_store_id = meta_data_key.ObjectStoreId(); | 1584 int64_t object_store_id = meta_data_key.ObjectStoreId(); |
| 1583 | 1585 |
| 1584 // TODO(jsbell): Do this by direct key lookup rather than iteration, to | 1586 // TODO(jsbell): Do this by direct key lookup rather than iteration, to |
| 1585 // simplify. | 1587 // simplify. |
| 1586 base::string16 object_store_name; | 1588 base::string16 object_store_name; |
| 1587 { | 1589 { |
| 1588 StringPiece slice(it->Value()); | 1590 StringPiece slice(it->Value()); |
| 1589 if (!DecodeString(&slice, &object_store_name) || !slice.empty()) | 1591 if (!DecodeString(&slice, &object_store_name) || !slice.empty()) |
| 1590 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1592 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1591 } | 1593 } |
| 1592 | 1594 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 if (!s.ok()) | 1654 if (!s.ok()) |
| 1653 break; | 1655 break; |
| 1654 if (!CheckObjectStoreAndMetaDataType( | 1656 if (!CheckObjectStoreAndMetaDataType( |
| 1655 it.get(), | 1657 it.get(), |
| 1656 stop_key, | 1658 stop_key, |
| 1657 object_store_id, | 1659 object_store_id, |
| 1658 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { | 1660 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { |
| 1659 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1661 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1660 break; | 1662 break; |
| 1661 } | 1663 } |
| 1662 int64 max_index_id; | 1664 int64_t max_index_id; |
| 1663 { | 1665 { |
| 1664 StringPiece slice(it->Value()); | 1666 StringPiece slice(it->Value()); |
| 1665 if (!DecodeInt(&slice, &max_index_id) || !slice.empty()) | 1667 if (!DecodeInt(&slice, &max_index_id) || !slice.empty()) |
| 1666 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1668 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1667 } | 1669 } |
| 1668 | 1670 |
| 1669 s = it->Next(); // [optional] has key path (is not null) | 1671 s = it->Next(); // [optional] has key path (is not null) |
| 1670 if (!s.ok()) | 1672 if (!s.ok()) |
| 1671 break; | 1673 break; |
| 1672 if (CheckObjectStoreAndMetaDataType(it.get(), | 1674 if (CheckObjectStoreAndMetaDataType(it.get(), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1689 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1691 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1690 break; | 1692 break; |
| 1691 } | 1693 } |
| 1692 if (!has_key_path) | 1694 if (!has_key_path) |
| 1693 key_path = IndexedDBKeyPath(); | 1695 key_path = IndexedDBKeyPath(); |
| 1694 s = it->Next(); | 1696 s = it->Next(); |
| 1695 if (!s.ok()) | 1697 if (!s.ok()) |
| 1696 break; | 1698 break; |
| 1697 } | 1699 } |
| 1698 | 1700 |
| 1699 int64 key_generator_current_number = -1; | 1701 int64_t key_generator_current_number = -1; |
| 1700 if (CheckObjectStoreAndMetaDataType( | 1702 if (CheckObjectStoreAndMetaDataType( |
| 1701 it.get(), | 1703 it.get(), |
| 1702 stop_key, | 1704 stop_key, |
| 1703 object_store_id, | 1705 object_store_id, |
| 1704 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { | 1706 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { |
| 1705 StringPiece slice(it->Value()); | 1707 StringPiece slice(it->Value()); |
| 1706 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) | 1708 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) |
| 1707 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1709 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1708 | 1710 |
| 1709 // TODO(jsbell): Return key_generator_current_number, cache in | 1711 // TODO(jsbell): Return key_generator_current_number, cache in |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1727 } | 1729 } |
| 1728 | 1730 |
| 1729 if (!s.ok()) | 1731 if (!s.ok()) |
| 1730 INTERNAL_READ_ERROR_UNTESTED(GET_OBJECT_STORES); | 1732 INTERNAL_READ_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1731 | 1733 |
| 1732 return s; | 1734 return s; |
| 1733 } | 1735 } |
| 1734 | 1736 |
| 1735 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId( | 1737 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId( |
| 1736 LevelDBTransaction* transaction, | 1738 LevelDBTransaction* transaction, |
| 1737 int64 database_id, | 1739 int64_t database_id, |
| 1738 int64 object_store_id) { | 1740 int64_t object_store_id) { |
| 1739 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( | 1741 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( |
| 1740 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); | 1742 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); |
| 1741 int64 max_object_store_id = -1; | 1743 int64_t max_object_store_id = -1; |
| 1742 leveldb::Status s = GetMaxObjectStoreId( | 1744 leveldb::Status s = GetMaxObjectStoreId( |
| 1743 transaction, max_object_store_id_key, &max_object_store_id); | 1745 transaction, max_object_store_id_key, &max_object_store_id); |
| 1744 if (!s.ok()) { | 1746 if (!s.ok()) { |
| 1745 INTERNAL_READ_ERROR_UNTESTED(SET_MAX_OBJECT_STORE_ID); | 1747 INTERNAL_READ_ERROR_UNTESTED(SET_MAX_OBJECT_STORE_ID); |
| 1746 return s; | 1748 return s; |
| 1747 } | 1749 } |
| 1748 | 1750 |
| 1749 if (object_store_id <= max_object_store_id) { | 1751 if (object_store_id <= max_object_store_id) { |
| 1750 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_MAX_OBJECT_STORE_ID); | 1752 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_MAX_OBJECT_STORE_ID); |
| 1751 return InternalInconsistencyStatus(); | 1753 return InternalInconsistencyStatus(); |
| 1752 } | 1754 } |
| 1753 PutInt(transaction, max_object_store_id_key, object_store_id); | 1755 PutInt(transaction, max_object_store_id_key, object_store_id); |
| 1754 return s; | 1756 return s; |
| 1755 } | 1757 } |
| 1756 | 1758 |
| 1757 void IndexedDBBackingStore::Compact() { db_->CompactAll(); } | 1759 void IndexedDBBackingStore::Compact() { db_->CompactAll(); } |
| 1758 | 1760 |
| 1759 leveldb::Status IndexedDBBackingStore::CreateObjectStore( | 1761 leveldb::Status IndexedDBBackingStore::CreateObjectStore( |
| 1760 IndexedDBBackingStore::Transaction* transaction, | 1762 IndexedDBBackingStore::Transaction* transaction, |
| 1761 int64 database_id, | 1763 int64_t database_id, |
| 1762 int64 object_store_id, | 1764 int64_t object_store_id, |
| 1763 const base::string16& name, | 1765 const base::string16& name, |
| 1764 const IndexedDBKeyPath& key_path, | 1766 const IndexedDBKeyPath& key_path, |
| 1765 bool auto_increment) { | 1767 bool auto_increment) { |
| 1766 IDB_TRACE("IndexedDBBackingStore::CreateObjectStore"); | 1768 IDB_TRACE("IndexedDBBackingStore::CreateObjectStore"); |
| 1767 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1769 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 1768 return InvalidDBKeyStatus(); | 1770 return InvalidDBKeyStatus(); |
| 1769 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1771 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 1770 leveldb::Status s = | 1772 leveldb::Status s = |
| 1771 SetMaxObjectStoreId(leveldb_transaction, database_id, object_store_id); | 1773 SetMaxObjectStoreId(leveldb_transaction, database_id, object_store_id); |
| 1772 if (!s.ok()) | 1774 if (!s.ok()) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1802 PutBool(leveldb_transaction, has_key_path_key, !key_path.IsNull()); | 1804 PutBool(leveldb_transaction, has_key_path_key, !key_path.IsNull()); |
| 1803 PutInt(leveldb_transaction, | 1805 PutInt(leveldb_transaction, |
| 1804 key_generator_current_number_key, | 1806 key_generator_current_number_key, |
| 1805 kKeyGeneratorInitialNumber); | 1807 kKeyGeneratorInitialNumber); |
| 1806 PutInt(leveldb_transaction, names_key, object_store_id); | 1808 PutInt(leveldb_transaction, names_key, object_store_id); |
| 1807 return s; | 1809 return s; |
| 1808 } | 1810 } |
| 1809 | 1811 |
| 1810 leveldb::Status IndexedDBBackingStore::DeleteObjectStore( | 1812 leveldb::Status IndexedDBBackingStore::DeleteObjectStore( |
| 1811 IndexedDBBackingStore::Transaction* transaction, | 1813 IndexedDBBackingStore::Transaction* transaction, |
| 1812 int64 database_id, | 1814 int64_t database_id, |
| 1813 int64 object_store_id) { | 1815 int64_t object_store_id) { |
| 1814 IDB_TRACE("IndexedDBBackingStore::DeleteObjectStore"); | 1816 IDB_TRACE("IndexedDBBackingStore::DeleteObjectStore"); |
| 1815 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1817 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 1816 return InvalidDBKeyStatus(); | 1818 return InvalidDBKeyStatus(); |
| 1817 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1819 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 1818 | 1820 |
| 1819 base::string16 object_store_name; | 1821 base::string16 object_store_name; |
| 1820 bool found = false; | 1822 bool found = false; |
| 1821 leveldb::Status s = | 1823 leveldb::Status s = |
| 1822 GetString(leveldb_transaction, | 1824 GetString(leveldb_transaction, |
| 1823 ObjectStoreMetaDataKey::Encode( | 1825 ObjectStoreMetaDataKey::Encode( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1867 if (!s.ok()) { | 1869 if (!s.ok()) { |
| 1868 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_OBJECT_STORE); | 1870 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_OBJECT_STORE); |
| 1869 return s; | 1871 return s; |
| 1870 } | 1872 } |
| 1871 | 1873 |
| 1872 return ClearObjectStore(transaction, database_id, object_store_id); | 1874 return ClearObjectStore(transaction, database_id, object_store_id); |
| 1873 } | 1875 } |
| 1874 | 1876 |
| 1875 leveldb::Status IndexedDBBackingStore::GetRecord( | 1877 leveldb::Status IndexedDBBackingStore::GetRecord( |
| 1876 IndexedDBBackingStore::Transaction* transaction, | 1878 IndexedDBBackingStore::Transaction* transaction, |
| 1877 int64 database_id, | 1879 int64_t database_id, |
| 1878 int64 object_store_id, | 1880 int64_t object_store_id, |
| 1879 const IndexedDBKey& key, | 1881 const IndexedDBKey& key, |
| 1880 IndexedDBValue* record) { | 1882 IndexedDBValue* record) { |
| 1881 IDB_TRACE("IndexedDBBackingStore::GetRecord"); | 1883 IDB_TRACE("IndexedDBBackingStore::GetRecord"); |
| 1882 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1884 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 1883 return InvalidDBKeyStatus(); | 1885 return InvalidDBKeyStatus(); |
| 1884 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1886 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 1885 | 1887 |
| 1886 const std::string leveldb_key = | 1888 const std::string leveldb_key = |
| 1887 ObjectStoreDataKey::Encode(database_id, object_store_id, key); | 1889 ObjectStoreDataKey::Encode(database_id, object_store_id, key); |
| 1888 std::string data; | 1890 std::string data; |
| 1889 | 1891 |
| 1890 record->clear(); | 1892 record->clear(); |
| 1891 | 1893 |
| 1892 bool found = false; | 1894 bool found = false; |
| 1893 leveldb::Status s = leveldb_transaction->Get(leveldb_key, &data, &found); | 1895 leveldb::Status s = leveldb_transaction->Get(leveldb_key, &data, &found); |
| 1894 if (!s.ok()) { | 1896 if (!s.ok()) { |
| 1895 INTERNAL_READ_ERROR(GET_RECORD); | 1897 INTERNAL_READ_ERROR(GET_RECORD); |
| 1896 return s; | 1898 return s; |
| 1897 } | 1899 } |
| 1898 if (!found) | 1900 if (!found) |
| 1899 return s; | 1901 return s; |
| 1900 if (data.empty()) { | 1902 if (data.empty()) { |
| 1901 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD); | 1903 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD); |
| 1902 return leveldb::Status::NotFound("Record contained no data"); | 1904 return leveldb::Status::NotFound("Record contained no data"); |
| 1903 } | 1905 } |
| 1904 | 1906 |
| 1905 int64 version; | 1907 int64_t version; |
| 1906 StringPiece slice(data); | 1908 StringPiece slice(data); |
| 1907 if (!DecodeVarInt(&slice, &version)) { | 1909 if (!DecodeVarInt(&slice, &version)) { |
| 1908 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD); | 1910 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD); |
| 1909 return InternalInconsistencyStatus(); | 1911 return InternalInconsistencyStatus(); |
| 1910 } | 1912 } |
| 1911 | 1913 |
| 1912 record->bits = slice.as_string(); | 1914 record->bits = slice.as_string(); |
| 1913 return transaction->GetBlobInfoForRecord(database_id, leveldb_key, record); | 1915 return transaction->GetBlobInfoForRecord(database_id, leveldb_key, record); |
| 1914 } | 1916 } |
| 1915 | 1917 |
| 1916 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber( | 1918 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber( |
| 1917 LevelDBTransaction* transaction, | 1919 LevelDBTransaction* transaction, |
| 1918 int64 database_id, | 1920 int64_t database_id, |
| 1919 int64 object_store_id, | 1921 int64_t object_store_id, |
| 1920 int64* new_version_number) { | 1922 int64_t* new_version_number) { |
| 1921 const std::string last_version_key = ObjectStoreMetaDataKey::Encode( | 1923 const std::string last_version_key = ObjectStoreMetaDataKey::Encode( |
| 1922 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); | 1924 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); |
| 1923 | 1925 |
| 1924 *new_version_number = -1; | 1926 *new_version_number = -1; |
| 1925 int64 last_version = -1; | 1927 int64_t last_version = -1; |
| 1926 bool found = false; | 1928 bool found = false; |
| 1927 leveldb::Status s = | 1929 leveldb::Status s = |
| 1928 GetInt(transaction, last_version_key, &last_version, &found); | 1930 GetInt(transaction, last_version_key, &last_version, &found); |
| 1929 if (!s.ok()) { | 1931 if (!s.ok()) { |
| 1930 INTERNAL_READ_ERROR_UNTESTED(GET_NEW_VERSION_NUMBER); | 1932 INTERNAL_READ_ERROR_UNTESTED(GET_NEW_VERSION_NUMBER); |
| 1931 return s; | 1933 return s; |
| 1932 } | 1934 } |
| 1933 if (!found) | 1935 if (!found) |
| 1934 last_version = 0; | 1936 last_version = 0; |
| 1935 | 1937 |
| 1936 DCHECK_GE(last_version, 0); | 1938 DCHECK_GE(last_version, 0); |
| 1937 | 1939 |
| 1938 int64 version = last_version + 1; | 1940 int64_t version = last_version + 1; |
| 1939 PutInt(transaction, last_version_key, version); | 1941 PutInt(transaction, last_version_key, version); |
| 1940 | 1942 |
| 1941 // TODO(jsbell): Think about how we want to handle the overflow scenario. | 1943 // TODO(jsbell): Think about how we want to handle the overflow scenario. |
| 1942 DCHECK(version > last_version); | 1944 DCHECK(version > last_version); |
| 1943 | 1945 |
| 1944 *new_version_number = version; | 1946 *new_version_number = version; |
| 1945 return s; | 1947 return s; |
| 1946 } | 1948 } |
| 1947 | 1949 |
| 1948 leveldb::Status IndexedDBBackingStore::PutRecord( | 1950 leveldb::Status IndexedDBBackingStore::PutRecord( |
| 1949 IndexedDBBackingStore::Transaction* transaction, | 1951 IndexedDBBackingStore::Transaction* transaction, |
| 1950 int64 database_id, | 1952 int64_t database_id, |
| 1951 int64 object_store_id, | 1953 int64_t object_store_id, |
| 1952 const IndexedDBKey& key, | 1954 const IndexedDBKey& key, |
| 1953 IndexedDBValue* value, | 1955 IndexedDBValue* value, |
| 1954 ScopedVector<storage::BlobDataHandle>* handles, | 1956 ScopedVector<storage::BlobDataHandle>* handles, |
| 1955 RecordIdentifier* record_identifier) { | 1957 RecordIdentifier* record_identifier) { |
| 1956 IDB_TRACE("IndexedDBBackingStore::PutRecord"); | 1958 IDB_TRACE("IndexedDBBackingStore::PutRecord"); |
| 1957 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1959 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 1958 return InvalidDBKeyStatus(); | 1960 return InvalidDBKeyStatus(); |
| 1959 DCHECK(key.IsValid()); | 1961 DCHECK(key.IsValid()); |
| 1960 | 1962 |
| 1961 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1963 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 1962 int64 version = -1; | 1964 int64_t version = -1; |
| 1963 leveldb::Status s = GetNewVersionNumber( | 1965 leveldb::Status s = GetNewVersionNumber( |
| 1964 leveldb_transaction, database_id, object_store_id, &version); | 1966 leveldb_transaction, database_id, object_store_id, &version); |
| 1965 if (!s.ok()) | 1967 if (!s.ok()) |
| 1966 return s; | 1968 return s; |
| 1967 DCHECK_GE(version, 0); | 1969 DCHECK_GE(version, 0); |
| 1968 const std::string object_store_data_key = | 1970 const std::string object_store_data_key = |
| 1969 ObjectStoreDataKey::Encode(database_id, object_store_id, key); | 1971 ObjectStoreDataKey::Encode(database_id, object_store_id, key); |
| 1970 | 1972 |
| 1971 std::string v; | 1973 std::string v; |
| 1972 EncodeVarInt(version, &v); | 1974 EncodeVarInt(version, &v); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1989 leveldb_transaction->Put(exists_entry_key, &version_encoded); | 1991 leveldb_transaction->Put(exists_entry_key, &version_encoded); |
| 1990 | 1992 |
| 1991 std::string key_encoded; | 1993 std::string key_encoded; |
| 1992 EncodeIDBKey(key, &key_encoded); | 1994 EncodeIDBKey(key, &key_encoded); |
| 1993 record_identifier->Reset(key_encoded, version); | 1995 record_identifier->Reset(key_encoded, version); |
| 1994 return s; | 1996 return s; |
| 1995 } | 1997 } |
| 1996 | 1998 |
| 1997 leveldb::Status IndexedDBBackingStore::ClearObjectStore( | 1999 leveldb::Status IndexedDBBackingStore::ClearObjectStore( |
| 1998 IndexedDBBackingStore::Transaction* transaction, | 2000 IndexedDBBackingStore::Transaction* transaction, |
| 1999 int64 database_id, | 2001 int64_t database_id, |
| 2000 int64 object_store_id) { | 2002 int64_t object_store_id) { |
| 2001 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); | 2003 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); |
| 2002 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 2004 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 2003 return InvalidDBKeyStatus(); | 2005 return InvalidDBKeyStatus(); |
| 2004 const std::string start_key = | 2006 const std::string start_key = |
| 2005 KeyPrefix(database_id, object_store_id).Encode(); | 2007 KeyPrefix(database_id, object_store_id).Encode(); |
| 2006 const std::string stop_key = | 2008 const std::string stop_key = |
| 2007 KeyPrefix(database_id, object_store_id + 1).Encode(); | 2009 KeyPrefix(database_id, object_store_id + 1).Encode(); |
| 2008 | 2010 |
| 2009 leveldb::Status s = | 2011 leveldb::Status s = |
| 2010 DeleteRangeBasic(transaction->transaction(), start_key, stop_key, true); | 2012 DeleteRangeBasic(transaction->transaction(), start_key, stop_key, true); |
| 2011 if (!s.ok()) { | 2013 if (!s.ok()) { |
| 2012 INTERNAL_WRITE_ERROR(CLEAR_OBJECT_STORE); | 2014 INTERNAL_WRITE_ERROR(CLEAR_OBJECT_STORE); |
| 2013 return s; | 2015 return s; |
| 2014 } | 2016 } |
| 2015 return DeleteBlobsInObjectStore(transaction, database_id, object_store_id); | 2017 return DeleteBlobsInObjectStore(transaction, database_id, object_store_id); |
| 2016 } | 2018 } |
| 2017 | 2019 |
| 2018 leveldb::Status IndexedDBBackingStore::DeleteRecord( | 2020 leveldb::Status IndexedDBBackingStore::DeleteRecord( |
| 2019 IndexedDBBackingStore::Transaction* transaction, | 2021 IndexedDBBackingStore::Transaction* transaction, |
| 2020 int64 database_id, | 2022 int64_t database_id, |
| 2021 int64 object_store_id, | 2023 int64_t object_store_id, |
| 2022 const RecordIdentifier& record_identifier) { | 2024 const RecordIdentifier& record_identifier) { |
| 2023 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); | 2025 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); |
| 2024 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 2026 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 2025 return InvalidDBKeyStatus(); | 2027 return InvalidDBKeyStatus(); |
| 2026 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 2028 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 2027 | 2029 |
| 2028 const std::string object_store_data_key = ObjectStoreDataKey::Encode( | 2030 const std::string object_store_data_key = ObjectStoreDataKey::Encode( |
| 2029 database_id, object_store_id, record_identifier.primary_key()); | 2031 database_id, object_store_id, record_identifier.primary_key()); |
| 2030 leveldb_transaction->Remove(object_store_data_key); | 2032 leveldb_transaction->Remove(object_store_data_key); |
| 2031 leveldb::Status s = transaction->PutBlobInfoIfNeeded( | 2033 leveldb::Status s = transaction->PutBlobInfoIfNeeded( |
| 2032 database_id, object_store_id, object_store_data_key, NULL, NULL); | 2034 database_id, object_store_id, object_store_data_key, NULL, NULL); |
| 2033 if (!s.ok()) | 2035 if (!s.ok()) |
| 2034 return s; | 2036 return s; |
| 2035 | 2037 |
| 2036 const std::string exists_entry_key = ExistsEntryKey::Encode( | 2038 const std::string exists_entry_key = ExistsEntryKey::Encode( |
| 2037 database_id, object_store_id, record_identifier.primary_key()); | 2039 database_id, object_store_id, record_identifier.primary_key()); |
| 2038 leveldb_transaction->Remove(exists_entry_key); | 2040 leveldb_transaction->Remove(exists_entry_key); |
| 2039 return leveldb::Status::OK(); | 2041 return leveldb::Status::OK(); |
| 2040 } | 2042 } |
| 2041 | 2043 |
| 2042 leveldb::Status IndexedDBBackingStore::DeleteRange( | 2044 leveldb::Status IndexedDBBackingStore::DeleteRange( |
| 2043 IndexedDBBackingStore::Transaction* transaction, | 2045 IndexedDBBackingStore::Transaction* transaction, |
| 2044 int64 database_id, | 2046 int64_t database_id, |
| 2045 int64 object_store_id, | 2047 int64_t object_store_id, |
| 2046 const IndexedDBKeyRange& key_range) { | 2048 const IndexedDBKeyRange& key_range) { |
| 2047 leveldb::Status s; | 2049 leveldb::Status s; |
| 2048 scoped_ptr<IndexedDBBackingStore::Cursor> start_cursor = | 2050 scoped_ptr<IndexedDBBackingStore::Cursor> start_cursor = |
| 2049 OpenObjectStoreCursor(transaction, | 2051 OpenObjectStoreCursor(transaction, |
| 2050 database_id, | 2052 database_id, |
| 2051 object_store_id, | 2053 object_store_id, |
| 2052 key_range, | 2054 key_range, |
| 2053 blink::WebIDBCursorDirectionNext, | 2055 blink::WebIDBCursorDirectionNext, |
| 2054 &s); | 2056 &s); |
| 2055 if (!s.ok()) | 2057 if (!s.ok()) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2097 start_key = | 2099 start_key = |
| 2098 ExistsEntryKey::Encode(database_id, object_store_id, start_cursor->key()); | 2100 ExistsEntryKey::Encode(database_id, object_store_id, start_cursor->key()); |
| 2099 stop_key = | 2101 stop_key = |
| 2100 ExistsEntryKey::Encode(database_id, object_store_id, end_cursor->key()); | 2102 ExistsEntryKey::Encode(database_id, object_store_id, end_cursor->key()); |
| 2101 return DeleteRangeBasic( | 2103 return DeleteRangeBasic( |
| 2102 transaction->transaction(), start_key, stop_key, false); | 2104 transaction->transaction(), start_key, stop_key, false); |
| 2103 } | 2105 } |
| 2104 | 2106 |
| 2105 leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( | 2107 leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( |
| 2106 IndexedDBBackingStore::Transaction* transaction, | 2108 IndexedDBBackingStore::Transaction* transaction, |
| 2107 int64 database_id, | 2109 int64_t database_id, |
| 2108 int64 object_store_id, | 2110 int64_t object_store_id, |
| 2109 int64* key_generator_current_number) { | 2111 int64_t* key_generator_current_number) { |
| 2110 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 2112 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 2111 return InvalidDBKeyStatus(); | 2113 return InvalidDBKeyStatus(); |
| 2112 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 2114 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 2113 | 2115 |
| 2114 const std::string key_generator_current_number_key = | 2116 const std::string key_generator_current_number_key = |
| 2115 ObjectStoreMetaDataKey::Encode( | 2117 ObjectStoreMetaDataKey::Encode( |
| 2116 database_id, | 2118 database_id, |
| 2117 object_store_id, | 2119 object_store_id, |
| 2118 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); | 2120 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); |
| 2119 | 2121 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2140 // but derived from the maximum numeric key present in existing | 2142 // but derived from the maximum numeric key present in existing |
| 2141 // data. This violates the spec as the data may be cleared but the | 2143 // data. This violates the spec as the data may be cleared but the |
| 2142 // key generator state must be preserved. | 2144 // key generator state must be preserved. |
| 2143 // TODO(jsbell): Fix this for all stores on database open? | 2145 // TODO(jsbell): Fix this for all stores on database open? |
| 2144 const std::string start_key = | 2146 const std::string start_key = |
| 2145 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); | 2147 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); |
| 2146 const std::string stop_key = | 2148 const std::string stop_key = |
| 2147 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); | 2149 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); |
| 2148 | 2150 |
| 2149 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); | 2151 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); |
| 2150 int64 max_numeric_key = 0; | 2152 int64_t max_numeric_key = 0; |
| 2151 | 2153 |
| 2152 for (s = it->Seek(start_key); | 2154 for (s = it->Seek(start_key); |
| 2153 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; | 2155 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| 2154 s = it->Next()) { | 2156 s = it->Next()) { |
| 2155 StringPiece slice(it->Key()); | 2157 StringPiece slice(it->Key()); |
| 2156 ObjectStoreDataKey data_key; | 2158 ObjectStoreDataKey data_key; |
| 2157 if (!ObjectStoreDataKey::Decode(&slice, &data_key) || !slice.empty()) { | 2159 if (!ObjectStoreDataKey::Decode(&slice, &data_key) || !slice.empty()) { |
| 2158 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); | 2160 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); |
| 2159 return InternalInconsistencyStatus(); | 2161 return InternalInconsistencyStatus(); |
| 2160 } | 2162 } |
| 2161 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); | 2163 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); |
| 2162 if (user_key->type() == blink::WebIDBKeyTypeNumber) { | 2164 if (user_key->type() == blink::WebIDBKeyTypeNumber) { |
| 2163 int64 n = static_cast<int64>(user_key->number()); | 2165 int64_t n = static_cast<int64_t>(user_key->number()); |
| 2164 if (n > max_numeric_key) | 2166 if (n > max_numeric_key) |
| 2165 max_numeric_key = n; | 2167 max_numeric_key = n; |
| 2166 } | 2168 } |
| 2167 } | 2169 } |
| 2168 | 2170 |
| 2169 if (s.ok()) | 2171 if (s.ok()) |
| 2170 *key_generator_current_number = max_numeric_key + 1; | 2172 *key_generator_current_number = max_numeric_key + 1; |
| 2171 else | 2173 else |
| 2172 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); | 2174 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); |
| 2173 | 2175 |
| 2174 return s; | 2176 return s; |
| 2175 } | 2177 } |
| 2176 | 2178 |
| 2177 leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber( | 2179 leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber( |
| 2178 IndexedDBBackingStore::Transaction* transaction, | 2180 IndexedDBBackingStore::Transaction* transaction, |
| 2179 int64 database_id, | 2181 int64_t database_id, |
| 2180 int64 object_store_id, | 2182 int64_t object_store_id, |
| 2181 int64 new_number, | 2183 int64_t new_number, |
| 2182 bool check_current) { | 2184 bool check_current) { |
| 2183 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 2185 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 2184 return InvalidDBKeyStatus(); | 2186 return InvalidDBKeyStatus(); |
| 2185 | 2187 |
| 2186 if (check_current) { | 2188 if (check_current) { |
| 2187 int64 current_number; | 2189 int64_t current_number; |
| 2188 leveldb::Status s = GetKeyGeneratorCurrentNumber( | 2190 leveldb::Status s = GetKeyGeneratorCurrentNumber( |
| 2189 transaction, database_id, object_store_id, ¤t_number); | 2191 transaction, database_id, object_store_id, ¤t_number); |
| 2190 if (!s.ok()) | 2192 if (!s.ok()) |
| 2191 return s; | 2193 return s; |
| 2192 if (new_number <= current_number) | 2194 if (new_number <= current_number) |
| 2193 return s; | 2195 return s; |
| 2194 } | 2196 } |
| 2195 | 2197 |
| 2196 const std::string key_generator_current_number_key = | 2198 const std::string key_generator_current_number_key = |
| 2197 ObjectStoreMetaDataKey::Encode( | 2199 ObjectStoreMetaDataKey::Encode( |
| 2198 database_id, | 2200 database_id, |
| 2199 object_store_id, | 2201 object_store_id, |
| 2200 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); | 2202 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); |
| 2201 PutInt( | 2203 PutInt( |
| 2202 transaction->transaction(), key_generator_current_number_key, new_number); | 2204 transaction->transaction(), key_generator_current_number_key, new_number); |
| 2203 return leveldb::Status::OK(); | 2205 return leveldb::Status::OK(); |
| 2204 } | 2206 } |
| 2205 | 2207 |
| 2206 leveldb::Status IndexedDBBackingStore::KeyExistsInObjectStore( | 2208 leveldb::Status IndexedDBBackingStore::KeyExistsInObjectStore( |
| 2207 IndexedDBBackingStore::Transaction* transaction, | 2209 IndexedDBBackingStore::Transaction* transaction, |
| 2208 int64 database_id, | 2210 int64_t database_id, |
| 2209 int64 object_store_id, | 2211 int64_t object_store_id, |
| 2210 const IndexedDBKey& key, | 2212 const IndexedDBKey& key, |
| 2211 RecordIdentifier* found_record_identifier, | 2213 RecordIdentifier* found_record_identifier, |
| 2212 bool* found) { | 2214 bool* found) { |
| 2213 IDB_TRACE("IndexedDBBackingStore::KeyExistsInObjectStore"); | 2215 IDB_TRACE("IndexedDBBackingStore::KeyExistsInObjectStore"); |
| 2214 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 2216 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 2215 return InvalidDBKeyStatus(); | 2217 return InvalidDBKeyStatus(); |
| 2216 *found = false; | 2218 *found = false; |
| 2217 const std::string leveldb_key = | 2219 const std::string leveldb_key = |
| 2218 ObjectStoreDataKey::Encode(database_id, object_store_id, key); | 2220 ObjectStoreDataKey::Encode(database_id, object_store_id, key); |
| 2219 std::string data; | 2221 std::string data; |
| 2220 | 2222 |
| 2221 leveldb::Status s = | 2223 leveldb::Status s = |
| 2222 transaction->transaction()->Get(leveldb_key, &data, found); | 2224 transaction->transaction()->Get(leveldb_key, &data, found); |
| 2223 if (!s.ok()) { | 2225 if (!s.ok()) { |
| 2224 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_OBJECT_STORE); | 2226 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_OBJECT_STORE); |
| 2225 return s; | 2227 return s; |
| 2226 } | 2228 } |
| 2227 if (!*found) | 2229 if (!*found) |
| 2228 return leveldb::Status::OK(); | 2230 return leveldb::Status::OK(); |
| 2229 if (!data.size()) { | 2231 if (!data.size()) { |
| 2230 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_OBJECT_STORE); | 2232 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_OBJECT_STORE); |
| 2231 return InternalInconsistencyStatus(); | 2233 return InternalInconsistencyStatus(); |
| 2232 } | 2234 } |
| 2233 | 2235 |
| 2234 int64 version; | 2236 int64_t version; |
| 2235 StringPiece slice(data); | 2237 StringPiece slice(data); |
| 2236 if (!DecodeVarInt(&slice, &version)) | 2238 if (!DecodeVarInt(&slice, &version)) |
| 2237 return InternalInconsistencyStatus(); | 2239 return InternalInconsistencyStatus(); |
| 2238 | 2240 |
| 2239 std::string encoded_key; | 2241 std::string encoded_key; |
| 2240 EncodeIDBKey(key, &encoded_key); | 2242 EncodeIDBKey(key, &encoded_key); |
| 2241 found_record_identifier->Reset(encoded_key, version); | 2243 found_record_identifier->Reset(encoded_key, version); |
| 2242 return s; | 2244 return s; |
| 2243 } | 2245 } |
| 2244 | 2246 |
| 2245 class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl | 2247 class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl |
| 2246 : public IndexedDBBackingStore::Transaction::ChainedBlobWriter { | 2248 : public IndexedDBBackingStore::Transaction::ChainedBlobWriter { |
| 2247 public: | 2249 public: |
| 2248 typedef IndexedDBBackingStore::Transaction::WriteDescriptorVec | 2250 typedef IndexedDBBackingStore::Transaction::WriteDescriptorVec |
| 2249 WriteDescriptorVec; | 2251 WriteDescriptorVec; |
| 2250 ChainedBlobWriterImpl( | 2252 ChainedBlobWriterImpl( |
| 2251 int64 database_id, | 2253 int64_t database_id, |
| 2252 IndexedDBBackingStore* backing_store, | 2254 IndexedDBBackingStore* backing_store, |
| 2253 WriteDescriptorVec* blobs, | 2255 WriteDescriptorVec* blobs, |
| 2254 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback) | 2256 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback) |
| 2255 : waiting_for_callback_(false), | 2257 : waiting_for_callback_(false), |
| 2256 database_id_(database_id), | 2258 database_id_(database_id), |
| 2257 backing_store_(backing_store), | 2259 backing_store_(backing_store), |
| 2258 callback_(callback), | 2260 callback_(callback), |
| 2259 aborted_(false) { | 2261 aborted_(false) { |
| 2260 blobs_.swap(*blobs); | 2262 blobs_.swap(*blobs); |
| 2261 iter_ = blobs_.begin(); | 2263 iter_ = blobs_.begin(); |
| 2262 backing_store->task_runner()->PostTask( | 2264 backing_store->task_runner()->PostTask( |
| 2263 FROM_HERE, base::Bind(&ChainedBlobWriterImpl::WriteNextFile, this)); | 2265 FROM_HERE, base::Bind(&ChainedBlobWriterImpl::WriteNextFile, this)); |
| 2264 } | 2266 } |
| 2265 | 2267 |
| 2266 void set_delegate(scoped_ptr<FileWriterDelegate> delegate) override { | 2268 void set_delegate(scoped_ptr<FileWriterDelegate> delegate) override { |
| 2267 delegate_.reset(delegate.release()); | 2269 delegate_.reset(delegate.release()); |
| 2268 } | 2270 } |
| 2269 | 2271 |
| 2270 void ReportWriteCompletion(bool succeeded, int64 bytes_written) override { | 2272 void ReportWriteCompletion(bool succeeded, int64_t bytes_written) override { |
| 2271 DCHECK(waiting_for_callback_); | 2273 DCHECK(waiting_for_callback_); |
| 2272 DCHECK(!succeeded || bytes_written >= 0); | 2274 DCHECK(!succeeded || bytes_written >= 0); |
| 2273 waiting_for_callback_ = false; | 2275 waiting_for_callback_ = false; |
| 2274 if (delegate_.get()) // Only present for Blob, not File. | 2276 if (delegate_.get()) // Only present for Blob, not File. |
| 2275 content::BrowserThread::DeleteSoon( | 2277 content::BrowserThread::DeleteSoon( |
| 2276 content::BrowserThread::IO, FROM_HERE, delegate_.release()); | 2278 content::BrowserThread::IO, FROM_HERE, delegate_.release()); |
| 2277 if (aborted_) { | 2279 if (aborted_) { |
| 2278 self_ref_ = NULL; | 2280 self_ref_ = NULL; |
| 2279 return; | 2281 return; |
| 2280 } | 2282 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 return; | 2316 return; |
| 2315 } | 2317 } |
| 2316 waiting_for_callback_ = true; | 2318 waiting_for_callback_ = true; |
| 2317 } | 2319 } |
| 2318 } | 2320 } |
| 2319 | 2321 |
| 2320 bool waiting_for_callback_; | 2322 bool waiting_for_callback_; |
| 2321 scoped_refptr<ChainedBlobWriterImpl> self_ref_; | 2323 scoped_refptr<ChainedBlobWriterImpl> self_ref_; |
| 2322 WriteDescriptorVec blobs_; | 2324 WriteDescriptorVec blobs_; |
| 2323 WriteDescriptorVec::const_iterator iter_; | 2325 WriteDescriptorVec::const_iterator iter_; |
| 2324 int64 database_id_; | 2326 int64_t database_id_; |
| 2325 IndexedDBBackingStore* backing_store_; | 2327 IndexedDBBackingStore* backing_store_; |
| 2326 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback_; | 2328 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback_; |
| 2327 scoped_ptr<FileWriterDelegate> delegate_; | 2329 scoped_ptr<FileWriterDelegate> delegate_; |
| 2328 bool aborted_; | 2330 bool aborted_; |
| 2329 | 2331 |
| 2330 DISALLOW_COPY_AND_ASSIGN(ChainedBlobWriterImpl); | 2332 DISALLOW_COPY_AND_ASSIGN(ChainedBlobWriterImpl); |
| 2331 }; | 2333 }; |
| 2332 | 2334 |
| 2333 class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback, | 2335 class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback, |
| 2334 public base::RefCountedThreadSafe<LocalWriteClosure> { | 2336 public base::RefCountedThreadSafe<LocalWriteClosure> { |
| 2335 public: | 2337 public: |
| 2336 LocalWriteClosure(IndexedDBBackingStore::Transaction::ChainedBlobWriter* | 2338 LocalWriteClosure(IndexedDBBackingStore::Transaction::ChainedBlobWriter* |
| 2337 chained_blob_writer, | 2339 chained_blob_writer, |
| 2338 base::SequencedTaskRunner* task_runner) | 2340 base::SequencedTaskRunner* task_runner) |
| 2339 : chained_blob_writer_(chained_blob_writer), | 2341 : chained_blob_writer_(chained_blob_writer), |
| 2340 task_runner_(task_runner), | 2342 task_runner_(task_runner), |
| 2341 bytes_written_(0) {} | 2343 bytes_written_(0) {} |
| 2342 | 2344 |
| 2343 void Run(base::File::Error rv, | 2345 void Run(base::File::Error rv, |
| 2344 int64 bytes, | 2346 int64_t bytes, |
| 2345 FileWriterDelegate::WriteProgressStatus write_status) { | 2347 FileWriterDelegate::WriteProgressStatus write_status) { |
| 2346 DCHECK_GE(bytes, 0); | 2348 DCHECK_GE(bytes, 0); |
| 2347 bytes_written_ += bytes; | 2349 bytes_written_ += bytes; |
| 2348 if (write_status == FileWriterDelegate::SUCCESS_IO_PENDING) | 2350 if (write_status == FileWriterDelegate::SUCCESS_IO_PENDING) |
| 2349 return; // We don't care about progress events. | 2351 return; // We don't care about progress events. |
| 2350 if (rv == base::File::FILE_OK) { | 2352 if (rv == base::File::FILE_OK) { |
| 2351 DCHECK_EQ(write_status, FileWriterDelegate::SUCCESS_COMPLETED); | 2353 DCHECK_EQ(write_status, FileWriterDelegate::SUCCESS_COMPLETED); |
| 2352 } else { | 2354 } else { |
| 2353 DCHECK(write_status == FileWriterDelegate::ERROR_WRITE_STARTED || | 2355 DCHECK(write_status == FileWriterDelegate::ERROR_WRITE_STARTED || |
| 2354 write_status == FileWriterDelegate::ERROR_WRITE_NOT_STARTED); | 2356 write_status == FileWriterDelegate::ERROR_WRITE_NOT_STARTED); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2433 !file.SetTimes(last_modified_, last_modified_)) { | 2435 !file.SetTimes(last_modified_, last_modified_)) { |
| 2434 // TODO(cmumford): Complain quietly; timestamp's probably not vital. | 2436 // TODO(cmumford): Complain quietly; timestamp's probably not vital. |
| 2435 } | 2437 } |
| 2436 file.Close(); | 2438 file.Close(); |
| 2437 chained_blob_writer_->ReportWriteCompletion(success, bytes_written_); | 2439 chained_blob_writer_->ReportWriteCompletion(success, bytes_written_); |
| 2438 } | 2440 } |
| 2439 | 2441 |
| 2440 scoped_refptr<IndexedDBBackingStore::Transaction::ChainedBlobWriter> | 2442 scoped_refptr<IndexedDBBackingStore::Transaction::ChainedBlobWriter> |
| 2441 chained_blob_writer_; | 2443 chained_blob_writer_; |
| 2442 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 2444 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 2443 int64 bytes_written_; | 2445 int64_t bytes_written_; |
| 2444 | 2446 |
| 2445 base::FilePath file_path_; | 2447 base::FilePath file_path_; |
| 2446 base::Time last_modified_; | 2448 base::Time last_modified_; |
| 2447 | 2449 |
| 2448 DISALLOW_COPY_AND_ASSIGN(LocalWriteClosure); | 2450 DISALLOW_COPY_AND_ASSIGN(LocalWriteClosure); |
| 2449 }; | 2451 }; |
| 2450 | 2452 |
| 2451 bool IndexedDBBackingStore::WriteBlobFile( | 2453 bool IndexedDBBackingStore::WriteBlobFile( |
| 2452 int64 database_id, | 2454 int64_t database_id, |
| 2453 const Transaction::WriteDescriptor& descriptor, | 2455 const Transaction::WriteDescriptor& descriptor, |
| 2454 Transaction::ChainedBlobWriter* chained_blob_writer) { | 2456 Transaction::ChainedBlobWriter* chained_blob_writer) { |
| 2455 | |
| 2456 if (!MakeIDBBlobDirectory(blob_path_, database_id, descriptor.key())) | 2457 if (!MakeIDBBlobDirectory(blob_path_, database_id, descriptor.key())) |
| 2457 return false; | 2458 return false; |
| 2458 | 2459 |
| 2459 FilePath path = GetBlobFileName(database_id, descriptor.key()); | 2460 FilePath path = GetBlobFileName(database_id, descriptor.key()); |
| 2460 | 2461 |
| 2461 if (descriptor.is_file() && !descriptor.file_path().empty()) { | 2462 if (descriptor.is_file() && !descriptor.file_path().empty()) { |
| 2462 if (!base::CopyFile(descriptor.file_path(), path)) | 2463 if (!base::CopyFile(descriptor.file_path(), path)) |
| 2463 return false; | 2464 return false; |
| 2464 | 2465 |
| 2465 base::File::Info info; | 2466 base::File::Info info; |
| 2466 if (base::GetFileInfo(descriptor.file_path(), &info)) { | 2467 if (base::GetFileInfo(descriptor.file_path(), &info)) { |
| 2467 if (descriptor.size() != -1) { | 2468 if (descriptor.size() != -1) { |
| 2468 if (descriptor.size() != info.size) | 2469 if (descriptor.size() != info.size) |
| 2469 return false; | 2470 return false; |
| 2470 // The round-trip can be lossy; round to nearest millisecond. | 2471 // The round-trip can be lossy; round to nearest millisecond. |
| 2471 int64 delta = (descriptor.last_modified() - | 2472 int64_t delta = |
| 2472 info.last_modified).InMilliseconds(); | 2473 (descriptor.last_modified() - info.last_modified).InMilliseconds(); |
| 2473 if (std::abs(delta) > 1) | 2474 if (std::abs(delta) > 1) |
| 2474 return false; | 2475 return false; |
| 2475 } | 2476 } |
| 2476 if (!base::TouchFile(path, info.last_accessed, info.last_modified)) { | 2477 if (!base::TouchFile(path, info.last_accessed, info.last_modified)) { |
| 2477 // TODO(ericu): Complain quietly; timestamp's probably not vital. | 2478 // TODO(ericu): Complain quietly; timestamp's probably not vital. |
| 2478 } | 2479 } |
| 2479 } else { | 2480 } else { |
| 2480 // TODO(ericu): Complain quietly; timestamp's probably not vital. | 2481 // TODO(ericu): Complain quietly; timestamp's probably not vital. |
| 2481 } | 2482 } |
| 2482 | 2483 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2496 base::Bind(&LocalWriteClosure::WriteBlobToFileOnIOThread, | 2497 base::Bind(&LocalWriteClosure::WriteBlobToFileOnIOThread, |
| 2497 write_closure.get(), | 2498 write_closure.get(), |
| 2498 path, | 2499 path, |
| 2499 descriptor.url(), | 2500 descriptor.url(), |
| 2500 descriptor.last_modified(), | 2501 descriptor.last_modified(), |
| 2501 request_context_)); | 2502 request_context_)); |
| 2502 } | 2503 } |
| 2503 return true; | 2504 return true; |
| 2504 } | 2505 } |
| 2505 | 2506 |
| 2506 void IndexedDBBackingStore::ReportBlobUnused(int64 database_id, | 2507 void IndexedDBBackingStore::ReportBlobUnused(int64_t database_id, |
| 2507 int64 blob_key) { | 2508 int64_t blob_key) { |
| 2508 DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); | 2509 DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); |
| 2509 bool all_blobs = blob_key == DatabaseMetaDataKey::kAllBlobsKey; | 2510 bool all_blobs = blob_key == DatabaseMetaDataKey::kAllBlobsKey; |
| 2510 DCHECK(all_blobs || DatabaseMetaDataKey::IsValidBlobKey(blob_key)); | 2511 DCHECK(all_blobs || DatabaseMetaDataKey::IsValidBlobKey(blob_key)); |
| 2511 scoped_refptr<LevelDBTransaction> transaction = | 2512 scoped_refptr<LevelDBTransaction> transaction = |
| 2512 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); | 2513 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); |
| 2513 | 2514 |
| 2514 BlobJournalType live_blob_journal, primary_journal; | 2515 BlobJournalType live_blob_journal, primary_journal; |
| 2515 if (!GetLiveBlobJournal(transaction.get(), &live_blob_journal).ok()) | 2516 if (!GetLiveBlobJournal(transaction.get(), &live_blob_journal).ok()) |
| 2516 return; | 2517 return; |
| 2517 DCHECK(!live_blob_journal.empty()); | 2518 DCHECK(!live_blob_journal.empty()); |
| 2518 if (!GetPrimaryBlobJournal(transaction.get(), &primary_journal).ok()) | 2519 if (!GetPrimaryBlobJournal(transaction.get(), &primary_journal).ok()) |
| 2519 return; | 2520 return; |
| 2520 | 2521 |
| 2521 // There are several cases to handle. If blob_key is kAllBlobsKey, we want to | 2522 // There are several cases to handle. If blob_key is kAllBlobsKey, we want to |
| 2522 // remove all entries with database_id from the live_blob journal and add only | 2523 // remove all entries with database_id from the live_blob journal and add only |
| 2523 // kAllBlobsKey to the primary journal. Otherwise if IsValidBlobKey(blob_key) | 2524 // kAllBlobsKey to the primary journal. Otherwise if IsValidBlobKey(blob_key) |
| 2524 // and we hit kAllBlobsKey for the right database_id in the journal, we leave | 2525 // and we hit kAllBlobsKey for the right database_id in the journal, we leave |
| 2525 // the kAllBlobsKey entry in the live_blob journal but add the specific blob | 2526 // the kAllBlobsKey entry in the live_blob journal but add the specific blob |
| 2526 // to the primary. Otherwise if IsValidBlobKey(blob_key) and we find a | 2527 // to the primary. Otherwise if IsValidBlobKey(blob_key) and we find a |
| 2527 // matching (database_id, blob_key) tuple, we should move it to the primary | 2528 // matching (database_id, blob_key) tuple, we should move it to the primary |
| 2528 // journal. | 2529 // journal. |
| 2529 BlobJournalType new_live_blob_journal; | 2530 BlobJournalType new_live_blob_journal; |
| 2530 for (BlobJournalType::iterator journal_iter = live_blob_journal.begin(); | 2531 for (BlobJournalType::iterator journal_iter = live_blob_journal.begin(); |
| 2531 journal_iter != live_blob_journal.end(); | 2532 journal_iter != live_blob_journal.end(); |
| 2532 ++journal_iter) { | 2533 ++journal_iter) { |
| 2533 int64 current_database_id = journal_iter->first; | 2534 int64_t current_database_id = journal_iter->first; |
| 2534 int64 current_blob_key = journal_iter->second; | 2535 int64_t current_blob_key = journal_iter->second; |
| 2535 bool current_all_blobs = | 2536 bool current_all_blobs = |
| 2536 current_blob_key == DatabaseMetaDataKey::kAllBlobsKey; | 2537 current_blob_key == DatabaseMetaDataKey::kAllBlobsKey; |
| 2537 DCHECK(KeyPrefix::IsValidDatabaseId(current_database_id) || | 2538 DCHECK(KeyPrefix::IsValidDatabaseId(current_database_id) || |
| 2538 current_all_blobs); | 2539 current_all_blobs); |
| 2539 if (current_database_id == database_id && | 2540 if (current_database_id == database_id && |
| 2540 (all_blobs || current_all_blobs || blob_key == current_blob_key)) { | 2541 (all_blobs || current_all_blobs || blob_key == current_blob_key)) { |
| 2541 if (!all_blobs) { | 2542 if (!all_blobs) { |
| 2542 primary_journal.push_back( | 2543 primary_journal.push_back( |
| 2543 std::make_pair(database_id, current_blob_key)); | 2544 std::make_pair(database_id, current_blob_key)); |
| 2544 if (current_all_blobs) | 2545 if (current_all_blobs) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2571 // deleted, the timer will automatically be canceled on destruction. | 2572 // deleted, the timer will automatically be canceled on destruction. |
| 2572 void IndexedDBBackingStore::StartJournalCleaningTimer() { | 2573 void IndexedDBBackingStore::StartJournalCleaningTimer() { |
| 2573 journal_cleaning_timer_.Start( | 2574 journal_cleaning_timer_.Start( |
| 2574 FROM_HERE, | 2575 FROM_HERE, |
| 2575 base::TimeDelta::FromSeconds(5), | 2576 base::TimeDelta::FromSeconds(5), |
| 2576 this, | 2577 this, |
| 2577 &IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn); | 2578 &IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn); |
| 2578 } | 2579 } |
| 2579 | 2580 |
| 2580 // This assumes a file path of dbId/second-to-LSB-of-counter/counter. | 2581 // This assumes a file path of dbId/second-to-LSB-of-counter/counter. |
| 2581 FilePath IndexedDBBackingStore::GetBlobFileName(int64 database_id, | 2582 FilePath IndexedDBBackingStore::GetBlobFileName(int64_t database_id, |
| 2582 int64 key) const { | 2583 int64_t key) const { |
| 2583 return GetBlobFileNameForKey(blob_path_, database_id, key); | 2584 return GetBlobFileNameForKey(blob_path_, database_id, key); |
| 2584 } | 2585 } |
| 2585 | 2586 |
| 2586 static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it, | 2587 static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it, |
| 2587 const std::string& stop_key, | 2588 const std::string& stop_key, |
| 2588 int64 index_id, | 2589 int64_t index_id, |
| 2589 unsigned char meta_data_type) { | 2590 unsigned char meta_data_type) { |
| 2590 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0) | 2591 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0) |
| 2591 return false; | 2592 return false; |
| 2592 | 2593 |
| 2593 StringPiece slice(it->Key()); | 2594 StringPiece slice(it->Key()); |
| 2594 IndexMetaDataKey meta_data_key; | 2595 IndexMetaDataKey meta_data_key; |
| 2595 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key); | 2596 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key); |
| 2596 DCHECK(ok); | 2597 DCHECK(ok); |
| 2597 if (meta_data_key.IndexId() != index_id) | 2598 if (meta_data_key.IndexId() != index_id) |
| 2598 return false; | 2599 return false; |
| 2599 if (meta_data_key.meta_data_type() != meta_data_type) | 2600 if (meta_data_key.meta_data_type() != meta_data_type) |
| 2600 return false; | 2601 return false; |
| 2601 return true; | 2602 return true; |
| 2602 } | 2603 } |
| 2603 | 2604 |
| 2604 // TODO(jsbell): This should do some error handling rather than plowing ahead | 2605 // TODO(jsbell): This should do some error handling rather than plowing ahead |
| 2605 // when bad data is encountered. | 2606 // when bad data is encountered. |
| 2606 leveldb::Status IndexedDBBackingStore::GetIndexes( | 2607 leveldb::Status IndexedDBBackingStore::GetIndexes( |
| 2607 int64 database_id, | 2608 int64_t database_id, |
| 2608 int64 object_store_id, | 2609 int64_t object_store_id, |
| 2609 IndexedDBObjectStoreMetadata::IndexMap* indexes) { | 2610 IndexedDBObjectStoreMetadata::IndexMap* indexes) { |
| 2610 IDB_TRACE("IndexedDBBackingStore::GetIndexes"); | 2611 IDB_TRACE("IndexedDBBackingStore::GetIndexes"); |
| 2611 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 2612 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
| 2612 return InvalidDBKeyStatus(); | 2613 return InvalidDBKeyStatus(); |
| 2613 const std::string start_key = | 2614 const std::string start_key = |
| 2614 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0); | 2615 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0); |
| 2615 const std::string stop_key = | 2616 const std::string stop_key = |
| 2616 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0); | 2617 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0); |
| 2617 | 2618 |
| 2618 DCHECK(indexes->empty()); | 2619 DCHECK(indexes->empty()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2629 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail | 2630 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail |
| 2630 // the load. | 2631 // the load. |
| 2631 s = it->Next(); | 2632 s = it->Next(); |
| 2632 if (!s.ok()) | 2633 if (!s.ok()) |
| 2633 break; | 2634 break; |
| 2634 continue; | 2635 continue; |
| 2635 } | 2636 } |
| 2636 | 2637 |
| 2637 // TODO(jsbell): Do this by direct key lookup rather than iteration, to | 2638 // TODO(jsbell): Do this by direct key lookup rather than iteration, to |
| 2638 // simplify. | 2639 // simplify. |
| 2639 int64 index_id = meta_data_key.IndexId(); | 2640 int64_t index_id = meta_data_key.IndexId(); |
| 2640 base::string16 index_name; | 2641 base::string16 index_name; |
| 2641 { | 2642 { |
| 2642 StringPiece slice(it->Value()); | 2643 StringPiece slice(it->Value()); |
| 2643 if (!DecodeString(&slice, &index_name) || !slice.empty()) | 2644 if (!DecodeString(&slice, &index_name) || !slice.empty()) |
| 2644 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); | 2645 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| 2645 } | 2646 } |
| 2646 | 2647 |
| 2647 s = it->Next(); // unique flag | 2648 s = it->Next(); // unique flag |
| 2648 if (!s.ok()) | 2649 if (!s.ok()) |
| 2649 break; | 2650 break; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 (*indexes)[index_id] = IndexedDBIndexMetadata( | 2693 (*indexes)[index_id] = IndexedDBIndexMetadata( |
| 2693 index_name, index_id, key_path, index_unique, index_multi_entry); | 2694 index_name, index_id, key_path, index_unique, index_multi_entry); |
| 2694 } | 2695 } |
| 2695 | 2696 |
| 2696 if (!s.ok()) | 2697 if (!s.ok()) |
| 2697 INTERNAL_READ_ERROR_UNTESTED(GET_INDEXES); | 2698 INTERNAL_READ_ERROR_UNTESTED(GET_INDEXES); |
| 2698 | 2699 |
| 2699 return s; | 2700 return s; |
| 2700 } | 2701 } |
| 2701 | 2702 |
| 2702 bool IndexedDBBackingStore::RemoveBlobFile(int64 database_id, int64 key) const { | 2703 bool IndexedDBBackingStore::RemoveBlobFile(int64_t database_id, |
| 2704 int64_t key) const { |
| 2703 FilePath path = GetBlobFileName(database_id, key); | 2705 FilePath path = GetBlobFileName(database_id, key); |
| 2704 return base::DeleteFile(path, false); | 2706 return base::DeleteFile(path, false); |
| 2705 } | 2707 } |
| 2706 | 2708 |
| 2707 bool IndexedDBBackingStore::RemoveBlobDirectory(int64 database_id) const { | 2709 bool IndexedDBBackingStore::RemoveBlobDirectory(int64_t database_id) const { |
| 2708 FilePath path = GetBlobDirectoryName(blob_path_, database_id); | 2710 FilePath path = GetBlobDirectoryName(blob_path_, database_id); |
| 2709 return base::DeleteFile(path, true); | 2711 return base::DeleteFile(path, true); |
| 2710 } | 2712 } |
| 2711 | 2713 |
| 2712 leveldb::Status IndexedDBBackingStore::CleanUpBlobJournalEntries( | 2714 leveldb::Status IndexedDBBackingStore::CleanUpBlobJournalEntries( |
| 2713 const BlobJournalType& journal) const { | 2715 const BlobJournalType& journal) const { |
| 2714 IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournalEntries"); | 2716 IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournalEntries"); |
| 2715 if (journal.empty()) | 2717 if (journal.empty()) |
| 2716 return leveldb::Status::OK(); | 2718 return leveldb::Status::OK(); |
| 2717 for (const auto& entry : journal) { | 2719 for (const auto& entry : journal) { |
| 2718 int64 database_id = entry.first; | 2720 int64_t database_id = entry.first; |
| 2719 int64 blob_key = entry.second; | 2721 int64_t blob_key = entry.second; |
| 2720 DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); | 2722 DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); |
| 2721 if (blob_key == DatabaseMetaDataKey::kAllBlobsKey) { | 2723 if (blob_key == DatabaseMetaDataKey::kAllBlobsKey) { |
| 2722 if (!RemoveBlobDirectory(database_id)) | 2724 if (!RemoveBlobDirectory(database_id)) |
| 2723 return IOErrorStatus(); | 2725 return IOErrorStatus(); |
| 2724 } else { | 2726 } else { |
| 2725 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); | 2727 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); |
| 2726 if (!RemoveBlobFile(database_id, blob_key)) | 2728 if (!RemoveBlobFile(database_id, blob_key)) |
| 2727 return IOErrorStatus(); | 2729 return IOErrorStatus(); |
| 2728 } | 2730 } |
| 2729 } | 2731 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2745 if (journal.empty()) | 2747 if (journal.empty()) |
| 2746 return leveldb::Status::OK(); | 2748 return leveldb::Status::OK(); |
| 2747 s = CleanUpBlobJournalEntries(journal); | 2749 s = CleanUpBlobJournalEntries(journal); |
| 2748 if (!s.ok()) | 2750 if (!s.ok()) |
| 2749 return s; | 2751 return s; |
| 2750 ClearBlobJournal(journal_transaction.get(), level_db_key); | 2752 ClearBlobJournal(journal_transaction.get(), level_db_key); |
| 2751 return journal_transaction->Commit(); | 2753 return journal_transaction->Commit(); |
| 2752 } | 2754 } |
| 2753 | 2755 |
| 2754 leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord( | 2756 leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord( |
| 2755 int64 database_id, | 2757 int64_t database_id, |
| 2756 const std::string& object_store_data_key, | 2758 const std::string& object_store_data_key, |
| 2757 IndexedDBValue* value) { | 2759 IndexedDBValue* value) { |
| 2758 BlobChangeRecord* change_record = NULL; | 2760 BlobChangeRecord* change_record = NULL; |
| 2759 BlobChangeMap::const_iterator blob_iter = | 2761 BlobChangeMap::const_iterator blob_iter = |
| 2760 blob_change_map_.find(object_store_data_key); | 2762 blob_change_map_.find(object_store_data_key); |
| 2761 if (blob_iter != blob_change_map_.end()) { | 2763 if (blob_iter != blob_change_map_.end()) { |
| 2762 change_record = blob_iter->second; | 2764 change_record = blob_iter->second; |
| 2763 } else { | 2765 } else { |
| 2764 blob_iter = incognito_blob_map_.find(object_store_data_key); | 2766 blob_iter = incognito_blob_map_.find(object_store_data_key); |
| 2765 if (blob_iter != incognito_blob_map_.end()) | 2767 if (blob_iter != incognito_blob_map_.end()) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2817 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() { | 2819 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() { |
| 2818 // While a transaction is busy it is not safe to clean the journal. | 2820 // While a transaction is busy it is not safe to clean the journal. |
| 2819 if (committing_transaction_count_ > 0) | 2821 if (committing_transaction_count_ > 0) |
| 2820 StartJournalCleaningTimer(); | 2822 StartJournalCleaningTimer(); |
| 2821 else | 2823 else |
| 2822 CleanUpBlobJournal(BlobJournalKey::Encode()); | 2824 CleanUpBlobJournal(BlobJournalKey::Encode()); |
| 2823 } | 2825 } |
| 2824 | 2826 |
| 2825 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( | 2827 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( |
| 2826 LevelDBTransaction* transaction, | 2828 LevelDBTransaction* transaction, |
| 2827 int64 database_id, | 2829 int64_t database_id, |
| 2828 int64 object_store_id, | 2830 int64_t object_store_id, |
| 2829 int64 index_id) { | 2831 int64_t index_id) { |
| 2830 int64 max_index_id = -1; | 2832 int64_t max_index_id = -1; |
| 2831 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode( | 2833 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode( |
| 2832 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); | 2834 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); |
| 2833 bool found = false; | 2835 bool found = false; |
| 2834 leveldb::Status s = | 2836 leveldb::Status s = |
| 2835 GetInt(transaction, max_index_id_key, &max_index_id, &found); | 2837 GetInt(transaction, max_index_id_key, &max_index_id, &found); |
| 2836 if (!s.ok()) { | 2838 if (!s.ok()) { |
| 2837 INTERNAL_READ_ERROR_UNTESTED(SET_MAX_INDEX_ID); | 2839 INTERNAL_READ_ERROR_UNTESTED(SET_MAX_INDEX_ID); |
| 2838 return s; | 2840 return s; |
| 2839 } | 2841 } |
| 2840 if (!found) | 2842 if (!found) |
| 2841 max_index_id = kMinimumIndexId; | 2843 max_index_id = kMinimumIndexId; |
| 2842 | 2844 |
| 2843 if (index_id <= max_index_id) { | 2845 if (index_id <= max_index_id) { |
| 2844 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_MAX_INDEX_ID); | 2846 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_MAX_INDEX_ID); |
| 2845 return InternalInconsistencyStatus(); | 2847 return InternalInconsistencyStatus(); |
| 2846 } | 2848 } |
| 2847 | 2849 |
| 2848 PutInt(transaction, max_index_id_key, index_id); | 2850 PutInt(transaction, max_index_id_key, index_id); |
| 2849 return s; | 2851 return s; |
| 2850 } | 2852 } |
| 2851 | 2853 |
| 2852 leveldb::Status IndexedDBBackingStore::CreateIndex( | 2854 leveldb::Status IndexedDBBackingStore::CreateIndex( |
| 2853 IndexedDBBackingStore::Transaction* transaction, | 2855 IndexedDBBackingStore::Transaction* transaction, |
| 2854 int64 database_id, | 2856 int64_t database_id, |
| 2855 int64 object_store_id, | 2857 int64_t object_store_id, |
| 2856 int64 index_id, | 2858 int64_t index_id, |
| 2857 const base::string16& name, | 2859 const base::string16& name, |
| 2858 const IndexedDBKeyPath& key_path, | 2860 const IndexedDBKeyPath& key_path, |
| 2859 bool is_unique, | 2861 bool is_unique, |
| 2860 bool is_multi_entry) { | 2862 bool is_multi_entry) { |
| 2861 IDB_TRACE("IndexedDBBackingStore::CreateIndex"); | 2863 IDB_TRACE("IndexedDBBackingStore::CreateIndex"); |
| 2862 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) | 2864 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) |
| 2863 return InvalidDBKeyStatus(); | 2865 return InvalidDBKeyStatus(); |
| 2864 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 2866 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 2865 leveldb::Status s = SetMaxIndexId( | 2867 leveldb::Status s = SetMaxIndexId( |
| 2866 leveldb_transaction, database_id, object_store_id, index_id); | 2868 leveldb_transaction, database_id, object_store_id, index_id); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2879 | 2881 |
| 2880 PutString(leveldb_transaction, name_key, name); | 2882 PutString(leveldb_transaction, name_key, name); |
| 2881 PutBool(leveldb_transaction, unique_key, is_unique); | 2883 PutBool(leveldb_transaction, unique_key, is_unique); |
| 2882 PutIDBKeyPath(leveldb_transaction, key_path_key, key_path); | 2884 PutIDBKeyPath(leveldb_transaction, key_path_key, key_path); |
| 2883 PutBool(leveldb_transaction, multi_entry_key, is_multi_entry); | 2885 PutBool(leveldb_transaction, multi_entry_key, is_multi_entry); |
| 2884 return s; | 2886 return s; |
| 2885 } | 2887 } |
| 2886 | 2888 |
| 2887 leveldb::Status IndexedDBBackingStore::DeleteIndex( | 2889 leveldb::Status IndexedDBBackingStore::DeleteIndex( |
| 2888 IndexedDBBackingStore::Transaction* transaction, | 2890 IndexedDBBackingStore::Transaction* transaction, |
| 2889 int64 database_id, | 2891 int64_t database_id, |
| 2890 int64 object_store_id, | 2892 int64_t object_store_id, |
| 2891 int64 index_id) { | 2893 int64_t index_id) { |
| 2892 IDB_TRACE("IndexedDBBackingStore::DeleteIndex"); | 2894 IDB_TRACE("IndexedDBBackingStore::DeleteIndex"); |
| 2893 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) | 2895 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) |
| 2894 return InvalidDBKeyStatus(); | 2896 return InvalidDBKeyStatus(); |
| 2895 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 2897 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 2896 | 2898 |
| 2897 const std::string index_meta_data_start = | 2899 const std::string index_meta_data_start = |
| 2898 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0); | 2900 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0); |
| 2899 const std::string index_meta_data_end = | 2901 const std::string index_meta_data_end = |
| 2900 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id); | 2902 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id); |
| 2901 leveldb::Status s = DeleteRangeBasic( | 2903 leveldb::Status s = DeleteRangeBasic( |
| 2902 leveldb_transaction, index_meta_data_start, index_meta_data_end, true); | 2904 leveldb_transaction, index_meta_data_start, index_meta_data_end, true); |
| 2903 | 2905 |
| 2904 if (s.ok()) { | 2906 if (s.ok()) { |
| 2905 const std::string index_data_start = | 2907 const std::string index_data_start = |
| 2906 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); | 2908 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); |
| 2907 const std::string index_data_end = | 2909 const std::string index_data_end = |
| 2908 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); | 2910 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); |
| 2909 s = DeleteRangeBasic( | 2911 s = DeleteRangeBasic( |
| 2910 leveldb_transaction, index_data_start, index_data_end, true); | 2912 leveldb_transaction, index_data_start, index_data_end, true); |
| 2911 } | 2913 } |
| 2912 | 2914 |
| 2913 if (!s.ok()) | 2915 if (!s.ok()) |
| 2914 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_INDEX); | 2916 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_INDEX); |
| 2915 | 2917 |
| 2916 return s; | 2918 return s; |
| 2917 } | 2919 } |
| 2918 | 2920 |
| 2919 leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord( | 2921 leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord( |
| 2920 IndexedDBBackingStore::Transaction* transaction, | 2922 IndexedDBBackingStore::Transaction* transaction, |
| 2921 int64 database_id, | 2923 int64_t database_id, |
| 2922 int64 object_store_id, | 2924 int64_t object_store_id, |
| 2923 int64 index_id, | 2925 int64_t index_id, |
| 2924 const IndexedDBKey& key, | 2926 const IndexedDBKey& key, |
| 2925 const RecordIdentifier& record_identifier) { | 2927 const RecordIdentifier& record_identifier) { |
| 2926 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord"); | 2928 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord"); |
| 2927 DCHECK(key.IsValid()); | 2929 DCHECK(key.IsValid()); |
| 2928 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) | 2930 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) |
| 2929 return InvalidDBKeyStatus(); | 2931 return InvalidDBKeyStatus(); |
| 2930 | 2932 |
| 2931 std::string encoded_key; | 2933 std::string encoded_key; |
| 2932 EncodeIDBKey(key, &encoded_key); | 2934 EncodeIDBKey(key, &encoded_key); |
| 2933 | 2935 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2972 *found_key = it->Key().as_string(); | 2974 *found_key = it->Key().as_string(); |
| 2973 | 2975 |
| 2974 // There can be several index keys that compare equal. We want the last one. | 2976 // There can be several index keys that compare equal. We want the last one. |
| 2975 *s = it->Next(); | 2977 *s = it->Next(); |
| 2976 } while (s->ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target)); | 2978 } while (s->ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target)); |
| 2977 | 2979 |
| 2978 return true; | 2980 return true; |
| 2979 } | 2981 } |
| 2980 | 2982 |
| 2981 static leveldb::Status VersionExists(LevelDBTransaction* transaction, | 2983 static leveldb::Status VersionExists(LevelDBTransaction* transaction, |
| 2982 int64 database_id, | 2984 int64_t database_id, |
| 2983 int64 object_store_id, | 2985 int64_t object_store_id, |
| 2984 int64 version, | 2986 int64_t version, |
| 2985 const std::string& encoded_primary_key, | 2987 const std::string& encoded_primary_key, |
| 2986 bool* exists) { | 2988 bool* exists) { |
| 2987 const std::string key = | 2989 const std::string key = |
| 2988 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key); | 2990 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key); |
| 2989 std::string data; | 2991 std::string data; |
| 2990 | 2992 |
| 2991 leveldb::Status s = transaction->Get(key, &data, exists); | 2993 leveldb::Status s = transaction->Get(key, &data, exists); |
| 2992 if (!s.ok()) { | 2994 if (!s.ok()) { |
| 2993 INTERNAL_READ_ERROR_UNTESTED(VERSION_EXISTS); | 2995 INTERNAL_READ_ERROR_UNTESTED(VERSION_EXISTS); |
| 2994 return s; | 2996 return s; |
| 2995 } | 2997 } |
| 2996 if (!*exists) | 2998 if (!*exists) |
| 2997 return s; | 2999 return s; |
| 2998 | 3000 |
| 2999 StringPiece slice(data); | 3001 StringPiece slice(data); |
| 3000 int64 decoded; | 3002 int64_t decoded; |
| 3001 if (!DecodeInt(&slice, &decoded) || !slice.empty()) | 3003 if (!DecodeInt(&slice, &decoded) || !slice.empty()) |
| 3002 return InternalInconsistencyStatus(); | 3004 return InternalInconsistencyStatus(); |
| 3003 *exists = (decoded == version); | 3005 *exists = (decoded == version); |
| 3004 return s; | 3006 return s; |
| 3005 } | 3007 } |
| 3006 | 3008 |
| 3007 leveldb::Status IndexedDBBackingStore::FindKeyInIndex( | 3009 leveldb::Status IndexedDBBackingStore::FindKeyInIndex( |
| 3008 IndexedDBBackingStore::Transaction* transaction, | 3010 IndexedDBBackingStore::Transaction* transaction, |
| 3009 int64 database_id, | 3011 int64_t database_id, |
| 3010 int64 object_store_id, | 3012 int64_t object_store_id, |
| 3011 int64 index_id, | 3013 int64_t index_id, |
| 3012 const IndexedDBKey& key, | 3014 const IndexedDBKey& key, |
| 3013 std::string* found_encoded_primary_key, | 3015 std::string* found_encoded_primary_key, |
| 3014 bool* found) { | 3016 bool* found) { |
| 3015 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex"); | 3017 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex"); |
| 3016 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id)); | 3018 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id)); |
| 3017 | 3019 |
| 3018 DCHECK(found_encoded_primary_key->empty()); | 3020 DCHECK(found_encoded_primary_key->empty()); |
| 3019 *found = false; | 3021 *found = false; |
| 3020 | 3022 |
| 3021 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 3023 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 3022 const std::string leveldb_key = | 3024 const std::string leveldb_key = |
| 3023 IndexDataKey::Encode(database_id, object_store_id, index_id, key); | 3025 IndexDataKey::Encode(database_id, object_store_id, index_id, key); |
| 3024 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); | 3026 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); |
| 3025 leveldb::Status s = it->Seek(leveldb_key); | 3027 leveldb::Status s = it->Seek(leveldb_key); |
| 3026 if (!s.ok()) { | 3028 if (!s.ok()) { |
| 3027 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); | 3029 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); |
| 3028 return s; | 3030 return s; |
| 3029 } | 3031 } |
| 3030 | 3032 |
| 3031 for (;;) { | 3033 for (;;) { |
| 3032 if (!it->IsValid()) | 3034 if (!it->IsValid()) |
| 3033 return leveldb::Status::OK(); | 3035 return leveldb::Status::OK(); |
| 3034 if (CompareIndexKeys(it->Key(), leveldb_key) > 0) | 3036 if (CompareIndexKeys(it->Key(), leveldb_key) > 0) |
| 3035 return leveldb::Status::OK(); | 3037 return leveldb::Status::OK(); |
| 3036 | 3038 |
| 3037 StringPiece slice(it->Value()); | 3039 StringPiece slice(it->Value()); |
| 3038 | 3040 |
| 3039 int64 version; | 3041 int64_t version; |
| 3040 if (!DecodeVarInt(&slice, &version)) { | 3042 if (!DecodeVarInt(&slice, &version)) { |
| 3041 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); | 3043 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); |
| 3042 return InternalInconsistencyStatus(); | 3044 return InternalInconsistencyStatus(); |
| 3043 } | 3045 } |
| 3044 *found_encoded_primary_key = slice.as_string(); | 3046 *found_encoded_primary_key = slice.as_string(); |
| 3045 | 3047 |
| 3046 bool exists = false; | 3048 bool exists = false; |
| 3047 s = VersionExists(leveldb_transaction, | 3049 s = VersionExists(leveldb_transaction, |
| 3048 database_id, | 3050 database_id, |
| 3049 object_store_id, | 3051 object_store_id, |
| 3050 version, | 3052 version, |
| 3051 *found_encoded_primary_key, | 3053 *found_encoded_primary_key, |
| 3052 &exists); | 3054 &exists); |
| 3053 if (!s.ok()) | 3055 if (!s.ok()) |
| 3054 return s; | 3056 return s; |
| 3055 if (!exists) { | 3057 if (!exists) { |
| 3056 // Delete stale index data entry and continue. | 3058 // Delete stale index data entry and continue. |
| 3057 leveldb_transaction->Remove(it->Key()); | 3059 leveldb_transaction->Remove(it->Key()); |
| 3058 s = it->Next(); | 3060 s = it->Next(); |
| 3059 continue; | 3061 continue; |
| 3060 } | 3062 } |
| 3061 *found = true; | 3063 *found = true; |
| 3062 return s; | 3064 return s; |
| 3063 } | 3065 } |
| 3064 } | 3066 } |
| 3065 | 3067 |
| 3066 leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex( | 3068 leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex( |
| 3067 IndexedDBBackingStore::Transaction* transaction, | 3069 IndexedDBBackingStore::Transaction* transaction, |
| 3068 int64 database_id, | 3070 int64_t database_id, |
| 3069 int64 object_store_id, | 3071 int64_t object_store_id, |
| 3070 int64 index_id, | 3072 int64_t index_id, |
| 3071 const IndexedDBKey& key, | 3073 const IndexedDBKey& key, |
| 3072 scoped_ptr<IndexedDBKey>* primary_key) { | 3074 scoped_ptr<IndexedDBKey>* primary_key) { |
| 3073 IDB_TRACE("IndexedDBBackingStore::GetPrimaryKeyViaIndex"); | 3075 IDB_TRACE("IndexedDBBackingStore::GetPrimaryKeyViaIndex"); |
| 3074 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) | 3076 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) |
| 3075 return InvalidDBKeyStatus(); | 3077 return InvalidDBKeyStatus(); |
| 3076 | 3078 |
| 3077 bool found = false; | 3079 bool found = false; |
| 3078 std::string found_encoded_primary_key; | 3080 std::string found_encoded_primary_key; |
| 3079 leveldb::Status s = FindKeyInIndex(transaction, | 3081 leveldb::Status s = FindKeyInIndex(transaction, |
| 3080 database_id, | 3082 database_id, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3096 | 3098 |
| 3097 StringPiece slice(found_encoded_primary_key); | 3099 StringPiece slice(found_encoded_primary_key); |
| 3098 if (DecodeIDBKey(&slice, primary_key) && slice.empty()) | 3100 if (DecodeIDBKey(&slice, primary_key) && slice.empty()) |
| 3099 return s; | 3101 return s; |
| 3100 else | 3102 else |
| 3101 return InvalidDBKeyStatus(); | 3103 return InvalidDBKeyStatus(); |
| 3102 } | 3104 } |
| 3103 | 3105 |
| 3104 leveldb::Status IndexedDBBackingStore::KeyExistsInIndex( | 3106 leveldb::Status IndexedDBBackingStore::KeyExistsInIndex( |
| 3105 IndexedDBBackingStore::Transaction* transaction, | 3107 IndexedDBBackingStore::Transaction* transaction, |
| 3106 int64 database_id, | 3108 int64_t database_id, |
| 3107 int64 object_store_id, | 3109 int64_t object_store_id, |
| 3108 int64 index_id, | 3110 int64_t index_id, |
| 3109 const IndexedDBKey& index_key, | 3111 const IndexedDBKey& index_key, |
| 3110 scoped_ptr<IndexedDBKey>* found_primary_key, | 3112 scoped_ptr<IndexedDBKey>* found_primary_key, |
| 3111 bool* exists) { | 3113 bool* exists) { |
| 3112 IDB_TRACE("IndexedDBBackingStore::KeyExistsInIndex"); | 3114 IDB_TRACE("IndexedDBBackingStore::KeyExistsInIndex"); |
| 3113 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) | 3115 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) |
| 3114 return InvalidDBKeyStatus(); | 3116 return InvalidDBKeyStatus(); |
| 3115 | 3117 |
| 3116 *exists = false; | 3118 *exists = false; |
| 3117 std::string found_encoded_primary_key; | 3119 std::string found_encoded_primary_key; |
| 3118 leveldb::Status s = FindKeyInIndex(transaction, | 3120 leveldb::Status s = FindKeyInIndex(transaction, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3154 leveldb::Status s = iterator_->Seek(other->iterator_->Key()); | 3156 leveldb::Status s = iterator_->Seek(other->iterator_->Key()); |
| 3155 // TODO(cmumford): Handle this error (crbug.com/363397) | 3157 // TODO(cmumford): Handle this error (crbug.com/363397) |
| 3156 DCHECK(iterator_->IsValid()); | 3158 DCHECK(iterator_->IsValid()); |
| 3157 } | 3159 } |
| 3158 } | 3160 } |
| 3159 } | 3161 } |
| 3160 | 3162 |
| 3161 IndexedDBBackingStore::Cursor::Cursor( | 3163 IndexedDBBackingStore::Cursor::Cursor( |
| 3162 scoped_refptr<IndexedDBBackingStore> backing_store, | 3164 scoped_refptr<IndexedDBBackingStore> backing_store, |
| 3163 IndexedDBBackingStore::Transaction* transaction, | 3165 IndexedDBBackingStore::Transaction* transaction, |
| 3164 int64 database_id, | 3166 int64_t database_id, |
| 3165 const CursorOptions& cursor_options) | 3167 const CursorOptions& cursor_options) |
| 3166 : backing_store_(backing_store.get()), | 3168 : backing_store_(backing_store.get()), |
| 3167 transaction_(transaction), | 3169 transaction_(transaction), |
| 3168 database_id_(database_id), | 3170 database_id_(database_id), |
| 3169 cursor_options_(cursor_options) { | 3171 cursor_options_(cursor_options) {} |
| 3170 } | |
| 3171 IndexedDBBackingStore::Cursor::~Cursor() {} | 3172 IndexedDBBackingStore::Cursor::~Cursor() {} |
| 3172 | 3173 |
| 3173 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) { | 3174 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) { |
| 3174 iterator_ = transaction_->transaction()->CreateIterator(); | 3175 iterator_ = transaction_->transaction()->CreateIterator(); |
| 3175 if (cursor_options_.forward) | 3176 if (cursor_options_.forward) |
| 3176 *s = iterator_->Seek(cursor_options_.low_key); | 3177 *s = iterator_->Seek(cursor_options_.low_key); |
| 3177 else | 3178 else |
| 3178 *s = iterator_->Seek(cursor_options_.high_key); | 3179 *s = iterator_->Seek(cursor_options_.high_key); |
| 3179 if (!s->ok()) | 3180 if (!s->ok()) |
| 3180 return false; | 3181 return false; |
| 3181 | 3182 |
| 3182 return Continue(0, READY, s); | 3183 return Continue(0, READY, s); |
| 3183 } | 3184 } |
| 3184 | 3185 |
| 3185 bool IndexedDBBackingStore::Cursor::Advance(uint32 count, leveldb::Status* s) { | 3186 bool IndexedDBBackingStore::Cursor::Advance(uint32_t count, |
| 3187 leveldb::Status* s) { |
| 3186 *s = leveldb::Status::OK(); | 3188 *s = leveldb::Status::OK(); |
| 3187 while (count--) { | 3189 while (count--) { |
| 3188 if (!Continue(s)) | 3190 if (!Continue(s)) |
| 3189 return false; | 3191 return false; |
| 3190 } | 3192 } |
| 3191 return true; | 3193 return true; |
| 3192 } | 3194 } |
| 3193 | 3195 |
| 3194 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, | 3196 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, |
| 3195 const IndexedDBKey* primary_key, | 3197 const IndexedDBKey* primary_key, |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3416 const IndexedDBBackingStore::RecordIdentifier& | 3418 const IndexedDBBackingStore::RecordIdentifier& |
| 3417 IndexedDBBackingStore::Cursor::record_identifier() const { | 3419 IndexedDBBackingStore::Cursor::record_identifier() const { |
| 3418 return record_identifier_; | 3420 return record_identifier_; |
| 3419 } | 3421 } |
| 3420 | 3422 |
| 3421 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { | 3423 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { |
| 3422 public: | 3424 public: |
| 3423 ObjectStoreKeyCursorImpl( | 3425 ObjectStoreKeyCursorImpl( |
| 3424 scoped_refptr<IndexedDBBackingStore> backing_store, | 3426 scoped_refptr<IndexedDBBackingStore> backing_store, |
| 3425 IndexedDBBackingStore::Transaction* transaction, | 3427 IndexedDBBackingStore::Transaction* transaction, |
| 3426 int64 database_id, | 3428 int64_t database_id, |
| 3427 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) | 3429 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) |
| 3428 : IndexedDBBackingStore::Cursor(backing_store, | 3430 : IndexedDBBackingStore::Cursor(backing_store, |
| 3429 transaction, | 3431 transaction, |
| 3430 database_id, | 3432 database_id, |
| 3431 cursor_options) {} | 3433 cursor_options) {} |
| 3432 | 3434 |
| 3433 Cursor* Clone() override { return new ObjectStoreKeyCursorImpl(this); } | 3435 Cursor* Clone() override { return new ObjectStoreKeyCursorImpl(this); } |
| 3434 | 3436 |
| 3435 // IndexedDBBackingStore::Cursor | 3437 // IndexedDBBackingStore::Cursor |
| 3436 IndexedDBValue* value() override { | 3438 IndexedDBValue* value() override { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3461 StringPiece slice(iterator_->Key()); | 3463 StringPiece slice(iterator_->Key()); |
| 3462 ObjectStoreDataKey object_store_data_key; | 3464 ObjectStoreDataKey object_store_data_key; |
| 3463 if (!ObjectStoreDataKey::Decode(&slice, &object_store_data_key)) { | 3465 if (!ObjectStoreDataKey::Decode(&slice, &object_store_data_key)) { |
| 3464 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3466 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3465 *s = InvalidDBKeyStatus(); | 3467 *s = InvalidDBKeyStatus(); |
| 3466 return false; | 3468 return false; |
| 3467 } | 3469 } |
| 3468 | 3470 |
| 3469 current_key_ = object_store_data_key.user_key(); | 3471 current_key_ = object_store_data_key.user_key(); |
| 3470 | 3472 |
| 3471 int64 version; | 3473 int64_t version; |
| 3472 slice = StringPiece(iterator_->Value()); | 3474 slice = StringPiece(iterator_->Value()); |
| 3473 if (!DecodeVarInt(&slice, &version)) { | 3475 if (!DecodeVarInt(&slice, &version)) { |
| 3474 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3476 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3475 *s = InternalInconsistencyStatus(); | 3477 *s = InternalInconsistencyStatus(); |
| 3476 return false; | 3478 return false; |
| 3477 } | 3479 } |
| 3478 | 3480 |
| 3479 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. | 3481 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. |
| 3480 std::string encoded_key; | 3482 std::string encoded_key; |
| 3481 EncodeIDBKey(*current_key_, &encoded_key); | 3483 EncodeIDBKey(*current_key_, &encoded_key); |
| 3482 record_identifier_.Reset(encoded_key, version); | 3484 record_identifier_.Reset(encoded_key, version); |
| 3483 | 3485 |
| 3484 return true; | 3486 return true; |
| 3485 } | 3487 } |
| 3486 | 3488 |
| 3487 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { | 3489 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { |
| 3488 public: | 3490 public: |
| 3489 ObjectStoreCursorImpl( | 3491 ObjectStoreCursorImpl( |
| 3490 scoped_refptr<IndexedDBBackingStore> backing_store, | 3492 scoped_refptr<IndexedDBBackingStore> backing_store, |
| 3491 IndexedDBBackingStore::Transaction* transaction, | 3493 IndexedDBBackingStore::Transaction* transaction, |
| 3492 int64 database_id, | 3494 int64_t database_id, |
| 3493 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) | 3495 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) |
| 3494 : IndexedDBBackingStore::Cursor(backing_store, | 3496 : IndexedDBBackingStore::Cursor(backing_store, |
| 3495 transaction, | 3497 transaction, |
| 3496 database_id, | 3498 database_id, |
| 3497 cursor_options) {} | 3499 cursor_options) {} |
| 3498 | 3500 |
| 3499 Cursor* Clone() override { return new ObjectStoreCursorImpl(this); } | 3501 Cursor* Clone() override { return new ObjectStoreCursorImpl(this); } |
| 3500 | 3502 |
| 3501 // IndexedDBBackingStore::Cursor | 3503 // IndexedDBBackingStore::Cursor |
| 3502 IndexedDBValue* value() override { return ¤t_value_; } | 3504 IndexedDBValue* value() override { return ¤t_value_; } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3527 StringPiece key_slice(iterator_->Key()); | 3529 StringPiece key_slice(iterator_->Key()); |
| 3528 ObjectStoreDataKey object_store_data_key; | 3530 ObjectStoreDataKey object_store_data_key; |
| 3529 if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) { | 3531 if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) { |
| 3530 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3532 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3531 *s = InvalidDBKeyStatus(); | 3533 *s = InvalidDBKeyStatus(); |
| 3532 return false; | 3534 return false; |
| 3533 } | 3535 } |
| 3534 | 3536 |
| 3535 current_key_ = object_store_data_key.user_key(); | 3537 current_key_ = object_store_data_key.user_key(); |
| 3536 | 3538 |
| 3537 int64 version; | 3539 int64_t version; |
| 3538 StringPiece value_slice = StringPiece(iterator_->Value()); | 3540 StringPiece value_slice = StringPiece(iterator_->Value()); |
| 3539 if (!DecodeVarInt(&value_slice, &version)) { | 3541 if (!DecodeVarInt(&value_slice, &version)) { |
| 3540 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3542 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3541 *s = InternalInconsistencyStatus(); | 3543 *s = InternalInconsistencyStatus(); |
| 3542 return false; | 3544 return false; |
| 3543 } | 3545 } |
| 3544 | 3546 |
| 3545 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. | 3547 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. |
| 3546 std::string encoded_key; | 3548 std::string encoded_key; |
| 3547 EncodeIDBKey(*current_key_, &encoded_key); | 3549 EncodeIDBKey(*current_key_, &encoded_key); |
| 3548 record_identifier_.Reset(encoded_key, version); | 3550 record_identifier_.Reset(encoded_key, version); |
| 3549 | 3551 |
| 3550 *s = transaction_->GetBlobInfoForRecord( | 3552 *s = transaction_->GetBlobInfoForRecord( |
| 3551 database_id_, iterator_->Key().as_string(), ¤t_value_); | 3553 database_id_, iterator_->Key().as_string(), ¤t_value_); |
| 3552 if (!s->ok()) | 3554 if (!s->ok()) |
| 3553 return false; | 3555 return false; |
| 3554 | 3556 |
| 3555 current_value_.bits = value_slice.as_string(); | 3557 current_value_.bits = value_slice.as_string(); |
| 3556 return true; | 3558 return true; |
| 3557 } | 3559 } |
| 3558 | 3560 |
| 3559 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { | 3561 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { |
| 3560 public: | 3562 public: |
| 3561 IndexKeyCursorImpl( | 3563 IndexKeyCursorImpl( |
| 3562 scoped_refptr<IndexedDBBackingStore> backing_store, | 3564 scoped_refptr<IndexedDBBackingStore> backing_store, |
| 3563 IndexedDBBackingStore::Transaction* transaction, | 3565 IndexedDBBackingStore::Transaction* transaction, |
| 3564 int64 database_id, | 3566 int64_t database_id, |
| 3565 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) | 3567 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) |
| 3566 : IndexedDBBackingStore::Cursor(backing_store, | 3568 : IndexedDBBackingStore::Cursor(backing_store, |
| 3567 transaction, | 3569 transaction, |
| 3568 database_id, | 3570 database_id, |
| 3569 cursor_options) {} | 3571 cursor_options) {} |
| 3570 | 3572 |
| 3571 Cursor* Clone() override { return new IndexKeyCursorImpl(this); } | 3573 Cursor* Clone() override { return new IndexKeyCursorImpl(this); } |
| 3572 | 3574 |
| 3573 // IndexedDBBackingStore::Cursor | 3575 // IndexedDBBackingStore::Cursor |
| 3574 IndexedDBValue* value() override { | 3576 IndexedDBValue* value() override { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3615 if (!IndexDataKey::Decode(&slice, &index_data_key)) { | 3617 if (!IndexDataKey::Decode(&slice, &index_data_key)) { |
| 3616 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3618 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3617 *s = InvalidDBKeyStatus(); | 3619 *s = InvalidDBKeyStatus(); |
| 3618 return false; | 3620 return false; |
| 3619 } | 3621 } |
| 3620 | 3622 |
| 3621 current_key_ = index_data_key.user_key(); | 3623 current_key_ = index_data_key.user_key(); |
| 3622 DCHECK(current_key_); | 3624 DCHECK(current_key_); |
| 3623 | 3625 |
| 3624 slice = StringPiece(iterator_->Value()); | 3626 slice = StringPiece(iterator_->Value()); |
| 3625 int64 index_data_version; | 3627 int64_t index_data_version; |
| 3626 if (!DecodeVarInt(&slice, &index_data_version)) { | 3628 if (!DecodeVarInt(&slice, &index_data_version)) { |
| 3627 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3629 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3628 *s = InternalInconsistencyStatus(); | 3630 *s = InternalInconsistencyStatus(); |
| 3629 return false; | 3631 return false; |
| 3630 } | 3632 } |
| 3631 | 3633 |
| 3632 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) { | 3634 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) { |
| 3633 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3635 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3634 *s = InternalInconsistencyStatus(); | 3636 *s = InternalInconsistencyStatus(); |
| 3635 return false; | 3637 return false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3649 } | 3651 } |
| 3650 if (!found) { | 3652 if (!found) { |
| 3651 transaction_->transaction()->Remove(iterator_->Key()); | 3653 transaction_->transaction()->Remove(iterator_->Key()); |
| 3652 return false; | 3654 return false; |
| 3653 } | 3655 } |
| 3654 if (!result.size()) { | 3656 if (!result.size()) { |
| 3655 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3657 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3656 return false; | 3658 return false; |
| 3657 } | 3659 } |
| 3658 | 3660 |
| 3659 int64 object_store_data_version; | 3661 int64_t object_store_data_version; |
| 3660 slice = StringPiece(result); | 3662 slice = StringPiece(result); |
| 3661 if (!DecodeVarInt(&slice, &object_store_data_version)) { | 3663 if (!DecodeVarInt(&slice, &object_store_data_version)) { |
| 3662 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3664 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3663 *s = InternalInconsistencyStatus(); | 3665 *s = InternalInconsistencyStatus(); |
| 3664 return false; | 3666 return false; |
| 3665 } | 3667 } |
| 3666 | 3668 |
| 3667 if (object_store_data_version != index_data_version) { | 3669 if (object_store_data_version != index_data_version) { |
| 3668 transaction_->transaction()->Remove(iterator_->Key()); | 3670 transaction_->transaction()->Remove(iterator_->Key()); |
| 3669 return false; | 3671 return false; |
| 3670 } | 3672 } |
| 3671 | 3673 |
| 3672 return true; | 3674 return true; |
| 3673 } | 3675 } |
| 3674 | 3676 |
| 3675 class IndexCursorImpl : public IndexedDBBackingStore::Cursor { | 3677 class IndexCursorImpl : public IndexedDBBackingStore::Cursor { |
| 3676 public: | 3678 public: |
| 3677 IndexCursorImpl( | 3679 IndexCursorImpl( |
| 3678 scoped_refptr<IndexedDBBackingStore> backing_store, | 3680 scoped_refptr<IndexedDBBackingStore> backing_store, |
| 3679 IndexedDBBackingStore::Transaction* transaction, | 3681 IndexedDBBackingStore::Transaction* transaction, |
| 3680 int64 database_id, | 3682 int64_t database_id, |
| 3681 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) | 3683 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) |
| 3682 : IndexedDBBackingStore::Cursor(backing_store, | 3684 : IndexedDBBackingStore::Cursor(backing_store, |
| 3683 transaction, | 3685 transaction, |
| 3684 database_id, | 3686 database_id, |
| 3685 cursor_options) {} | 3687 cursor_options) {} |
| 3686 | 3688 |
| 3687 Cursor* Clone() override { return new IndexCursorImpl(this); } | 3689 Cursor* Clone() override { return new IndexCursorImpl(this); } |
| 3688 | 3690 |
| 3689 // IndexedDBBackingStore::Cursor | 3691 // IndexedDBBackingStore::Cursor |
| 3690 IndexedDBValue* value() override { return ¤t_value_; } | 3692 IndexedDBValue* value() override { return ¤t_value_; } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3732 if (!IndexDataKey::Decode(&slice, &index_data_key)) { | 3734 if (!IndexDataKey::Decode(&slice, &index_data_key)) { |
| 3733 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3735 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3734 *s = InvalidDBKeyStatus(); | 3736 *s = InvalidDBKeyStatus(); |
| 3735 return false; | 3737 return false; |
| 3736 } | 3738 } |
| 3737 | 3739 |
| 3738 current_key_ = index_data_key.user_key(); | 3740 current_key_ = index_data_key.user_key(); |
| 3739 DCHECK(current_key_); | 3741 DCHECK(current_key_); |
| 3740 | 3742 |
| 3741 slice = StringPiece(iterator_->Value()); | 3743 slice = StringPiece(iterator_->Value()); |
| 3742 int64 index_data_version; | 3744 int64_t index_data_version; |
| 3743 if (!DecodeVarInt(&slice, &index_data_version)) { | 3745 if (!DecodeVarInt(&slice, &index_data_version)) { |
| 3744 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3746 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3745 *s = InternalInconsistencyStatus(); | 3747 *s = InternalInconsistencyStatus(); |
| 3746 return false; | 3748 return false; |
| 3747 } | 3749 } |
| 3748 if (!DecodeIDBKey(&slice, &primary_key_)) { | 3750 if (!DecodeIDBKey(&slice, &primary_key_)) { |
| 3749 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3751 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3750 *s = InvalidDBKeyStatus(); | 3752 *s = InvalidDBKeyStatus(); |
| 3751 return false; | 3753 return false; |
| 3752 } | 3754 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3766 } | 3768 } |
| 3767 if (!found) { | 3769 if (!found) { |
| 3768 transaction_->transaction()->Remove(iterator_->Key()); | 3770 transaction_->transaction()->Remove(iterator_->Key()); |
| 3769 return false; | 3771 return false; |
| 3770 } | 3772 } |
| 3771 if (!result.size()) { | 3773 if (!result.size()) { |
| 3772 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3774 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3773 return false; | 3775 return false; |
| 3774 } | 3776 } |
| 3775 | 3777 |
| 3776 int64 object_store_data_version; | 3778 int64_t object_store_data_version; |
| 3777 slice = StringPiece(result); | 3779 slice = StringPiece(result); |
| 3778 if (!DecodeVarInt(&slice, &object_store_data_version)) { | 3780 if (!DecodeVarInt(&slice, &object_store_data_version)) { |
| 3779 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); | 3781 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); |
| 3780 *s = InternalInconsistencyStatus(); | 3782 *s = InternalInconsistencyStatus(); |
| 3781 return false; | 3783 return false; |
| 3782 } | 3784 } |
| 3783 | 3785 |
| 3784 if (object_store_data_version != index_data_version) { | 3786 if (object_store_data_version != index_data_version) { |
| 3785 transaction_->transaction()->Remove(iterator_->Key()); | 3787 transaction_->transaction()->Remove(iterator_->Key()); |
| 3786 return false; | 3788 return false; |
| 3787 } | 3789 } |
| 3788 | 3790 |
| 3789 current_value_.bits = slice.as_string(); | 3791 current_value_.bits = slice.as_string(); |
| 3790 *s = transaction_->GetBlobInfoForRecord(database_id_, primary_leveldb_key_, | 3792 *s = transaction_->GetBlobInfoForRecord(database_id_, primary_leveldb_key_, |
| 3791 ¤t_value_); | 3793 ¤t_value_); |
| 3792 return s->ok(); | 3794 return s->ok(); |
| 3793 } | 3795 } |
| 3794 | 3796 |
| 3795 bool ObjectStoreCursorOptions( | 3797 bool ObjectStoreCursorOptions( |
| 3796 LevelDBTransaction* transaction, | 3798 LevelDBTransaction* transaction, |
| 3797 int64 database_id, | 3799 int64_t database_id, |
| 3798 int64 object_store_id, | 3800 int64_t object_store_id, |
| 3799 const IndexedDBKeyRange& range, | 3801 const IndexedDBKeyRange& range, |
| 3800 blink::WebIDBCursorDirection direction, | 3802 blink::WebIDBCursorDirection direction, |
| 3801 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { | 3803 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { |
| 3802 cursor_options->database_id = database_id; | 3804 cursor_options->database_id = database_id; |
| 3803 cursor_options->object_store_id = object_store_id; | 3805 cursor_options->object_store_id = object_store_id; |
| 3804 | 3806 |
| 3805 bool lower_bound = range.lower().IsValid(); | 3807 bool lower_bound = range.lower().IsValid(); |
| 3806 bool upper_bound = range.upper().IsValid(); | 3808 bool upper_bound = range.upper().IsValid(); |
| 3807 cursor_options->forward = | 3809 cursor_options->forward = |
| 3808 (direction == blink::WebIDBCursorDirectionNextNoDuplicate || | 3810 (direction == blink::WebIDBCursorDirectionNextNoDuplicate || |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3860 | 3862 |
| 3861 cursor_options->high_key = found_high_key; | 3863 cursor_options->high_key = found_high_key; |
| 3862 } | 3864 } |
| 3863 } | 3865 } |
| 3864 | 3866 |
| 3865 return true; | 3867 return true; |
| 3866 } | 3868 } |
| 3867 | 3869 |
| 3868 bool IndexCursorOptions( | 3870 bool IndexCursorOptions( |
| 3869 LevelDBTransaction* transaction, | 3871 LevelDBTransaction* transaction, |
| 3870 int64 database_id, | 3872 int64_t database_id, |
| 3871 int64 object_store_id, | 3873 int64_t object_store_id, |
| 3872 int64 index_id, | 3874 int64_t index_id, |
| 3873 const IndexedDBKeyRange& range, | 3875 const IndexedDBKeyRange& range, |
| 3874 blink::WebIDBCursorDirection direction, | 3876 blink::WebIDBCursorDirection direction, |
| 3875 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { | 3877 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { |
| 3876 DCHECK(transaction); | 3878 DCHECK(transaction); |
| 3877 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) | 3879 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) |
| 3878 return false; | 3880 return false; |
| 3879 | 3881 |
| 3880 cursor_options->database_id = database_id; | 3882 cursor_options->database_id = database_id; |
| 3881 cursor_options->object_store_id = object_store_id; | 3883 cursor_options->object_store_id = object_store_id; |
| 3882 cursor_options->index_id = index_id; | 3884 cursor_options->index_id = index_id; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3935 | 3937 |
| 3936 cursor_options->high_key = found_high_key; | 3938 cursor_options->high_key = found_high_key; |
| 3937 } | 3939 } |
| 3938 | 3940 |
| 3939 return true; | 3941 return true; |
| 3940 } | 3942 } |
| 3941 | 3943 |
| 3942 scoped_ptr<IndexedDBBackingStore::Cursor> | 3944 scoped_ptr<IndexedDBBackingStore::Cursor> |
| 3943 IndexedDBBackingStore::OpenObjectStoreCursor( | 3945 IndexedDBBackingStore::OpenObjectStoreCursor( |
| 3944 IndexedDBBackingStore::Transaction* transaction, | 3946 IndexedDBBackingStore::Transaction* transaction, |
| 3945 int64 database_id, | 3947 int64_t database_id, |
| 3946 int64 object_store_id, | 3948 int64_t object_store_id, |
| 3947 const IndexedDBKeyRange& range, | 3949 const IndexedDBKeyRange& range, |
| 3948 blink::WebIDBCursorDirection direction, | 3950 blink::WebIDBCursorDirection direction, |
| 3949 leveldb::Status* s) { | 3951 leveldb::Status* s) { |
| 3950 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor"); | 3952 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor"); |
| 3951 *s = leveldb::Status::OK(); | 3953 *s = leveldb::Status::OK(); |
| 3952 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 3954 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 3953 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; | 3955 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| 3954 if (!ObjectStoreCursorOptions(leveldb_transaction, | 3956 if (!ObjectStoreCursorOptions(leveldb_transaction, |
| 3955 database_id, | 3957 database_id, |
| 3956 object_store_id, | 3958 object_store_id, |
| 3957 range, | 3959 range, |
| 3958 direction, | 3960 direction, |
| 3959 &cursor_options)) | 3961 &cursor_options)) |
| 3960 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 3962 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 3961 scoped_ptr<ObjectStoreCursorImpl> cursor(new ObjectStoreCursorImpl( | 3963 scoped_ptr<ObjectStoreCursorImpl> cursor(new ObjectStoreCursorImpl( |
| 3962 this, transaction, database_id, cursor_options)); | 3964 this, transaction, database_id, cursor_options)); |
| 3963 if (!cursor->FirstSeek(s)) | 3965 if (!cursor->FirstSeek(s)) |
| 3964 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 3966 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 3965 | 3967 |
| 3966 return cursor.Pass(); | 3968 return cursor.Pass(); |
| 3967 } | 3969 } |
| 3968 | 3970 |
| 3969 scoped_ptr<IndexedDBBackingStore::Cursor> | 3971 scoped_ptr<IndexedDBBackingStore::Cursor> |
| 3970 IndexedDBBackingStore::OpenObjectStoreKeyCursor( | 3972 IndexedDBBackingStore::OpenObjectStoreKeyCursor( |
| 3971 IndexedDBBackingStore::Transaction* transaction, | 3973 IndexedDBBackingStore::Transaction* transaction, |
| 3972 int64 database_id, | 3974 int64_t database_id, |
| 3973 int64 object_store_id, | 3975 int64_t object_store_id, |
| 3974 const IndexedDBKeyRange& range, | 3976 const IndexedDBKeyRange& range, |
| 3975 blink::WebIDBCursorDirection direction, | 3977 blink::WebIDBCursorDirection direction, |
| 3976 leveldb::Status* s) { | 3978 leveldb::Status* s) { |
| 3977 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); | 3979 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); |
| 3978 *s = leveldb::Status::OK(); | 3980 *s = leveldb::Status::OK(); |
| 3979 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 3981 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 3980 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; | 3982 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| 3981 if (!ObjectStoreCursorOptions(leveldb_transaction, | 3983 if (!ObjectStoreCursorOptions(leveldb_transaction, |
| 3982 database_id, | 3984 database_id, |
| 3983 object_store_id, | 3985 object_store_id, |
| 3984 range, | 3986 range, |
| 3985 direction, | 3987 direction, |
| 3986 &cursor_options)) | 3988 &cursor_options)) |
| 3987 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 3989 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 3988 scoped_ptr<ObjectStoreKeyCursorImpl> cursor(new ObjectStoreKeyCursorImpl( | 3990 scoped_ptr<ObjectStoreKeyCursorImpl> cursor(new ObjectStoreKeyCursorImpl( |
| 3989 this, transaction, database_id, cursor_options)); | 3991 this, transaction, database_id, cursor_options)); |
| 3990 if (!cursor->FirstSeek(s)) | 3992 if (!cursor->FirstSeek(s)) |
| 3991 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 3993 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 3992 | 3994 |
| 3993 return cursor.Pass(); | 3995 return cursor.Pass(); |
| 3994 } | 3996 } |
| 3995 | 3997 |
| 3996 scoped_ptr<IndexedDBBackingStore::Cursor> | 3998 scoped_ptr<IndexedDBBackingStore::Cursor> |
| 3997 IndexedDBBackingStore::OpenIndexKeyCursor( | 3999 IndexedDBBackingStore::OpenIndexKeyCursor( |
| 3998 IndexedDBBackingStore::Transaction* transaction, | 4000 IndexedDBBackingStore::Transaction* transaction, |
| 3999 int64 database_id, | 4001 int64_t database_id, |
| 4000 int64 object_store_id, | 4002 int64_t object_store_id, |
| 4001 int64 index_id, | 4003 int64_t index_id, |
| 4002 const IndexedDBKeyRange& range, | 4004 const IndexedDBKeyRange& range, |
| 4003 blink::WebIDBCursorDirection direction, | 4005 blink::WebIDBCursorDirection direction, |
| 4004 leveldb::Status* s) { | 4006 leveldb::Status* s) { |
| 4005 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); | 4007 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); |
| 4006 *s = leveldb::Status::OK(); | 4008 *s = leveldb::Status::OK(); |
| 4007 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 4009 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 4008 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; | 4010 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| 4009 if (!IndexCursorOptions(leveldb_transaction, | 4011 if (!IndexCursorOptions(leveldb_transaction, |
| 4010 database_id, | 4012 database_id, |
| 4011 object_store_id, | 4013 object_store_id, |
| 4012 index_id, | 4014 index_id, |
| 4013 range, | 4015 range, |
| 4014 direction, | 4016 direction, |
| 4015 &cursor_options)) | 4017 &cursor_options)) |
| 4016 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 4018 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 4017 scoped_ptr<IndexKeyCursorImpl> cursor( | 4019 scoped_ptr<IndexKeyCursorImpl> cursor( |
| 4018 new IndexKeyCursorImpl(this, transaction, database_id, cursor_options)); | 4020 new IndexKeyCursorImpl(this, transaction, database_id, cursor_options)); |
| 4019 if (!cursor->FirstSeek(s)) | 4021 if (!cursor->FirstSeek(s)) |
| 4020 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 4022 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 4021 | 4023 |
| 4022 return cursor.Pass(); | 4024 return cursor.Pass(); |
| 4023 } | 4025 } |
| 4024 | 4026 |
| 4025 scoped_ptr<IndexedDBBackingStore::Cursor> | 4027 scoped_ptr<IndexedDBBackingStore::Cursor> |
| 4026 IndexedDBBackingStore::OpenIndexCursor( | 4028 IndexedDBBackingStore::OpenIndexCursor( |
| 4027 IndexedDBBackingStore::Transaction* transaction, | 4029 IndexedDBBackingStore::Transaction* transaction, |
| 4028 int64 database_id, | 4030 int64_t database_id, |
| 4029 int64 object_store_id, | 4031 int64_t object_store_id, |
| 4030 int64 index_id, | 4032 int64_t index_id, |
| 4031 const IndexedDBKeyRange& range, | 4033 const IndexedDBKeyRange& range, |
| 4032 blink::WebIDBCursorDirection direction, | 4034 blink::WebIDBCursorDirection direction, |
| 4033 leveldb::Status* s) { | 4035 leveldb::Status* s) { |
| 4034 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); | 4036 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); |
| 4035 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 4037 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| 4036 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; | 4038 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| 4037 if (!IndexCursorOptions(leveldb_transaction, | 4039 if (!IndexCursorOptions(leveldb_transaction, |
| 4038 database_id, | 4040 database_id, |
| 4039 object_store_id, | 4041 object_store_id, |
| 4040 index_id, | 4042 index_id, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4093 return leveldb::Status::OK(); | 4095 return leveldb::Status::OK(); |
| 4094 | 4096 |
| 4095 // Create LevelDBTransaction for the name generator seed and add-journal. | 4097 // Create LevelDBTransaction for the name generator seed and add-journal. |
| 4096 scoped_refptr<LevelDBTransaction> pre_transaction = | 4098 scoped_refptr<LevelDBTransaction> pre_transaction = |
| 4097 IndexedDBClassFactory::Get()->CreateLevelDBTransaction( | 4099 IndexedDBClassFactory::Get()->CreateLevelDBTransaction( |
| 4098 backing_store_->db_.get()); | 4100 backing_store_->db_.get()); |
| 4099 | 4101 |
| 4100 for (auto& iter : blob_change_map_) { | 4102 for (auto& iter : blob_change_map_) { |
| 4101 std::vector<IndexedDBBlobInfo*> new_blob_keys; | 4103 std::vector<IndexedDBBlobInfo*> new_blob_keys; |
| 4102 for (auto& entry : iter.second->mutable_blob_info()) { | 4104 for (auto& entry : iter.second->mutable_blob_info()) { |
| 4103 int64 next_blob_key = -1; | 4105 int64_t next_blob_key = -1; |
| 4104 bool result = GetBlobKeyGeneratorCurrentNumber( | 4106 bool result = GetBlobKeyGeneratorCurrentNumber( |
| 4105 pre_transaction.get(), database_id_, &next_blob_key); | 4107 pre_transaction.get(), database_id_, &next_blob_key); |
| 4106 if (!result || next_blob_key < 0) | 4108 if (!result || next_blob_key < 0) |
| 4107 return InternalInconsistencyStatus(); | 4109 return InternalInconsistencyStatus(); |
| 4108 blobs_to_write_.push_back(std::make_pair(database_id_, next_blob_key)); | 4110 blobs_to_write_.push_back(std::make_pair(database_id_, next_blob_key)); |
| 4109 if (entry.is_file() && !entry.file_path().empty()) { | 4111 if (entry.is_file() && !entry.file_path().empty()) { |
| 4110 new_files_to_write->push_back( | 4112 new_files_to_write->push_back( |
| 4111 WriteDescriptor(entry.file_path(), next_blob_key, entry.size(), | 4113 WriteDescriptor(entry.file_path(), next_blob_key, entry.size(), |
| 4112 entry.last_modified())); | 4114 entry.last_modified())); |
| 4113 } else { | 4115 } else { |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4394 chained_blob_writer_ = NULL; | 4396 chained_blob_writer_ = NULL; |
| 4395 } | 4397 } |
| 4396 if (transaction_.get() == NULL) | 4398 if (transaction_.get() == NULL) |
| 4397 return; | 4399 return; |
| 4398 transaction_->Rollback(); | 4400 transaction_->Rollback(); |
| 4399 transaction_ = NULL; | 4401 transaction_ = NULL; |
| 4400 } | 4402 } |
| 4401 | 4403 |
| 4402 IndexedDBBackingStore::BlobChangeRecord::BlobChangeRecord( | 4404 IndexedDBBackingStore::BlobChangeRecord::BlobChangeRecord( |
| 4403 const std::string& key, | 4405 const std::string& key, |
| 4404 int64 object_store_id) | 4406 int64_t object_store_id) |
| 4405 : key_(key), object_store_id_(object_store_id) { | 4407 : key_(key), object_store_id_(object_store_id) {} |
| 4406 } | |
| 4407 | 4408 |
| 4408 IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() { | 4409 IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() { |
| 4409 } | 4410 } |
| 4410 | 4411 |
| 4411 void IndexedDBBackingStore::BlobChangeRecord::SetBlobInfo( | 4412 void IndexedDBBackingStore::BlobChangeRecord::SetBlobInfo( |
| 4412 std::vector<IndexedDBBlobInfo>* blob_info) { | 4413 std::vector<IndexedDBBlobInfo>* blob_info) { |
| 4413 blob_info_.clear(); | 4414 blob_info_.clear(); |
| 4414 if (blob_info) | 4415 if (blob_info) |
| 4415 blob_info_.swap(*blob_info); | 4416 blob_info_.swap(*blob_info); |
| 4416 } | 4417 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4427 scoped_ptr<IndexedDBBackingStore::BlobChangeRecord> record( | 4428 scoped_ptr<IndexedDBBackingStore::BlobChangeRecord> record( |
| 4428 new BlobChangeRecord(key_, object_store_id_)); | 4429 new BlobChangeRecord(key_, object_store_id_)); |
| 4429 record->blob_info_ = blob_info_; | 4430 record->blob_info_ = blob_info_; |
| 4430 | 4431 |
| 4431 for (const auto* handle : handles_) | 4432 for (const auto* handle : handles_) |
| 4432 record->handles_.push_back(new storage::BlobDataHandle(*handle)); | 4433 record->handles_.push_back(new storage::BlobDataHandle(*handle)); |
| 4433 return record.Pass(); | 4434 return record.Pass(); |
| 4434 } | 4435 } |
| 4435 | 4436 |
| 4436 leveldb::Status IndexedDBBackingStore::Transaction::PutBlobInfoIfNeeded( | 4437 leveldb::Status IndexedDBBackingStore::Transaction::PutBlobInfoIfNeeded( |
| 4437 int64 database_id, | 4438 int64_t database_id, |
| 4438 int64 object_store_id, | 4439 int64_t object_store_id, |
| 4439 const std::string& object_store_data_key, | 4440 const std::string& object_store_data_key, |
| 4440 std::vector<IndexedDBBlobInfo>* blob_info, | 4441 std::vector<IndexedDBBlobInfo>* blob_info, |
| 4441 ScopedVector<storage::BlobDataHandle>* handles) { | 4442 ScopedVector<storage::BlobDataHandle>* handles) { |
| 4442 if (!blob_info || blob_info->empty()) { | 4443 if (!blob_info || blob_info->empty()) { |
| 4443 blob_change_map_.erase(object_store_data_key); | 4444 blob_change_map_.erase(object_store_data_key); |
| 4444 incognito_blob_map_.erase(object_store_data_key); | 4445 incognito_blob_map_.erase(object_store_data_key); |
| 4445 | 4446 |
| 4446 BlobEntryKey blob_entry_key; | 4447 BlobEntryKey blob_entry_key; |
| 4447 StringPiece leveldb_key_piece(object_store_data_key); | 4448 StringPiece leveldb_key_piece(object_store_data_key); |
| 4448 if (!BlobEntryKey::FromObjectStoreDataKey(&leveldb_key_piece, | 4449 if (!BlobEntryKey::FromObjectStoreDataKey(&leveldb_key_piece, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4462 PutBlobInfo( | 4463 PutBlobInfo( |
| 4463 database_id, object_store_id, object_store_data_key, blob_info, handles); | 4464 database_id, object_store_id, object_store_data_key, blob_info, handles); |
| 4464 return leveldb::Status::OK(); | 4465 return leveldb::Status::OK(); |
| 4465 } | 4466 } |
| 4466 | 4467 |
| 4467 // This is storing an info, even if empty, even if the previous key had no blob | 4468 // This is storing an info, even if empty, even if the previous key had no blob |
| 4468 // info that we know of. It duplicates a bunch of information stored in the | 4469 // info that we know of. It duplicates a bunch of information stored in the |
| 4469 // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the | 4470 // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the |
| 4470 // changes to exists or index keys here. | 4471 // changes to exists or index keys here. |
| 4471 void IndexedDBBackingStore::Transaction::PutBlobInfo( | 4472 void IndexedDBBackingStore::Transaction::PutBlobInfo( |
| 4472 int64 database_id, | 4473 int64_t database_id, |
| 4473 int64 object_store_id, | 4474 int64_t object_store_id, |
| 4474 const std::string& object_store_data_key, | 4475 const std::string& object_store_data_key, |
| 4475 std::vector<IndexedDBBlobInfo>* blob_info, | 4476 std::vector<IndexedDBBlobInfo>* blob_info, |
| 4476 ScopedVector<storage::BlobDataHandle>* handles) { | 4477 ScopedVector<storage::BlobDataHandle>* handles) { |
| 4477 DCHECK_GT(object_store_data_key.size(), 0UL); | 4478 DCHECK_GT(object_store_data_key.size(), 0UL); |
| 4478 if (database_id_ < 0) | 4479 if (database_id_ < 0) |
| 4479 database_id_ = database_id; | 4480 database_id_ = database_id; |
| 4480 DCHECK_EQ(database_id_, database_id); | 4481 DCHECK_EQ(database_id_, database_id); |
| 4481 | 4482 |
| 4482 BlobChangeMap::iterator it = blob_change_map_.find(object_store_data_key); | 4483 BlobChangeMap::iterator it = blob_change_map_.find(object_store_data_key); |
| 4483 BlobChangeRecord* record = NULL; | 4484 BlobChangeRecord* record = NULL; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4519 | 4520 |
| 4520 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( | 4521 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( |
| 4521 const WriteDescriptor& other) = default; | 4522 const WriteDescriptor& other) = default; |
| 4522 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = | 4523 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = |
| 4523 default; | 4524 default; |
| 4524 IndexedDBBackingStore::Transaction::WriteDescriptor& | 4525 IndexedDBBackingStore::Transaction::WriteDescriptor& |
| 4525 IndexedDBBackingStore::Transaction::WriteDescriptor:: | 4526 IndexedDBBackingStore::Transaction::WriteDescriptor:: |
| 4526 operator=(const WriteDescriptor& other) = default; | 4527 operator=(const WriteDescriptor& other) = default; |
| 4527 | 4528 |
| 4528 } // namespace content | 4529 } // namespace content |
| OLD | NEW |