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

Side by Side Diff: webkit/dom_storage/session_storage_database.cc

Issue 10176005: Add dom_storage::SessionStorageDatabase. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "webkit/dom_storage/session_storage_database.h"
6
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "base/stringprintf.h"
10 #include "base/string_number_conversions.h"
11 #include "base/utf_string_conversions.h"
12 #include "googleurl/src/gurl.h"
13 #include "third_party/leveldatabase/src/include/leveldb/db.h"
14 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
15 #include "third_party/leveldatabase/src/include/leveldb/status.h"
16 #include "third_party/leveldatabase/src/include/leveldb/options.h"
17 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
18
19 // Layout of the database:
20 // | key | value |
21 // -----------------------------------------------------------------------
22 // | map-1 | 2 (refcount, start of map-1-* keys)|
23 // | map-1-a | b (a = b in map 1) |
24 // | ... | |
25 // | namespace- | dummy (start of namespace-* keys) |
26 // | namespace-1 (1 = namespace id) | dummy (start of namespace-1-* keys)|
27 // | namespace-1-origin1 | 1 (mapid) |
28 // | namespace-1-origin2 | 2 |
29 // | namespace-2 | dummy |
30 // | namespace-2-origin1 | 1 (shallow copy) |
31 // | namespace-2-origin2 | 2 (shallow copy) |
32 // | namespace-3 | dummy |
33 // | namespace-3-origin1 | 3 (deep copy) |
34 // | namespace-3-origin2 | 2 (shallow copy) |
35 // | next-namespace-id | 4 |
36 // | next-map-id | 4 |
37
38 namespace dom_storage {
39
40 SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path)
41 : file_path_(file_path),
42 db_error_(false),
43 is_inconsistent_(false),
44 namespace_offset_(0) { }
45
46 SessionStorageDatabase::~SessionStorageDatabase() {
47 }
48
49 void SessionStorageDatabase::ReadAreaValues(int64 namespace_id,
50 const GURL& origin,
51 ValuesMap* result) {
52 // We don't create a database if it doesn't exist. In that case, there is
53 // nothing to be added to the result.
54 if (!LazyOpen(false))
55 return;
56 std::string map_id;
57 bool exists;
58 if (!GetMapForArea(namespace_id, origin, &exists, &map_id))
59 return;
60 if (exists)
61 ReadMap(map_id, result, false);
62 }
63
64 bool SessionStorageDatabase::CommitAreaChanges(int64 namespace_id,
65 const GURL& origin,
66 bool clear_all_first,
67 const ValuesMap& changes) {
68 // Even if |changes| is empty, we need to write the appropriate placeholders
69 // in the database, so that it can be later shallow-copied succssfully.
70 if (!LazyOpen(true))
71 return false;
72
73 leveldb::WriteBatch batch;
74 // Ensure that the keys "namespace-" "namespace-N" (see the schema above)
75 // exist.
76 if (!CreateNamespace(namespace_id, true, &batch))
michaeln 2012/04/26 05:07:43 webkit style rubbing off on me too much maybe... m
marja 2012/04/27 07:34:47 Done.
77 return false;
78
79 std::string map_id;
80 bool exists;
81 if (!GetMapForArea(namespace_id, origin, &exists, &map_id))
82 return false;
83 if (exists) {
84 // We shouldn't write data to a shallow copy.
85 int64 ref_count;
86 if (!GetMapRefCount(map_id, &ref_count))
87 return false;
88 if (!ConsistencyCheck(ref_count == 1))
michaeln 2012/04/26 05:07:43 This feel like a programming error more than a dat
marja 2012/04/27 07:34:47 Done, added CallerErrorCheck which will be called
89 return false;
90 if (clear_all_first) {
91 if (!ClearMap(map_id, &batch))
92 return false;
93 }
94 } else {
95 // Map doesn't exist, create it now if needed.
96 if (!changes.empty()) {
97 if (!CreateMapForArea(namespace_id, origin, &map_id, &batch))
98 return false;
99 }
100 }
101
102 WriteValuesToMap(map_id, changes, &batch);
103
104 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
105 return DatabaseErrorCheck(s.ok());
106 }
107
108 bool SessionStorageDatabase::CloneNamespace(int64 namespace_id,
109 int64 new_namespace_id) {
110 // Go through all origins in the namespace |namespace_id|, create placeholders
111 // for them in |new_namespace_id|, and associate them with the existing maps.
112
113 // Example, data before shallow copy:
114 // | map-1 | 1 (refcount) |
115 // | map-1-a | b |
116 // | namespace-1 (1 = namespace id) | dummy |
117 // | namespace-1-origin1 | 1 (mapid) |
118
119 // Example, data after shallow copy:
120 // | map-1 | 2 (inc. refcount) |
121 // | map-1-a | b |
122 // | namespace-1 (1 = namespace id) | dummy |
123 // | namespace-1-origin1 | 1 (mapid) |
124 // | namespace-2 | dummy |
125 // | namespace-2-origin1 | 1 (mapid) << references the same map
126
127 if (!LazyOpen(true))
128 return false;
129
130 leveldb::WriteBatch batch;
131 if (!CreateNamespace(new_namespace_id, false, &batch))
michaeln 2012/04/26 05:07:43 simlarly, const bool kFailIfExists = false local f
marja 2012/04/27 07:34:47 Done.
132 return false;
133
134 std::map<std::string, std::string> areas;
135 if (!GetAreasInNamespace(namespace_id, &areas))
136 return false;
137
138 for (std::map<std::string, std::string>::const_iterator it = areas.begin();
139 it != areas.end(); ++it) {
140 const std::string& origin = it->first;
141 const std::string& map_id = it->second;
142 if (!IncreaseMapRefCount(map_id, &batch))
143 return false;
144 AddAreaToNamespace(new_namespace_id, origin, map_id, &batch);
145 }
146 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
147 return DatabaseErrorCheck(s.ok());
148 }
149
150 bool SessionStorageDatabase::DeepCopyArea(int64 namespace_id,
151 const GURL& origin) {
152 // Example, data before deep copy:
153 // | namespace-1 (1 = namespace id) | dummy |
154 // | namespace-1-origin1 | 1 (mapid) |
155 // | namespace-2 | dummy |
156 // | namespace-2-origin1 | 1 (mapid) << references the same map
157 // | map-1 | 2 (refcount) |
158 // | map-1-a | b |
159
160 // Example, data after deep copy copy:
161 // | namespace-1 (1 = namespace id) | dummy |
162 // | namespace-1-origin1 | 1 (mapid) |
163 // | namespace-2 | dummy |
164 // | namespace-2-origin1 | 2 (mapid) << references the new map
165 // | map-1 | 1 (dec. refcount) |
166 // | map-1-a | b |
167 // | map-2 | 1 (refcount) |
168 // | map-2-a | b |
169
170 if (!LazyOpen(true))
michaeln 2012/04/26 05:07:43 maybe LazyOpen(false) here, if the db doesnt exist
marja 2012/04/27 07:34:47 Below we check that the thing to copy must exist,
171 return false;
172
173 std::string old_map_id;
174 bool exists;
175 if (!GetMapForArea(namespace_id, origin, &exists, &old_map_id))
176 return false;
177 if (!ConsistencyCheck(exists))
178 return false;
179
180 // At least one other namespace should refer to the same map. Otherwise this
181 // copy is not shallow, and the upper layer shouldn't call this function.
182 int64 ref_count;
183 if (!GetMapRefCount(old_map_id, &ref_count))
184 return false;
185 if (!ConsistencyCheck(ref_count > 1))
186 return false;
187
188 leveldb::WriteBatch batch;
189 std::string new_map_id;
190 if (!CreateMapForArea(namespace_id, origin, &new_map_id, &batch))
191 return false;
192
193 // Copy the values in the map.
194 ValuesMap values;
195 if (!ReadMap(old_map_id, &values, false))
196 return false;
197 WriteValuesToMap(new_map_id, values, &batch);
198
199 if (!DecreaseMapRefCount(old_map_id, 1, &batch))
200 return false;
201
202 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
203 return DatabaseErrorCheck(s.ok());
204 }
205
206 bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
207 const GURL& origin) {
208 if (!LazyOpen(false)) {
209 // No need to create the database if it doesn't exist.
210 return true;
211 }
212 leveldb::WriteBatch batch;
213 if (!DeleteArea(namespace_id, origin.spec(), &batch))
214 return false;
215 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
216 return DatabaseErrorCheck(s.ok());
217 }
218
219 bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) {
220 if (!LazyOpen(false)) {
221 // No need to create the database if it doesn't exist.
222 return true;
223 }
224 // Itereate through the areas in the namespace.
225 leveldb::WriteBatch batch;
226 std::map<std::string, std::string> areas;
227 if (!GetAreasInNamespace(namespace_id, &areas))
228 return false;
229 for (std::map<std::string, std::string>::const_iterator it = areas.begin();
230 it != areas.end(); ++it) {
231 const std::string& origin = it->first;
michaeln 2012/04/26 05:07:43 thnx for the self-document-code that tells me what
232 if (!DeleteArea(namespace_id, origin, &batch))
233 return false;
234 }
235 batch.Delete(NamespaceStartKey(namespace_id, namespace_offset_));
236 leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
237 return DatabaseErrorCheck(s.ok());
238 }
239
240 bool SessionStorageDatabase::LazyOpen(bool create_if_needed) {
michaeln 2012/04/26 05:07:43 I think we may need a mutex locker around this met
marja 2012/04/27 07:34:47 Done.
241 if (db_error_ || is_inconsistent_) {
michaeln 2012/04/26 05:07:43 If we trip on any 'consistency' error that's reall
marja 2012/04/27 07:34:47 Now this should distinguish better between incorre
242 // Don't try to open a database that we know has failed already.
243 return false;
244 }
245 if (IsOpen())
246 return true;
247
248 if (!create_if_needed &&
249 (!file_util::PathExists(file_path_) ||
250 file_util::IsDirectoryEmpty(file_path_))) {
251 // If the directory doesn't exist already and we haven't been asked to
252 // create a file on disk, then we don't bother opening the database. This
253 // means we wait until we absolutely need to put something onto disk before
254 // we do so.
255 return false;
256 }
257
258 leveldb::DB* db;
259 leveldb::Status s = TryToOpen(file_path_, &db);
260 if (!s.ok()) {
261 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value()
262 << ", error: " << s.ToString();
263 DCHECK(db == NULL);
264
265 // Clear the directory and try again.
266 file_util::Delete(file_path_, true);
267 s = TryToOpen(file_path_, &db);
268 if (!s.ok()) {
269 LOG(WARNING) << "Failed to open leveldb in " << file_path_.value()
270 << ", error: " << s.ToString();
271 DCHECK(db == NULL);
272 db_error_ = true;
273 return false;
274 }
275 }
276 db_.reset(db);
277
278 return GetNextNamespaceId(&namespace_offset_);
279 }
280
281 leveldb::Status SessionStorageDatabase::TryToOpen(const FilePath& file_path,
282 leveldb::DB** db) {
283 leveldb::Options options;
284 // The directory exists but a valid leveldb database might not exist inside it
285 // (e.g., a subset of the needed files might be missing). Handle this
286 // situation gracefully by creating the database now.
287 options.create_if_missing = true;
288 #if defined(OS_WIN)
289 return leveldb::DB::Open(options, WideToUTF8(file_path.value()), db);
290 #elif defined(OS_POSIX)
291 return leveldb::DB::Open(options, file_path.value(), db);
292 #endif
293 }
294
295 bool SessionStorageDatabase::IsOpen() const {
296 return db_.get() != NULL;
297 }
298
299 bool SessionStorageDatabase::ConsistencyCheck(bool ok) {
300 DCHECK(ok);
301 is_inconsistent_ = !ok;
302 // We cannot recover the database during this run, e.g., the upper layer can
303 // have a different understanding of the database state (shallow and deep
304 // copies).
305 // TODO(marja): Error handling.
306 return ok;
307 }
308
309 bool SessionStorageDatabase::DatabaseErrorCheck(bool ok) {
310 db_error_ = !ok;
311 // TODO(marja): Error handling.
312 return ok;
313 }
314
315 bool SessionStorageDatabase::CreateNamespace(int64 namespace_id,
316 bool ok_if_exists,
317 leveldb::WriteBatch* batch) {
318 std::string namespace_prefix = NamespacePrefix();
319 std::string dummy;
320 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_prefix,
321 &dummy);
322 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
323 return false;
324 if (s.IsNotFound())
325 batch->Put(namespace_prefix, "");
326
327 std::string namespace_start_key =
328 NamespaceStartKey(namespace_id, namespace_offset_);
329 s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy);
330 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
331 return false;
332 if (s.IsNotFound()) {
333 batch->Put(namespace_start_key, "");
334 return UpdateNextNamespaceId(namespace_id, batch);
335 }
336 return ConsistencyCheck(ok_if_exists);
michaeln 2012/04/26 05:07:43 Is this really a consistency error? Or possibly a
marja 2012/04/27 07:34:47 Done.
337 }
338
339 bool SessionStorageDatabase::GetNextNamespaceId(int64* next_namespace_id) {
340 std::string next_namespace_id_string;
341 leveldb::Status s = db_->Get(leveldb::ReadOptions(), NextNamespaceIdKey(),
342 &next_namespace_id_string);
343 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
344 return false;
345 if (s.IsNotFound()) {
346 *next_namespace_id = 0;
347 return true;
348 }
349 bool conversion_ok =
350 base::StringToInt64(next_namespace_id_string, next_namespace_id);
351 return ConsistencyCheck(conversion_ok);
352 }
353
354 bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id,
355 leveldb::WriteBatch* batch) {
356 int64 next_namespace_id;
357 if (!GetNextNamespaceId(&next_namespace_id))
358 return false;
359 if (next_namespace_id < namespace_id + namespace_offset_ + 1) {
360 next_namespace_id = namespace_id + namespace_offset_ + 1;
361 batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id));
362 }
363 return true;
364 }
365
366 bool SessionStorageDatabase::GetAreasInNamespace(
367 int64 namespace_id,
368 std::map<std::string, std::string>* areas) {
369 return GetAreasInNamespace(NamespaceIdStr(namespace_id, namespace_offset_),
370 areas);
371 }
372
373 bool SessionStorageDatabase::GetAreasInNamespace(
374 const std::string& namespace_id_str,
375 std::map<std::string, std::string>* areas) {
376 std::string namespace_start_key = NamespaceStartKey(namespace_id_str);
377 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
378 it->Seek(namespace_start_key);
379 if (it->status().IsNotFound()) {
380 // The namespace_start_key is not found when the namespace doesn't contain
381 // any areas. We don't need to do anything.
382 return true;
383 }
384 if (!DatabaseErrorCheck(it->status().ok()))
385 return false;
386
387 // Skip the dummy entry "namespace-<namespaceid>" and iterate the origins.
388 for (it->Next(); it->Valid(); it->Next()) {
389 std::string key = it->key().ToString();
390 if (key.find(namespace_start_key) != 0) {
391 // Iterated past the origins for this namespace.
392 break;
393 }
394 size_t second_dash = key.find('-', namespace_start_key.length());
395 if (!ConsistencyCheck(second_dash != std::string::npos))
396 return false;
397 std::string origin = key.substr(second_dash + 1);
398 std::string map_id = it->value().ToString();
399 (*areas)[origin] = map_id;
400 }
401 return true;
402 }
403
404 void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id,
405 const std::string& origin,
406 const std::string& map_id,
407 leveldb::WriteBatch* batch) {
408 std::string namespace_key = NamespaceKey(
409 NamespaceIdStr(namespace_id, namespace_offset_), origin);
410 batch->Put(namespace_key, map_id);
411 }
412
413 bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
414 const std::string& origin,
415 leveldb::WriteBatch* batch) {
416 return DeleteArea(NamespaceIdStr(namespace_id, namespace_offset_),
417 origin, batch);
418 }
419
420 bool SessionStorageDatabase::DeleteArea(const std::string& namespace_id_str,
421 const std::string& origin,
422 leveldb::WriteBatch* batch) {
423 std::string map_id;
424 bool exists;
425 if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id))
426 return false;
427 if (!exists)
428 return true; // Nothing to delete.
429 if (!DecreaseMapRefCount(map_id, 1, batch))
430 return false;
431 std::string namespace_key = NamespaceKey(namespace_id_str, origin);
432 batch->Delete(namespace_key);
433 return true;
434 }
435
436 bool SessionStorageDatabase::GetMapForArea(int64 namespace_id,
437 const GURL& origin,
438 bool* exists,
439 std::string* map_id) {
440 return GetMapForArea(
441 base::Int64ToString(namespace_id + namespace_offset_),
442 origin.spec(), exists, map_id);
443 }
444
445 bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str,
446 const std::string& origin,
447 bool* exists, std::string* map_id) {
448 std::string namespace_key = NamespaceKey(namespace_id_str, origin);
449 leveldb::Status s = db_->Get(leveldb::ReadOptions(), namespace_key, map_id);
450 if (s.IsNotFound()) {
451 *exists = false;
452 return true;
453 }
454 *exists = true;
455 return DatabaseErrorCheck(s.ok());
456 }
457
458 bool SessionStorageDatabase::CreateMapForArea(int64 namespace_id,
459 const GURL& origin,
460 std::string* map_id,
461 leveldb::WriteBatch* batch) {
462 std::string next_map_id_key = NextMapIdKey();
463 leveldb::Status s = db_->Get(leveldb::ReadOptions(), next_map_id_key, map_id);
464 if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
465 return false;
466 int64 next_map_id = 0;
467 if (s.IsNotFound()) {
468 *map_id = "0";
469 } else {
470 bool conversion_ok = base::StringToInt64(*map_id, &next_map_id);
471 if (!ConsistencyCheck(conversion_ok))
472 return false;
473 }
474 batch->Put(next_map_id_key, base::Int64ToString(++next_map_id));
475 std::string namespace_key =
476 NamespaceKey(namespace_id, namespace_offset_, origin);
477 batch->Put(namespace_key, *map_id);
478 batch->Put(MapRefCountKey(*map_id), base::Int64ToString(1));
michaeln 2012/04/26 05:07:43 maybe "1"?
marja 2012/04/27 07:34:47 Done.
479 return true;
480 }
481
482 bool SessionStorageDatabase::ReadMap(const std::string& map_id,
483 ValuesMap* result,
484 bool only_keys) {
485 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
486 std::string map_start_key = MapRefCountKey(map_id);
487 it->Seek(map_start_key);
488 // The map needs to exist, otherwise we have a stale map_id in the database.
489 if (!ConsistencyCheck(!it->status().IsNotFound()))
490 return false;
491 if (!DatabaseErrorCheck(it->status().ok()))
492 return false;
493 // Skip the dummy entry "map-<mapid>".
494 for (it->Next(); it->Valid(); it->Next()) {
495 // Key is of the form "map-<mapid>-<key>".
496 std::string key = it->key().ToString();
497 int prefix_length = MapPrefix().length();
498 size_t second_dash = key.find('-', prefix_length);
499 if (second_dash == std::string::npos ||
500 key.substr(prefix_length, second_dash - prefix_length) != map_id) {
501 // Iterated beyond the keys in this map.
502 break;
503 }
504 string16 key16 = UTF8ToUTF16(key.substr(second_dash + 1));
505 if (only_keys) {
506 (*result)[key16] = NullableString16(true);
507 } else {
508 // Convert the raw data stored in std::string (it->value()) to raw data
509 // stored in string16.
510 size_t len = it->value().size() / sizeof(char16);
511 const char16* data_ptr =
512 reinterpret_cast<const char16*>(it->value().data());
513 (*result)[key16] = NullableString16(string16(data_ptr, len), false);
514 }
515 }
516 return true;
517 }
518
519 void SessionStorageDatabase::WriteValuesToMap(const std::string& map_id,
520 const ValuesMap& values,
521 leveldb::WriteBatch* batch) {
522 for (ValuesMap::const_iterator it = values.begin(); it != values.end();
523 ++it) {
524 NullableString16 value = it->second;
525 std::string key = MapKey(map_id, UTF16ToUTF8(it->first));
526 if (value.is_null()) {
527 batch->Delete(key);
528 } else {
529 // Convert the raw data stored in string16 to raw data stored in
530 // std::string.
531 const char* data = reinterpret_cast<const char*>(value.string().data());
532 size_t size = value.string().size() * 2;
533 batch->Put(key, leveldb::Slice(data, size));
534 }
535 }
536 }
537
538 bool SessionStorageDatabase::GetMapRefCount(const std::string& map_id,
539 int64* ref_count) {
540 std::string ref_count_string;
541 leveldb::Status s = db_->Get(leveldb::ReadOptions(),
542 MapRefCountKey(map_id), &ref_count_string);
543 if (!ConsistencyCheck(s.ok()))
544 return false;
545 bool conversion_ok = base::StringToInt64(ref_count_string, ref_count);
546 return ConsistencyCheck(conversion_ok);
547 }
548
549 bool SessionStorageDatabase::IncreaseMapRefCount(const std::string& map_id,
550 leveldb::WriteBatch* batch) {
551 // Increase the ref count for the map.
552 int64 old_ref_count;
553 if (!GetMapRefCount(map_id, &old_ref_count))
554 return false;
555 batch->Put(MapRefCountKey(map_id), base::Int64ToString(++old_ref_count));
556 return true;
557 }
558
559 bool SessionStorageDatabase::DecreaseMapRefCount(const std::string& map_id,
560 int decrease,
561 leveldb::WriteBatch* batch) {
562 // Decrease the ref count for the map.
563 int64 ref_count;
564 if (!GetMapRefCount(map_id, &ref_count))
565 return false;
566 if (!ConsistencyCheck(decrease <= ref_count))
567 return false;
568 ref_count -= decrease;
569 if (ref_count > 0) {
570 batch->Put(MapRefCountKey(map_id), base::Int64ToString(ref_count));
571 } else {
572 // Clear all keys in the map.
573 if (!ClearMap(map_id, batch))
574 return false;
575 batch->Delete(MapRefCountKey(map_id));
576 }
577 return true;
578 }
579
580 bool SessionStorageDatabase::ClearMap(const std::string& map_id,
581 leveldb::WriteBatch* batch) {
582 ValuesMap values;
583 if (!ReadMap(map_id, &values, true))
584 return false;
585 for (ValuesMap::const_iterator it = values.begin(); it != values.end(); ++it)
586 batch->Delete(MapKey(map_id, UTF16ToUTF8(it->first)));
587 return true;
588 }
589
590 std::string SessionStorageDatabase::NamespaceStartKey(
591 const std::string& namespace_id_str) {
592 return base::StringPrintf("namespace-%s", namespace_id_str.c_str());
593 }
594
595 std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id,
596 int64 namespace_offset) {
597 return NamespaceStartKey(NamespaceIdStr(namespace_id, namespace_offset));
598 }
599
600 std::string SessionStorageDatabase::NamespaceKey(
601 const std::string& namespace_id_str, const std::string& origin) {
602 return base::StringPrintf("namespace-%s-%s", namespace_id_str.c_str(),
603 origin.c_str());
604 }
605
606 std::string SessionStorageDatabase::NamespaceKey(
607 int64 namespace_id, int64 namespace_offset, const GURL& origin) {
608 return NamespaceKey(NamespaceIdStr(namespace_id, namespace_offset),
609 origin.spec());
610 }
611
612 std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id,
613 int64 namespace_offset) {
614 return base::Int64ToString(namespace_id + namespace_offset);
615 }
616
617 std::string SessionStorageDatabase::NamespacePrefix() {
michaeln 2012/04/26 05:07:43 maybe consider making the truely constant 'prefix'
marja 2012/04/27 07:34:47 Done.
618 return std::string("namespace-");
619 }
620
621 std::string SessionStorageDatabase::MapRefCountKey(const std::string& map_id) {
622 return base::StringPrintf("map-%s", map_id.c_str());
623 }
624
625 std::string SessionStorageDatabase::MapKey(const std::string& map_id,
626 const std::string& key) {
627 return base::StringPrintf("map-%s-%s", map_id.c_str(), key.c_str());
628 }
629
630 std::string SessionStorageDatabase::MapPrefix() {
631 return std::string("map-");
632 }
633
634 std::string SessionStorageDatabase::NextNamespaceIdKey() {
635 return "next-namespace-id";
636 }
637
638 std::string SessionStorageDatabase::NextMapIdKey() {
639 return "next-map-id";
640 }
641
642 } // namespace dom_storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698