Respond with QuotaExceededError when IndexedDB has no disk space on open.
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_leveldb_coding.cc
blob3a7028012a37beb119db04d8401a8397a684423a
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
3 // found in the LICENSE file.
5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
7 #include <iterator>
8 #include <limits>
10 #include "base/logging.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/sys_byteorder.h"
14 #include "content/common/indexed_db/indexed_db_key.h"
15 #include "content/common/indexed_db/indexed_db_key_path.h"
17 // LevelDB Coding Scheme
18 // =====================
20 // LevelDB stores key/value pairs. Keys and values are strings of bytes,
21 // normally of type std::string.
23 // The keys in the backing store are variable-length tuples with different
24 // types of fields. Each key in the backing store starts with a ternary
25 // prefix: (database id, object store id, index id). For each, 0 is reserved
26 // for metadata. See KeyPrefix::Decode() for details of the prefix coding.
28 // The prefix makes sure that data for a specific database, object store, and
29 // index are grouped together. The locality is important for performance:
30 // common operations should only need a minimal number of seek operations. For
31 // example, all the metadata for a database is grouped together so that
32 // reading that metadata only requires one seek.
34 // Each key type has a class (in square brackets below) which knows how to
35 // encode, decode, and compare that key type.
37 // Strings (origins, names, etc) are encoded as UTF-16BE.
40 // Global metadata
41 // ---------------
42 // The prefix is <0, 0, 0>, followed by a metadata type byte:
44 // <0, 0, 0, 0> => backing store schema version [SchemaVersionKey]
45 // <0, 0, 0, 1> => maximum allocated database [MaxDatabaseIdKey]
46 // <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey]
47 // <0, 0, 0, 100, database id>
48 // => Existence implies the database id is in the free list
49 // [DatabaseFreeListKey]
50 // <0, 0, 0, 201, origin, database name> => Database id [DatabaseNameKey]
53 // Database metadata: [DatabaseMetaDataKey]
54 // ----------------------------------------
55 // The prefix is <database id, 0, 0> followed by a metadata type byte:
57 // <database id, 0, 0, 0> => origin name
58 // <database id, 0, 0, 1> => database name
59 // <database id, 0, 0, 2> => IDB string version data (obsolete)
60 // <database id, 0, 0, 3> => maximum allocated object store id
61 // <database id, 0, 0, 4> => IDB integer version (var int)
64 // Object store metadata: [ObjectStoreMetaDataKey]
65 // -----------------------------------------------
66 // The prefix is <database id, 0, 0>, followed by a type byte (50), then the
67 // object store id (var int), then a metadata type byte.
69 // <database id, 0, 0, 50, object store id, 0> => object store name
70 // <database id, 0, 0, 50, object store id, 1> => key path
71 // <database id, 0, 0, 50, object store id, 2> => auto increment flag
72 // <database id, 0, 0, 50, object store id, 3> => is evictable
73 // <database id, 0, 0, 50, object store id, 4> => last "version" number
74 // <database id, 0, 0, 50, object store id, 5> => maximum allocated index id
75 // <database id, 0, 0, 50, object store id, 6> => has key path flag (obsolete)
76 // <database id, 0, 0, 50, object store id, 7> => key generator current number
78 // The key path was originally just a string (#1) or null (identified by flag,
79 // #6). To support null, string, or array the coding is now identified by the
80 // leading bytes in #1 - see EncodeIDBKeyPath.
82 // The "version" field is used to weed out stale index data. Whenever new
83 // object store data is inserted, it gets a new "version" number, and new
84 // index data is written with this number. When the index is used for
85 // look-ups, entries are validated against the "exists" entries, and records
86 // with old "version" numbers are deleted when they are encountered in
87 // GetPrimaryKeyViaIndex, IndexCursorImpl::LoadCurrentRow and
88 // IndexKeyCursorImpl::LoadCurrentRow.
91 // Index metadata: [IndexMetaDataKey]
92 // ----------------------------------
93 // The prefix is <database id, 0, 0>, followed by a type byte (100), then the
94 // object store id (var int), then the index id (var int), then a metadata
95 // type byte.
97 // <database id, 0, 0, 100, object store id, index id, 0> => index name
98 // <database id, 0, 0, 100, object store id, index id, 1> => unique flag
99 // <database id, 0, 0, 100, object store id, index id, 2> => key path
100 // <database id, 0, 0, 100, object store id, index id, 3> => multi-entry flag
103 // Other object store and index metadata
104 // -------------------------------------
105 // The prefix is <database id, 0, 0> followed by a type byte. The object
106 // store and index id are variable length integers, the names are variable
107 // length strings.
109 // <database id, 0, 0, 150, object store id>
110 // => existence implies the object store id is in the free list
111 // [ObjectStoreFreeListKey]
112 // <database id, 0, 0, 151, object store id, index id>
113 // => existence implies the index id is in the free list [IndexFreeListKey]
114 // <database id, 0, 0, 200, object store name>
115 // => object store id [ObjectStoreNamesKey]
116 // <database id, 0, 0, 201, object store id, index name>
117 // => index id [IndexNamesKey]
120 // Object store data: [ObjectStoreDataKey]
121 // ---------------------------------------
122 // The prefix is followed by a type byte and the encoded IDB primary key. The
123 // data has a "version" prefix followed by the serialized script value.
125 // <database id, object store id, 1, user key>
126 // => "version", serialized script value
129 // "Exists" entry: [ExistsEntryKey]
130 // --------------------------------
131 // The prefix is followed by a type byte and the encoded IDB primary key.
133 // <database id, object store id, 2, user key> => "version"
136 // Index data
137 // ----------
138 // The prefix is followed by a type byte, the encoded IDB index key, a
139 // "sequence" number (obsolete; var int), and the encoded IDB primary key.
141 // <database id, object store id, index id, index key, sequence number,
142 // primary key> => "version", primary key [IndexDataKey]
144 // The sequence number is obsolete; it was used to allow two entries with the
145 // same user (index) key in non-unique indexes prior to the inclusion of the
146 // primary key in the data.
149 using base::StringPiece;
150 using WebKit::WebIDBKeyType;
151 using WebKit::WebIDBKeyTypeArray;
152 using WebKit::WebIDBKeyTypeDate;
153 using WebKit::WebIDBKeyTypeInvalid;
154 using WebKit::WebIDBKeyTypeMin;
155 using WebKit::WebIDBKeyTypeNull;
156 using WebKit::WebIDBKeyTypeNumber;
157 using WebKit::WebIDBKeyTypeString;
158 using WebKit::WebIDBKeyPathType;
159 using WebKit::WebIDBKeyPathTypeArray;
160 using WebKit::WebIDBKeyPathTypeNull;
161 using WebKit::WebIDBKeyPathTypeString;
163 namespace content {
165 // As most of the IndexedDBKeys and encoded values are short, we
166 // initialize some Vectors with a default inline buffer size to reduce
167 // the memory re-allocations when the Vectors are appended.
168 static const size_t kDefaultInlineBufferSize = 32;
170 static const unsigned char kIndexedDBKeyNullTypeByte = 0;
171 static const unsigned char kIndexedDBKeyStringTypeByte = 1;
172 static const unsigned char kIndexedDBKeyDateTypeByte = 2;
173 static const unsigned char kIndexedDBKeyNumberTypeByte = 3;
174 static const unsigned char kIndexedDBKeyArrayTypeByte = 4;
175 static const unsigned char kIndexedDBKeyMinKeyTypeByte = 5;
177 static const unsigned char kIndexedDBKeyPathTypeCodedByte1 = 0;
178 static const unsigned char kIndexedDBKeyPathTypeCodedByte2 = 0;
180 static const unsigned char kObjectStoreDataIndexId = 1;
181 static const unsigned char kExistsEntryIndexId = 2;
183 static const unsigned char kSchemaVersionTypeByte = 0;
184 static const unsigned char kMaxDatabaseIdTypeByte = 1;
185 static const unsigned char kDataVersionTypeByte = 2;
186 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte =
187 3; // Insert before this and increment.
188 static const unsigned char kDatabaseFreeListTypeByte = 100;
189 static const unsigned char kDatabaseNameTypeByte = 201;
191 static const unsigned char kObjectStoreMetaDataTypeByte = 50;
192 static const unsigned char kIndexMetaDataTypeByte = 100;
193 static const unsigned char kObjectStoreFreeListTypeByte = 150;
194 static const unsigned char kIndexFreeListTypeByte = 151;
195 static const unsigned char kObjectStoreNamesTypeByte = 200;
196 static const unsigned char kIndexNamesKeyTypeByte = 201;
198 static const unsigned char kObjectMetaDataTypeMaximum = 255;
199 static const unsigned char kIndexMetaDataTypeMaximum = 255;
201 const unsigned char kMinimumIndexId = 30;
203 inline void EncodeIntSafely(int64 nParam, int64 max, std::string* into) {
204 DCHECK_LE(nParam, max);
205 return EncodeInt(nParam, into);
208 std::string MaxIDBKey() {
209 std::string ret;
210 EncodeByte(kIndexedDBKeyNullTypeByte, &ret);
211 return ret;
214 std::string MinIDBKey() {
215 std::string ret;
216 EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret);
217 return ret;
220 void EncodeByte(unsigned char value, std::string* into) {
221 into->push_back(value);
224 void EncodeBool(bool value, std::string* into) {
225 into->push_back(value ? 1 : 0);
228 void EncodeInt(int64 value, std::string* into) {
229 #ifndef NDEBUG
230 // Exercised by unit tests in debug only.
231 DCHECK_GE(value, 0);
232 #endif
233 uint64 n = static_cast<uint64>(value);
235 do {
236 unsigned char c = n;
237 into->push_back(c);
238 n >>= 8;
239 } while (n);
242 void EncodeVarInt(int64 value, std::string* into) {
243 #ifndef NDEBUG
244 // Exercised by unit tests in debug only.
245 DCHECK_GE(value, 0);
246 #endif
247 uint64 n = static_cast<uint64>(value);
249 do {
250 unsigned char c = n & 0x7f;
251 n >>= 7;
252 if (n)
253 c |= 0x80;
254 into->push_back(c);
255 } while (n);
258 void EncodeString(const string16& value, std::string* into) {
259 if (value.empty())
260 return;
261 // Backing store is UTF-16BE, convert from host endianness.
262 size_t length = value.length();
263 size_t current = into->size();
264 into->resize(into->size() + length * sizeof(char16));
266 const char16* src = value.c_str();
267 char16* dst = reinterpret_cast<char16*>(&*into->begin() + current);
268 for (unsigned i = 0; i < length; ++i)
269 *dst++ = htons(*src++);
272 void EncodeStringWithLength(const string16& value, std::string* into) {
273 EncodeVarInt(value.length(), into);
274 EncodeString(value, into);
277 void EncodeDouble(double value, std::string* into) {
278 // This always has host endianness.
279 const char* p = reinterpret_cast<char*>(&value);
280 into->insert(into->end(), p, p + sizeof(value));
283 void EncodeIDBKey(const IndexedDBKey& value, std::string* into) {
284 size_t previous_size = into->size();
285 DCHECK(value.IsValid());
286 switch (value.type()) {
287 case WebIDBKeyTypeNull:
288 case WebIDBKeyTypeInvalid:
289 case WebIDBKeyTypeMin: {
290 NOTREACHED();
291 EncodeByte(kIndexedDBKeyNullTypeByte, into);
292 return;
294 case WebIDBKeyTypeArray: {
295 EncodeByte(kIndexedDBKeyArrayTypeByte, into);
296 size_t length = value.array().size();
297 EncodeVarInt(length, into);
298 for (size_t i = 0; i < length; ++i)
299 EncodeIDBKey(value.array()[i], into);
300 DCHECK_GT(into->size(), previous_size);
301 return;
303 case WebIDBKeyTypeString: {
304 EncodeByte(kIndexedDBKeyStringTypeByte, into);
305 EncodeStringWithLength(value.string(), into);
306 DCHECK_GT(into->size(), previous_size);
307 return;
309 case WebIDBKeyTypeDate: {
310 EncodeByte(kIndexedDBKeyDateTypeByte, into);
311 EncodeDouble(value.date(), into);
312 DCHECK_EQ(static_cast<size_t>(9),
313 static_cast<size_t>(into->size() - previous_size));
314 return;
316 case WebIDBKeyTypeNumber: {
317 EncodeByte(kIndexedDBKeyNumberTypeByte, into);
318 EncodeDouble(value.number(), into);
319 DCHECK_EQ(static_cast<size_t>(9),
320 static_cast<size_t>(into->size() - previous_size));
321 return;
325 NOTREACHED();
328 void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into) {
329 // May be typed, or may be a raw string. An invalid leading
330 // byte is used to identify typed coding. New records are
331 // always written as typed.
332 EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into);
333 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into);
334 EncodeByte(static_cast<char>(value.type()), into);
335 switch (value.type()) {
336 case WebIDBKeyPathTypeNull:
337 break;
338 case WebIDBKeyPathTypeString: {
339 EncodeStringWithLength(value.string(), into);
340 break;
342 case WebIDBKeyPathTypeArray: {
343 const std::vector<string16>& array = value.array();
344 size_t count = array.size();
345 EncodeVarInt(count, into);
346 for (size_t i = 0; i < count; ++i) {
347 EncodeStringWithLength(array[i], into);
349 break;
354 bool DecodeByte(StringPiece* slice, unsigned char* value) {
355 if (slice->empty())
356 return false;
358 *value = (*slice)[0];
359 slice->remove_prefix(1);
360 return true;
363 bool DecodeBool(StringPiece* slice, bool* value) {
364 if (slice->empty())
365 return false;
367 *value = !!(*slice)[0];
368 slice->remove_prefix(1);
369 return true;
372 bool DecodeInt(StringPiece* slice, int64* value) {
373 if (slice->empty())
374 return false;
376 StringPiece::const_iterator it = slice->begin();
377 int shift = 0;
378 int64 ret = 0;
379 while (it != slice->end()) {
380 unsigned char c = *it++;
381 ret |= static_cast<int64>(c) << shift;
382 shift += 8;
384 *value = ret;
385 slice->remove_prefix(it - slice->begin());
386 return true;
389 bool DecodeVarInt(StringPiece* slice, int64* value) {
390 if (slice->empty())
391 return false;
393 StringPiece::const_iterator it = slice->begin();
394 int shift = 0;
395 int64 ret = 0;
396 do {
397 if (it == slice->end())
398 return false;
400 unsigned char c = *it;
401 ret |= static_cast<int64>(c & 0x7f) << shift;
402 shift += 7;
403 } while (*it++ & 0x80);
404 *value = ret;
405 slice->remove_prefix(it - slice->begin());
406 return true;
409 bool DecodeString(StringPiece* slice, string16* value) {
410 if (slice->empty()) {
411 value->clear();
412 return true;
415 // Backing store is UTF-16BE, convert to host endianness.
416 DCHECK(!(slice->size() % sizeof(char16)));
417 size_t length = slice->size() / sizeof(char16);
418 string16 decoded;
419 decoded.reserve(length);
420 const char16* encoded = reinterpret_cast<const char16*>(slice->begin());
421 for (unsigned i = 0; i < length; ++i)
422 decoded.push_back(ntohs(*encoded++));
424 *value = decoded;
425 slice->remove_prefix(length * sizeof(char16));
426 return true;
429 bool DecodeStringWithLength(StringPiece* slice, string16* value) {
430 if (slice->empty())
431 return false;
433 int64 length = 0;
434 if (!DecodeVarInt(slice, &length) || length < 0)
435 return false;
436 size_t bytes = length * sizeof(char16);
437 if (slice->size() < bytes)
438 return false;
440 StringPiece subpiece(slice->begin(), bytes);
441 slice->remove_prefix(bytes);
442 if (!DecodeString(&subpiece, value))
443 return false;
445 return true;
448 bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
449 if (slice->empty())
450 return false;
452 unsigned char type = (*slice)[0];
453 slice->remove_prefix(1);
455 switch (type) {
456 case kIndexedDBKeyNullTypeByte:
457 *value = make_scoped_ptr(new IndexedDBKey());
458 return true;
460 case kIndexedDBKeyArrayTypeByte: {
461 int64 length = 0;
462 if (!DecodeVarInt(slice, &length) || length < 0)
463 return false;
464 IndexedDBKey::KeyArray array;
465 while (length--) {
466 scoped_ptr<IndexedDBKey> key;
467 if (!DecodeIDBKey(slice, &key))
468 return false;
469 array.push_back(*key);
471 *value = make_scoped_ptr(new IndexedDBKey(array));
472 return true;
474 case kIndexedDBKeyStringTypeByte: {
475 string16 s;
476 if (!DecodeStringWithLength(slice, &s))
477 return false;
478 *value = make_scoped_ptr(new IndexedDBKey(s));
479 return true;
481 case kIndexedDBKeyDateTypeByte: {
482 double d;
483 if (!DecodeDouble(slice, &d))
484 return false;
485 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate));
486 return true;
488 case kIndexedDBKeyNumberTypeByte: {
489 double d;
490 if (!DecodeDouble(slice, &d))
491 return false;
492 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeNumber));
493 return true;
497 NOTREACHED();
498 return false;
501 bool DecodeDouble(StringPiece* slice, double* value) {
502 if (slice->size() < sizeof(*value))
503 return false;
505 memcpy(value, slice->begin(), sizeof(*value));
506 slice->remove_prefix(sizeof(*value));
507 return true;
510 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
511 // May be typed, or may be a raw string. An invalid leading
512 // byte sequence is used to identify typed coding. New records are
513 // always written as typed.
514 if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 ||
515 (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) {
516 string16 s;
517 if (!DecodeString(slice, &s))
518 return false;
519 *value = IndexedDBKeyPath(s);
520 return true;
523 slice->remove_prefix(2);
524 DCHECK(!slice->empty());
525 WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]);
526 slice->remove_prefix(1);
528 switch (type) {
529 case WebIDBKeyPathTypeNull:
530 DCHECK(slice->empty());
531 *value = IndexedDBKeyPath();
532 return true;
533 case WebIDBKeyPathTypeString: {
534 string16 string;
535 if (!DecodeStringWithLength(slice, &string))
536 return false;
537 DCHECK(slice->empty());
538 *value = IndexedDBKeyPath(string);
539 return true;
541 case WebIDBKeyPathTypeArray: {
542 std::vector<string16> array;
543 int64 count;
544 if (!DecodeVarInt(slice, &count))
545 return false;
546 DCHECK_GE(count, 0);
547 while (count--) {
548 string16 string;
549 if (!DecodeStringWithLength(slice, &string))
550 return false;
551 array.push_back(string);
553 DCHECK(slice->empty());
554 *value = IndexedDBKeyPath(array);
555 return true;
558 NOTREACHED();
559 return false;
562 bool ConsumeEncodedIDBKey(StringPiece* slice) {
563 unsigned char type = (*slice)[0];
564 slice->remove_prefix(1);
566 switch (type) {
567 case kIndexedDBKeyNullTypeByte:
568 case kIndexedDBKeyMinKeyTypeByte:
569 return true;
570 case kIndexedDBKeyArrayTypeByte: {
571 int64 length;
572 if (!DecodeVarInt(slice, &length))
573 return false;
574 while (length--) {
575 if (!ConsumeEncodedIDBKey(slice))
576 return false;
578 return true;
580 case kIndexedDBKeyStringTypeByte: {
581 int64 length = 0;
582 if (!DecodeVarInt(slice, &length) || length < 0)
583 return false;
584 if (slice->size() < static_cast<size_t>(length) * sizeof(char16))
585 return false;
586 slice->remove_prefix(length * sizeof(char16));
587 return true;
589 case kIndexedDBKeyDateTypeByte:
590 case kIndexedDBKeyNumberTypeByte:
591 if (slice->size() < sizeof(double))
592 return false;
593 slice->remove_prefix(sizeof(double));
594 return true;
596 NOTREACHED();
597 return false;
600 bool ExtractEncodedIDBKey(StringPiece* slice, std::string* result) {
601 const char* start = slice->begin();
602 if (!ConsumeEncodedIDBKey(slice))
603 return false;
605 if (result)
606 result->assign(start, slice->begin());
607 return true;
610 static WebIDBKeyType KeyTypeByteToKeyType(unsigned char type) {
611 switch (type) {
612 case kIndexedDBKeyNullTypeByte:
613 return WebIDBKeyTypeInvalid;
614 case kIndexedDBKeyArrayTypeByte:
615 return WebIDBKeyTypeArray;
616 case kIndexedDBKeyStringTypeByte:
617 return WebIDBKeyTypeString;
618 case kIndexedDBKeyDateTypeByte:
619 return WebIDBKeyTypeDate;
620 case kIndexedDBKeyNumberTypeByte:
621 return WebIDBKeyTypeNumber;
622 case kIndexedDBKeyMinKeyTypeByte:
623 return WebIDBKeyTypeMin;
626 NOTREACHED();
627 return WebIDBKeyTypeInvalid;
630 int CompareEncodedStringsWithLength(StringPiece* slice1,
631 StringPiece* slice2,
632 bool* ok) {
633 int64 len1, len2;
634 if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
635 *ok = false;
636 return 0;
638 DCHECK_GE(len1, 0);
639 DCHECK_GE(len2, 0);
640 if (len1 < 0 || len2 < 0) {
641 *ok = false;
642 return 0;
644 DCHECK_GE(slice1->size(), len1 * sizeof(char16));
645 DCHECK_GE(slice2->size(), len2 * sizeof(char16));
646 if (slice1->size() < len1 * sizeof(char16) ||
647 slice2->size() < len2 * sizeof(char16)) {
648 *ok = false;
649 return 0;
652 StringPiece string1(slice1->begin(), len1 * sizeof(char16));
653 StringPiece string2(slice2->begin(), len2 * sizeof(char16));
654 slice1->remove_prefix(len1 * sizeof(char16));
655 slice2->remove_prefix(len2 * sizeof(char16));
657 *ok = true;
658 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
659 return string1.compare(string2);
662 static int CompareInts(int64 a, int64 b) {
663 #ifndef NDEBUG
664 // Exercised by unit tests in debug only.
665 DCHECK_GE(a, 0);
666 DCHECK_GE(b, 0);
667 #endif
668 int64 diff = a - b;
669 if (diff < 0)
670 return -1;
671 if (diff > 0)
672 return 1;
673 return 0;
676 static inline int CompareSizes(size_t a, size_t b) {
677 if (a > b)
678 return 1;
679 if (b > a)
680 return -1;
681 return 0;
684 static int CompareTypes(WebIDBKeyType a, WebIDBKeyType b) { return b - a; }
686 int CompareEncodedIDBKeys(StringPiece* slice_a,
687 StringPiece* slice_b,
688 bool* ok) {
689 DCHECK(!slice_a->empty());
690 DCHECK(!slice_b->empty());
691 *ok = true;
692 unsigned char type_a = (*slice_a)[0];
693 unsigned char type_b = (*slice_b)[0];
694 slice_a->remove_prefix(1);
695 slice_b->remove_prefix(1);
697 if (int x = CompareTypes(KeyTypeByteToKeyType(type_a),
698 KeyTypeByteToKeyType(type_b)))
699 return x;
701 switch (type_a) {
702 case kIndexedDBKeyNullTypeByte:
703 case kIndexedDBKeyMinKeyTypeByte:
704 // Null type or max type; no payload to compare.
705 return 0;
706 case kIndexedDBKeyArrayTypeByte: {
707 int64 length_a, length_b;
708 if (!DecodeVarInt(slice_a, &length_a) ||
709 !DecodeVarInt(slice_b, &length_b)) {
710 *ok = false;
711 return 0;
713 for (int64 i = 0; i < length_a && i < length_b; ++i) {
714 int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
715 if (!*ok || result)
716 return result;
718 return length_a - length_b;
720 case kIndexedDBKeyStringTypeByte:
721 return CompareEncodedStringsWithLength(slice_a, slice_b, ok);
722 case kIndexedDBKeyDateTypeByte:
723 case kIndexedDBKeyNumberTypeByte: {
724 double d, e;
725 if (!DecodeDouble(slice_a, &d) || !DecodeDouble(slice_b, &e)) {
726 *ok = false;
727 return 0;
729 if (d < e)
730 return -1;
731 if (d > e)
732 return 1;
733 return 0;
737 NOTREACHED();
738 return 0;
741 int CompareEncodedIDBKeys(const std::string& key_a,
742 const std::string& key_b,
743 bool* ok) {
744 DCHECK(!key_a.empty());
745 DCHECK(!key_b.empty());
747 StringPiece slice_a(key_a);
748 StringPiece slice_b(key_b);
749 return CompareEncodedIDBKeys(&slice_a, &slice_b, ok);
752 namespace {
754 template <typename KeyType>
755 int Compare(const StringPiece& a,
756 const StringPiece& b,
757 bool only_compare_index_keys,
758 bool* ok) {
759 KeyType key_a;
760 KeyType key_b;
762 StringPiece slice_a(a);
763 if (!KeyType::Decode(&slice_a, &key_a)) {
764 *ok = false;
765 return 0;
767 StringPiece slice_b(b);
768 if (!KeyType::Decode(&slice_b, &key_b)) {
769 *ok = false;
770 return 0;
773 *ok = true;
774 return key_a.Compare(key_b);
777 template <typename KeyType>
778 int CompareSuffix(StringPiece* a,
779 StringPiece* b,
780 bool only_compare_index_keys,
781 bool* ok) {
782 NOTREACHED();
783 return 0;
786 template <>
787 int CompareSuffix<ExistsEntryKey>(StringPiece* slice_a,
788 StringPiece* slice_b,
789 bool only_compare_index_keys,
790 bool* ok) {
791 DCHECK(!slice_a->empty());
792 DCHECK(!slice_b->empty());
793 return CompareEncodedIDBKeys(slice_a, slice_b, ok);
796 template <>
797 int Compare<ExistsEntryKey>(const StringPiece& a,
798 const StringPiece& b,
799 bool only_compare_index_keys,
800 bool* ok) {
801 KeyPrefix prefix_a;
802 KeyPrefix prefix_b;
803 StringPiece slice_a(a);
804 StringPiece slice_b(b);
805 bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
806 bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
807 DCHECK(ok_a);
808 DCHECK(ok_b);
809 DCHECK(prefix_a.database_id_);
810 DCHECK(prefix_a.object_store_id_);
811 DCHECK_EQ(prefix_a.index_id_, ExistsEntryKey::kSpecialIndexNumber);
812 DCHECK(prefix_b.database_id_);
813 DCHECK(prefix_b.object_store_id_);
814 DCHECK_EQ(prefix_b.index_id_, ExistsEntryKey::kSpecialIndexNumber);
815 DCHECK(!slice_a.empty());
816 DCHECK(!slice_b.empty());
817 // Prefixes are not compared - it is assumed this was already done.
818 DCHECK(!prefix_a.Compare(prefix_b));
820 return CompareSuffix<ExistsEntryKey>(
821 &slice_a, &slice_b, only_compare_index_keys, ok);
824 template <>
825 int CompareSuffix<ObjectStoreDataKey>(StringPiece* slice_a,
826 StringPiece* slice_b,
827 bool only_compare_index_keys,
828 bool* ok) {
829 return CompareEncodedIDBKeys(slice_a, slice_b, ok);
832 template <>
833 int Compare<ObjectStoreDataKey>(const StringPiece& a,
834 const StringPiece& b,
835 bool only_compare_index_keys,
836 bool* ok) {
837 KeyPrefix prefix_a;
838 KeyPrefix prefix_b;
839 StringPiece slice_a(a);
840 StringPiece slice_b(b);
841 bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
842 bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
843 DCHECK(ok_a);
844 DCHECK(ok_b);
845 DCHECK(prefix_a.database_id_);
846 DCHECK(prefix_a.object_store_id_);
847 DCHECK_EQ(prefix_a.index_id_, ObjectStoreDataKey::kSpecialIndexNumber);
848 DCHECK(prefix_b.database_id_);
849 DCHECK(prefix_b.object_store_id_);
850 DCHECK_EQ(prefix_b.index_id_, ObjectStoreDataKey::kSpecialIndexNumber);
851 DCHECK(!slice_a.empty());
852 DCHECK(!slice_b.empty());
853 // Prefixes are not compared - it is assumed this was already done.
854 DCHECK(!prefix_a.Compare(prefix_b));
856 return CompareSuffix<ObjectStoreDataKey>(
857 &slice_a, &slice_b, only_compare_index_keys, ok);
860 template <>
861 int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
862 StringPiece* slice_b,
863 bool only_compare_index_keys,
864 bool* ok) {
865 // index key
866 int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
867 if (!*ok || result)
868 return result;
869 if (only_compare_index_keys)
870 return 0;
872 // sequence number [optional]
873 int64 sequence_number_a = -1;
874 int64 sequence_number_b = -1;
875 if (!slice_a->empty() && !DecodeVarInt(slice_a, &sequence_number_a))
876 return 0;
877 if (!slice_b->empty() && !DecodeVarInt(slice_b, &sequence_number_b))
878 return 0;
880 if (slice_a->empty() || slice_b->empty())
881 return CompareSizes(slice_a->size(), slice_b->size());
883 // primary key [optional]
884 result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
885 if (!*ok || result)
886 return result;
888 return CompareInts(sequence_number_a, sequence_number_b);
891 template <>
892 int Compare<IndexDataKey>(const StringPiece& a,
893 const StringPiece& b,
894 bool only_compare_index_keys,
895 bool* ok) {
896 KeyPrefix prefix_a;
897 KeyPrefix prefix_b;
898 StringPiece slice_a(a);
899 StringPiece slice_b(b);
900 bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
901 bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
902 DCHECK(ok_a);
903 DCHECK(ok_b);
904 DCHECK(prefix_a.database_id_);
905 DCHECK(prefix_a.object_store_id_);
906 DCHECK_GE(prefix_a.index_id_, kMinimumIndexId);
907 DCHECK(prefix_b.database_id_);
908 DCHECK(prefix_b.object_store_id_);
909 DCHECK_GE(prefix_b.index_id_, kMinimumIndexId);
910 DCHECK(!slice_a.empty());
911 DCHECK(!slice_b.empty());
912 // Prefixes are not compared - it is assumed this was already done.
913 DCHECK(!prefix_a.Compare(prefix_b));
915 return CompareSuffix<IndexDataKey>(
916 &slice_a, &slice_b, only_compare_index_keys, ok);
919 int Compare(const StringPiece& a,
920 const StringPiece& b,
921 bool only_compare_index_keys,
922 bool* ok) {
923 StringPiece slice_a(a);
924 StringPiece slice_b(b);
925 KeyPrefix prefix_a;
926 KeyPrefix prefix_b;
927 bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
928 bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
929 DCHECK(ok_a);
930 DCHECK(ok_b);
931 if (!ok_a || !ok_b) {
932 *ok = false;
933 return 0;
936 *ok = true;
937 if (int x = prefix_a.Compare(prefix_b))
938 return x;
940 switch (prefix_a.type()) {
941 case KeyPrefix::GLOBAL_METADATA: {
942 DCHECK(!slice_a.empty());
943 DCHECK(!slice_b.empty());
945 unsigned char type_byte_a;
946 if (!DecodeByte(&slice_a, &type_byte_a)) {
947 *ok = false;
948 return 0;
951 unsigned char type_byte_b;
952 if (!DecodeByte(&slice_b, &type_byte_b)) {
953 *ok = false;
954 return 0;
957 if (int x = type_byte_a - type_byte_b)
958 return x;
959 if (type_byte_a < kMaxSimpleGlobalMetaDataTypeByte)
960 return 0;
962 // Compare<> is used (which re-decodes the prefix) rather than an
963 // specialized CompareSuffix<> because metadata is relatively uncommon
964 // in the database.
966 if (type_byte_a == kDatabaseFreeListTypeByte)
967 return Compare<DatabaseFreeListKey>(
968 a, b, only_compare_index_keys, ok);
969 if (type_byte_a == kDatabaseNameTypeByte)
970 return Compare<DatabaseNameKey>(
971 a, b, /*only_compare_index_keys*/ false, ok);
972 break;
975 case KeyPrefix::DATABASE_METADATA: {
976 DCHECK(!slice_a.empty());
977 DCHECK(!slice_b.empty());
979 unsigned char type_byte_a;
980 if (!DecodeByte(&slice_a, &type_byte_a)) {
981 *ok = false;
982 return 0;
985 unsigned char type_byte_b;
986 if (!DecodeByte(&slice_b, &type_byte_b)) {
987 *ok = false;
988 return 0;
991 if (int x = type_byte_a - type_byte_b)
992 return x;
993 if (type_byte_a < DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE)
994 return 0;
996 // Compare<> is used (which re-decodes the prefix) rather than an
997 // specialized CompareSuffix<> because metadata is relatively uncommon
998 // in the database.
1000 if (type_byte_a == kObjectStoreMetaDataTypeByte)
1001 return Compare<ObjectStoreMetaDataKey>(
1002 a, b, only_compare_index_keys, ok);
1003 if (type_byte_a == kIndexMetaDataTypeByte)
1004 return Compare<IndexMetaDataKey>(
1005 a, b, /*only_compare_index_keys*/ false, ok);
1006 if (type_byte_a == kObjectStoreFreeListTypeByte)
1007 return Compare<ObjectStoreFreeListKey>(
1008 a, b, only_compare_index_keys, ok);
1009 if (type_byte_a == kIndexFreeListTypeByte)
1010 return Compare<IndexFreeListKey>(
1011 a, b, /*only_compare_index_keys*/ false, ok);
1012 if (type_byte_a == kObjectStoreNamesTypeByte)
1013 return Compare<ObjectStoreNamesKey>(
1014 a, b, only_compare_index_keys, ok);
1015 if (type_byte_a == kIndexNamesKeyTypeByte)
1016 return Compare<IndexNamesKey>(
1017 a, b, /*only_compare_index_keys*/ false, ok);
1018 break;
1021 case KeyPrefix::OBJECT_STORE_DATA: {
1022 // Provide a stable ordering for invalid data.
1023 if (slice_a.empty() || slice_b.empty())
1024 return CompareSizes(slice_a.size(), slice_b.size());
1026 return CompareSuffix<ObjectStoreDataKey>(
1027 &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1030 case KeyPrefix::EXISTS_ENTRY: {
1031 // Provide a stable ordering for invalid data.
1032 if (slice_a.empty() || slice_b.empty())
1033 return CompareSizes(slice_a.size(), slice_b.size());
1035 return CompareSuffix<ExistsEntryKey>(
1036 &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1039 case KeyPrefix::INDEX_DATA: {
1040 // Provide a stable ordering for invalid data.
1041 if (slice_a.empty() || slice_b.empty())
1042 return CompareSizes(slice_a.size(), slice_b.size());
1044 return CompareSuffix<IndexDataKey>(
1045 &slice_a, &slice_b, only_compare_index_keys, ok);
1048 case KeyPrefix::INVALID_TYPE:
1049 break;
1052 NOTREACHED();
1053 *ok = false;
1054 return 0;
1057 } // namespace
1059 int Compare(const StringPiece& a,
1060 const StringPiece& b,
1061 bool only_compare_index_keys) {
1062 bool ok;
1063 int result = Compare(a, b, only_compare_index_keys, &ok);
1064 DCHECK(ok);
1065 if (!ok)
1066 return 0;
1067 return result;
1070 KeyPrefix::KeyPrefix()
1071 : database_id_(INVALID_TYPE),
1072 object_store_id_(INVALID_TYPE),
1073 index_id_(INVALID_TYPE) {}
1075 KeyPrefix::KeyPrefix(int64 database_id)
1076 : database_id_(database_id), object_store_id_(0), index_id_(0) {
1077 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1080 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
1081 : database_id_(database_id),
1082 object_store_id_(object_store_id),
1083 index_id_(0) {
1084 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1085 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1088 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
1089 : database_id_(database_id),
1090 object_store_id_(object_store_id),
1091 index_id_(index_id) {
1092 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1093 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1094 DCHECK(KeyPrefix::IsValidIndexId(index_id));
1097 KeyPrefix::KeyPrefix(enum Type type,
1098 int64 database_id,
1099 int64 object_store_id,
1100 int64 index_id)
1101 : database_id_(database_id),
1102 object_store_id_(object_store_id),
1103 index_id_(index_id) {
1104 DCHECK_EQ(type, INVALID_TYPE);
1105 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1106 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1109 KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64 database_id,
1110 int64 object_store_id,
1111 int64 index_id) {
1112 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1113 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1114 DCHECK(index_id);
1115 return KeyPrefix(INVALID_TYPE, database_id, object_store_id, index_id);
1118 bool KeyPrefix::IsValidDatabaseId(int64 database_id) {
1119 return (database_id > 0) && (database_id < KeyPrefix::kMaxDatabaseId);
1122 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id) {
1123 return (object_store_id > 0) &&
1124 (object_store_id < KeyPrefix::kMaxObjectStoreId);
1127 bool KeyPrefix::IsValidIndexId(int64 index_id) {
1128 return (index_id >= kMinimumIndexId) && (index_id < KeyPrefix::kMaxIndexId);
1131 bool KeyPrefix::Decode(StringPiece* slice, KeyPrefix* result) {
1132 unsigned char first_byte;
1133 if (!DecodeByte(slice, &first_byte))
1134 return false;
1136 size_t database_id_bytes = ((first_byte >> 5) & 0x7) + 1;
1137 size_t object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1;
1138 size_t index_id_bytes = (first_byte & 0x3) + 1;
1140 if (database_id_bytes + object_store_id_bytes + index_id_bytes >
1141 slice->size())
1142 return false;
1145 StringPiece tmp(slice->begin(), database_id_bytes);
1146 if (!DecodeInt(&tmp, &result->database_id_))
1147 return false;
1149 slice->remove_prefix(database_id_bytes);
1151 StringPiece tmp(slice->begin(), object_store_id_bytes);
1152 if (!DecodeInt(&tmp, &result->object_store_id_))
1153 return false;
1155 slice->remove_prefix(object_store_id_bytes);
1157 StringPiece tmp(slice->begin(), index_id_bytes);
1158 if (!DecodeInt(&tmp, &result->index_id_))
1159 return false;
1161 slice->remove_prefix(index_id_bytes);
1162 return true;
1165 std::string KeyPrefix::EncodeEmpty() {
1166 const std::string result(4, 0);
1167 DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1168 return result;
1171 std::string KeyPrefix::Encode() const {
1172 DCHECK(database_id_ != kInvalidId);
1173 DCHECK(object_store_id_ != kInvalidId);
1174 DCHECK(index_id_ != kInvalidId);
1175 return EncodeInternal(database_id_, object_store_id_, index_id_);
1178 std::string KeyPrefix::EncodeInternal(int64 database_id,
1179 int64 object_store_id,
1180 int64 index_id) {
1181 std::string database_id_string;
1182 std::string object_store_id_string;
1183 std::string index_id_string;
1185 EncodeIntSafely(database_id, kMaxDatabaseId, &database_id_string);
1186 EncodeIntSafely(object_store_id, kMaxObjectStoreId, &object_store_id_string);
1187 EncodeIntSafely(index_id, kMaxIndexId, &index_id_string);
1189 DCHECK(database_id_string.size() <= kMaxDatabaseIdSizeBytes);
1190 DCHECK(object_store_id_string.size() <= kMaxObjectStoreIdSizeBytes);
1191 DCHECK(index_id_string.size() <= kMaxIndexIdSizeBytes);
1193 unsigned char first_byte =
1194 (database_id_string.size() - 1) << (kMaxObjectStoreIdSizeBits +
1195 kMaxIndexIdSizeBits) |
1196 (object_store_id_string.size() - 1) << kMaxIndexIdSizeBits |
1197 (index_id_string.size() - 1);
1198 COMPILE_ASSERT(kMaxDatabaseIdSizeBits + kMaxObjectStoreIdSizeBits +
1199 kMaxIndexIdSizeBits ==
1200 sizeof(first_byte) * 8,
1201 CANT_ENCODE_IDS);
1202 std::string ret;
1203 ret.reserve(kDefaultInlineBufferSize);
1204 ret.push_back(first_byte);
1205 ret.append(database_id_string);
1206 ret.append(object_store_id_string);
1207 ret.append(index_id_string);
1209 DCHECK_LE(ret.size(), kDefaultInlineBufferSize);
1210 return ret;
1213 int KeyPrefix::Compare(const KeyPrefix& other) const {
1214 DCHECK(database_id_ != kInvalidId);
1215 DCHECK(object_store_id_ != kInvalidId);
1216 DCHECK(index_id_ != kInvalidId);
1218 if (database_id_ != other.database_id_)
1219 return CompareInts(database_id_, other.database_id_);
1220 if (object_store_id_ != other.object_store_id_)
1221 return CompareInts(object_store_id_, other.object_store_id_);
1222 if (index_id_ != other.index_id_)
1223 return CompareInts(index_id_, other.index_id_);
1224 return 0;
1227 KeyPrefix::Type KeyPrefix::type() const {
1228 DCHECK(database_id_ != kInvalidId);
1229 DCHECK(object_store_id_ != kInvalidId);
1230 DCHECK(index_id_ != kInvalidId);
1232 if (!database_id_)
1233 return GLOBAL_METADATA;
1234 if (!object_store_id_)
1235 return DATABASE_METADATA;
1236 if (index_id_ == kObjectStoreDataIndexId)
1237 return OBJECT_STORE_DATA;
1238 if (index_id_ == kExistsEntryIndexId)
1239 return EXISTS_ENTRY;
1240 if (index_id_ >= kMinimumIndexId)
1241 return INDEX_DATA;
1243 NOTREACHED();
1244 return INVALID_TYPE;
1247 std::string SchemaVersionKey::Encode() {
1248 std::string ret = KeyPrefix::EncodeEmpty();
1249 ret.push_back(kSchemaVersionTypeByte);
1250 return ret;
1253 std::string MaxDatabaseIdKey::Encode() {
1254 std::string ret = KeyPrefix::EncodeEmpty();
1255 ret.push_back(kMaxDatabaseIdTypeByte);
1256 return ret;
1259 std::string DataVersionKey::Encode() {
1260 std::string ret = KeyPrefix::EncodeEmpty();
1261 ret.push_back(kDataVersionTypeByte);
1262 return ret;
1265 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1267 bool DatabaseFreeListKey::Decode(StringPiece* slice,
1268 DatabaseFreeListKey* result) {
1269 KeyPrefix prefix;
1270 if (!KeyPrefix::Decode(slice, &prefix))
1271 return false;
1272 DCHECK(!prefix.database_id_);
1273 DCHECK(!prefix.object_store_id_);
1274 DCHECK(!prefix.index_id_);
1275 unsigned char type_byte = 0;
1276 if (!DecodeByte(slice, &type_byte))
1277 return false;
1278 DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte);
1279 if (!DecodeVarInt(slice, &result->database_id_))
1280 return false;
1281 return true;
1284 std::string DatabaseFreeListKey::Encode(int64 database_id) {
1285 std::string ret = KeyPrefix::EncodeEmpty();
1286 ret.push_back(kDatabaseFreeListTypeByte);
1287 EncodeVarInt(database_id, &ret);
1288 return ret;
1291 std::string DatabaseFreeListKey::EncodeMaxKey() {
1292 return Encode(std::numeric_limits<int64>::max());
1295 int64 DatabaseFreeListKey::DatabaseId() const {
1296 DCHECK_GE(database_id_, 0);
1297 return database_id_;
1300 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey& other) const {
1301 DCHECK_GE(database_id_, 0);
1302 return CompareInts(database_id_, other.database_id_);
1305 bool DatabaseNameKey::Decode(StringPiece* slice, DatabaseNameKey* result) {
1306 KeyPrefix prefix;
1307 if (!KeyPrefix::Decode(slice, &prefix))
1308 return false;
1309 DCHECK(!prefix.database_id_);
1310 DCHECK(!prefix.object_store_id_);
1311 DCHECK(!prefix.index_id_);
1312 unsigned char type_byte = 0;
1313 if (!DecodeByte(slice, &type_byte))
1314 return false;
1315 DCHECK_EQ(type_byte, kDatabaseNameTypeByte);
1316 if (!DecodeStringWithLength(slice, &result->origin_))
1317 return false;
1318 if (!DecodeStringWithLength(slice, &result->database_name_))
1319 return false;
1320 return true;
1323 std::string DatabaseNameKey::Encode(const std::string& origin_identifier,
1324 const string16& database_name) {
1325 std::string ret = KeyPrefix::EncodeEmpty();
1326 ret.push_back(kDatabaseNameTypeByte);
1327 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret);
1328 EncodeStringWithLength(database_name, &ret);
1329 return ret;
1332 std::string DatabaseNameKey::EncodeMinKeyForOrigin(
1333 const std::string& origin_identifier) {
1334 return Encode(origin_identifier, string16());
1337 std::string DatabaseNameKey::EncodeStopKeyForOrigin(
1338 const std::string& origin_identifier) {
1339 // just after origin in collation order
1340 return EncodeMinKeyForOrigin(origin_identifier + '\x01');
1343 int DatabaseNameKey::Compare(const DatabaseNameKey& other) {
1344 if (int x = origin_.compare(other.origin_))
1345 return x;
1346 return database_name_.compare(other.database_name_);
1349 std::string DatabaseMetaDataKey::Encode(int64 database_id,
1350 MetaDataType meta_data_type) {
1351 KeyPrefix prefix(database_id);
1352 std::string ret = prefix.Encode();
1353 ret.push_back(meta_data_type);
1354 return ret;
1357 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1358 : object_store_id_(-1), meta_data_type_(-1) {}
1360 bool ObjectStoreMetaDataKey::Decode(StringPiece* slice,
1361 ObjectStoreMetaDataKey* result) {
1362 KeyPrefix prefix;
1363 if (!KeyPrefix::Decode(slice, &prefix))
1364 return false;
1365 DCHECK(prefix.database_id_);
1366 DCHECK(!prefix.object_store_id_);
1367 DCHECK(!prefix.index_id_);
1368 unsigned char type_byte = 0;
1369 if (!DecodeByte(slice, &type_byte))
1370 return false;
1371 DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte);
1372 if (!DecodeVarInt(slice, &result->object_store_id_))
1373 return false;
1374 DCHECK(result->object_store_id_);
1375 if (!DecodeByte(slice, &result->meta_data_type_))
1376 return false;
1377 return true;
1380 std::string ObjectStoreMetaDataKey::Encode(int64 database_id,
1381 int64 object_store_id,
1382 unsigned char meta_data_type) {
1383 KeyPrefix prefix(database_id);
1384 std::string ret = prefix.Encode();
1385 ret.push_back(kObjectStoreMetaDataTypeByte);
1386 EncodeVarInt(object_store_id, &ret);
1387 ret.push_back(meta_data_type);
1388 return ret;
1391 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id) {
1392 return Encode(database_id,
1393 std::numeric_limits<int64>::max(),
1394 kObjectMetaDataTypeMaximum);
1397 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id,
1398 int64 object_store_id) {
1399 return Encode(database_id, object_store_id, kObjectMetaDataTypeMaximum);
1402 int64 ObjectStoreMetaDataKey::ObjectStoreId() const {
1403 DCHECK_GE(object_store_id_, 0);
1404 return object_store_id_;
1406 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1407 return meta_data_type_;
1410 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey& other) {
1411 DCHECK_GE(object_store_id_, 0);
1412 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1413 return x;
1414 return meta_data_type_ - other.meta_data_type_;
1417 IndexMetaDataKey::IndexMetaDataKey()
1418 : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1420 bool IndexMetaDataKey::Decode(StringPiece* slice, IndexMetaDataKey* result) {
1421 KeyPrefix prefix;
1422 if (!KeyPrefix::Decode(slice, &prefix))
1423 return false;
1424 DCHECK(prefix.database_id_);
1425 DCHECK(!prefix.object_store_id_);
1426 DCHECK(!prefix.index_id_);
1427 unsigned char type_byte = 0;
1428 if (!DecodeByte(slice, &type_byte))
1429 return false;
1430 DCHECK_EQ(type_byte, kIndexMetaDataTypeByte);
1431 if (!DecodeVarInt(slice, &result->object_store_id_))
1432 return false;
1433 if (!DecodeVarInt(slice, &result->index_id_))
1434 return false;
1435 if (!DecodeByte(slice, &result->meta_data_type_))
1436 return false;
1437 return true;
1440 std::string IndexMetaDataKey::Encode(int64 database_id,
1441 int64 object_store_id,
1442 int64 index_id,
1443 unsigned char meta_data_type) {
1444 KeyPrefix prefix(database_id);
1445 std::string ret = prefix.Encode();
1446 ret.push_back(kIndexMetaDataTypeByte);
1447 EncodeVarInt(object_store_id, &ret);
1448 EncodeVarInt(index_id, &ret);
1449 EncodeByte(meta_data_type, &ret);
1450 return ret;
1453 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
1454 int64 object_store_id) {
1455 return Encode(database_id,
1456 object_store_id,
1457 std::numeric_limits<int64>::max(),
1458 kIndexMetaDataTypeMaximum);
1461 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
1462 int64 object_store_id,
1463 int64 index_id) {
1464 return Encode(
1465 database_id, object_store_id, index_id, kIndexMetaDataTypeMaximum);
1468 int IndexMetaDataKey::Compare(const IndexMetaDataKey& other) {
1469 DCHECK_GE(object_store_id_, 0);
1470 DCHECK_GE(index_id_, 0);
1472 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1473 return x;
1474 if (int x = CompareInts(index_id_, other.index_id_))
1475 return x;
1476 return meta_data_type_ - other.meta_data_type_;
1479 int64 IndexMetaDataKey::IndexId() const {
1480 DCHECK_GE(index_id_, 0);
1481 return index_id_;
1484 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1486 bool ObjectStoreFreeListKey::Decode(StringPiece* slice,
1487 ObjectStoreFreeListKey* result) {
1488 KeyPrefix prefix;
1489 if (!KeyPrefix::Decode(slice, &prefix))
1490 return false;
1491 DCHECK(prefix.database_id_);
1492 DCHECK(!prefix.object_store_id_);
1493 DCHECK(!prefix.index_id_);
1494 unsigned char type_byte = 0;
1495 if (!DecodeByte(slice, &type_byte))
1496 return false;
1497 DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte);
1498 if (!DecodeVarInt(slice, &result->object_store_id_))
1499 return false;
1500 return true;
1503 std::string ObjectStoreFreeListKey::Encode(int64 database_id,
1504 int64 object_store_id) {
1505 KeyPrefix prefix(database_id);
1506 std::string ret = prefix.Encode();
1507 ret.push_back(kObjectStoreFreeListTypeByte);
1508 EncodeVarInt(object_store_id, &ret);
1509 return ret;
1512 std::string ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id) {
1513 return Encode(database_id, std::numeric_limits<int64>::max());
1516 int64 ObjectStoreFreeListKey::ObjectStoreId() const {
1517 DCHECK_GE(object_store_id_, 0);
1518 return object_store_id_;
1521 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey& other) {
1522 // TODO(jsbell): It may seem strange that we're not comparing database id's,
1523 // but that comparison will have been made earlier.
1524 // We should probably make this more clear, though...
1525 DCHECK_GE(object_store_id_, 0);
1526 return CompareInts(object_store_id_, other.object_store_id_);
1529 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1531 bool IndexFreeListKey::Decode(StringPiece* slice, IndexFreeListKey* result) {
1532 KeyPrefix prefix;
1533 if (!KeyPrefix::Decode(slice, &prefix))
1534 return false;
1535 DCHECK(prefix.database_id_);
1536 DCHECK(!prefix.object_store_id_);
1537 DCHECK(!prefix.index_id_);
1538 unsigned char type_byte = 0;
1539 if (!DecodeByte(slice, &type_byte))
1540 return false;
1541 DCHECK_EQ(type_byte, kIndexFreeListTypeByte);
1542 if (!DecodeVarInt(slice, &result->object_store_id_))
1543 return false;
1544 if (!DecodeVarInt(slice, &result->index_id_))
1545 return false;
1546 return true;
1549 std::string IndexFreeListKey::Encode(int64 database_id,
1550 int64 object_store_id,
1551 int64 index_id) {
1552 KeyPrefix prefix(database_id);
1553 std::string ret = prefix.Encode();
1554 ret.push_back(kIndexFreeListTypeByte);
1555 EncodeVarInt(object_store_id, &ret);
1556 EncodeVarInt(index_id, &ret);
1557 return ret;
1560 std::string IndexFreeListKey::EncodeMaxKey(int64 database_id,
1561 int64 object_store_id) {
1562 return Encode(
1563 database_id, object_store_id, std::numeric_limits<int64>::max());
1566 int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
1567 DCHECK_GE(object_store_id_, 0);
1568 DCHECK_GE(index_id_, 0);
1569 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1570 return x;
1571 return CompareInts(index_id_, other.index_id_);
1574 int64 IndexFreeListKey::ObjectStoreId() const {
1575 DCHECK_GE(object_store_id_, 0);
1576 return object_store_id_;
1579 int64 IndexFreeListKey::IndexId() const {
1580 DCHECK_GE(index_id_, 0);
1581 return index_id_;
1584 // TODO(jsbell): We never use this to look up object store ids,
1585 // because a mapping is kept in the IndexedDBDatabase. Can the
1586 // mapping become unreliable? Can we remove this?
1587 bool ObjectStoreNamesKey::Decode(StringPiece* slice,
1588 ObjectStoreNamesKey* result) {
1589 KeyPrefix prefix;
1590 if (!KeyPrefix::Decode(slice, &prefix))
1591 return false;
1592 DCHECK(prefix.database_id_);
1593 DCHECK(!prefix.object_store_id_);
1594 DCHECK(!prefix.index_id_);
1595 unsigned char type_byte = 0;
1596 if (!DecodeByte(slice, &type_byte))
1597 return false;
1598 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte);
1599 if (!DecodeStringWithLength(slice, &result->object_store_name_))
1600 return false;
1601 return true;
1604 std::string ObjectStoreNamesKey::Encode(int64 database_id,
1605 const string16& object_store_name) {
1606 KeyPrefix prefix(database_id);
1607 std::string ret = prefix.Encode();
1608 ret.push_back(kObjectStoreNamesTypeByte);
1609 EncodeStringWithLength(object_store_name, &ret);
1610 return ret;
1613 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) {
1614 return object_store_name_.compare(other.object_store_name_);
1617 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1619 // TODO(jsbell): We never use this to look up index ids, because a mapping
1620 // is kept at a higher level.
1621 bool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
1622 KeyPrefix prefix;
1623 if (!KeyPrefix::Decode(slice, &prefix))
1624 return false;
1625 DCHECK(prefix.database_id_);
1626 DCHECK(!prefix.object_store_id_);
1627 DCHECK(!prefix.index_id_);
1628 unsigned char type_byte = 0;
1629 if (!DecodeByte(slice, &type_byte))
1630 return false;
1631 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte);
1632 if (!DecodeVarInt(slice, &result->object_store_id_))
1633 return false;
1634 if (!DecodeStringWithLength(slice, &result->index_name_))
1635 return false;
1636 return true;
1639 std::string IndexNamesKey::Encode(int64 database_id,
1640 int64 object_store_id,
1641 const string16& index_name) {
1642 KeyPrefix prefix(database_id);
1643 std::string ret = prefix.Encode();
1644 ret.push_back(kIndexNamesKeyTypeByte);
1645 EncodeVarInt(object_store_id, &ret);
1646 EncodeStringWithLength(index_name, &ret);
1647 return ret;
1650 int IndexNamesKey::Compare(const IndexNamesKey& other) {
1651 DCHECK_GE(object_store_id_, 0);
1652 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1653 return x;
1654 return index_name_.compare(other.index_name_);
1657 ObjectStoreDataKey::ObjectStoreDataKey() {}
1658 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1660 bool ObjectStoreDataKey::Decode(StringPiece* slice,
1661 ObjectStoreDataKey* result) {
1662 KeyPrefix prefix;
1663 if (!KeyPrefix::Decode(slice, &prefix))
1664 return false;
1665 DCHECK(prefix.database_id_);
1666 DCHECK(prefix.object_store_id_);
1667 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1668 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1669 return false;
1670 return true;
1673 std::string ObjectStoreDataKey::Encode(int64 database_id,
1674 int64 object_store_id,
1675 const std::string encoded_user_key) {
1676 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1677 database_id, object_store_id, kSpecialIndexNumber));
1678 std::string ret = prefix.Encode();
1679 ret.append(encoded_user_key);
1681 return ret;
1684 std::string ObjectStoreDataKey::Encode(int64 database_id,
1685 int64 object_store_id,
1686 const IndexedDBKey& user_key) {
1687 std::string encoded_key;
1688 EncodeIDBKey(user_key, &encoded_key);
1689 return Encode(database_id, object_store_id, encoded_key);
1692 int ObjectStoreDataKey::Compare(const ObjectStoreDataKey& other, bool* ok) {
1693 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
1696 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
1697 scoped_ptr<IndexedDBKey> key;
1698 StringPiece slice(encoded_user_key_);
1699 if (!DecodeIDBKey(&slice, &key)) {
1700 // TODO(jsbell): Return error.
1702 return key.Pass();
1705 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
1707 ExistsEntryKey::ExistsEntryKey() {}
1708 ExistsEntryKey::~ExistsEntryKey() {}
1710 bool ExistsEntryKey::Decode(StringPiece* slice, ExistsEntryKey* result) {
1711 KeyPrefix prefix;
1712 if (!KeyPrefix::Decode(slice, &prefix))
1713 return false;
1714 DCHECK(prefix.database_id_);
1715 DCHECK(prefix.object_store_id_);
1716 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1717 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1718 return false;
1719 return true;
1722 std::string ExistsEntryKey::Encode(int64 database_id,
1723 int64 object_store_id,
1724 const std::string& encoded_key) {
1725 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1726 database_id, object_store_id, kSpecialIndexNumber));
1727 std::string ret = prefix.Encode();
1728 ret.append(encoded_key);
1729 return ret;
1732 std::string ExistsEntryKey::Encode(int64 database_id,
1733 int64 object_store_id,
1734 const IndexedDBKey& user_key) {
1735 std::string encoded_key;
1736 EncodeIDBKey(user_key, &encoded_key);
1737 return Encode(database_id, object_store_id, encoded_key);
1740 int ExistsEntryKey::Compare(const ExistsEntryKey& other, bool* ok) {
1741 return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
1744 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
1745 scoped_ptr<IndexedDBKey> key;
1746 StringPiece slice(encoded_user_key_);
1747 if (!DecodeIDBKey(&slice, &key)) {
1748 // TODO(jsbell): Return error.
1750 return key.Pass();
1753 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
1755 IndexDataKey::IndexDataKey()
1756 : database_id_(-1),
1757 object_store_id_(-1),
1758 index_id_(-1),
1759 sequence_number_(-1) {}
1761 IndexDataKey::~IndexDataKey() {}
1763 bool IndexDataKey::Decode(StringPiece* slice, IndexDataKey* result) {
1764 KeyPrefix prefix;
1765 if (!KeyPrefix::Decode(slice, &prefix))
1766 return false;
1767 DCHECK(prefix.database_id_);
1768 DCHECK(prefix.object_store_id_);
1769 DCHECK_GE(prefix.index_id_, kMinimumIndexId);
1770 result->database_id_ = prefix.database_id_;
1771 result->object_store_id_ = prefix.object_store_id_;
1772 result->index_id_ = prefix.index_id_;
1773 result->sequence_number_ = -1;
1774 result->encoded_primary_key_ = MinIDBKey();
1776 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1777 return false;
1779 // [optional] sequence number
1780 if (slice->empty())
1781 return true;
1782 if (!DecodeVarInt(slice, &result->sequence_number_))
1783 return false;
1785 // [optional] primary key
1786 if (slice->empty())
1787 return true;
1788 if (!ExtractEncodedIDBKey(slice, &result->encoded_primary_key_))
1789 return false;
1790 return true;
1793 std::string IndexDataKey::Encode(int64 database_id,
1794 int64 object_store_id,
1795 int64 index_id,
1796 const std::string& encoded_user_key,
1797 const std::string& encoded_primary_key,
1798 int64 sequence_number) {
1799 KeyPrefix prefix(database_id, object_store_id, index_id);
1800 std::string ret = prefix.Encode();
1801 ret.append(encoded_user_key);
1802 EncodeVarInt(sequence_number, &ret);
1803 ret.append(encoded_primary_key);
1804 return ret;
1807 std::string IndexDataKey::Encode(int64 database_id,
1808 int64 object_store_id,
1809 int64 index_id,
1810 const IndexedDBKey& user_key) {
1811 std::string encoded_key;
1812 EncodeIDBKey(user_key, &encoded_key);
1813 return Encode(
1814 database_id, object_store_id, index_id, encoded_key, MinIDBKey(), 0);
1817 std::string IndexDataKey::EncodeMinKey(int64 database_id,
1818 int64 object_store_id,
1819 int64 index_id) {
1820 return Encode(
1821 database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey(), 0);
1824 std::string IndexDataKey::EncodeMaxKey(int64 database_id,
1825 int64 object_store_id,
1826 int64 index_id) {
1827 return Encode(database_id,
1828 object_store_id,
1829 index_id,
1830 MaxIDBKey(),
1831 MaxIDBKey(),
1832 std::numeric_limits<int64>::max());
1835 int IndexDataKey::Compare(const IndexDataKey& other,
1836 bool only_compare_index_keys,
1837 bool* ok) {
1838 DCHECK_GE(database_id_, 0);
1839 DCHECK_GE(object_store_id_, 0);
1840 DCHECK_GE(index_id_, 0);
1841 int result =
1842 CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
1843 if (!*ok || result)
1844 return result;
1845 if (only_compare_index_keys)
1846 return 0;
1847 result = CompareEncodedIDBKeys(
1848 encoded_primary_key_, other.encoded_primary_key_, ok);
1849 if (!*ok || result)
1850 return result;
1851 return CompareInts(sequence_number_, other.sequence_number_);
1854 int64 IndexDataKey::DatabaseId() const {
1855 DCHECK_GE(database_id_, 0);
1856 return database_id_;
1859 int64 IndexDataKey::ObjectStoreId() const {
1860 DCHECK_GE(object_store_id_, 0);
1861 return object_store_id_;
1864 int64 IndexDataKey::IndexId() const {
1865 DCHECK_GE(index_id_, 0);
1866 return index_id_;
1869 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
1870 scoped_ptr<IndexedDBKey> key;
1871 StringPiece slice(encoded_user_key_);
1872 if (!DecodeIDBKey(&slice, &key)) {
1873 // TODO(jsbell): Return error.
1875 return key.Pass();
1878 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
1879 scoped_ptr<IndexedDBKey> key;
1880 StringPiece slice(encoded_primary_key_);
1881 if (!DecodeIDBKey(&slice, &key)) {
1882 // TODO(jsbell): Return error.
1884 return key.Pass();
1887 } // namespace content