OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/fileapi/file_system_directory_database.h" | 5 #include "webkit/fileapi/file_system_directory_database.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
| 9 #include "base/file_util.h" |
9 #include "base/location.h" | 10 #include "base/location.h" |
10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
11 #include "base/pickle.h" | 12 #include "base/pickle.h" |
12 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
13 #include "base/string_util.h" | 14 #include "base/string_util.h" |
14 #include "base/sys_string_conversions.h" | |
15 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 15 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
16 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 16 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
17 #include "webkit/fileapi/file_system_util.h" | 17 #include "webkit/fileapi/file_system_util.h" |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 bool PickleFromFileInfo( | 21 bool PickleFromFileInfo( |
22 const fileapi::FileSystemDirectoryDatabase::FileInfo& info, | 22 const fileapi::FileSystemDirectoryDatabase::FileInfo& info, |
23 Pickle* pickle) { | 23 Pickle* pickle) { |
24 DCHECK(pickle); | 24 DCHECK(pickle); |
25 std::string data_path; | 25 std::string data_path; |
26 // Round off here to match the behavior of the filesystem on real files. | 26 // Round off here to match the behavior of the filesystem on real files. |
27 base::Time time = | 27 base::Time time = |
28 base::Time::FromDoubleT(floor(info.modification_time.ToDoubleT())); | 28 base::Time::FromDoubleT(floor(info.modification_time.ToDoubleT())); |
29 std::string name; | 29 std::string name; |
30 | 30 |
31 #if defined(OS_POSIX) | 31 data_path = fileapi::FilePathToString(info.data_path); |
32 data_path = info.data_path.value(); | 32 name = fileapi::FilePathToString(FilePath(info.name)); |
33 name = info.name; | 33 |
34 #elif defined(OS_WIN) | |
35 data_path = base::SysWideToUTF8(info.data_path.value()); | |
36 name = base::SysWideToUTF8(info.name); | |
37 #endif | |
38 if (pickle->WriteInt64(info.parent_id) && | 34 if (pickle->WriteInt64(info.parent_id) && |
39 pickle->WriteString(data_path) && | 35 pickle->WriteString(data_path) && |
40 pickle->WriteString(name) && | 36 pickle->WriteString(name) && |
41 pickle->WriteInt64(time.ToInternalValue())) | 37 pickle->WriteInt64(time.ToInternalValue())) |
42 return true; | 38 return true; |
43 | 39 |
44 NOTREACHED(); | 40 NOTREACHED(); |
45 return false; | 41 return false; |
46 } | 42 } |
47 | 43 |
48 bool FileInfoFromPickle( | 44 bool FileInfoFromPickle( |
49 const Pickle& pickle, | 45 const Pickle& pickle, |
50 fileapi::FileSystemDirectoryDatabase::FileInfo* info) { | 46 fileapi::FileSystemDirectoryDatabase::FileInfo* info) { |
51 PickleIterator iter(pickle); | 47 PickleIterator iter(pickle); |
52 std::string data_path; | 48 std::string data_path; |
53 std::string name; | 49 std::string name; |
54 int64 internal_time; | 50 int64 internal_time; |
55 | 51 |
56 if (pickle.ReadInt64(&iter, &info->parent_id) && | 52 if (pickle.ReadInt64(&iter, &info->parent_id) && |
57 pickle.ReadString(&iter, &data_path) && | 53 pickle.ReadString(&iter, &data_path) && |
58 pickle.ReadString(&iter, &name) && | 54 pickle.ReadString(&iter, &name) && |
59 pickle.ReadInt64(&iter, &internal_time)) { | 55 pickle.ReadInt64(&iter, &internal_time)) { |
60 #if defined(OS_POSIX) | 56 |
61 info->data_path = FilePath(data_path); | 57 info->data_path = fileapi::StringToFilePath(data_path); |
62 info->name = name; | 58 info->name = fileapi::StringToFilePath(name).value(); |
63 #elif defined(OS_WIN) | |
64 info->data_path = FilePath(base::SysUTF8ToWide(data_path)); | |
65 info->name = base::SysUTF8ToWide(name); | |
66 #endif | |
67 info->modification_time = base::Time::FromInternalValue(internal_time); | 59 info->modification_time = base::Time::FromInternalValue(internal_time); |
68 return true; | 60 return true; |
69 } | 61 } |
70 LOG(ERROR) << "Pickle could not be digested!"; | 62 LOG(ERROR) << "Pickle could not be digested!"; |
71 return false; | 63 return false; |
72 } | 64 } |
73 | 65 |
| 66 const FilePath::CharType kDirectoryDatabaseName[] = FILE_PATH_LITERAL("Paths"); |
74 const char kChildLookupPrefix[] = "CHILD_OF:"; | 67 const char kChildLookupPrefix[] = "CHILD_OF:"; |
75 const char kChildLookupSeparator[] = ":"; | 68 const char kChildLookupSeparator[] = ":"; |
76 const char kLastFileIdKey[] = "LAST_FILE_ID"; | 69 const char kLastFileIdKey[] = "LAST_FILE_ID"; |
77 const char kLastIntegerKey[] = "LAST_INTEGER"; | 70 const char kLastIntegerKey[] = "LAST_INTEGER"; |
78 const int64 kMinimumReportIntervalHours = 1; | 71 const int64 kMinimumReportIntervalHours = 1; |
79 const char kInitStatusHistogramLabel[] = "FileSystem.DirectoryDatabaseInit"; | 72 const char kInitStatusHistogramLabel[] = "FileSystem.DirectoryDatabaseInit"; |
80 | 73 |
81 enum InitStatus { | 74 enum InitStatus { |
82 INIT_STATUS_OK = 0, | 75 INIT_STATUS_OK = 0, |
83 INIT_STATUS_CORRUPTION, | 76 INIT_STATUS_CORRUPTION, |
84 INIT_STATUS_MAX | 77 INIT_STATUS_MAX |
85 }; | 78 }; |
86 | 79 |
87 std::string GetChildLookupKey( | 80 std::string GetChildLookupKey( |
88 fileapi::FileSystemDirectoryDatabase::FileId parent_id, | 81 fileapi::FileSystemDirectoryDatabase::FileId parent_id, |
89 const FilePath::StringType& child_name) { | 82 const FilePath::StringType& child_name) { |
90 std::string name; | 83 std::string name; |
91 #if defined(OS_POSIX) | 84 name = fileapi::FilePathToString(FilePath(child_name)); |
92 name = child_name; | |
93 #elif defined(OS_WIN) | |
94 name = base::SysWideToUTF8(child_name); | |
95 #endif | |
96 return std::string(kChildLookupPrefix) + base::Int64ToString(parent_id) + | 85 return std::string(kChildLookupPrefix) + base::Int64ToString(parent_id) + |
97 std::string(kChildLookupSeparator) + name; | 86 std::string(kChildLookupSeparator) + name; |
98 } | 87 } |
99 | 88 |
100 std::string GetChildListingKeyPrefix( | 89 std::string GetChildListingKeyPrefix( |
101 fileapi::FileSystemDirectoryDatabase::FileId parent_id) { | 90 fileapi::FileSystemDirectoryDatabase::FileId parent_id) { |
102 return std::string(kChildLookupPrefix) + base::Int64ToString(parent_id) + | 91 return std::string(kChildLookupPrefix) + base::Int64ToString(parent_id) + |
103 std::string(kChildLookupSeparator); | 92 std::string(kChildLookupSeparator); |
104 } | 93 } |
105 | 94 |
(...skipping 13 matching lines...) Expand all Loading... |
119 } // namespace | 108 } // namespace |
120 | 109 |
121 namespace fileapi { | 110 namespace fileapi { |
122 | 111 |
123 FileSystemDirectoryDatabase::FileInfo::FileInfo() : parent_id(0) { | 112 FileSystemDirectoryDatabase::FileInfo::FileInfo() : parent_id(0) { |
124 } | 113 } |
125 | 114 |
126 FileSystemDirectoryDatabase::FileInfo::~FileInfo() { | 115 FileSystemDirectoryDatabase::FileInfo::~FileInfo() { |
127 } | 116 } |
128 | 117 |
129 FileSystemDirectoryDatabase::FileSystemDirectoryDatabase(const FilePath& path) { | 118 FileSystemDirectoryDatabase::FileSystemDirectoryDatabase( |
130 #if defined(OS_POSIX) | 119 const FilePath& filesystem_data_directory) |
131 path_ = path.value(); | 120 : filesystem_data_directory_(filesystem_data_directory) { |
132 #elif defined(OS_WIN) | |
133 path_ = base::SysWideToUTF8(path.value()); | |
134 #endif | |
135 } | 121 } |
136 | 122 |
137 FileSystemDirectoryDatabase::~FileSystemDirectoryDatabase() { | 123 FileSystemDirectoryDatabase::~FileSystemDirectoryDatabase() { |
138 } | 124 } |
139 | 125 |
140 bool FileSystemDirectoryDatabase::GetChildWithName( | 126 bool FileSystemDirectoryDatabase::GetChildWithName( |
141 FileId parent_id, const FilePath::StringType& name, FileId* child_id) { | 127 FileId parent_id, const FilePath::StringType& name, FileId* child_id) { |
142 if (!Init()) | 128 if (!Init(FAIL_ON_CORRUPTION)) |
143 return false; | 129 return false; |
144 DCHECK(child_id); | 130 DCHECK(child_id); |
145 std::string child_key = GetChildLookupKey(parent_id, name); | 131 std::string child_key = GetChildLookupKey(parent_id, name); |
146 std::string child_id_string; | 132 std::string child_id_string; |
147 leveldb::Status status = | 133 leveldb::Status status = |
148 db_->Get(leveldb::ReadOptions(), child_key, &child_id_string); | 134 db_->Get(leveldb::ReadOptions(), child_key, &child_id_string); |
149 if (status.IsNotFound()) | 135 if (status.IsNotFound()) |
150 return false; | 136 return false; |
151 if (status.ok()) { | 137 if (status.ok()) { |
152 if (!base::StringToInt64(child_id_string, child_id)) { | 138 if (!base::StringToInt64(child_id_string, child_id)) { |
(...skipping 20 matching lines...) Expand all Loading... |
173 if (!GetChildWithName(local_id, name, &local_id)) | 159 if (!GetChildWithName(local_id, name, &local_id)) |
174 return false; | 160 return false; |
175 } | 161 } |
176 *file_id = local_id; | 162 *file_id = local_id; |
177 return true; | 163 return true; |
178 } | 164 } |
179 | 165 |
180 bool FileSystemDirectoryDatabase::ListChildren( | 166 bool FileSystemDirectoryDatabase::ListChildren( |
181 FileId parent_id, std::vector<FileId>* children) { | 167 FileId parent_id, std::vector<FileId>* children) { |
182 // Check to add later: fail if parent is a file, at least in debug builds. | 168 // Check to add later: fail if parent is a file, at least in debug builds. |
183 if (!Init()) | 169 if (!Init(FAIL_ON_CORRUPTION)) |
184 return false; | 170 return false; |
185 DCHECK(children); | 171 DCHECK(children); |
186 std::string child_key_prefix = GetChildListingKeyPrefix(parent_id); | 172 std::string child_key_prefix = GetChildListingKeyPrefix(parent_id); |
187 | 173 |
188 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); | 174 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); |
189 iter->Seek(child_key_prefix); | 175 iter->Seek(child_key_prefix); |
190 children->clear(); | 176 children->clear(); |
191 while (iter->Valid() && | 177 while (iter->Valid() && |
192 StartsWithASCII(iter->key().ToString(), child_key_prefix, true)) { | 178 StartsWithASCII(iter->key().ToString(), child_key_prefix, true)) { |
193 std::string child_id_string = iter->value().ToString(); | 179 std::string child_id_string = iter->value().ToString(); |
194 FileId child_id; | 180 FileId child_id; |
195 if (!base::StringToInt64(child_id_string, &child_id)) { | 181 if (!base::StringToInt64(child_id_string, &child_id)) { |
196 LOG(ERROR) << "Hit database corruption!"; | 182 LOG(ERROR) << "Hit database corruption!"; |
197 return false; | 183 return false; |
198 } | 184 } |
199 children->push_back(child_id); | 185 children->push_back(child_id); |
200 iter->Next(); | 186 iter->Next(); |
201 } | 187 } |
202 return true; | 188 return true; |
203 } | 189 } |
204 | 190 |
205 bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) { | 191 bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) { |
206 if (!Init()) | 192 if (!Init(FAIL_ON_CORRUPTION)) |
207 return false; | 193 return false; |
208 DCHECK(info); | 194 DCHECK(info); |
209 std::string file_key = GetFileLookupKey(file_id); | 195 std::string file_key = GetFileLookupKey(file_id); |
210 std::string file_data_string; | 196 std::string file_data_string; |
211 leveldb::Status status = | 197 leveldb::Status status = |
212 db_->Get(leveldb::ReadOptions(), file_key, &file_data_string); | 198 db_->Get(leveldb::ReadOptions(), file_key, &file_data_string); |
213 if (status.ok()) { | 199 if (status.ok()) { |
214 return FileInfoFromPickle( | 200 return FileInfoFromPickle( |
215 Pickle(file_data_string.data(), file_data_string.length()), info); | 201 Pickle(file_data_string.data(), file_data_string.length()), info); |
216 } | 202 } |
217 // Special-case the root, for databases that haven't been initialized yet. | 203 // Special-case the root, for databases that haven't been initialized yet. |
218 // Without this, a query for the root's file info, made before creating the | 204 // Without this, a query for the root's file info, made before creating the |
219 // first file in the database, will fail and confuse callers. | 205 // first file in the database, will fail and confuse callers. |
220 if (status.IsNotFound() && !file_id) { | 206 if (status.IsNotFound() && !file_id) { |
221 info->name = FilePath::StringType(); | 207 info->name = FilePath::StringType(); |
222 info->data_path = FilePath(); | 208 info->data_path = FilePath(); |
223 info->modification_time = base::Time::Now(); | 209 info->modification_time = base::Time::Now(); |
224 info->parent_id = 0; | 210 info->parent_id = 0; |
225 return true; | 211 return true; |
226 } | 212 } |
227 HandleError(FROM_HERE, status); | 213 HandleError(FROM_HERE, status); |
228 return false; | 214 return false; |
229 } | 215 } |
230 | 216 |
231 bool FileSystemDirectoryDatabase::AddFileInfo( | 217 bool FileSystemDirectoryDatabase::AddFileInfo( |
232 const FileInfo& info, FileId* file_id) { | 218 const FileInfo& info, FileId* file_id) { |
233 if (!Init()) | 219 if (!Init(FAIL_ON_CORRUPTION)) |
234 return false; | 220 return false; |
235 DCHECK(file_id); | 221 DCHECK(file_id); |
236 std::string child_key = GetChildLookupKey(info.parent_id, info.name); | 222 std::string child_key = GetChildLookupKey(info.parent_id, info.name); |
237 std::string child_id_string; | 223 std::string child_id_string; |
238 leveldb::Status status = | 224 leveldb::Status status = |
239 db_->Get(leveldb::ReadOptions(), child_key, &child_id_string); | 225 db_->Get(leveldb::ReadOptions(), child_key, &child_id_string); |
240 if (status.ok()) { | 226 if (status.ok()) { |
241 LOG(ERROR) << "File exists already!"; | 227 LOG(ERROR) << "File exists already!"; |
242 return false; | 228 return false; |
243 } | 229 } |
(...skipping 21 matching lines...) Expand all Loading... |
265 status = db_->Write(leveldb::WriteOptions(), &batch); | 251 status = db_->Write(leveldb::WriteOptions(), &batch); |
266 if (!status.ok()) { | 252 if (!status.ok()) { |
267 HandleError(FROM_HERE, status); | 253 HandleError(FROM_HERE, status); |
268 return false; | 254 return false; |
269 } | 255 } |
270 *file_id = temp_id; | 256 *file_id = temp_id; |
271 return true; | 257 return true; |
272 } | 258 } |
273 | 259 |
274 bool FileSystemDirectoryDatabase::RemoveFileInfo(FileId file_id) { | 260 bool FileSystemDirectoryDatabase::RemoveFileInfo(FileId file_id) { |
275 if (!Init()) | 261 if (!Init(FAIL_ON_CORRUPTION)) |
276 return false; | 262 return false; |
277 leveldb::WriteBatch batch; | 263 leveldb::WriteBatch batch; |
278 if (!RemoveFileInfoHelper(file_id, &batch)) | 264 if (!RemoveFileInfoHelper(file_id, &batch)) |
279 return false; | 265 return false; |
280 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); | 266 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); |
281 if (!status.ok()) { | 267 if (!status.ok()) { |
282 HandleError(FROM_HERE, status); | 268 HandleError(FROM_HERE, status); |
283 return false; | 269 return false; |
284 } | 270 } |
285 return true; | 271 return true; |
286 } | 272 } |
287 | 273 |
288 bool FileSystemDirectoryDatabase::UpdateFileInfo( | 274 bool FileSystemDirectoryDatabase::UpdateFileInfo( |
289 FileId file_id, const FileInfo& new_info) { | 275 FileId file_id, const FileInfo& new_info) { |
290 // TODO: We should also check to see that this doesn't create a loop, but | 276 // TODO: We should also check to see that this doesn't create a loop, but |
291 // perhaps only in a debug build. | 277 // perhaps only in a debug build. |
292 if (!Init()) | 278 if (!Init(FAIL_ON_CORRUPTION)) |
293 return false; | 279 return false; |
294 DCHECK(file_id); // You can't remove the root, ever. Just delete the DB. | 280 DCHECK(file_id); // You can't remove the root, ever. Just delete the DB. |
295 FileInfo old_info; | 281 FileInfo old_info; |
296 if (!GetFileInfo(file_id, &old_info)) | 282 if (!GetFileInfo(file_id, &old_info)) |
297 return false; | 283 return false; |
298 if (old_info.parent_id != new_info.parent_id && | 284 if (old_info.parent_id != new_info.parent_id && |
299 !VerifyIsDirectory(new_info.parent_id)) | 285 !VerifyIsDirectory(new_info.parent_id)) |
300 return false; | 286 return false; |
301 if (old_info.parent_id != new_info.parent_id || | 287 if (old_info.parent_id != new_info.parent_id || |
302 old_info.name != new_info.name) { | 288 old_info.name != new_info.name) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 pickle.size())); | 352 pickle.size())); |
367 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); | 353 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); |
368 if (!status.ok()) { | 354 if (!status.ok()) { |
369 HandleError(FROM_HERE, status); | 355 HandleError(FROM_HERE, status); |
370 return false; | 356 return false; |
371 } | 357 } |
372 return true; | 358 return true; |
373 } | 359 } |
374 | 360 |
375 bool FileSystemDirectoryDatabase::GetNextInteger(int64* next) { | 361 bool FileSystemDirectoryDatabase::GetNextInteger(int64* next) { |
376 if (!Init()) | 362 if (!Init(FAIL_ON_CORRUPTION)) |
377 return false; | 363 return false; |
378 DCHECK(next); | 364 DCHECK(next); |
379 std::string int_string; | 365 std::string int_string; |
380 leveldb::Status status = | 366 leveldb::Status status = |
381 db_->Get(leveldb::ReadOptions(), LastIntegerKey(), &int_string); | 367 db_->Get(leveldb::ReadOptions(), LastIntegerKey(), &int_string); |
382 if (status.ok()) { | 368 if (status.ok()) { |
383 int64 temp; | 369 int64 temp; |
384 if (!base::StringToInt64(int_string, &temp)) { | 370 if (!base::StringToInt64(int_string, &temp)) { |
385 LOG(ERROR) << "Hit database corruption!"; | 371 LOG(ERROR) << "Hit database corruption!"; |
386 return false; | 372 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
401 } | 387 } |
402 // The database must not yet exist; initialize it. | 388 // The database must not yet exist; initialize it. |
403 if (!StoreDefaultValues()) | 389 if (!StoreDefaultValues()) |
404 return false; | 390 return false; |
405 | 391 |
406 return GetNextInteger(next); | 392 return GetNextInteger(next); |
407 } | 393 } |
408 | 394 |
409 // static | 395 // static |
410 bool FileSystemDirectoryDatabase::DestroyDatabase(const FilePath& path) { | 396 bool FileSystemDirectoryDatabase::DestroyDatabase(const FilePath& path) { |
411 std::string name; | 397 std::string name = FilePathToString(path.Append(kDirectoryDatabaseName)); |
412 #if defined(OS_POSIX) | |
413 name = path.value(); | |
414 #elif defined(OS_WIN) | |
415 name = base::SysWideToUTF8(path.value()); | |
416 #endif | |
417 leveldb::Status status = leveldb::DestroyDB(name, leveldb::Options()); | 398 leveldb::Status status = leveldb::DestroyDB(name, leveldb::Options()); |
418 if (status.ok()) | 399 if (status.ok()) |
419 return true; | 400 return true; |
420 LOG(WARNING) << "Failed to destroy a database with status " << | 401 LOG(WARNING) << "Failed to destroy a database with status " << |
421 status.ToString(); | 402 status.ToString(); |
422 return false; | 403 return false; |
423 } | 404 } |
424 | 405 |
425 bool FileSystemDirectoryDatabase::Init() { | 406 bool FileSystemDirectoryDatabase::Init(RecoveryOption recovery_option) { |
426 if (db_.get()) | 407 if (db_.get()) |
427 return true; | 408 return true; |
428 | 409 |
429 leveldb::Options options; | 410 std::string path = |
430 options.create_if_missing = true; | 411 FilePathToString(filesystem_data_directory_.Append( |
431 leveldb::DB* db; | 412 kDirectoryDatabaseName)); |
432 leveldb::Status status = leveldb::DB::Open(options, path_, &db); | 413 leveldb::Options options; |
433 ReportInitStatus(status); | 414 options.create_if_missing = true; |
434 if (status.ok()) { | 415 leveldb::DB* db; |
435 db_.reset(db); | 416 leveldb::Status status = leveldb::DB::Open(options, path, &db); |
436 return true; | 417 ReportInitStatus(status); |
437 } | 418 if (status.ok()) { |
438 HandleError(FROM_HERE, status); | 419 db_.reset(db); |
439 return false; | 420 return true; |
| 421 } |
| 422 HandleError(FROM_HERE, status); |
| 423 |
| 424 if (recovery_option == FAIL_ON_CORRUPTION) |
| 425 return false; |
| 426 |
| 427 DCHECK_EQ(DELETE_ON_CORRUPTION, recovery_option); |
| 428 if (!file_util::Delete(filesystem_data_directory_, true)) |
| 429 return false; |
| 430 if (!file_util::CreateDirectory(filesystem_data_directory_)) |
| 431 return false; |
| 432 return Init(FAIL_ON_CORRUPTION); |
440 } | 433 } |
441 | 434 |
442 void FileSystemDirectoryDatabase::ReportInitStatus( | 435 void FileSystemDirectoryDatabase::ReportInitStatus( |
443 const leveldb::Status& status) { | 436 const leveldb::Status& status) { |
444 base::Time now = base::Time::Now(); | 437 base::Time now = base::Time::Now(); |
445 const base::TimeDelta minimum_interval = | 438 const base::TimeDelta minimum_interval = |
446 base::TimeDelta::FromHours(kMinimumReportIntervalHours); | 439 base::TimeDelta::FromHours(kMinimumReportIntervalHours); |
447 if (last_reported_time_ + minimum_interval >= now) | 440 if (last_reported_time_ + minimum_interval >= now) |
448 return; | 441 return; |
449 last_reported_time_ = now; | 442 last_reported_time_ = now; |
(...skipping 27 matching lines...) Expand all Loading... |
477 batch.Put(LastIntegerKey(), base::Int64ToString(-1)); | 470 batch.Put(LastIntegerKey(), base::Int64ToString(-1)); |
478 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); | 471 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); |
479 if (!status.ok()) { | 472 if (!status.ok()) { |
480 HandleError(FROM_HERE, status); | 473 HandleError(FROM_HERE, status); |
481 return false; | 474 return false; |
482 } | 475 } |
483 return true; | 476 return true; |
484 } | 477 } |
485 | 478 |
486 bool FileSystemDirectoryDatabase::GetLastFileId(FileId* file_id) { | 479 bool FileSystemDirectoryDatabase::GetLastFileId(FileId* file_id) { |
487 if (!Init()) | 480 if (!Init(FAIL_ON_CORRUPTION)) |
488 return false; | 481 return false; |
489 DCHECK(file_id); | 482 DCHECK(file_id); |
490 std::string id_string; | 483 std::string id_string; |
491 leveldb::Status status = | 484 leveldb::Status status = |
492 db_->Get(leveldb::ReadOptions(), LastFileIdKey(), &id_string); | 485 db_->Get(leveldb::ReadOptions(), LastFileIdKey(), &id_string); |
493 if (status.ok()) { | 486 if (status.ok()) { |
494 if (!base::StringToInt64(id_string, file_id)) { | 487 if (!base::StringToInt64(id_string, file_id)) { |
495 LOG(ERROR) << "Hit database corruption!"; | 488 LOG(ERROR) << "Hit database corruption!"; |
496 return false; | 489 return false; |
497 } | 490 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 | 560 |
568 void FileSystemDirectoryDatabase::HandleError( | 561 void FileSystemDirectoryDatabase::HandleError( |
569 const tracked_objects::Location& from_here, | 562 const tracked_objects::Location& from_here, |
570 const leveldb::Status& status) { | 563 const leveldb::Status& status) { |
571 LOG(ERROR) << "FileSystemDirectoryDatabase failed at: " | 564 LOG(ERROR) << "FileSystemDirectoryDatabase failed at: " |
572 << from_here.ToString() << " with error: " << status.ToString(); | 565 << from_here.ToString() << " with error: " << status.ToString(); |
573 db_.reset(); | 566 db_.reset(); |
574 } | 567 } |
575 | 568 |
576 } // namespace fileapi | 569 } // namespace fileapi |
OLD | NEW |