Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(883)

Side by Side Diff: content/browser/indexed_db/indexed_db_database.cc

Issue 2506773002: [IndexedDB] Integrating failures and corruption with transaction (Closed)
Patch Set: removed extra log statements Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_database.h" 5 #include "content/browser/indexed_db/indexed_db_database.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <set> 10 #include <set>
(...skipping 26 matching lines...) Expand all
37 #include "storage/browser/blob/blob_data_handle.h" 37 #include "storage/browser/blob/blob_data_handle.h"
38 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" 38 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h"
39 #include "third_party/leveldatabase/env_chromium.h" 39 #include "third_party/leveldatabase/env_chromium.h"
40 #include "url/origin.h" 40 #include "url/origin.h"
41 41
42 using base::ASCIIToUTF16; 42 using base::ASCIIToUTF16;
43 using base::Int64ToString16; 43 using base::Int64ToString16;
44 using blink::WebIDBKeyTypeNumber; 44 using blink::WebIDBKeyTypeNumber;
45 45
46 namespace content { 46 namespace content {
47
48 namespace { 47 namespace {
49 48
50 // Used for WebCore.IndexedDB.Schema.ObjectStore.KeyPathType and 49 // Used for WebCore.IndexedDB.Schema.ObjectStore.KeyPathType and
51 // WebCore.IndexedDB.Schema.Index.KeyPathType histograms. Do not 50 // WebCore.IndexedDB.Schema.Index.KeyPathType histograms. Do not
52 // modify (delete, re-order, renumber) these values other than 51 // modify (delete, re-order, renumber) these values other than
53 // the _MAX value. 52 // the _MAX value.
54 enum HistogramIDBKeyPathType { 53 enum HistogramIDBKeyPathType {
55 KEY_PATH_TYPE_NONE = 0, 54 KEY_PATH_TYPE_NONE = 0,
56 KEY_PATH_TYPE_STRING = 1, 55 KEY_PATH_TYPE_STRING = 1,
57 KEY_PATH_TYPE_ARRAY = 2, 56 KEY_PATH_TYPE_ARRAY = 2,
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 } 701 }
703 702
704 AddIndex(object_store_id, index_metadata, index_id); 703 AddIndex(object_store_id, index_metadata, index_id);
705 transaction->ScheduleAbortTask( 704 transaction->ScheduleAbortTask(
706 base::Bind(&IndexedDBDatabase::CreateIndexAbortOperation, 705 base::Bind(&IndexedDBDatabase::CreateIndexAbortOperation,
707 this, 706 this,
708 object_store_id, 707 object_store_id,
709 index_id)); 708 index_id));
710 } 709 }
711 710
712 void IndexedDBDatabase::CreateIndexAbortOperation( 711 void IndexedDBDatabase::CreateIndexAbortOperation(int64_t object_store_id,
713 int64_t object_store_id, 712 int64_t index_id) {
714 int64_t index_id,
715 IndexedDBTransaction* transaction) {
716 DCHECK(!transaction);
717 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); 713 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation");
718 RemoveIndex(object_store_id, index_id); 714 RemoveIndex(object_store_id, index_id);
719 } 715 }
720 716
721 void IndexedDBDatabase::DeleteIndex(int64_t transaction_id, 717 void IndexedDBDatabase::DeleteIndex(int64_t transaction_id,
722 int64_t object_store_id, 718 int64_t object_store_id,
723 int64_t index_id) { 719 int64_t index_id) {
724 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); 720 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id);
725 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 721 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
726 if (!transaction) 722 if (!transaction)
727 return; 723 return;
728 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 724 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
729 725
730 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 726 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id))
731 return; 727 return;
732 728
733 transaction->ScheduleTask( 729 transaction->ScheduleTask(
734 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, 730 base::Bind(&IndexedDBDatabase::DeleteIndexOperation,
735 this, 731 this,
736 object_store_id, 732 object_store_id,
737 index_id)); 733 index_id));
738 } 734 }
739 735
740 void IndexedDBDatabase::DeleteIndexOperation( 736 leveldb::Status IndexedDBDatabase::DeleteIndexOperation(
741 int64_t object_store_id, 737 int64_t object_store_id,
742 int64_t index_id, 738 int64_t index_id,
743 IndexedDBTransaction* transaction) { 739 IndexedDBTransaction* transaction) {
744 IDB_TRACE1( 740 IDB_TRACE1(
745 "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id()); 741 "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id());
746 742
747 const IndexedDBIndexMetadata index_metadata = 743 const IndexedDBIndexMetadata index_metadata =
748 metadata_.object_stores[object_store_id].indexes[index_id]; 744 metadata_.object_stores[object_store_id].indexes[index_id];
749 745
750 leveldb::Status s = 746 leveldb::Status s =
751 backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 747 backing_store_->DeleteIndex(transaction->BackingStoreTransaction(),
752 transaction->database()->id(), 748 transaction->database()->id(),
753 object_store_id, 749 object_store_id,
754 index_id); 750 index_id);
755 if (!s.ok()) { 751 if (!s.ok()) {
756 base::string16 error_string = 752 base::string16 error_string =
757 ASCIIToUTF16("Internal error deleting index '") + 753 ASCIIToUTF16("Internal error deleting index '") +
758 index_metadata.name + ASCIIToUTF16("'."); 754 index_metadata.name + ASCIIToUTF16("'.");
759 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 755 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
760 error_string); 756 error_string);
761 transaction->Abort(error); 757 transaction->Abort(error);
762 if (s.IsCorruption()) 758 return s;
763 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
764 return;
765 } 759 }
766 760
767 RemoveIndex(object_store_id, index_id); 761 RemoveIndex(object_store_id, index_id);
768 transaction->ScheduleAbortTask( 762 transaction->ScheduleAbortTask(
769 base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation, 763 base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation,
770 this, 764 this,
771 object_store_id, 765 object_store_id,
772 index_metadata)); 766 index_metadata));
767 return s;
773 } 768 }
774 769
775 void IndexedDBDatabase::DeleteIndexAbortOperation( 770 void IndexedDBDatabase::DeleteIndexAbortOperation(
776 int64_t object_store_id, 771 int64_t object_store_id,
777 const IndexedDBIndexMetadata& index_metadata, 772 const IndexedDBIndexMetadata& index_metadata) {
778 IndexedDBTransaction* transaction) {
779 DCHECK(!transaction);
780 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); 773 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation");
781 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); 774 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId);
782 } 775 }
783 776
784 void IndexedDBDatabase::RenameIndex(int64_t transaction_id, 777 void IndexedDBDatabase::RenameIndex(int64_t transaction_id,
785 int64_t object_store_id, 778 int64_t object_store_id,
786 int64_t index_id, 779 int64_t index_id,
787 const base::string16& new_name) { 780 const base::string16& new_name) {
788 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction_id); 781 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction_id);
789 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 782 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
(...skipping 14 matching lines...) Expand all
804 backing_store_->RenameIndex(transaction->BackingStoreTransaction(), 797 backing_store_->RenameIndex(transaction->BackingStoreTransaction(),
805 transaction->database()->id(), 798 transaction->database()->id(),
806 object_store_id, 799 object_store_id,
807 index_id, 800 index_id,
808 new_name); 801 new_name);
809 if (!s.ok()) { 802 if (!s.ok()) {
810 base::string16 error_string = 803 base::string16 error_string =
811 ASCIIToUTF16("Internal error renaming index '") + 804 ASCIIToUTF16("Internal error renaming index '") +
812 index_metadata.name + ASCIIToUTF16("' to '") + new_name + 805 index_metadata.name + ASCIIToUTF16("' to '") + new_name +
813 ASCIIToUTF16("'."); 806 ASCIIToUTF16("'.");
814 transaction->Abort(IndexedDBDatabaseError( 807 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
815 blink::WebIDBDatabaseExceptionUnknownError, error_string)); 808 error_string);
809 transaction->Abort(error);
810 if (s.IsCorruption())
811 factory_->HandleBackingStoreCorruption(origin(), error);
812 else
813 factory_->HandleBackingStoreFailure(origin());
816 return; 814 return;
817 } 815 }
818 816
819 transaction->ScheduleAbortTask( 817 transaction->ScheduleAbortTask(
820 base::Bind(&IndexedDBDatabase::RenameIndexAbortOperation, 818 base::Bind(&IndexedDBDatabase::RenameIndexAbortOperation,
821 this, 819 this,
822 object_store_id, 820 object_store_id,
823 index_id, 821 index_id,
824 index_metadata.name)); 822 index_metadata.name));
825 SetIndexName(object_store_id, index_id, new_name); 823 SetIndexName(object_store_id, index_id, new_name);
826 } 824 }
827 825
828 void IndexedDBDatabase::RenameIndexAbortOperation( 826 void IndexedDBDatabase::RenameIndexAbortOperation(
829 int64_t object_store_id, 827 int64_t object_store_id,
830 int64_t index_id, 828 int64_t index_id,
831 const base::string16& old_name, 829 const base::string16& old_name) {
832 IndexedDBTransaction* transaction) {
833 DCHECK(!transaction);
834 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation"); 830 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation");
835 SetIndexName(object_store_id, index_id, old_name); 831 SetIndexName(object_store_id, index_id, old_name);
836 } 832 }
837 833
838 void IndexedDBDatabase::Commit(int64_t transaction_id) { 834 void IndexedDBDatabase::Commit(int64_t transaction_id) {
839 // The frontend suggests that we commit, but we may have previously initiated 835 // The frontend suggests that we commit, but we may have previously initiated
840 // an abort, and so have disposed of the transaction. on_abort has already 836 // an abort, and so have disposed of the transaction. on_abort has already
841 // been dispatched to the frontend, so it will find out about that 837 // been dispatched to the frontend, so it will find out about that
842 // asynchronously. 838 // asynchronously.
843 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 839 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
844 if (transaction) { 840 if (transaction) {
845 scoped_refptr<IndexedDBFactory> factory = factory_; 841 scoped_refptr<IndexedDBFactory> factory = factory_;
846 leveldb::Status s = transaction->Commit(); 842 leveldb::Status result = transaction->Commit();
847 if (s.IsCorruption()) { 843 if (!result.ok()) {
848 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 844 if (result.IsCorruption()) {
849 "Internal error committing transaction."); 845 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
850 factory->HandleBackingStoreCorruption(identifier_.first, error); 846 base::ASCIIToUTF16(result.ToString()));
847 factory->HandleBackingStoreCorruption(origin(), error);
848 } else {
849 factory->HandleBackingStoreFailure(origin());
850 }
851 } 851 }
852 } 852 }
853 } 853 }
854 854
855 void IndexedDBDatabase::Abort(int64_t transaction_id) { 855 void IndexedDBDatabase::Abort(int64_t transaction_id) {
856 // If the transaction is unknown, then it has already been aborted by the 856 // If the transaction is unknown, then it has already been aborted by the
857 // backend before this call so it is safe to ignore it. 857 // backend before this call so it is safe to ignore it.
858 IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id); 858 IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id);
859 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 859 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
860 if (transaction) 860 if (transaction)
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 964 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
965 return; 965 return;
966 966
967 transaction->ScheduleTask(base::Bind( 967 transaction->ScheduleTask(base::Bind(
968 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id, 968 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id,
969 base::Passed(&key_range), 969 base::Passed(&key_range),
970 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 970 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
971 callbacks)); 971 callbacks));
972 } 972 }
973 973
974 void IndexedDBDatabase::GetOperation( 974 leveldb::Status IndexedDBDatabase::GetOperation(
975 int64_t object_store_id, 975 int64_t object_store_id,
976 int64_t index_id, 976 int64_t index_id,
977 std::unique_ptr<IndexedDBKeyRange> key_range, 977 std::unique_ptr<IndexedDBKeyRange> key_range,
978 indexed_db::CursorType cursor_type, 978 indexed_db::CursorType cursor_type,
979 scoped_refptr<IndexedDBCallbacks> callbacks, 979 scoped_refptr<IndexedDBCallbacks> callbacks,
980 IndexedDBTransaction* transaction) { 980 IndexedDBTransaction* transaction) {
981 IDB_TRACE1("IndexedDBDatabase::GetOperation", "txn.id", transaction->id()); 981 IDB_TRACE1("IndexedDBDatabase::GetOperation", "txn.id", transaction->id());
982 982
983 DCHECK(metadata_.object_stores.find(object_store_id) != 983 DCHECK(metadata_.object_stores.find(object_store_id) !=
984 metadata_.object_stores.end()); 984 metadata_.object_stores.end());
985 const IndexedDBObjectStoreMetadata& object_store_metadata = 985 const IndexedDBObjectStoreMetadata& object_store_metadata =
986 metadata_.object_stores[object_store_id]; 986 metadata_.object_stores[object_store_id];
987 987
988 const IndexedDBKey* key; 988 const IndexedDBKey* key;
989 989
990 leveldb::Status s; 990 leveldb::Status s = leveldb::Status::OK();
991 std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 991 std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
992 if (key_range->IsOnlyKey()) { 992 if (key_range->IsOnlyKey()) {
993 key = &key_range->lower(); 993 key = &key_range->lower();
994 } else { 994 } else {
995 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 995 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
996 // ObjectStore Retrieval Operation 996 // ObjectStore Retrieval Operation
997 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 997 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
998 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 998 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor(
999 transaction->BackingStoreTransaction(), id(), object_store_id, 999 transaction->BackingStoreTransaction(), id(), object_store_id,
1000 *key_range, blink::WebIDBCursorDirectionNext, &s); 1000 *key_range, blink::WebIDBCursorDirectionNext, &s);
(...skipping 21 matching lines...) Expand all
1022 index_id, 1022 index_id,
1023 *key_range, 1023 *key_range,
1024 blink::WebIDBCursorDirectionNext, 1024 blink::WebIDBCursorDirectionNext,
1025 &s); 1025 &s);
1026 } 1026 }
1027 1027
1028 if (!s.ok()) { 1028 if (!s.ok()) {
1029 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1029 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1030 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1030 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1031 "Internal error deleting data in range"); 1031 "Internal error deleting data in range");
1032 if (s.IsCorruption()) { 1032 callbacks->OnError(error);
1033 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); 1033 return s;
1034 }
1035 } 1034 }
1036 1035
1037 if (!backing_store_cursor) { 1036 if (!backing_store_cursor) {
1037 // This means we've run out of data.
1038 callbacks->OnSuccess(); 1038 callbacks->OnSuccess();
1039 return; 1039 return s;
1040 } 1040 }
1041 1041
1042 key = &backing_store_cursor->key(); 1042 key = &backing_store_cursor->key();
1043 } 1043 }
1044 1044
1045 std::unique_ptr<IndexedDBKey> primary_key; 1045 std::unique_ptr<IndexedDBKey> primary_key;
1046 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1046 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
1047 // Object Store Retrieval Operation 1047 // Object Store Retrieval Operation
1048 IndexedDBReturnValue value; 1048 IndexedDBReturnValue value;
1049 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 1049 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
1050 id(), 1050 id(),
1051 object_store_id, 1051 object_store_id,
1052 *key, 1052 *key,
1053 &value); 1053 &value);
1054 if (!s.ok()) { 1054 if (!s.ok()) {
1055 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1055 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1056 "Internal error in GetRecord."); 1056 "Internal error in GetRecord.");
1057 callbacks->OnError(error); 1057 callbacks->OnError(error);
1058 1058 return s;
1059 if (s.IsCorruption())
1060 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1061 return;
1062 } 1059 }
1063 1060
1064 if (value.empty()) { 1061 if (value.empty()) {
1065 callbacks->OnSuccess(); 1062 callbacks->OnSuccess();
1066 return; 1063 return s;
1067 } 1064 }
1068 1065
1069 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1066 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1070 callbacks->OnSuccess(*key); 1067 callbacks->OnSuccess(*key);
1071 return; 1068 return s;
1072 } 1069 }
1073 1070
1074 if (object_store_metadata.auto_increment && 1071 if (object_store_metadata.auto_increment &&
1075 !object_store_metadata.key_path.IsNull()) { 1072 !object_store_metadata.key_path.IsNull()) {
1076 value.primary_key = *key; 1073 value.primary_key = *key;
1077 value.key_path = object_store_metadata.key_path; 1074 value.key_path = object_store_metadata.key_path;
1078 } 1075 }
1079 1076
1080 callbacks->OnSuccess(&value); 1077 callbacks->OnSuccess(&value);
1081 return; 1078 return s;
1082 } 1079 }
1083 1080
1084 // From here we are dealing only with indexes. 1081 // From here we are dealing only with indexes.
1085 s = backing_store_->GetPrimaryKeyViaIndex( 1082 s = backing_store_->GetPrimaryKeyViaIndex(
1086 transaction->BackingStoreTransaction(), 1083 transaction->BackingStoreTransaction(),
1087 id(), 1084 id(),
1088 object_store_id, 1085 object_store_id,
1089 index_id, 1086 index_id,
1090 *key, 1087 *key,
1091 &primary_key); 1088 &primary_key);
1092 if (!s.ok()) { 1089 if (!s.ok()) {
1093 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1090 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1094 "Internal error in GetPrimaryKeyViaIndex."); 1091 "Internal error in GetPrimaryKeyViaIndex.");
1095 callbacks->OnError(error); 1092 callbacks->OnError(error);
1096 if (s.IsCorruption()) 1093 return s;
1097 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1098 return;
1099 } 1094 }
1100 if (!primary_key) { 1095 if (!primary_key) {
1101 callbacks->OnSuccess(); 1096 callbacks->OnSuccess();
1102 return; 1097 return s;
1103 } 1098 }
1104 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1099 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1105 // Index Value Retrieval Operation 1100 // Index Value Retrieval Operation
1106 callbacks->OnSuccess(*primary_key); 1101 callbacks->OnSuccess(*primary_key);
1107 return; 1102 return s;
1108 } 1103 }
1109 1104
1110 // Index Referenced Value Retrieval Operation 1105 // Index Referenced Value Retrieval Operation
1111 IndexedDBReturnValue value; 1106 IndexedDBReturnValue value;
1112 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 1107 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
1113 id(), 1108 id(),
1114 object_store_id, 1109 object_store_id,
1115 *primary_key, 1110 *primary_key,
1116 &value); 1111 &value);
1117 if (!s.ok()) { 1112 if (!s.ok()) {
1118 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1113 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1119 "Internal error in GetRecord."); 1114 "Internal error in GetRecord.");
1120 callbacks->OnError(error); 1115 callbacks->OnError(error);
1121 if (s.IsCorruption()) 1116 return s;
1122 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1123 return;
1124 } 1117 }
1125 1118
1126 if (value.empty()) { 1119 if (value.empty()) {
1127 callbacks->OnSuccess(); 1120 callbacks->OnSuccess();
1128 return; 1121 return s;
1129 } 1122 }
1130 if (object_store_metadata.auto_increment && 1123 if (object_store_metadata.auto_increment &&
1131 !object_store_metadata.key_path.IsNull()) { 1124 !object_store_metadata.key_path.IsNull()) {
1132 value.primary_key = *primary_key; 1125 value.primary_key = *primary_key;
1133 value.key_path = object_store_metadata.key_path; 1126 value.key_path = object_store_metadata.key_path;
1134 } 1127 }
1135 callbacks->OnSuccess(&value); 1128 callbacks->OnSuccess(&value);
1129 return s;
1136 } 1130 }
1137 1131
1138 void IndexedDBDatabase::GetAllOperation( 1132 leveldb::Status IndexedDBDatabase::GetAllOperation(
1139 int64_t object_store_id, 1133 int64_t object_store_id,
1140 int64_t index_id, 1134 int64_t index_id,
1141 std::unique_ptr<IndexedDBKeyRange> key_range, 1135 std::unique_ptr<IndexedDBKeyRange> key_range,
1142 indexed_db::CursorType cursor_type, 1136 indexed_db::CursorType cursor_type,
1143 int64_t max_count, 1137 int64_t max_count,
1144 scoped_refptr<IndexedDBCallbacks> callbacks, 1138 scoped_refptr<IndexedDBCallbacks> callbacks,
1145 IndexedDBTransaction* transaction) { 1139 IndexedDBTransaction* transaction) {
1146 IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id()); 1140 IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id());
1147 1141
1148 DCHECK_GT(max_count, 0); 1142 DCHECK_GT(max_count, 0);
1149 1143
1150 DCHECK(metadata_.object_stores.find(object_store_id) != 1144 DCHECK(metadata_.object_stores.find(object_store_id) !=
1151 metadata_.object_stores.end()); 1145 metadata_.object_stores.end());
1152 const IndexedDBObjectStoreMetadata& object_store_metadata = 1146 const IndexedDBObjectStoreMetadata& object_store_metadata =
1153 metadata_.object_stores[object_store_id]; 1147 metadata_.object_stores[object_store_id];
1154 1148
1155 leveldb::Status s; 1149 leveldb::Status s = leveldb::Status::OK();
1156 1150
1157 std::unique_ptr<IndexedDBBackingStore::Cursor> cursor; 1151 std::unique_ptr<IndexedDBBackingStore::Cursor> cursor;
1158 1152
1159 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1153 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1160 // Retrieving keys 1154 // Retrieving keys
1161 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1155 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
1162 // Object Store: Key Retrieval Operation 1156 // Object Store: Key Retrieval Operation
1163 cursor = backing_store_->OpenObjectStoreKeyCursor( 1157 cursor = backing_store_->OpenObjectStoreKeyCursor(
1164 transaction->BackingStoreTransaction(), id(), object_store_id, 1158 transaction->BackingStoreTransaction(), id(), object_store_id,
1165 *key_range, blink::WebIDBCursorDirectionNext, &s); 1159 *key_range, blink::WebIDBCursorDirectionNext, &s);
(...skipping 16 matching lines...) Expand all
1182 transaction->BackingStoreTransaction(), id(), object_store_id, 1176 transaction->BackingStoreTransaction(), id(), object_store_id,
1183 index_id, *key_range, blink::WebIDBCursorDirectionNext, &s); 1177 index_id, *key_range, blink::WebIDBCursorDirectionNext, &s);
1184 } 1178 }
1185 } 1179 }
1186 1180
1187 if (!s.ok()) { 1181 if (!s.ok()) {
1188 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1182 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1189 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1183 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1190 "Internal error in GetAllOperation"); 1184 "Internal error in GetAllOperation");
1191 callbacks->OnError(error); 1185 callbacks->OnError(error);
1192 if (s.IsCorruption()) { 1186 return s;
1193 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1194 }
1195 return;
1196 } 1187 }
1197 1188
1198 std::vector<IndexedDBKey> found_keys; 1189 std::vector<IndexedDBKey> found_keys;
1199 std::vector<IndexedDBReturnValue> found_values; 1190 std::vector<IndexedDBReturnValue> found_values;
1200 if (!cursor) { 1191 if (!cursor) {
1201 // Doesn't matter if key or value array here - will be empty array when it 1192 // Doesn't matter if key or value array here - will be empty array when it
1202 // hits JavaScript. 1193 // hits JavaScript.
1203 callbacks->OnSuccessArray(&found_values); 1194 callbacks->OnSuccessArray(&found_values);
1204 return; 1195 return s;
1205 } 1196 }
1206 1197
1207 bool did_first_seek = false; 1198 bool did_first_seek = false;
1208 bool generated_key = object_store_metadata.auto_increment && 1199 bool generated_key = object_store_metadata.auto_increment &&
1209 !object_store_metadata.key_path.IsNull(); 1200 !object_store_metadata.key_path.IsNull();
1210 1201
1211 size_t response_size = kMaxIDBMessageOverhead; 1202 size_t response_size = kMaxIDBMessageOverhead;
1212 int64_t num_found_items = 0; 1203 int64_t num_found_items = 0;
1213 while (num_found_items++ < max_count) { 1204 while (num_found_items++ < max_count) {
1214 bool cursor_valid; 1205 bool cursor_valid;
1215 if (did_first_seek) { 1206 if (did_first_seek) {
1216 cursor_valid = cursor->Continue(&s); 1207 cursor_valid = cursor->Continue(&s);
1217 } else { 1208 } else {
1218 cursor_valid = cursor->FirstSeek(&s); 1209 cursor_valid = cursor->FirstSeek(&s);
1219 did_first_seek = true; 1210 did_first_seek = true;
1220 } 1211 }
1221 if (!s.ok()) { 1212 if (!s.ok()) {
1222 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1213 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1223 "Internal error in GetAllOperation."); 1214 "Internal error in GetAllOperation.");
1224 callbacks->OnError(error); 1215 callbacks->OnError(error);
1225 if (s.IsCorruption()) 1216 return s;
1226 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1227 return;
1228 } 1217 }
1229 1218
1230 if (!cursor_valid) 1219 if (!cursor_valid)
1231 break; 1220 break;
1232 1221
1233 IndexedDBReturnValue return_value; 1222 IndexedDBReturnValue return_value;
1234 IndexedDBKey return_key; 1223 IndexedDBKey return_key;
1235 1224
1236 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1225 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1237 return_key = cursor->primary_key(); 1226 return_key = cursor->primary_key();
1238 } else { 1227 } else {
1239 // Retrieving values 1228 // Retrieving values
1240 return_value.swap(*cursor->value()); 1229 return_value.swap(*cursor->value());
1241 if (!return_value.empty() && generated_key) { 1230 if (!return_value.empty() && generated_key) {
1242 return_value.primary_key = cursor->primary_key(); 1231 return_value.primary_key = cursor->primary_key();
1243 return_value.key_path = object_store_metadata.key_path; 1232 return_value.key_path = object_store_metadata.key_path;
1244 } 1233 }
1245 } 1234 }
1246 1235
1247 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) 1236 if (cursor_type == indexed_db::CURSOR_KEY_ONLY)
1248 response_size += return_key.size_estimate(); 1237 response_size += return_key.size_estimate();
1249 else 1238 else
1250 response_size += return_value.SizeEstimate(); 1239 response_size += return_value.SizeEstimate();
1251 if (response_size > GetMaxMessageSizeInBytes()) { 1240 if (response_size > GetMaxMessageSizeInBytes()) {
1252 callbacks->OnError( 1241 callbacks->OnError(
1253 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1242 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
1254 "Maximum IPC message size exceeded.")); 1243 "Maximum IPC message size exceeded."));
1255 return; 1244 return s;
1256 } 1245 }
1257 1246
1258 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) 1247 if (cursor_type == indexed_db::CURSOR_KEY_ONLY)
1259 found_keys.push_back(return_key); 1248 found_keys.push_back(return_key);
1260 else 1249 else
1261 found_values.push_back(return_value); 1250 found_values.push_back(return_value);
1262 } 1251 }
1263 1252
1264 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1253 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1265 // IndexedDBKey already supports an array of values so we can leverage this 1254 // IndexedDBKey already supports an array of values so we can leverage this
1266 // to return an array of keys - no need to create our own array of keys. 1255 // to return an array of keys - no need to create our own array of keys.
1267 callbacks->OnSuccess(IndexedDBKey(found_keys)); 1256 callbacks->OnSuccess(IndexedDBKey(found_keys));
1268 } else { 1257 } else {
1269 callbacks->OnSuccessArray(&found_values); 1258 callbacks->OnSuccessArray(&found_values);
1270 } 1259 }
1260 return s;
1271 } 1261 }
1272 1262
1273 static std::unique_ptr<IndexedDBKey> GenerateKey( 1263 static std::unique_ptr<IndexedDBKey> GenerateKey(
1274 IndexedDBBackingStore* backing_store, 1264 IndexedDBBackingStore* backing_store,
1275 IndexedDBTransaction* transaction, 1265 IndexedDBTransaction* transaction,
1276 int64_t database_id, 1266 int64_t database_id,
1277 int64_t object_store_id) { 1267 int64_t object_store_id) {
1278 const int64_t max_generator_value = 1268 const int64_t max_generator_value =
1279 9007199254740992LL; // Maximum integer storable as ECMAScript number. 1269 9007199254740992LL; // Maximum integer storable as ECMAScript number.
1280 int64_t current_number; 1270 int64_t current_number;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 params->value.swap(*value); 1335 params->value.swap(*value);
1346 params->handles.swap(*handles); 1336 params->handles.swap(*handles);
1347 params->key = std::move(key); 1337 params->key = std::move(key);
1348 params->put_mode = put_mode; 1338 params->put_mode = put_mode;
1349 params->callbacks = callbacks; 1339 params->callbacks = callbacks;
1350 params->index_keys = index_keys; 1340 params->index_keys = index_keys;
1351 transaction->ScheduleTask(base::Bind( 1341 transaction->ScheduleTask(base::Bind(
1352 &IndexedDBDatabase::PutOperation, this, base::Passed(&params))); 1342 &IndexedDBDatabase::PutOperation, this, base::Passed(&params)));
1353 } 1343 }
1354 1344
1355 void IndexedDBDatabase::PutOperation(std::unique_ptr<PutOperationParams> params, 1345 leveldb::Status IndexedDBDatabase::PutOperation(
1356 IndexedDBTransaction* transaction) { 1346 std::unique_ptr<PutOperationParams> params,
1347 IndexedDBTransaction* transaction) {
1357 IDB_TRACE1("IndexedDBDatabase::PutOperation", "txn.id", transaction->id()); 1348 IDB_TRACE1("IndexedDBDatabase::PutOperation", "txn.id", transaction->id());
1358 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1349 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1359 bool key_was_generated = false; 1350 bool key_was_generated = false;
1351 leveldb::Status s = leveldb::Status::OK();
1360 1352
1361 DCHECK(metadata_.object_stores.find(params->object_store_id) != 1353 DCHECK(metadata_.object_stores.find(params->object_store_id) !=
1362 metadata_.object_stores.end()); 1354 metadata_.object_stores.end());
1363 const IndexedDBObjectStoreMetadata& object_store = 1355 const IndexedDBObjectStoreMetadata& object_store =
1364 metadata_.object_stores[params->object_store_id]; 1356 metadata_.object_stores[params->object_store_id];
1365 DCHECK(object_store.auto_increment || params->key->IsValid()); 1357 DCHECK(object_store.auto_increment || params->key->IsValid());
1366 1358
1367 std::unique_ptr<IndexedDBKey> key; 1359 std::unique_ptr<IndexedDBKey> key;
1368 if (params->put_mode != blink::WebIDBPutModeCursorUpdate && 1360 if (params->put_mode != blink::WebIDBPutModeCursorUpdate &&
1369 object_store.auto_increment && !params->key->IsValid()) { 1361 object_store.auto_increment && !params->key->IsValid()) {
1370 std::unique_ptr<IndexedDBKey> auto_inc_key = GenerateKey( 1362 std::unique_ptr<IndexedDBKey> auto_inc_key = GenerateKey(
1371 backing_store_.get(), transaction, id(), params->object_store_id); 1363 backing_store_.get(), transaction, id(), params->object_store_id);
1372 key_was_generated = true; 1364 key_was_generated = true;
1373 if (!auto_inc_key->IsValid()) { 1365 if (!auto_inc_key->IsValid()) {
1374 params->callbacks->OnError( 1366 params->callbacks->OnError(
1375 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 1367 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError,
1376 "Maximum key generator value reached.")); 1368 "Maximum key generator value reached."));
1377 return; 1369 return s;
1378 } 1370 }
1379 key = std::move(auto_inc_key); 1371 key = std::move(auto_inc_key);
1380 } else { 1372 } else {
1381 key = std::move(params->key); 1373 key = std::move(params->key);
1382 } 1374 }
1383 1375
1384 DCHECK(key->IsValid()); 1376 DCHECK(key->IsValid());
1385 1377
1386 IndexedDBBackingStore::RecordIdentifier record_identifier; 1378 IndexedDBBackingStore::RecordIdentifier record_identifier;
1387 if (params->put_mode == blink::WebIDBPutModeAddOnly) { 1379 if (params->put_mode == blink::WebIDBPutModeAddOnly) {
1388 bool found = false; 1380 bool found = false;
1389 leveldb::Status s = backing_store_->KeyExistsInObjectStore( 1381 leveldb::Status s = backing_store_->KeyExistsInObjectStore(
1390 transaction->BackingStoreTransaction(), 1382 transaction->BackingStoreTransaction(),
1391 id(), 1383 id(),
1392 params->object_store_id, 1384 params->object_store_id,
1393 *key, 1385 *key,
1394 &record_identifier, 1386 &record_identifier,
1395 &found); 1387 &found);
1396 if (!s.ok()) { 1388 if (!s.ok()) {
1397 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1389 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1398 "Internal error checking key existence."); 1390 "Internal error checking key existence.");
1399 params->callbacks->OnError(error); 1391 params->callbacks->OnError(error);
1400 if (s.IsCorruption()) 1392 return s;
1401 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1402 return;
1403 } 1393 }
1404 if (found) { 1394 if (found) {
1405 params->callbacks->OnError( 1395 params->callbacks->OnError(
1406 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 1396 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError,
1407 "Key already exists in the object store.")); 1397 "Key already exists in the object store."));
1408 return; 1398 return s;
1409 } 1399 }
1410 } 1400 }
1411 1401
1412 std::vector<std::unique_ptr<IndexWriter>> index_writers; 1402 std::vector<std::unique_ptr<IndexWriter>> index_writers;
1413 base::string16 error_message; 1403 base::string16 error_message;
1414 bool obeys_constraints = false; 1404 bool obeys_constraints = false;
1415 bool backing_store_success = MakeIndexWriters(transaction, 1405 bool backing_store_success = MakeIndexWriters(transaction,
1416 backing_store_.get(), 1406 backing_store_.get(),
1417 id(), 1407 id(),
1418 object_store, 1408 object_store,
1419 *key, 1409 *key,
1420 key_was_generated, 1410 key_was_generated,
1421 params->index_keys, 1411 params->index_keys,
1422 &index_writers, 1412 &index_writers,
1423 &error_message, 1413 &error_message,
1424 &obeys_constraints); 1414 &obeys_constraints);
1425 if (!backing_store_success) { 1415 if (!backing_store_success) {
1426 params->callbacks->OnError(IndexedDBDatabaseError( 1416 params->callbacks->OnError(IndexedDBDatabaseError(
1427 blink::WebIDBDatabaseExceptionUnknownError, 1417 blink::WebIDBDatabaseExceptionUnknownError,
1428 "Internal error: backing store error updating index keys.")); 1418 "Internal error: backing store error updating index keys."));
1429 return; 1419 return s;
1430 } 1420 }
1431 if (!obeys_constraints) { 1421 if (!obeys_constraints) {
1432 params->callbacks->OnError(IndexedDBDatabaseError( 1422 params->callbacks->OnError(IndexedDBDatabaseError(
1433 blink::WebIDBDatabaseExceptionConstraintError, error_message)); 1423 blink::WebIDBDatabaseExceptionConstraintError, error_message));
1434 return; 1424 return s;
1435 } 1425 }
1436 1426
1437 // Before this point, don't do any mutation. After this point, rollback the 1427 // Before this point, don't do any mutation. After this point, rollback the
1438 // transaction in case of error. 1428 // transaction in case of error.
1439 leveldb::Status s = 1429 s = backing_store_->PutRecord(transaction->BackingStoreTransaction(), id(),
1440 backing_store_->PutRecord(transaction->BackingStoreTransaction(), 1430 params->object_store_id, *key, &params->value,
1441 id(), 1431 &params->handles, &record_identifier);
1442 params->object_store_id,
1443 *key,
1444 &params->value,
1445 &params->handles,
1446 &record_identifier);
1447 if (!s.ok()) { 1432 if (!s.ok()) {
1448 IndexedDBDatabaseError error( 1433 IndexedDBDatabaseError error(
1449 blink::WebIDBDatabaseExceptionUnknownError, 1434 blink::WebIDBDatabaseExceptionUnknownError,
1450 "Internal error: backing store error performing put/add."); 1435 "Internal error: backing store error performing put/add.");
1451 params->callbacks->OnError(error); 1436 params->callbacks->OnError(error);
1452 if (s.IsCorruption()) 1437 return s;
1453 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1454 return;
1455 } 1438 }
1456 { 1439 {
1457 IDB_TRACE1("IndexedDBDatabase::PutOperation.UpdateIndexes", "txn.id", 1440 IDB_TRACE1("IndexedDBDatabase::PutOperation.UpdateIndexes", "txn.id",
1458 transaction->id()); 1441 transaction->id());
1459 for (const auto& writer : index_writers) { 1442 for (const auto& writer : index_writers) {
1460 writer->WriteIndexKeys(record_identifier, backing_store_.get(), 1443 writer->WriteIndexKeys(record_identifier, backing_store_.get(),
1461 transaction->BackingStoreTransaction(), id(), 1444 transaction->BackingStoreTransaction(), id(),
1462 params->object_store_id); 1445 params->object_store_id);
1463 } 1446 }
1464 } 1447 }
1465 1448
1466 if (object_store.auto_increment && 1449 if (object_store.auto_increment &&
1467 params->put_mode != blink::WebIDBPutModeCursorUpdate && 1450 params->put_mode != blink::WebIDBPutModeCursorUpdate &&
1468 key->type() == WebIDBKeyTypeNumber) { 1451 key->type() == WebIDBKeyTypeNumber) {
1469 IDB_TRACE1("IndexedDBDatabase::PutOperation.AutoIncrement", "txn.id", 1452 IDB_TRACE1("IndexedDBDatabase::PutOperation.AutoIncrement", "txn.id",
1470 transaction->id()); 1453 transaction->id());
1471 leveldb::Status s = UpdateKeyGenerator(backing_store_.get(), 1454 s = UpdateKeyGenerator(backing_store_.get(), transaction, id(),
1472 transaction, 1455 params->object_store_id, *key, !key_was_generated);
1473 id(),
1474 params->object_store_id,
1475 *key,
1476 !key_was_generated);
1477 if (!s.ok()) { 1456 if (!s.ok()) {
1478 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1457 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1479 "Internal error updating key generator."); 1458 "Internal error updating key generator.");
1480 params->callbacks->OnError(error); 1459 params->callbacks->OnError(error);
1481 if (s.IsCorruption()) 1460 return s;
1482 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1483 return;
1484 } 1461 }
1485 } 1462 }
1486 { 1463 {
1487 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id", 1464 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id",
1488 transaction->id()); 1465 transaction->id());
1489 params->callbacks->OnSuccess(*key); 1466 params->callbacks->OnSuccess(*key);
1490 } 1467 }
1491 FilterObservation(transaction, params->object_store_id, 1468 FilterObservation(transaction, params->object_store_id,
1492 params->put_mode == blink::WebIDBPutModeAddOnly 1469 params->put_mode == blink::WebIDBPutModeAddOnly
1493 ? blink::WebIDBAdd 1470 ? blink::WebIDBAdd
1494 : blink::WebIDBPut, 1471 : blink::WebIDBPut,
1495 IndexedDBKeyRange(*key)); 1472 IndexedDBKeyRange(*key));
1473 return s;
1496 } 1474 }
1497 1475
1498 void IndexedDBDatabase::SetIndexKeys( 1476 void IndexedDBDatabase::SetIndexKeys(
1499 int64_t transaction_id, 1477 int64_t transaction_id,
1500 int64_t object_store_id, 1478 int64_t object_store_id,
1501 std::unique_ptr<IndexedDBKey> primary_key, 1479 std::unique_ptr<IndexedDBKey> primary_key,
1502 const std::vector<IndexedDBIndexKeys>& index_keys) { 1480 const std::vector<IndexedDBIndexKeys>& index_keys) {
1503 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); 1481 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id);
1482
1504 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1483 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1505 if (!transaction) 1484 if (!transaction)
1506 return; 1485 return;
1507 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 1486 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
1508 1487
1509 // TODO(alecflett): This method could be asynchronous, but we need to 1488 // TODO(alecflett): This method could be asynchronous, but we need to
1510 // evaluate if it's worth the extra complexity. 1489 // evaluate if it's worth the extra complexity.
1511 IndexedDBBackingStore::RecordIdentifier record_identifier; 1490 IndexedDBBackingStore::RecordIdentifier record_identifier;
1512 bool found = false; 1491 bool found = false;
1513 leveldb::Status s = backing_store_->KeyExistsInObjectStore( 1492 leveldb::Status s = backing_store_->KeyExistsInObjectStore(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 return; 1555 return;
1577 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 1556 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
1578 1557
1579 transaction->ScheduleTask( 1558 transaction->ScheduleTask(
1580 blink::WebIDBTaskTypePreemptive, 1559 blink::WebIDBTaskTypePreemptive,
1581 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, 1560 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation,
1582 this, 1561 this,
1583 index_ids.size())); 1562 index_ids.size()));
1584 } 1563 }
1585 1564
1586 void IndexedDBDatabase::SetIndexesReadyOperation( 1565 leveldb::Status IndexedDBDatabase::SetIndexesReadyOperation(
1587 size_t index_count, 1566 size_t index_count,
1588 IndexedDBTransaction* transaction) { 1567 IndexedDBTransaction* transaction) {
1589 for (size_t i = 0; i < index_count; ++i) 1568 for (size_t i = 0; i < index_count; ++i)
1590 transaction->DidCompletePreemptiveEvent(); 1569 transaction->DidCompletePreemptiveEvent();
1570 return leveldb::Status::OK();
1591 } 1571 }
1592 1572
1593 struct IndexedDBDatabase::OpenCursorOperationParams { 1573 struct IndexedDBDatabase::OpenCursorOperationParams {
1594 OpenCursorOperationParams() {} 1574 OpenCursorOperationParams() {}
1595 int64_t object_store_id; 1575 int64_t object_store_id;
1596 int64_t index_id; 1576 int64_t index_id;
1597 std::unique_ptr<IndexedDBKeyRange> key_range; 1577 std::unique_ptr<IndexedDBKeyRange> key_range;
1598 blink::WebIDBCursorDirection direction; 1578 blink::WebIDBCursorDirection direction;
1599 indexed_db::CursorType cursor_type; 1579 indexed_db::CursorType cursor_type;
1600 blink::WebIDBTaskType task_type; 1580 blink::WebIDBTaskType task_type;
(...skipping 27 matching lines...) Expand all
1628 params->key_range = std::move(key_range); 1608 params->key_range = std::move(key_range);
1629 params->direction = direction; 1609 params->direction = direction;
1630 params->cursor_type = 1610 params->cursor_type =
1631 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE; 1611 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE;
1632 params->task_type = task_type; 1612 params->task_type = task_type;
1633 params->callbacks = callbacks; 1613 params->callbacks = callbacks;
1634 transaction->ScheduleTask(base::Bind( 1614 transaction->ScheduleTask(base::Bind(
1635 &IndexedDBDatabase::OpenCursorOperation, this, base::Passed(&params))); 1615 &IndexedDBDatabase::OpenCursorOperation, this, base::Passed(&params)));
1636 } 1616 }
1637 1617
1638 void IndexedDBDatabase::OpenCursorOperation( 1618 leveldb::Status IndexedDBDatabase::OpenCursorOperation(
1639 std::unique_ptr<OpenCursorOperationParams> params, 1619 std::unique_ptr<OpenCursorOperationParams> params,
1640 IndexedDBTransaction* transaction) { 1620 IndexedDBTransaction* transaction) {
1641 IDB_TRACE1( 1621 IDB_TRACE1(
1642 "IndexedDBDatabase::OpenCursorOperation", "txn.id", transaction->id()); 1622 "IndexedDBDatabase::OpenCursorOperation", "txn.id", transaction->id());
1643 1623
1644 // The frontend has begun indexing, so this pauses the transaction 1624 // The frontend has begun indexing, so this pauses the transaction
1645 // until the indexing is complete. This can't happen any earlier 1625 // until the indexing is complete. This can't happen any earlier
1646 // because we don't want to switch to early mode in case multiple 1626 // because we don't want to switch to early mode in case multiple
1647 // indexes are being created in a row, with Put()'s in between. 1627 // indexes are being created in a row, with Put()'s in between.
1648 if (params->task_type == blink::WebIDBTaskTypePreemptive) 1628 if (params->task_type == blink::WebIDBTaskTypePreemptive)
1649 transaction->AddPreemptiveEvent(); 1629 transaction->AddPreemptiveEvent();
1650 1630
1651 leveldb::Status s; 1631 leveldb::Status s = leveldb::Status::OK();
1652 std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1632 std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
1653 if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { 1633 if (params->index_id == IndexedDBIndexMetadata::kInvalidId) {
1654 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1634 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1655 DCHECK_EQ(params->task_type, blink::WebIDBTaskTypeNormal); 1635 DCHECK_EQ(params->task_type, blink::WebIDBTaskTypeNormal);
1656 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1636 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor(
1657 transaction->BackingStoreTransaction(), 1637 transaction->BackingStoreTransaction(),
1658 id(), 1638 id(),
1659 params->object_store_id, 1639 params->object_store_id,
1660 *params->key_range, 1640 *params->key_range,
1661 params->direction, 1641 params->direction,
(...skipping 27 matching lines...) Expand all
1689 *params->key_range, 1669 *params->key_range,
1690 params->direction, 1670 params->direction,
1691 &s); 1671 &s);
1692 } 1672 }
1693 } 1673 }
1694 1674
1695 if (!s.ok()) { 1675 if (!s.ok()) {
1696 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1676 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1697 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1677 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1698 "Internal error opening cursor operation"); 1678 "Internal error opening cursor operation");
1699 if (s.IsCorruption()) { 1679 return s;
1700 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1701 }
1702 } 1680 }
1703 1681
1704 if (!backing_store_cursor) { 1682 if (!backing_store_cursor) {
1705 // Why is Success being called? 1683 // Occurs when we've reached the end of cursor's data.
1706 params->callbacks->OnSuccess(nullptr); 1684 params->callbacks->OnSuccess(nullptr);
1707 return; 1685 return s;
1708 } 1686 }
1709 1687
1710 scoped_refptr<IndexedDBCursor> cursor = 1688 scoped_refptr<IndexedDBCursor> cursor =
1711 new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type, 1689 new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type,
1712 params->task_type, transaction); 1690 params->task_type, transaction);
1713 params->callbacks->OnSuccess( 1691 params->callbacks->OnSuccess(
1714 cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1692 cursor, cursor->key(), cursor->primary_key(), cursor->Value());
1693 return s;
1715 } 1694 }
1716 1695
1717 void IndexedDBDatabase::Count(int64_t transaction_id, 1696 void IndexedDBDatabase::Count(int64_t transaction_id,
1718 int64_t object_store_id, 1697 int64_t object_store_id,
1719 int64_t index_id, 1698 int64_t index_id,
1720 std::unique_ptr<IndexedDBKeyRange> key_range, 1699 std::unique_ptr<IndexedDBKeyRange> key_range,
1721 scoped_refptr<IndexedDBCallbacks> callbacks) { 1700 scoped_refptr<IndexedDBCallbacks> callbacks) {
1722 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id); 1701 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id);
1723 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1702 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1724 if (!transaction) 1703 if (!transaction)
1725 return; 1704 return;
1726 1705
1727 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1706 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
1728 return; 1707 return;
1729 1708
1730 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, 1709 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation,
1731 this, 1710 this,
1732 object_store_id, 1711 object_store_id,
1733 index_id, 1712 index_id,
1734 base::Passed(&key_range), 1713 base::Passed(&key_range),
1735 callbacks)); 1714 callbacks));
1736 } 1715 }
1737 1716
1738 void IndexedDBDatabase::CountOperation( 1717 leveldb::Status IndexedDBDatabase::CountOperation(
1739 int64_t object_store_id, 1718 int64_t object_store_id,
1740 int64_t index_id, 1719 int64_t index_id,
1741 std::unique_ptr<IndexedDBKeyRange> key_range, 1720 std::unique_ptr<IndexedDBKeyRange> key_range,
1742 scoped_refptr<IndexedDBCallbacks> callbacks, 1721 scoped_refptr<IndexedDBCallbacks> callbacks,
1743 IndexedDBTransaction* transaction) { 1722 IndexedDBTransaction* transaction) {
1744 IDB_TRACE1("IndexedDBDatabase::CountOperation", "txn.id", transaction->id()); 1723 IDB_TRACE1("IndexedDBDatabase::CountOperation", "txn.id", transaction->id());
1745 uint32_t count = 0; 1724 uint32_t count = 0;
1746 std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1725 std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
1747 1726
1748 leveldb::Status s; 1727 leveldb::Status s = leveldb::Status::OK();
1749 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1728 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
1750 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1729 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor(
1751 transaction->BackingStoreTransaction(), 1730 transaction->BackingStoreTransaction(),
1752 id(), 1731 id(),
1753 object_store_id, 1732 object_store_id,
1754 *key_range, 1733 *key_range,
1755 blink::WebIDBCursorDirectionNext, 1734 blink::WebIDBCursorDirectionNext,
1756 &s); 1735 &s);
1757 } else { 1736 } else {
1758 backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1737 backing_store_cursor = backing_store_->OpenIndexKeyCursor(
1759 transaction->BackingStoreTransaction(), 1738 transaction->BackingStoreTransaction(),
1760 id(), 1739 id(),
1761 object_store_id, 1740 object_store_id,
1762 index_id, 1741 index_id,
1763 *key_range, 1742 *key_range,
1764 blink::WebIDBCursorDirectionNext, 1743 blink::WebIDBCursorDirectionNext,
1765 &s); 1744 &s);
1766 } 1745 }
1767 if (!s.ok()) { 1746 if (!s.ok()) {
1768 DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); 1747 DLOG(ERROR) << "Unable perform count operation: " << s.ToString();
1769 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1748 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1770 "Internal error performing count operation"); 1749 "Internal error performing count operation");
1771 if (s.IsCorruption()) { 1750 return s;
1772 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1773 }
1774 } 1751 }
1775 if (!backing_store_cursor) { 1752 if (!backing_store_cursor) {
1776 callbacks->OnSuccess(count); 1753 callbacks->OnSuccess(count);
1777 return; 1754 return s;
1778 } 1755 }
1779 1756
1780 do { 1757 do {
1758 if (!s.ok())
1759 return s;
1781 ++count; 1760 ++count;
1782 } while (backing_store_cursor->Continue(&s)); 1761 } while (backing_store_cursor->Continue(&s));
1783 1762
1784 // TODO(cmumford): Check for database corruption.
1785
1786 callbacks->OnSuccess(count); 1763 callbacks->OnSuccess(count);
1764 return s;
1787 } 1765 }
1788 1766
1789 void IndexedDBDatabase::DeleteRange( 1767 void IndexedDBDatabase::DeleteRange(
1790 int64_t transaction_id, 1768 int64_t transaction_id,
1791 int64_t object_store_id, 1769 int64_t object_store_id,
1792 std::unique_ptr<IndexedDBKeyRange> key_range, 1770 std::unique_ptr<IndexedDBKeyRange> key_range,
1793 scoped_refptr<IndexedDBCallbacks> callbacks) { 1771 scoped_refptr<IndexedDBCallbacks> callbacks) {
1794 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); 1772 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id);
1795 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1773 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1796 if (!transaction) 1774 if (!transaction)
1797 return; 1775 return;
1798 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1776 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1799 1777
1800 if (!ValidateObjectStoreId(object_store_id)) 1778 if (!ValidateObjectStoreId(object_store_id))
1801 return; 1779 return;
1802 1780
1803 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, 1781 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation,
1804 this, 1782 this,
1805 object_store_id, 1783 object_store_id,
1806 base::Passed(&key_range), 1784 base::Passed(&key_range),
1807 callbacks)); 1785 callbacks));
1808 } 1786 }
1809 1787
1810 void IndexedDBDatabase::DeleteRangeOperation( 1788 leveldb::Status IndexedDBDatabase::DeleteRangeOperation(
1811 int64_t object_store_id, 1789 int64_t object_store_id,
1812 std::unique_ptr<IndexedDBKeyRange> key_range, 1790 std::unique_ptr<IndexedDBKeyRange> key_range,
1813 scoped_refptr<IndexedDBCallbacks> callbacks, 1791 scoped_refptr<IndexedDBCallbacks> callbacks,
1814 IndexedDBTransaction* transaction) { 1792 IndexedDBTransaction* transaction) {
1815 IDB_TRACE1("IndexedDBDatabase::DeleteRangeOperation", "txn.id", 1793 IDB_TRACE1("IndexedDBDatabase::DeleteRangeOperation", "txn.id",
1816 transaction->id()); 1794 transaction->id());
1817 size_t delete_count = 0; 1795 size_t delete_count = 0;
1818 leveldb::Status s = 1796 leveldb::Status s =
1819 backing_store_->DeleteRange(transaction->BackingStoreTransaction(), id(), 1797 backing_store_->DeleteRange(transaction->BackingStoreTransaction(), id(),
1820 object_store_id, *key_range, &delete_count); 1798 object_store_id, *key_range, &delete_count);
1821 if (!s.ok()) { 1799 if (!s.ok()) {
1822 base::string16 error_string = 1800 base::string16 error_string =
1823 ASCIIToUTF16("Internal error deleting data in range"); 1801 ASCIIToUTF16("Internal error deleting data in range");
1824 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1802 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1825 error_string); 1803 error_string);
1826 transaction->Abort(error); 1804 transaction->Abort(error);
1827 if (s.IsCorruption()) { 1805 return s;
1828 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1829 }
1830 return;
1831 } 1806 }
1832 callbacks->OnSuccess(); 1807 callbacks->OnSuccess();
1833 FilterObservation(transaction, object_store_id, blink::WebIDBDelete, 1808 FilterObservation(transaction, object_store_id, blink::WebIDBDelete,
1834 *key_range); 1809 *key_range);
1810 return s;
1835 } 1811 }
1836 1812
1837 void IndexedDBDatabase::Clear(int64_t transaction_id, 1813 void IndexedDBDatabase::Clear(int64_t transaction_id,
1838 int64_t object_store_id, 1814 int64_t object_store_id,
1839 scoped_refptr<IndexedDBCallbacks> callbacks) { 1815 scoped_refptr<IndexedDBCallbacks> callbacks) {
1840 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); 1816 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id);
1841 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1817 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1842 if (!transaction) 1818 if (!transaction)
1843 return; 1819 return;
1844 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1820 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1845 1821
1846 if (!ValidateObjectStoreId(object_store_id)) 1822 if (!ValidateObjectStoreId(object_store_id))
1847 return; 1823 return;
1848 1824
1849 transaction->ScheduleTask(base::Bind( 1825 transaction->ScheduleTask(base::Bind(
1850 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); 1826 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks));
1851 } 1827 }
1852 1828
1853 void IndexedDBDatabase::ClearOperation( 1829 leveldb::Status IndexedDBDatabase::ClearOperation(
1854 int64_t object_store_id, 1830 int64_t object_store_id,
1855 scoped_refptr<IndexedDBCallbacks> callbacks, 1831 scoped_refptr<IndexedDBCallbacks> callbacks,
1856 IndexedDBTransaction* transaction) { 1832 IndexedDBTransaction* transaction) {
1857 IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id()); 1833 IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id());
1858 leveldb::Status s = backing_store_->ClearObjectStore( 1834 leveldb::Status s = backing_store_->ClearObjectStore(
1859 transaction->BackingStoreTransaction(), id(), object_store_id); 1835 transaction->BackingStoreTransaction(), id(), object_store_id);
1860 if (!s.ok()) { 1836 if (!s.ok()) {
1861 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1837 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1862 "Internal error clearing object store"); 1838 "Internal error clearing object store");
1863 callbacks->OnError(error); 1839 callbacks->OnError(error);
1864 if (s.IsCorruption()) { 1840 return s;
1865 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1866 }
1867 return;
1868 } 1841 }
1869 callbacks->OnSuccess(); 1842 callbacks->OnSuccess();
1870 1843
1871 FilterObservation(transaction, object_store_id, blink::WebIDBClear, 1844 FilterObservation(transaction, object_store_id, blink::WebIDBClear,
1872 IndexedDBKeyRange()); 1845 IndexedDBKeyRange());
1846 return s;
1873 } 1847 }
1874 1848
1875 void IndexedDBDatabase::DeleteObjectStoreOperation( 1849 leveldb::Status IndexedDBDatabase::DeleteObjectStoreOperation(
1876 int64_t object_store_id, 1850 int64_t object_store_id,
1877 IndexedDBTransaction* transaction) { 1851 IndexedDBTransaction* transaction) {
1878 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation", 1852 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation",
1879 "txn.id", 1853 "txn.id",
1880 transaction->id()); 1854 transaction->id());
1881 1855
1882 const IndexedDBObjectStoreMetadata object_store_metadata = 1856 const IndexedDBObjectStoreMetadata object_store_metadata =
1883 metadata_.object_stores[object_store_id]; 1857 metadata_.object_stores[object_store_id];
1884 leveldb::Status s = 1858 leveldb::Status s =
1885 backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1859 backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(),
1886 transaction->database()->id(), 1860 transaction->database()->id(),
1887 object_store_id); 1861 object_store_id);
1888 if (!s.ok()) { 1862 if (!s.ok()) {
1889 base::string16 error_string = 1863 base::string16 error_string =
1890 ASCIIToUTF16("Internal error deleting object store '") + 1864 ASCIIToUTF16("Internal error deleting object store '") +
1891 object_store_metadata.name + ASCIIToUTF16("'."); 1865 object_store_metadata.name + ASCIIToUTF16("'.");
1892 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1866 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1893 error_string); 1867 error_string);
1894 transaction->Abort(error); 1868 transaction->Abort(error);
1895 if (s.IsCorruption()) 1869 return s;
1896 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1897 return;
1898 } 1870 }
1899 1871
1900 RemoveObjectStore(object_store_id); 1872 RemoveObjectStore(object_store_id);
1901 transaction->ScheduleAbortTask( 1873 transaction->ScheduleAbortTask(
1902 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, 1874 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation,
1903 this, 1875 this,
1904 object_store_metadata)); 1876 object_store_metadata));
1877 return s;
1905 } 1878 }
1906 1879
1907 void IndexedDBDatabase::VersionChangeOperation( 1880 leveldb::Status IndexedDBDatabase::VersionChangeOperation(
1908 int64_t version, 1881 int64_t version,
1909 scoped_refptr<IndexedDBCallbacks> callbacks, 1882 scoped_refptr<IndexedDBCallbacks> callbacks,
1910 IndexedDBTransaction* transaction) { 1883 IndexedDBTransaction* transaction) {
1911 IDB_TRACE1( 1884 IDB_TRACE1(
1912 "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id()); 1885 "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id());
1913 int64_t old_version = metadata_.version; 1886 int64_t old_version = metadata_.version;
1914 DCHECK_GT(version, old_version); 1887 DCHECK_GT(version, old_version);
1915 1888
1916 if (!backing_store_->UpdateIDBDatabaseIntVersion( 1889 backing_store_->UpdateIDBDatabaseIntVersion(
1917 transaction->BackingStoreTransaction(), id(), version)) { 1890 transaction->BackingStoreTransaction(), id(), version);
1918 IndexedDBDatabaseError error(
1919 blink::WebIDBDatabaseExceptionUnknownError,
1920 ASCIIToUTF16(
1921 "Internal error writing data to stable storage when "
1922 "updating version."));
1923 callbacks->OnError(error);
1924 transaction->Abort(error);
1925 return;
1926 }
1927 1891
1928 transaction->ScheduleAbortTask( 1892 transaction->ScheduleAbortTask(
1929 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, 1893 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this,
1930 metadata_.version)); 1894 metadata_.version));
1931 metadata_.version = version; 1895 metadata_.version = version;
1932 1896
1933 active_request_->UpgradeTransactionStarted(old_version); 1897 active_request_->UpgradeTransactionStarted(old_version);
1898 return leveldb::Status::OK();
1934 } 1899 }
1935 1900
1936 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, 1901 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
1937 bool committed) { 1902 bool committed) {
1938 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); 1903 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id());
1939 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1904 DCHECK(transactions_.find(transaction->id()) != transactions_.end());
1940 DCHECK_EQ(transactions_[transaction->id()], transaction); 1905 DCHECK_EQ(transactions_[transaction->id()], transaction);
1941 transactions_.erase(transaction->id()); 1906 transactions_.erase(transaction->id());
1942 1907
1943 // This may be an unrelated transaction finishing while waiting for 1908 // This may be an unrelated transaction finishing while waiting for
1944 // connections to close, or the actual upgrade transaction from an active 1909 // connections to close, or the actual upgrade transaction from an active
1945 // request. Notify the active request if it's the latter. 1910 // request. Notify the active request if it's the latter.
1946 if (active_request_ && 1911 if (active_request_ &&
1947 transaction->mode() == blink::WebIDBTransactionModeVersionChange) { 1912 transaction->mode() == blink::WebIDBTransactionModeVersionChange) {
1948 active_request_->UpgradeTransactionFinished(committed); 1913 active_request_->UpgradeTransactionFinished(committed);
1949 } 1914 }
1950 } 1915 }
1951 1916
1952 void IndexedDBDatabase::TransactionCommitFailed(const leveldb::Status& status) {
1953 if (status.IsCorruption()) {
1954 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1955 "Error committing transaction");
1956 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1957 } else {
1958 factory_->HandleBackingStoreFailure(backing_store_->origin());
1959 }
1960 }
1961
1962 void IndexedDBDatabase::AppendRequest( 1917 void IndexedDBDatabase::AppendRequest(
1963 std::unique_ptr<ConnectionRequest> request) { 1918 std::unique_ptr<ConnectionRequest> request) {
1964 pending_requests_.push(std::move(request)); 1919 pending_requests_.push(std::move(request));
1965 1920
1966 if (!active_request_) 1921 if (!active_request_)
1967 ProcessRequestQueue(); 1922 ProcessRequestQueue();
1968 } 1923 }
1969 1924
1970 void IndexedDBDatabase::RequestComplete(ConnectionRequest* request) { 1925 void IndexedDBDatabase::RequestComplete(ConnectionRequest* request) {
1971 DCHECK_EQ(request, active_request_.get()); 1926 DCHECK_EQ(request, active_request_.get());
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2086 // If there are no more connections (current, active, or pending), tell the 2041 // If there are no more connections (current, active, or pending), tell the
2087 // factory to clean us up. 2042 // factory to clean us up.
2088 if (connections_.empty() && !active_request_ && pending_requests_.empty()) { 2043 if (connections_.empty() && !active_request_ && pending_requests_.empty()) {
2089 DCHECK(transactions_.empty()); 2044 DCHECK(transactions_.empty());
2090 backing_store_ = nullptr; 2045 backing_store_ = nullptr;
2091 factory_->ReleaseDatabase(identifier_, forced); 2046 factory_->ReleaseDatabase(identifier_, forced);
2092 } 2047 }
2093 } 2048 }
2094 2049
2095 void IndexedDBDatabase::CreateObjectStoreAbortOperation( 2050 void IndexedDBDatabase::CreateObjectStoreAbortOperation(
2096 int64_t object_store_id, 2051 int64_t object_store_id) {
2097 IndexedDBTransaction* transaction) {
2098 DCHECK(!transaction);
2099 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); 2052 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation");
2100 RemoveObjectStore(object_store_id); 2053 RemoveObjectStore(object_store_id);
2101 } 2054 }
2102 2055
2103 void IndexedDBDatabase::DeleteObjectStoreAbortOperation( 2056 void IndexedDBDatabase::DeleteObjectStoreAbortOperation(
2104 const IndexedDBObjectStoreMetadata& object_store_metadata, 2057 const IndexedDBObjectStoreMetadata& object_store_metadata) {
2105 IndexedDBTransaction* transaction) {
2106 DCHECK(!transaction);
2107 IDB_TRACE("IndexedDBDatabase::DeleteObjectStoreAbortOperation"); 2058 IDB_TRACE("IndexedDBDatabase::DeleteObjectStoreAbortOperation");
2108 AddObjectStore(object_store_metadata, 2059 AddObjectStore(object_store_metadata,
2109 IndexedDBObjectStoreMetadata::kInvalidId); 2060 IndexedDBObjectStoreMetadata::kInvalidId);
2110 } 2061 }
2111 2062
2112 void IndexedDBDatabase::RenameObjectStoreAbortOperation( 2063 void IndexedDBDatabase::RenameObjectStoreAbortOperation(
2113 int64_t object_store_id, 2064 int64_t object_store_id,
2114 const base::string16& old_name, 2065 const base::string16& old_name) {
2115 IndexedDBTransaction* transaction) {
2116 DCHECK(!transaction);
2117 IDB_TRACE("IndexedDBDatabase::RenameObjectStoreAbortOperation"); 2066 IDB_TRACE("IndexedDBDatabase::RenameObjectStoreAbortOperation");
2118 SetObjectStoreName(object_store_id, old_name); 2067 SetObjectStoreName(object_store_id, old_name);
2119 } 2068 }
2120 2069
2121 void IndexedDBDatabase::VersionChangeAbortOperation( 2070 void IndexedDBDatabase::VersionChangeAbortOperation(int64_t previous_version) {
2122 int64_t previous_version,
2123 IndexedDBTransaction* transaction) {
2124 DCHECK(!transaction);
2125 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 2071 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
2126 metadata_.version = previous_version; 2072 metadata_.version = previous_version;
2127 } 2073 }
2128 2074
2129 } // namespace content 2075 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_database.h ('k') | content/browser/indexed_db/indexed_db_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698