| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 GET_NEW_DATABASE_ID, | 55 GET_NEW_DATABASE_ID, |
| 56 GET_NEW_VERSION_NUMBER, | 56 GET_NEW_VERSION_NUMBER, |
| 57 CREATE_IDBDATABASE_METADATA, | 57 CREATE_IDBDATABASE_METADATA, |
| 58 DELETE_DATABASE, | 58 DELETE_DATABASE, |
| 59 TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro | 59 TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro |
| 60 INTERNAL_ERROR_MAX, | 60 INTERNAL_ERROR_MAX, |
| 61 }; | 61 }; |
| 62 | 62 |
| 63 static void RecordInternalError(const char* type, | 63 static void RecordInternalError(const char* type, |
| 64 IndexedDBBackingStoreErrorSource location) { | 64 IndexedDBBackingStoreErrorSource location) { |
| 65 string16 name = ASCIIToUTF16("WebCore.IndexedDB.BackingStore.") + | 65 std::string name; |
| 66 UTF8ToUTF16(type) + ASCIIToUTF16("Error"); | 66 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error"); |
| 67 base::Histogram::FactoryGet(UTF16ToUTF8(name), | 67 base::Histogram::FactoryGet(name, |
| 68 1, | 68 1, |
| 69 INTERNAL_ERROR_MAX, | 69 INTERNAL_ERROR_MAX, |
| 70 INTERNAL_ERROR_MAX + 1, | 70 INTERNAL_ERROR_MAX + 1, |
| 71 base::HistogramBase::kUmaTargetedHistogramFlag) | 71 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 72 ->Add(location); | 72 ->Add(location); |
| 73 } | 73 } |
| 74 | 74 |
| 75 // Use to signal conditions that usually indicate developer error, but | 75 // Use to signal conditions that usually indicate developer error, but |
| 76 // could be caused by data corruption. A macro is used instead of an | 76 // could be caused by data corruption. A macro is used instead of an |
| 77 // inline function so that the assert and log report the line number. | 77 // inline function so that the assert and log report the line number. |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 std::vector<char> buffer; | 172 std::vector<char> buffer; |
| 173 EncodeIDBKeyPath(value, &buffer); | 173 EncodeIDBKeyPath(value, &buffer); |
| 174 transaction->Put(key, &buffer); | 174 transaction->Put(key, &buffer); |
| 175 } | 175 } |
| 176 | 176 |
| 177 static int CompareKeys(const LevelDBSlice& a, const LevelDBSlice& b) { | 177 static int CompareKeys(const LevelDBSlice& a, const LevelDBSlice& b) { |
| 178 return Compare(a, b, false /*index_keys*/); | 178 return Compare(a, b, false /*index_keys*/); |
| 179 } | 179 } |
| 180 | 180 |
| 181 static int CompareIndexKeys(const LevelDBSlice& a, const LevelDBSlice& b) { | 181 static int CompareIndexKeys(const LevelDBSlice& a, const LevelDBSlice& b) { |
| 182 return Compare(a, b, true /*index_keys*/); | 182 return Compare(a, b, true /*index_keys*/); |
| 183 } | 183 } |
| 184 | 184 |
| 185 class Comparator : public LevelDBComparator { | 185 class Comparator : public LevelDBComparator { |
| 186 public: | 186 public: |
| 187 virtual int Compare(const LevelDBSlice& a, const LevelDBSlice& b) const | 187 virtual int Compare(const LevelDBSlice& a, const LevelDBSlice& b) const |
| 188 OVERRIDE { | 188 OVERRIDE { |
| 189 return content::Compare(a, b, false /*index_keys*/); | 189 return content::Compare(a, b, false /*index_keys*/); |
| 190 } | 190 } |
| 191 virtual const char* Name() const OVERRIDE { return "idb_cmp1"; } | 191 virtual const char* Name() const OVERRIDE { return "idb_cmp1"; } |
| 192 }; | 192 }; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 224 |
| 225 if (db_data_version > latest_known_data_version) { | 225 if (db_data_version > latest_known_data_version) { |
| 226 *known = false; | 226 *known = false; |
| 227 return true; | 227 return true; |
| 228 } | 228 } |
| 229 | 229 |
| 230 *known = true; | 230 *known = true; |
| 231 return true; | 231 return true; |
| 232 } | 232 } |
| 233 | 233 |
| 234 WARN_UNUSED_RESULT static bool SetUpMetadata(LevelDBDatabase* db, | 234 WARN_UNUSED_RESULT static bool SetUpMetadata( |
| 235 const string16& origin) { | 235 LevelDBDatabase* db, |
| 236 const std::string& origin_identifier) { |
| 236 const uint32 latest_known_data_version = kWireVersion; | 237 const uint32 latest_known_data_version = kWireVersion; |
| 237 const std::vector<char> schema_version_key = SchemaVersionKey::Encode(); | 238 const std::vector<char> schema_version_key = SchemaVersionKey::Encode(); |
| 238 const std::vector<char> data_version_key = DataVersionKey::Encode(); | 239 const std::vector<char> data_version_key = DataVersionKey::Encode(); |
| 239 | 240 |
| 240 scoped_refptr<LevelDBTransaction> transaction = | 241 scoped_refptr<LevelDBTransaction> transaction = |
| 241 LevelDBTransaction::Create(db); | 242 LevelDBTransaction::Create(db); |
| 242 | 243 |
| 243 int64 db_schema_version = 0; | 244 int64 db_schema_version = 0; |
| 244 int64 db_data_version = 0; | 245 int64 db_data_version = 0; |
| 245 bool found = false; | 246 bool found = false; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 260 PutInt(transaction.get(), LevelDBSlice(data_version_key), db_data_version); | 261 PutInt(transaction.get(), LevelDBSlice(data_version_key), db_data_version); |
| 261 } else { | 262 } else { |
| 262 // Upgrade old backing store. | 263 // Upgrade old backing store. |
| 263 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); | 264 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); |
| 264 if (db_schema_version < 1) { | 265 if (db_schema_version < 1) { |
| 265 db_schema_version = 1; | 266 db_schema_version = 1; |
| 266 PutInt(transaction.get(), | 267 PutInt(transaction.get(), |
| 267 LevelDBSlice(schema_version_key), | 268 LevelDBSlice(schema_version_key), |
| 268 db_schema_version); | 269 db_schema_version); |
| 269 const std::vector<char> start_key = | 270 const std::vector<char> start_key = |
| 270 DatabaseNameKey::EncodeMinKeyForOrigin(origin); | 271 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); |
| 271 const std::vector<char> stop_key = | 272 const std::vector<char> stop_key = |
| 272 DatabaseNameKey::EncodeStopKeyForOrigin(origin); | 273 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); |
| 273 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); | 274 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); |
| 274 for (it->Seek(LevelDBSlice(start_key)); | 275 for (it->Seek(LevelDBSlice(start_key)); |
| 275 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; | 276 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; |
| 276 it->Next()) { | 277 it->Next()) { |
| 277 int64 database_id = 0; | 278 int64 database_id = 0; |
| 278 found = false; | 279 found = false; |
| 279 bool ok = GetInt(transaction.get(), it->Key(), &database_id, &found); | 280 bool ok = GetInt(transaction.get(), it->Key(), &database_id, &found); |
| 280 if (!ok) { | 281 if (!ok) { |
| 281 INTERNAL_READ_ERROR(SET_UP_METADATA); | 282 INTERNAL_READ_ERROR(SET_UP_METADATA); |
| 282 return false; | 283 return false; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 *max_object_store_id = 0; | 359 *max_object_store_id = 0; |
| 359 | 360 |
| 360 DCHECK_GE(*max_object_store_id, 0); | 361 DCHECK_GE(*max_object_store_id, 0); |
| 361 return true; | 362 return true; |
| 362 } | 363 } |
| 363 | 364 |
| 364 class DefaultLevelDBFactory : public LevelDBFactory { | 365 class DefaultLevelDBFactory : public LevelDBFactory { |
| 365 public: | 366 public: |
| 366 virtual scoped_ptr<LevelDBDatabase> OpenLevelDB( | 367 virtual scoped_ptr<LevelDBDatabase> OpenLevelDB( |
| 367 const base::FilePath& file_name, | 368 const base::FilePath& file_name, |
| 368 const LevelDBComparator* comparator, bool* is_disk_full) OVERRIDE { | 369 const LevelDBComparator* comparator, |
| 370 bool* is_disk_full) OVERRIDE { |
| 369 return LevelDBDatabase::Open(file_name, comparator, is_disk_full); | 371 return LevelDBDatabase::Open(file_name, comparator, is_disk_full); |
| 370 } | 372 } |
| 371 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE { | 373 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE { |
| 372 return LevelDBDatabase::Destroy(file_name); | 374 return LevelDBDatabase::Destroy(file_name); |
| 373 } | 375 } |
| 374 }; | 376 }; |
| 375 | 377 |
| 376 IndexedDBBackingStore::IndexedDBBackingStore( | 378 IndexedDBBackingStore::IndexedDBBackingStore( |
| 377 const string16& identifier, | 379 const std::string& identifier, |
| 378 scoped_ptr<LevelDBDatabase> db, | 380 scoped_ptr<LevelDBDatabase> db, |
| 379 scoped_ptr<LevelDBComparator> comparator) | 381 scoped_ptr<LevelDBComparator> comparator) |
| 380 : identifier_(identifier), | 382 : identifier_(identifier), |
| 381 db_(db.Pass()), | 383 db_(db.Pass()), |
| 382 comparator_(comparator.Pass()), | 384 comparator_(comparator.Pass()), |
| 383 weak_factory_(this) {} | 385 weak_factory_(this) {} |
| 384 | 386 |
| 385 IndexedDBBackingStore::~IndexedDBBackingStore() { | 387 IndexedDBBackingStore::~IndexedDBBackingStore() { |
| 386 // db_'s destructor uses comparator_. The order of destruction is important. | 388 // db_'s destructor uses comparator_. The order of destruction is important. |
| 387 db_.reset(); | 389 db_.reset(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 412 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, | 414 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, |
| 413 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, | 415 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, |
| 414 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED, | 416 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED, |
| 415 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, | 417 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, |
| 416 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_DISK_FULL, | 418 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_DISK_FULL, |
| 417 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, | 419 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, |
| 418 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 420 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 419 }; | 421 }; |
| 420 | 422 |
| 421 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( | 423 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( |
| 422 const string16& database_identifier, | 424 const std::string& origin_identifier, |
| 423 const base::FilePath& path_base, | 425 const base::FilePath& path_base, |
| 424 const string16& file_identifier, | 426 const std::string& file_identifier, |
| 425 WebKit::WebIDBCallbacks::DataLoss* data_loss) { | 427 WebKit::WebIDBCallbacks::DataLoss* data_loss) { |
| 426 *data_loss = WebKit::WebIDBCallbacks::DataLossNone; | 428 *data_loss = WebKit::WebIDBCallbacks::DataLossNone; |
| 427 DefaultLevelDBFactory leveldb_factory; | 429 DefaultLevelDBFactory leveldb_factory; |
| 428 return IndexedDBBackingStore::Open(database_identifier, | 430 return IndexedDBBackingStore::Open(origin_identifier, |
| 429 path_base, | 431 path_base, |
| 430 file_identifier, | 432 file_identifier, |
| 431 data_loss, | 433 data_loss, |
| 432 &leveldb_factory); | 434 &leveldb_factory); |
| 433 } | 435 } |
| 434 | 436 |
| 435 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( | 437 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( |
| 436 const string16& database_identifier, | 438 const std::string& origin_identifier, |
| 437 const base::FilePath& path_base, | 439 const base::FilePath& path_base, |
| 438 const string16& file_identifier, | 440 const std::string& file_identifier, |
| 439 WebKit::WebIDBCallbacks::DataLoss* data_loss, | 441 WebKit::WebIDBCallbacks::DataLoss* data_loss, |
| 440 LevelDBFactory* leveldb_factory) { | 442 LevelDBFactory* leveldb_factory) { |
| 441 IDB_TRACE("IndexedDBBackingStore::Open"); | 443 IDB_TRACE("IndexedDBBackingStore::Open"); |
| 442 DCHECK(!path_base.empty()); | 444 DCHECK(!path_base.empty()); |
| 443 *data_loss = WebKit::WebIDBCallbacks::DataLossNone; | 445 *data_loss = WebKit::WebIDBCallbacks::DataLossNone; |
| 444 | 446 |
| 445 scoped_ptr<LevelDBComparator> comparator(new Comparator()); | 447 scoped_ptr<LevelDBComparator> comparator(new Comparator()); |
| 446 scoped_ptr<LevelDBDatabase> db; | 448 scoped_ptr<LevelDBDatabase> db; |
| 447 | 449 |
| 448 if (!IsStringASCII(path_base.AsUTF8Unsafe())) { | 450 if (!IsStringASCII(path_base.AsUTF8Unsafe())) { |
| 449 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 451 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 450 1, | 452 1, |
| 451 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 453 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 452 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 454 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 453 base::HistogramBase::kUmaTargetedHistogramFlag) | 455 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 454 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII); | 456 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII); |
| 455 } | 457 } |
| 456 if (!file_util::CreateDirectory(path_base)) { | 458 if (!file_util::CreateDirectory(path_base)) { |
| 457 LOG(ERROR) << "Unable to create IndexedDB database path " | 459 LOG(ERROR) << "Unable to create IndexedDB database path " |
| 458 << path_base.AsUTF8Unsafe(); | 460 << path_base.AsUTF8Unsafe(); |
| 459 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 461 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 460 1, | 462 1, |
| 461 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 463 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 462 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 464 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 463 base::HistogramBase::kUmaTargetedHistogramFlag) | 465 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 464 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY); | 466 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY); |
| 465 return scoped_refptr<IndexedDBBackingStore>(); | 467 return scoped_refptr<IndexedDBBackingStore>(); |
| 466 } | 468 } |
| 467 | 469 |
| 468 base::FilePath identifier_path = base::FilePath::FromUTF8Unsafe( | 470 base::FilePath identifier_path = |
| 469 UTF16ToUTF8(database_identifier) + ".indexeddb.leveldb"); | 471 base::FilePath().AppendASCII(origin_identifier). |
| 472 AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); |
| 473 |
| 470 int limit = file_util::GetMaximumPathComponentLength(path_base); | 474 int limit = file_util::GetMaximumPathComponentLength(path_base); |
| 471 if (limit == -1) { | 475 if (limit == -1) { |
| 472 DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; | 476 DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; |
| 473 // In limited testing, ChromeOS returns 143, other OSes 255. | 477 // In limited testing, ChromeOS returns 143, other OSes 255. |
| 474 #if defined(OS_CHROMEOS) | 478 #if defined(OS_CHROMEOS) |
| 475 limit = 143; | 479 limit = 143; |
| 476 #else | 480 #else |
| 477 limit = 255; | 481 limit = 255; |
| 478 #endif | 482 #endif |
| 479 } | 483 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 602 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 599 base::HistogramBase::kUmaTargetedHistogramFlag) | 603 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 600 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR); | 604 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR); |
| 601 return scoped_refptr<IndexedDBBackingStore>(); | 605 return scoped_refptr<IndexedDBBackingStore>(); |
| 602 } | 606 } |
| 603 | 607 |
| 604 return Create(file_identifier, db.Pass(), comparator.Pass()); | 608 return Create(file_identifier, db.Pass(), comparator.Pass()); |
| 605 } | 609 } |
| 606 | 610 |
| 607 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 611 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
| 608 const string16& identifier) { | 612 const std::string& file_identifier) { |
| 609 DefaultLevelDBFactory leveldb_factory; | 613 DefaultLevelDBFactory leveldb_factory; |
| 610 return IndexedDBBackingStore::OpenInMemory(identifier, &leveldb_factory); | 614 return IndexedDBBackingStore::OpenInMemory(file_identifier, &leveldb_factory); |
| 611 } | 615 } |
| 612 | 616 |
| 613 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 617 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
| 614 const string16& identifier, | 618 const std::string& file_identifier, |
| 615 LevelDBFactory* leveldb_factory) { | 619 LevelDBFactory* leveldb_factory) { |
| 616 IDB_TRACE("IndexedDBBackingStore::OpenInMemory"); | 620 IDB_TRACE("IndexedDBBackingStore::OpenInMemory"); |
| 617 | 621 |
| 618 scoped_ptr<LevelDBComparator> comparator(new Comparator()); | 622 scoped_ptr<LevelDBComparator> comparator(new Comparator()); |
| 619 scoped_ptr<LevelDBDatabase> db = | 623 scoped_ptr<LevelDBDatabase> db = |
| 620 LevelDBDatabase::OpenInMemory(comparator.get()); | 624 LevelDBDatabase::OpenInMemory(comparator.get()); |
| 621 if (!db) { | 625 if (!db) { |
| 622 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; | 626 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; |
| 623 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 627 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 624 1, | 628 1, |
| 625 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 629 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 626 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 630 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 627 base::HistogramBase::kUmaTargetedHistogramFlag) | 631 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 628 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED); | 632 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED); |
| 629 return scoped_refptr<IndexedDBBackingStore>(); | 633 return scoped_refptr<IndexedDBBackingStore>(); |
| 630 } | 634 } |
| 631 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 635 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 632 1, | 636 1, |
| 633 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 637 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 634 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 638 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 635 base::HistogramBase::kUmaTargetedHistogramFlag) | 639 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 636 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS); | 640 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS); |
| 637 | 641 |
| 638 return Create(identifier, db.Pass(), comparator.Pass()); | 642 return Create(file_identifier, db.Pass(), comparator.Pass()); |
| 639 } | 643 } |
| 640 | 644 |
| 641 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( | 645 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( |
| 642 const string16& identifier, | 646 const std::string& identifier, |
| 643 scoped_ptr<LevelDBDatabase> db, | 647 scoped_ptr<LevelDBDatabase> db, |
| 644 scoped_ptr<LevelDBComparator> comparator) { | 648 scoped_ptr<LevelDBComparator> comparator) { |
| 645 // TODO(jsbell): Handle comparator name changes. | 649 // TODO(jsbell): Handle comparator name changes. |
| 646 scoped_refptr<IndexedDBBackingStore> backing_store( | 650 scoped_refptr<IndexedDBBackingStore> backing_store( |
| 647 new IndexedDBBackingStore(identifier, db.Pass(), comparator.Pass())); | 651 new IndexedDBBackingStore(identifier, db.Pass(), comparator.Pass())); |
| 648 | 652 |
| 649 if (!SetUpMetadata(backing_store->db_.get(), identifier)) | 653 if (!SetUpMetadata(backing_store->db_.get(), identifier)) |
| 650 return scoped_refptr<IndexedDBBackingStore>(); | 654 return scoped_refptr<IndexedDBBackingStore>(); |
| 651 | 655 |
| 652 return backing_store; | 656 return backing_store; |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 return false; | 1229 return false; |
| 1226 } | 1230 } |
| 1227 if (!found) | 1231 if (!found) |
| 1228 last_version = 0; | 1232 last_version = 0; |
| 1229 | 1233 |
| 1230 DCHECK_GE(last_version, 0); | 1234 DCHECK_GE(last_version, 0); |
| 1231 | 1235 |
| 1232 int64 version = last_version + 1; | 1236 int64 version = last_version + 1; |
| 1233 PutInt(transaction, LevelDBSlice(last_version_key), version); | 1237 PutInt(transaction, LevelDBSlice(last_version_key), version); |
| 1234 | 1238 |
| 1235 DCHECK(version > | 1239 // TODO(jsbell): Think about how we want to handle the overflow scenario. |
| 1236 last_version); // TODO(jsbell): Think about how we want to handle | 1240 DCHECK(version > last_version); |
| 1237 // the overflow scenario. | |
| 1238 | 1241 |
| 1239 *new_version_number = version; | 1242 *new_version_number = version; |
| 1240 return true; | 1243 return true; |
| 1241 } | 1244 } |
| 1242 | 1245 |
| 1243 bool IndexedDBBackingStore::PutRecord( | 1246 bool IndexedDBBackingStore::PutRecord( |
| 1244 IndexedDBBackingStore::Transaction* transaction, | 1247 IndexedDBBackingStore::Transaction* transaction, |
| 1245 int64 database_id, | 1248 int64 database_id, |
| 1246 int64 object_store_id, | 1249 int64 object_store_id, |
| 1247 const IndexedDBKey& key, | 1250 const IndexedDBKey& key, |
| (...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2482 transaction, cursor_options->high_key, &cursor_options->high_key)) | 2485 transaction, cursor_options->high_key, &cursor_options->high_key)) |
| 2483 return false; | 2486 return false; |
| 2484 cursor_options->high_open = false; | 2487 cursor_options->high_open = false; |
| 2485 } | 2488 } |
| 2486 } else { | 2489 } else { |
| 2487 cursor_options->high_key = IndexDataKey::Encode( | 2490 cursor_options->high_key = IndexDataKey::Encode( |
| 2488 database_id, object_store_id, index_id, range.upper()); | 2491 database_id, object_store_id, index_id, range.upper()); |
| 2489 cursor_options->high_open = range.upperOpen(); | 2492 cursor_options->high_open = range.upperOpen(); |
| 2490 | 2493 |
| 2491 std::vector<char> found_high_key; | 2494 std::vector<char> found_high_key; |
| 2495 // Seek to the *last* key in the set of non-unique keys |
| 2492 if (!FindGreatestKeyLessThanOrEqual( | 2496 if (!FindGreatestKeyLessThanOrEqual( |
| 2493 transaction, | 2497 transaction, cursor_options->high_key, &found_high_key)) |
| 2494 cursor_options->high_key, | |
| 2495 &found_high_key)) // Seek to the *last* key in the set of | |
| 2496 // non-unique | |
| 2497 // keys. | |
| 2498 return false; | 2498 return false; |
| 2499 | 2499 |
| 2500 // If the target key should not be included, but we end up with a smaller | 2500 // If the target key should not be included, but we end up with a smaller |
| 2501 // key, we should include that. | 2501 // key, we should include that. |
| 2502 if (cursor_options->high_open && | 2502 if (cursor_options->high_open && |
| 2503 CompareIndexKeys(LevelDBSlice(found_high_key), | 2503 CompareIndexKeys(LevelDBSlice(found_high_key), |
| 2504 LevelDBSlice(cursor_options->high_key)) < | 2504 LevelDBSlice(cursor_options->high_key)) < |
| 2505 0) | 2505 0) |
| 2506 cursor_options->high_open = false; | 2506 cursor_options->high_open = false; |
| 2507 | 2507 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2642 } | 2642 } |
| 2643 | 2643 |
| 2644 void IndexedDBBackingStore::Transaction::Rollback() { | 2644 void IndexedDBBackingStore::Transaction::Rollback() { |
| 2645 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); | 2645 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); |
| 2646 DCHECK(transaction_.get()); | 2646 DCHECK(transaction_.get()); |
| 2647 transaction_->Rollback(); | 2647 transaction_->Rollback(); |
| 2648 transaction_ = NULL; | 2648 transaction_ = NULL; |
| 2649 } | 2649 } |
| 2650 | 2650 |
| 2651 } // namespace content | 2651 } // namespace content |
| OLD | NEW |