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/dom_storage/session_storage_database.h" | 5 #include "webkit/dom_storage/session_storage_database.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 // | namespace-3-origin2 | 2 (shallow copy) | | 34 // | namespace-3-origin2 | 2 (shallow copy) | |
35 // | next-namespace-id | 4 | | 35 // | next-namespace-id | 4 | |
36 // | next-map-id | 4 | | 36 // | next-map-id | 4 | |
37 | 37 |
38 namespace dom_storage { | 38 namespace dom_storage { |
39 | 39 |
40 SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path) | 40 SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path) |
41 : file_path_(file_path), | 41 : file_path_(file_path), |
42 db_error_(false), | 42 db_error_(false), |
43 is_inconsistent_(false), | 43 is_inconsistent_(false), |
44 namespace_offset_(0) { | 44 next_namespace_id_(0), |
| 45 next_negative_namespace_id_(-1) { |
| 46 } |
| 47 |
| 48 SessionStorageDatabase::SessionStorageDatabase( |
| 49 const FilePath& file_path, |
| 50 const SessionStorageAssociatedCallback& associated_callback) |
| 51 : file_path_(file_path), |
| 52 db_error_(false), |
| 53 is_inconsistent_(false), |
| 54 next_namespace_id_(0), |
| 55 next_negative_namespace_id_(-1), |
| 56 associated_callback_(associated_callback) { |
45 } | 57 } |
46 | 58 |
47 SessionStorageDatabase::~SessionStorageDatabase() { | 59 SessionStorageDatabase::~SessionStorageDatabase() { |
48 } | 60 } |
49 | 61 |
50 void SessionStorageDatabase::ReadAreaValues(int64 namespace_id, | 62 void SessionStorageDatabase::ReadAreaValues(int64 namespace_id, |
51 const GURL& origin, | 63 const GURL& origin, |
52 ValuesMap* result) { | 64 ValuesMap* result) { |
53 // We don't create a database if it doesn't exist. In that case, there is | 65 // We don't create a database if it doesn't exist. In that case, there is |
54 // nothing to be added to the result. | 66 // nothing to be added to the result. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 return DatabaseErrorCheck(s.ok()); | 164 return DatabaseErrorCheck(s.ok()); |
153 } | 165 } |
154 | 166 |
155 bool SessionStorageDatabase::DeleteArea(int64 namespace_id, | 167 bool SessionStorageDatabase::DeleteArea(int64 namespace_id, |
156 const GURL& origin) { | 168 const GURL& origin) { |
157 if (!LazyOpen(false)) { | 169 if (!LazyOpen(false)) { |
158 // No need to create the database if it doesn't exist. | 170 // No need to create the database if it doesn't exist. |
159 return true; | 171 return true; |
160 } | 172 } |
161 leveldb::WriteBatch batch; | 173 leveldb::WriteBatch batch; |
162 if (!DeleteArea(namespace_id, origin.spec(), &batch)) | 174 if (!DeleteAreaHelper(namespace_id, origin.spec(), &batch)) |
163 return false; | 175 return false; |
164 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); | 176 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); |
165 return DatabaseErrorCheck(s.ok()); | 177 return DatabaseErrorCheck(s.ok()); |
166 } | 178 } |
167 | 179 |
168 bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) { | 180 bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) { |
169 if (!LazyOpen(false)) { | 181 if (!LazyOpen(false)) { |
170 // No need to create the database if it doesn't exist. | 182 // No need to create the database if it doesn't exist. |
171 return true; | 183 return true; |
172 } | 184 } |
173 // Itereate through the areas in the namespace. | 185 // Itereate through the areas in the namespace. |
174 leveldb::WriteBatch batch; | 186 leveldb::WriteBatch batch; |
175 std::map<std::string, std::string> areas; | 187 std::map<std::string, std::string> areas; |
176 if (!GetAreasInNamespace(namespace_id, &areas)) | 188 if (!GetAreasInNamespace(namespace_id, &areas)) |
177 return false; | 189 return false; |
178 for (std::map<std::string, std::string>::const_iterator it = areas.begin(); | 190 for (std::map<std::string, std::string>::const_iterator it = areas.begin(); |
179 it != areas.end(); ++it) { | 191 it != areas.end(); ++it) { |
180 const std::string& origin = it->first; | 192 const std::string& origin = it->first; |
181 if (!DeleteArea(namespace_id, origin, &batch)) | 193 if (!DeleteAreaHelper(namespace_id, origin, &batch)) |
182 return false; | 194 return false; |
183 } | 195 } |
184 batch.Delete(NamespaceStartKey(namespace_id, namespace_offset_)); | 196 batch.Delete(NamespaceStartKey(namespace_id)); |
185 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); | 197 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch); |
186 return DatabaseErrorCheck(s.ok()); | 198 return DatabaseErrorCheck(s.ok()); |
187 } | 199 } |
188 | 200 |
| 201 bool SessionStorageDatabase::ReadNamespaceIds( |
| 202 std::vector<int64>* namespace_ids) { |
| 203 if (!LazyOpen(true)) |
| 204 return false; |
| 205 |
| 206 std::string namespace_prefix = NamespacePrefix(); |
| 207 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
| 208 it->Seek(namespace_prefix); |
| 209 if (it->status().IsNotFound()) |
| 210 return true; |
| 211 |
| 212 if (!DatabaseErrorCheck(it->status().ok())) |
| 213 return false; |
| 214 |
| 215 // Skip the dummy entry "namespace-" and iterate the namespaces. |
| 216 for (it->Next(); it->Valid(); it->Next()) { |
| 217 std::string key = it->key().ToString(); |
| 218 if (key.find(namespace_prefix) != 0) { |
| 219 // Iterated past the "namespace-" keys. |
| 220 break; |
| 221 } |
| 222 size_t second_dash = key.find('-', namespace_prefix.length()); |
| 223 if (second_dash != std::string::npos) |
| 224 continue; |
| 225 |
| 226 // The key is of the form "namespace-<namespaceid>". |
| 227 std::string namespace_id_str = key.substr(namespace_prefix.length()); |
| 228 int64 real_namespace_id; |
| 229 bool conversion_ok = |
| 230 base::StringToInt64(namespace_id_str, &real_namespace_id); |
| 231 if (!ConsistencyCheck(conversion_ok)) |
| 232 return false; |
| 233 std::map<int64, int64>::const_iterator it = |
| 234 real_id_to_id_.find(real_namespace_id); |
| 235 if (it != real_id_to_id_.end()) { |
| 236 namespace_ids->push_back(it->second); |
| 237 } else { |
| 238 // There is no known upper layer ID for this namespace. Create one. (The |
| 239 // upper layer will only create positive IDs, so this won't overlap with |
| 240 // the IDs created by it.) |
| 241 int64 upper_layer_id = next_negative_namespace_id_--; |
| 242 AssociateNamespaceId(upper_layer_id, real_namespace_id); |
| 243 namespace_ids->push_back(upper_layer_id); |
| 244 } |
| 245 } |
| 246 return true; |
| 247 } |
| 248 |
| 249 void SessionStorageDatabase::AssociateNamespaceId(int64 namespace_id, |
| 250 int64 real_id) { |
| 251 id_to_real_id_[namespace_id] = real_id; |
| 252 real_id_to_id_[real_id] = namespace_id; |
| 253 } |
| 254 |
189 bool SessionStorageDatabase::LazyOpen(bool create_if_needed) { | 255 bool SessionStorageDatabase::LazyOpen(bool create_if_needed) { |
190 base::AutoLock auto_lock(db_lock_); | 256 base::AutoLock auto_lock(db_lock_); |
191 if (db_error_ || is_inconsistent_) { | 257 if (db_error_ || is_inconsistent_) { |
192 // Don't try to open a database that we know has failed already. | 258 // Don't try to open a database that we know has failed already. |
193 return false; | 259 return false; |
194 } | 260 } |
195 if (IsOpen()) | 261 if (IsOpen()) |
196 return true; | 262 return true; |
197 | 263 |
198 if (!create_if_needed && | 264 if (!create_if_needed && |
(...skipping 18 matching lines...) Expand all Loading... |
217 s = TryToOpen(&db); | 283 s = TryToOpen(&db); |
218 if (!s.ok()) { | 284 if (!s.ok()) { |
219 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value() | 285 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value() |
220 << ", error: " << s.ToString(); | 286 << ", error: " << s.ToString(); |
221 DCHECK(db == NULL); | 287 DCHECK(db == NULL); |
222 db_error_ = true; | 288 db_error_ = true; |
223 return false; | 289 return false; |
224 } | 290 } |
225 } | 291 } |
226 db_.reset(db); | 292 db_.reset(db); |
227 | 293 return GetNextNamespaceId(&next_namespace_id_); |
228 return GetNextNamespaceId(&namespace_offset_); | |
229 } | 294 } |
230 | 295 |
231 leveldb::Status SessionStorageDatabase::TryToOpen(leveldb::DB** db) { | 296 leveldb::Status SessionStorageDatabase::TryToOpen(leveldb::DB** db) { |
232 leveldb::Options options; | 297 leveldb::Options options; |
233 // The directory exists but a valid leveldb database might not exist inside it | 298 // The directory exists but a valid leveldb database might not exist inside it |
234 // (e.g., a subset of the needed files might be missing). Handle this | 299 // (e.g., a subset of the needed files might be missing). Handle this |
235 // situation gracefully by creating the database now. | 300 // situation gracefully by creating the database now. |
236 options.create_if_missing = true; | 301 options.create_if_missing = true; |
237 #if defined(OS_WIN) | 302 #if defined(OS_WIN) |
238 return leveldb::DB::Open(options, WideToUTF8(file_path_.value()), db); | 303 return leveldb::DB::Open(options, WideToUTF8(file_path_.value()), db); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 leveldb::WriteBatch* batch) { | 342 leveldb::WriteBatch* batch) { |
278 leveldb::Slice namespace_prefix = NamespacePrefix(); | 343 leveldb::Slice namespace_prefix = NamespacePrefix(); |
279 std::string dummy; | 344 std::string dummy; |
280 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_prefix, | 345 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_prefix, |
281 &dummy); | 346 &dummy); |
282 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) | 347 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) |
283 return false; | 348 return false; |
284 if (s.IsNotFound()) | 349 if (s.IsNotFound()) |
285 batch->Put(namespace_prefix, ""); | 350 batch->Put(namespace_prefix, ""); |
286 | 351 |
287 std::string namespace_start_key = | 352 std::string namespace_start_key = NamespaceStartKey(namespace_id); |
288 NamespaceStartKey(namespace_id, namespace_offset_); | |
289 s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy); | 353 s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy); |
290 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) | 354 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound())) |
291 return false; | 355 return false; |
292 if (s.IsNotFound()) { | 356 if (s.IsNotFound()) { |
293 batch->Put(namespace_start_key, ""); | 357 batch->Put(namespace_start_key, ""); |
294 return UpdateNextNamespaceId(namespace_id, batch); | 358 return UpdateNextNamespaceId(namespace_id, batch); |
295 } | 359 } |
296 return CallerErrorCheck(ok_if_exists); | 360 return CallerErrorCheck(ok_if_exists); |
297 } | 361 } |
298 | 362 |
(...skipping 10 matching lines...) Expand all Loading... |
309 bool conversion_ok = | 373 bool conversion_ok = |
310 base::StringToInt64(next_namespace_id_string, next_namespace_id); | 374 base::StringToInt64(next_namespace_id_string, next_namespace_id); |
311 return ConsistencyCheck(conversion_ok); | 375 return ConsistencyCheck(conversion_ok); |
312 } | 376 } |
313 | 377 |
314 bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id, | 378 bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id, |
315 leveldb::WriteBatch* batch) { | 379 leveldb::WriteBatch* batch) { |
316 int64 next_namespace_id; | 380 int64 next_namespace_id; |
317 if (!GetNextNamespaceId(&next_namespace_id)) | 381 if (!GetNextNamespaceId(&next_namespace_id)) |
318 return false; | 382 return false; |
319 if (next_namespace_id < namespace_id + namespace_offset_ + 1) { | 383 int64 real_id; |
320 next_namespace_id = namespace_id + namespace_offset_ + 1; | 384 if (!GetRealId(namespace_id, &real_id)) |
| 385 return false; |
| 386 if (next_namespace_id < real_id + 1) { |
| 387 next_namespace_id = real_id + 1; |
321 batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id)); | 388 batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id)); |
322 } | 389 } |
323 return true; | 390 return true; |
324 } | 391 } |
325 | 392 |
326 bool SessionStorageDatabase::GetAreasInNamespace( | 393 bool SessionStorageDatabase::GetAreasInNamespace( |
327 int64 namespace_id, | 394 int64 namespace_id, |
328 std::map<std::string, std::string>* areas) { | 395 std::map<std::string, std::string>* areas) { |
329 return GetAreasInNamespace(NamespaceIdStr(namespace_id, namespace_offset_), | 396 return GetAreasInNamespace(NamespaceIdStr(namespace_id), areas); |
330 areas); | |
331 } | 397 } |
332 | 398 |
333 bool SessionStorageDatabase::GetAreasInNamespace( | 399 bool SessionStorageDatabase::GetAreasInNamespace( |
334 const std::string& namespace_id_str, | 400 const std::string& namespace_id_str, |
335 std::map<std::string, std::string>* areas) { | 401 std::map<std::string, std::string>* areas) { |
336 std::string namespace_start_key = NamespaceStartKey(namespace_id_str); | 402 std::string namespace_start_key = NamespaceStartKey(namespace_id_str); |
337 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); | 403 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
338 it->Seek(namespace_start_key); | 404 it->Seek(namespace_start_key); |
339 if (it->status().IsNotFound()) { | 405 if (it->status().IsNotFound()) { |
340 // The namespace_start_key is not found when the namespace doesn't contain | 406 // The namespace_start_key is not found when the namespace doesn't contain |
341 // any areas. We don't need to do anything. | 407 // any areas. We don't need to do anything. |
342 return true; | 408 return true; |
343 } | 409 } |
344 if (!DatabaseErrorCheck(it->status().ok())) | 410 if (!DatabaseErrorCheck(it->status().ok())) |
345 return false; | 411 return false; |
346 | 412 |
347 // Skip the dummy entry "namespace-<namespaceid>" and iterate the origins. | 413 // Skip the dummy entry "namespace-<namespaceid>" and iterate the origins. |
348 for (it->Next(); it->Valid(); it->Next()) { | 414 for (it->Next(); it->Valid(); it->Next()) { |
349 std::string key = it->key().ToString(); | 415 std::string key = it->key().ToString(); |
350 if (key.find(namespace_start_key) != 0) { | 416 if (key.find(namespace_start_key) != 0) { |
351 // Iterated past the origins for this namespace. | 417 // Iterated past the origins for this namespace. |
352 break; | 418 break; |
353 } | 419 } |
354 size_t second_dash = key.find('-', namespace_start_key.length()); | 420 size_t second_dash = key.find('-', namespace_start_key.length()); |
355 if (!ConsistencyCheck(second_dash != std::string::npos)) | 421 if (second_dash == std::string::npos) |
356 return false; | 422 break; |
357 std::string origin = key.substr(second_dash + 1); | 423 std::string origin = key.substr(second_dash + 1); |
358 std::string map_id = it->value().ToString(); | 424 std::string map_id = it->value().ToString(); |
359 (*areas)[origin] = map_id; | 425 (*areas)[origin] = map_id; |
360 } | 426 } |
361 return true; | 427 return true; |
362 } | 428 } |
363 | 429 |
364 void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id, | 430 void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id, |
365 const std::string& origin, | 431 const std::string& origin, |
366 const std::string& map_id, | 432 const std::string& map_id, |
367 leveldb::WriteBatch* batch) { | 433 leveldb::WriteBatch* batch) { |
368 std::string namespace_key = NamespaceKey( | 434 std::string namespace_key = |
369 NamespaceIdStr(namespace_id, namespace_offset_), origin); | 435 NamespaceKey(NamespaceIdStr(namespace_id), origin); |
370 batch->Put(namespace_key, map_id); | 436 batch->Put(namespace_key, map_id); |
371 } | 437 } |
372 | 438 |
373 bool SessionStorageDatabase::DeleteArea(int64 namespace_id, | 439 bool SessionStorageDatabase::DeleteAreaHelper(int64 namespace_id, |
374 const std::string& origin, | 440 const std::string& origin, |
375 leveldb::WriteBatch* batch) { | 441 leveldb::WriteBatch* batch) { |
376 return DeleteArea(NamespaceIdStr(namespace_id, namespace_offset_), | 442 return DeleteAreaHelper(NamespaceIdStr(namespace_id), origin, batch); |
377 origin, batch); | |
378 } | 443 } |
379 | 444 |
380 bool SessionStorageDatabase::DeleteArea(const std::string& namespace_id_str, | 445 bool SessionStorageDatabase::DeleteAreaHelper( |
381 const std::string& origin, | 446 const std::string& namespace_id_str, |
382 leveldb::WriteBatch* batch) { | 447 const std::string& origin, |
| 448 leveldb::WriteBatch* batch) { |
383 std::string map_id; | 449 std::string map_id; |
384 bool exists; | 450 bool exists; |
385 if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id)) | 451 if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id)) |
386 return false; | 452 return false; |
387 if (!exists) | 453 if (!exists) |
388 return true; // Nothing to delete. | 454 return true; // Nothing to delete. |
389 if (!DecreaseMapRefCount(map_id, 1, batch)) | 455 if (!DecreaseMapRefCount(map_id, 1, batch)) |
390 return false; | 456 return false; |
391 std::string namespace_key = NamespaceKey(namespace_id_str, origin); | 457 std::string namespace_key = NamespaceKey(namespace_id_str, origin); |
392 batch->Delete(namespace_key); | 458 batch->Delete(namespace_key); |
393 return true; | 459 return true; |
394 } | 460 } |
395 | 461 |
396 bool SessionStorageDatabase::GetMapForArea(int64 namespace_id, | 462 bool SessionStorageDatabase::GetMapForArea(int64 namespace_id, |
397 const GURL& origin, | 463 const GURL& origin, |
398 bool* exists, | 464 bool* exists, |
399 std::string* map_id) { | 465 std::string* map_id) { |
400 return GetMapForArea( | 466 int64 real_id; |
401 base::Int64ToString(namespace_id + namespace_offset_), | 467 if (!GetRealId(namespace_id, &real_id)) |
402 origin.spec(), exists, map_id); | 468 return false; |
| 469 return GetMapForArea(base::Int64ToString(real_id), origin.spec(), |
| 470 exists, map_id); |
403 } | 471 } |
404 | 472 |
405 bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str, | 473 bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str, |
406 const std::string& origin, | 474 const std::string& origin, |
407 bool* exists, std::string* map_id) { | 475 bool* exists, std::string* map_id) { |
408 std::string namespace_key = NamespaceKey(namespace_id_str, origin); | 476 std::string namespace_key = NamespaceKey(namespace_id_str, origin); |
409 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_key, map_id); | 477 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_key, map_id); |
410 if (s.IsNotFound()) { | 478 if (s.IsNotFound()) { |
411 *exists = false; | 479 *exists = false; |
412 return true; | 480 return true; |
(...skipping 12 matching lines...) Expand all Loading... |
425 return false; | 493 return false; |
426 int64 next_map_id = 0; | 494 int64 next_map_id = 0; |
427 if (s.IsNotFound()) { | 495 if (s.IsNotFound()) { |
428 *map_id = "0"; | 496 *map_id = "0"; |
429 } else { | 497 } else { |
430 bool conversion_ok = base::StringToInt64(*map_id, &next_map_id); | 498 bool conversion_ok = base::StringToInt64(*map_id, &next_map_id); |
431 if (!ConsistencyCheck(conversion_ok)) | 499 if (!ConsistencyCheck(conversion_ok)) |
432 return false; | 500 return false; |
433 } | 501 } |
434 batch->Put(next_map_id_key, base::Int64ToString(++next_map_id)); | 502 batch->Put(next_map_id_key, base::Int64ToString(++next_map_id)); |
435 std::string namespace_key = | 503 std::string namespace_key = NamespaceKey(namespace_id, origin); |
436 NamespaceKey(namespace_id, namespace_offset_, origin); | |
437 batch->Put(namespace_key, *map_id); | 504 batch->Put(namespace_key, *map_id); |
438 batch->Put(MapRefCountKey(*map_id), "1"); | 505 batch->Put(MapRefCountKey(*map_id), "1"); |
439 return true; | 506 return true; |
440 } | 507 } |
441 | 508 |
442 bool SessionStorageDatabase::ReadMap(const std::string& map_id, | 509 bool SessionStorageDatabase::ReadMap(const std::string& map_id, |
443 ValuesMap* result, | 510 ValuesMap* result, |
444 bool only_keys) { | 511 bool only_keys) { |
445 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); | 512 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
446 std::string map_start_key = MapRefCountKey(map_id); | 513 std::string map_start_key = MapRefCountKey(map_id); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 return false; | 644 return false; |
578 // Create a new map (this will also break the association to the old map) and | 645 // Create a new map (this will also break the association to the old map) and |
579 // write the old data into it. This will write the id of the created map into | 646 // write the old data into it. This will write the id of the created map into |
580 // |map_id|. | 647 // |map_id|. |
581 if (!CreateMapForArea(namespace_id, origin, map_id, batch)) | 648 if (!CreateMapForArea(namespace_id, origin, map_id, batch)) |
582 return false; | 649 return false; |
583 WriteValuesToMap(*map_id, values, batch); | 650 WriteValuesToMap(*map_id, values, batch); |
584 return true; | 651 return true; |
585 } | 652 } |
586 | 653 |
| 654 bool SessionStorageDatabase::AllocateNamespaceId(int64* namespace_id) { |
| 655 if (!LazyOpen(true)) |
| 656 return false; |
| 657 *namespace_id = next_namespace_id_++; |
| 658 // The next namespace id field in the db will be increased when data is |
| 659 // actually written to the namespace. |
| 660 return true; |
| 661 } |
| 662 |
| 663 bool SessionStorageDatabase::GetRealId(int64 namespace_id, int64* real_id) { |
| 664 std::map<int64, int64>::const_iterator it = id_to_real_id_.find(namespace_id); |
| 665 if (it != id_to_real_id_.end()) { |
| 666 *real_id = it->second; |
| 667 return true; |
| 668 } |
| 669 if (!AllocateNamespaceId(real_id)) |
| 670 return false; |
| 671 if (!associated_callback_.is_null()) |
| 672 associated_callback_.Run(namespace_id, *real_id); |
| 673 AssociateNamespaceId(namespace_id, *real_id); |
| 674 return true; |
| 675 } |
| 676 |
587 std::string SessionStorageDatabase::NamespaceStartKey( | 677 std::string SessionStorageDatabase::NamespaceStartKey( |
588 const std::string& namespace_id_str) { | 678 const std::string& namespace_id_str) { |
589 return base::StringPrintf("namespace-%s", namespace_id_str.c_str()); | 679 return base::StringPrintf("namespace-%s", namespace_id_str.c_str()); |
590 } | 680 } |
591 | 681 |
592 std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id, | 682 std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id) { |
593 int64 namespace_offset) { | 683 return NamespaceStartKey(NamespaceIdStr(namespace_id)); |
594 return NamespaceStartKey(NamespaceIdStr(namespace_id, namespace_offset)); | |
595 } | 684 } |
596 | 685 |
597 std::string SessionStorageDatabase::NamespaceKey( | 686 std::string SessionStorageDatabase::NamespaceKey( |
598 const std::string& namespace_id_str, const std::string& origin) { | 687 const std::string& namespace_id_str, const std::string& origin) { |
599 return base::StringPrintf("namespace-%s-%s", namespace_id_str.c_str(), | 688 return base::StringPrintf("namespace-%s-%s", namespace_id_str.c_str(), |
600 origin.c_str()); | 689 origin.c_str()); |
601 } | 690 } |
602 | 691 |
603 std::string SessionStorageDatabase::NamespaceKey( | 692 std::string SessionStorageDatabase::NamespaceKey(int64 namespace_id, |
604 int64 namespace_id, int64 namespace_offset, const GURL& origin) { | 693 const GURL& origin) { |
605 return NamespaceKey(NamespaceIdStr(namespace_id, namespace_offset), | 694 return NamespaceKey(NamespaceIdStr(namespace_id), origin.spec()); |
606 origin.spec()); | |
607 } | 695 } |
608 | 696 |
609 std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id, | 697 std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id) { |
610 int64 namespace_offset) { | 698 int64 real_id; |
611 return base::Int64ToString(namespace_id + namespace_offset); | 699 if (!GetRealId(namespace_id, &real_id)) |
| 700 return ""; |
| 701 return base::Int64ToString(real_id); |
612 } | 702 } |
613 | 703 |
614 const char* SessionStorageDatabase::NamespacePrefix() { | 704 const char* SessionStorageDatabase::NamespacePrefix() { |
615 return "namespace-"; | 705 return "namespace-"; |
616 } | 706 } |
617 | 707 |
618 std::string SessionStorageDatabase::MapRefCountKey(const std::string& map_id) { | 708 std::string SessionStorageDatabase::MapRefCountKey(const std::string& map_id) { |
619 return base::StringPrintf("map-%s", map_id.c_str()); | 709 return base::StringPrintf("map-%s", map_id.c_str()); |
620 } | 710 } |
621 | 711 |
622 std::string SessionStorageDatabase::MapKey(const std::string& map_id, | 712 std::string SessionStorageDatabase::MapKey(const std::string& map_id, |
623 const std::string& key) { | 713 const std::string& key) { |
624 return base::StringPrintf("map-%s-%s", map_id.c_str(), key.c_str()); | 714 return base::StringPrintf("map-%s-%s", map_id.c_str(), key.c_str()); |
625 } | 715 } |
626 | 716 |
627 const char* SessionStorageDatabase::MapPrefix() { | 717 const char* SessionStorageDatabase::MapPrefix() { |
628 return "map-"; | 718 return "map-"; |
629 } | 719 } |
630 | 720 |
631 const char* SessionStorageDatabase::NextNamespaceIdKey() { | 721 const char* SessionStorageDatabase::NextNamespaceIdKey() { |
632 return "next-namespace-id"; | 722 return "next-namespace-id"; |
633 } | 723 } |
634 | 724 |
635 const char* SessionStorageDatabase::NextMapIdKey() { | 725 const char* SessionStorageDatabase::NextMapIdKey() { |
636 return "next-map-id"; | 726 return "next-map-id"; |
637 } | 727 } |
638 | 728 |
639 } // namespace dom_storage | 729 } // namespace dom_storage |
OLD | NEW |