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

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

Issue 2773823002: Use a two-part data format version in IndexedDB metadata. (Closed)
Patch Set: base::MakeShared Created 3 years, 8 months 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_backing_store.h" 5 #include "content/browser/indexed_db/indexed_db_backing_store.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/json/json_reader.h" 13 #include "base/json/json_reader.h"
14 #include "base/json/json_writer.h" 14 #include "base/json/json_writer.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
18 #include "base/metrics/histogram_macros.h" 18 #include "base/metrics/histogram_macros.h"
19 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
22 #include "base/trace_event/memory_dump_manager.h" 22 #include "base/trace_event/memory_dump_manager.h"
23 #include "build/build_config.h" 23 #include "build/build_config.h"
24 #include "content/browser/child_process_security_policy_impl.h" 24 #include "content/browser/child_process_security_policy_impl.h"
25 #include "content/browser/indexed_db/indexed_db_blob_info.h" 25 #include "content/browser/indexed_db/indexed_db_blob_info.h"
26 #include "content/browser/indexed_db/indexed_db_class_factory.h" 26 #include "content/browser/indexed_db/indexed_db_class_factory.h"
27 #include "content/browser/indexed_db/indexed_db_context_impl.h" 27 #include "content/browser/indexed_db/indexed_db_context_impl.h"
28 #include "content/browser/indexed_db/indexed_db_data_format_version.h"
28 #include "content/browser/indexed_db/indexed_db_database_error.h" 29 #include "content/browser/indexed_db/indexed_db_database_error.h"
29 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 30 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
30 #include "content/browser/indexed_db/indexed_db_tracing.h" 31 #include "content/browser/indexed_db/indexed_db_tracing.h"
31 #include "content/browser/indexed_db/indexed_db_value.h" 32 #include "content/browser/indexed_db/indexed_db_value.h"
32 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 33 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
33 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 34 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
34 #include "content/browser/indexed_db/leveldb/leveldb_factory.h" 35 #include "content/browser/indexed_db/leveldb/leveldb_factory.h"
35 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 36 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
36 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 37 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
37 #include "content/common/indexed_db/indexed_db_key.h" 38 #include "content/common/indexed_db/indexed_db_key.h"
38 #include "content/common/indexed_db/indexed_db_key_path.h" 39 #include "content/common/indexed_db/indexed_db_key_path.h"
39 #include "content/common/indexed_db/indexed_db_key_range.h" 40 #include "content/common/indexed_db/indexed_db_key_range.h"
40 #include "content/public/browser/browser_thread.h" 41 #include "content/public/browser/browser_thread.h"
41 #include "net/url_request/url_request_context.h" 42 #include "net/url_request/url_request_context.h"
42 #include "storage/browser/blob/blob_data_handle.h" 43 #include "storage/browser/blob/blob_data_handle.h"
43 #include "storage/browser/fileapi/file_stream_writer.h" 44 #include "storage/browser/fileapi/file_stream_writer.h"
44 #include "storage/browser/fileapi/file_writer_delegate.h" 45 #include "storage/browser/fileapi/file_writer_delegate.h"
45 #include "storage/browser/fileapi/local_file_stream_writer.h" 46 #include "storage/browser/fileapi/local_file_stream_writer.h"
46 #include "storage/common/database/database_identifier.h" 47 #include "storage/common/database/database_identifier.h"
47 #include "storage/common/fileapi/file_system_mount_option.h" 48 #include "storage/common/fileapi/file_system_mount_option.h"
48 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" 49 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
49 #include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h"
50 #include "third_party/leveldatabase/env_chromium.h" 50 #include "third_party/leveldatabase/env_chromium.h"
51 51
52 using base::FilePath; 52 using base::FilePath;
53 using base::StringPiece; 53 using base::StringPiece;
54 using leveldb::Status; 54 using leveldb::Status;
55 using storage::FileWriterDelegate; 55 using storage::FileWriterDelegate;
56 using url::Origin; 56 using url::Origin;
57 57
58 namespace content { 58 namespace content {
59 59
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, 109 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
110 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, 110 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION,
111 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, 111 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR,
112 INDEXED_DB_BACKING_STORE_OPEN_MAX, 112 INDEXED_DB_BACKING_STORE_OPEN_MAX,
113 }; 113 };
114 114
115 // 0 - Initial version. 115 // 0 - Initial version.
116 // 1 - Adds UserIntVersion to DatabaseMetaData. 116 // 1 - Adds UserIntVersion to DatabaseMetaData.
117 // 2 - Adds DataVersion to to global metadata. 117 // 2 - Adds DataVersion to to global metadata.
118 // 3 - Adds metadata needed for blob support. 118 // 3 - Adds metadata needed for blob support.
119 const int64_t kLatestKnownSchemaVersion = 3; 119 const int64_t kLatestKnownSchemaVersion = 3;
jsbell 2017/04/07 16:30:01 Just calling out: we're explicitly NOT bumping thi
120 120
121 // From the IndexedDB specification. 121 // From the IndexedDB specification.
122 const int64_t kKeyGeneratorInitialNumber = 1; 122 const int64_t kKeyGeneratorInitialNumber = 1;
123 123
124 FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) { 124 FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) {
125 return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id)); 125 return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id));
126 } 126 }
127 127
128 FilePath GetBlobDirectoryNameForKey(const FilePath& path_base, 128 FilePath GetBlobDirectoryNameForKey(const FilePath& path_base,
129 int64_t database_id, 129 int64_t database_id,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 *known = true; 328 *known = true;
329 return true; 329 return true;
330 } 330 }
331 if (db_schema_version < 0) 331 if (db_schema_version < 0)
332 return false; // Only corruption should cause this. 332 return false; // Only corruption should cause this.
333 if (db_schema_version > kLatestKnownSchemaVersion) { 333 if (db_schema_version > kLatestKnownSchemaVersion) {
334 *known = false; 334 *known = false;
335 return true; 335 return true;
336 } 336 }
337 337
338 const uint32_t latest_known_data_version = 338 int64_t raw_db_data_version = 0;
339 blink::kSerializedScriptValueVersion; 339 s = GetInt(db, DataVersionKey::Encode(), &raw_db_data_version, &found);
340 int64_t db_data_version = 0;
341 s = GetInt(db, DataVersionKey::Encode(), &db_data_version, &found);
342 if (!s.ok()) 340 if (!s.ok())
343 return false; 341 return false;
344 if (!found) { 342 if (!found) {
345 *known = true; 343 *known = true;
346 return true; 344 return true;
347 } 345 }
348 if (db_data_version < 0) 346 if (raw_db_data_version < 0)
349 return false; // Only corruption should cause this. 347 return false; // Only corruption should cause this.
350 if (db_data_version > latest_known_data_version) {
351 *known = false;
352 return true;
353 }
354 348
355 *known = true; 349 *known = IndexedDBDataFormatVersion::GetCurrent().IsAtLeast(
350 IndexedDBDataFormatVersion::Decode(raw_db_data_version));
356 return true; 351 return true;
357 } 352 }
358 353
359 template <typename DBOrTransaction> 354 template <typename DBOrTransaction>
360 WARN_UNUSED_RESULT Status 355 WARN_UNUSED_RESULT Status
361 GetMaxObjectStoreId(DBOrTransaction* db, 356 GetMaxObjectStoreId(DBOrTransaction* db,
362 const std::string& max_object_store_id_key, 357 const std::string& max_object_store_id_key,
363 int64_t* max_object_store_id) { 358 int64_t* max_object_store_id) {
364 *max_object_store_id = -1; 359 *max_object_store_id = -1;
365 bool found = false; 360 bool found = false;
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1131
1137 Status IndexedDBBackingStore::DestroyBackingStore(const FilePath& path_base, 1132 Status IndexedDBBackingStore::DestroyBackingStore(const FilePath& path_base,
1138 const Origin& origin) { 1133 const Origin& origin) {
1139 const FilePath file_path = 1134 const FilePath file_path =
1140 path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin)); 1135 path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin));
1141 DefaultLevelDBFactory leveldb_factory; 1136 DefaultLevelDBFactory leveldb_factory;
1142 return leveldb_factory.DestroyLevelDB(file_path); 1137 return leveldb_factory.DestroyLevelDB(file_path);
1143 } 1138 }
1144 1139
1145 WARN_UNUSED_RESULT Status IndexedDBBackingStore::SetUpMetadata() { 1140 WARN_UNUSED_RESULT Status IndexedDBBackingStore::SetUpMetadata() {
1146 const uint32_t latest_known_data_version = 1141 const IndexedDBDataFormatVersion latest_known_data_version =
1147 blink::kSerializedScriptValueVersion; 1142 IndexedDBDataFormatVersion::GetCurrent();
1148 const std::string schema_version_key = SchemaVersionKey::Encode(); 1143 const std::string schema_version_key = SchemaVersionKey::Encode();
1149 const std::string data_version_key = DataVersionKey::Encode(); 1144 const std::string data_version_key = DataVersionKey::Encode();
1150 1145
1151 scoped_refptr<LevelDBTransaction> transaction = 1146 scoped_refptr<LevelDBTransaction> transaction =
1152 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); 1147 IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
1153 1148
1154 int64_t db_schema_version = 0; 1149 int64_t db_schema_version = 0;
1155 int64_t db_data_version = 0; 1150 IndexedDBDataFormatVersion db_data_version;
1156 bool found = false; 1151 bool found = false;
1157 Status s = 1152 Status s =
1158 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found); 1153 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
1159 if (!s.ok()) { 1154 if (!s.ok()) {
1160 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 1155 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
1161 return s; 1156 return s;
1162 } 1157 }
1163 if (!found) { 1158 if (!found) {
1164 // Initialize new backing store. 1159 // Initialize new backing store.
1165 db_schema_version = kLatestKnownSchemaVersion; 1160 db_schema_version = kLatestKnownSchemaVersion;
1166 PutInt(transaction.get(), schema_version_key, db_schema_version); 1161 PutInt(transaction.get(), schema_version_key, db_schema_version);
1167 db_data_version = latest_known_data_version; 1162 db_data_version = latest_known_data_version;
1168 PutInt(transaction.get(), data_version_key, db_data_version); 1163 PutInt(transaction.get(), data_version_key, db_data_version.Encode());
1169 // If a blob directory already exists for this database, blow it away. It's 1164 // If a blob directory already exists for this database, blow it away. It's
1170 // leftover from a partially-purged previous generation of data. 1165 // leftover from a partially-purged previous generation of data.
1171 if (!base::DeleteFile(blob_path_, true)) { 1166 if (!base::DeleteFile(blob_path_, true)) {
1172 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); 1167 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
1173 return IOErrorStatus(); 1168 return IOErrorStatus();
1174 } 1169 }
1175 } else { 1170 } else {
1176 // Upgrade old backing store. 1171 // Upgrade old backing store.
1177 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); 1172 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion);
1178 if (db_schema_version < 1) { 1173 if (db_schema_version < 1) {
(...skipping 20 matching lines...) Expand all
1199 } 1194 }
1200 std::string version_key = DatabaseMetaDataKey::Encode( 1195 std::string version_key = DatabaseMetaDataKey::Encode(
1201 database_id, DatabaseMetaDataKey::USER_VERSION); 1196 database_id, DatabaseMetaDataKey::USER_VERSION);
1202 PutVarInt(transaction.get(), version_key, 1197 PutVarInt(transaction.get(), version_key,
1203 IndexedDBDatabaseMetadata::DEFAULT_VERSION); 1198 IndexedDBDatabaseMetadata::DEFAULT_VERSION);
1204 } 1199 }
1205 } 1200 }
1206 if (s.ok() && db_schema_version < 2) { 1201 if (s.ok() && db_schema_version < 2) {
1207 db_schema_version = 2; 1202 db_schema_version = 2;
1208 PutInt(transaction.get(), schema_version_key, db_schema_version); 1203 PutInt(transaction.get(), schema_version_key, db_schema_version);
1209 db_data_version = blink::kSerializedScriptValueVersion; 1204 db_data_version = latest_known_data_version;
1210 PutInt(transaction.get(), data_version_key, db_data_version); 1205 PutInt(transaction.get(), data_version_key, db_data_version.Encode());
1211 } 1206 }
1212 if (db_schema_version < 3) { 1207 if (db_schema_version < 3) {
1213 db_schema_version = 3; 1208 db_schema_version = 3;
1214 if (!base::DeleteFile(blob_path_, true)) { 1209 if (!base::DeleteFile(blob_path_, true)) {
1215 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); 1210 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
1216 return IOErrorStatus(); 1211 return IOErrorStatus();
1217 } 1212 }
1218 } 1213 }
1219 } 1214 }
1220 1215
1221 if (!s.ok()) { 1216 if (!s.ok()) {
1222 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 1217 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
1223 return s; 1218 return s;
1224 } 1219 }
1225 1220
1226 // All new values will be written using this serialization version. 1221 // All new values will be written using this serialization version.
1227 found = false; 1222 found = false;
1228 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found); 1223 int64_t raw_db_data_version = 0;
1224 s = GetInt(transaction.get(), data_version_key, &raw_db_data_version, &found);
1229 if (!s.ok()) { 1225 if (!s.ok()) {
1230 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 1226 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
1231 return s; 1227 return s;
1232 } 1228 }
1233 if (!found) { 1229 if (!found) {
1234 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA); 1230 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
1235 return InternalInconsistencyStatus(); 1231 return InternalInconsistencyStatus();
1236 } 1232 }
1237 if (db_data_version < latest_known_data_version) { 1233 db_data_version = IndexedDBDataFormatVersion::Decode(raw_db_data_version);
1234 if (latest_known_data_version == db_data_version) {
1235 // Up to date. Nothing to do.
1236 } else if (latest_known_data_version.IsAtLeast(db_data_version)) {
1238 db_data_version = latest_known_data_version; 1237 db_data_version = latest_known_data_version;
1239 PutInt(transaction.get(), data_version_key, db_data_version); 1238 PutInt(transaction.get(), data_version_key, db_data_version.Encode());
1239 } else {
1240 // |db_data_version| is in the future according to at least one component.
1241 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
1242 return InternalInconsistencyStatus();
1240 } 1243 }
1241 1244
1242 DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion); 1245 DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion);
1243 DCHECK_EQ(db_data_version, latest_known_data_version); 1246 DCHECK(db_data_version == latest_known_data_version);
1244 1247
1245 s = transaction->Commit(); 1248 s = transaction->Commit();
1246 if (!s.ok()) 1249 if (!s.ok())
1247 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); 1250 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
1248 return s; 1251 return s;
1249 } 1252 }
1250 1253
1251 bool IndexedDBBackingStore::ReadCorruptionInfo(const FilePath& path_base, 1254 bool IndexedDBBackingStore::ReadCorruptionInfo(const FilePath& path_base,
1252 const Origin& origin, 1255 const Origin& origin,
1253 std::string* message) { 1256 std::string* message) {
(...skipping 3202 matching lines...) Expand 10 before | Expand all | Expand 10 after
4456 4459
4457 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( 4460 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor(
4458 const WriteDescriptor& other) = default; 4461 const WriteDescriptor& other) = default;
4459 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = 4462 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() =
4460 default; 4463 default;
4461 IndexedDBBackingStore::Transaction::WriteDescriptor& 4464 IndexedDBBackingStore::Transaction::WriteDescriptor&
4462 IndexedDBBackingStore::Transaction::WriteDescriptor:: 4465 IndexedDBBackingStore::Transaction::WriteDescriptor::
4463 operator=(const WriteDescriptor& other) = default; 4466 operator=(const WriteDescriptor& other) = default;
4464 4467
4465 } // namespace content 4468 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698