Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/indexed_db/indexed_db_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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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(¶ms))); | 1346 &IndexedDBDatabase::PutOperation, this, base::Passed(¶ms))); |
| 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, ¶ms->value, |
| 1447 id(), | 1435 ¶ms->handles, &record_identifier); |
| 1448 params->object_store_id, | |
| 1449 *key, | |
| 1450 ¶ms->value, | |
| 1451 ¶ms->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 Loading... | |
| 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 Loading... | |
| 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(¶ms))); | 1622 &IndexedDBDatabase::OpenCursorOperation, this, base::Passed(¶ms))); |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |