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

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

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

Powered by Google App Engine
This is Rietveld 408576698