Home | History | Annotate | Download | only in indexed_db
      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.
      4 
      5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
      6 
      7 #include <iterator>
      8 #include <limits>
      9 
     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"
     16 
     17 // LevelDB Coding Scheme
     18 // =====================
     19 //
     20 // LevelDB stores key/value pairs. Keys and values are strings of bytes,
     21 // normally of type std::string.
     22 //
     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.
     27 //
     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.
     33 //
     34 // Each key type has a class (in square brackets below) which knows how to
     35 // encode, decode, and compare that key type.
     36 //
     37 // Strings (origins, names, etc) are encoded as UTF-16BE.
     38 //
     39 //
     40 // Global metadata
     41 // ---------------
     42 // The prefix is <0, 0, 0>, followed by a metadata type byte:
     43 //
     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]
     51 //
     52 //
     53 // Database metadata: [DatabaseMetaDataKey]
     54 // ----------------------------------------
     55 // The prefix is <database id, 0, 0> followed by a metadata type byte:
     56 //
     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)
     62 //
     63 //
     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.
     68 //
     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
     77 //
     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.
     81 //
     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.
     89 //
     90 //
     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.
     96 //
     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
    101 //
    102 //
    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.
    108 //
    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]
    118 //
    119 //
    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.
    124 //
    125 // <database id, object store id, 1, user key>
    126 //   => "version", serialized script value
    127 //
    128 //
    129 // "Exists" entry: [ExistsEntryKey]
    130 // --------------------------------
    131 // The prefix is followed by a type byte and the encoded IDB primary key.
    132 //
    133 // <database id, object store id, 2, user key> => "version"
    134 //
    135 //
    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.
    140 //
    141 // <database id, object store id, index id, index key, sequence number,
    142 //   primary key> => "version", primary key [IndexDataKey]
    143 //
    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.
    147 
    148 
    149 using base::StringPiece;
    150 using blink::WebIDBKeyType;
    151 using blink::WebIDBKeyTypeArray;
    152 using blink::WebIDBKeyTypeBinary;
    153 using blink::WebIDBKeyTypeDate;
    154 using blink::WebIDBKeyTypeInvalid;
    155 using blink::WebIDBKeyTypeMin;
    156 using blink::WebIDBKeyTypeNull;
    157 using blink::WebIDBKeyTypeNumber;
    158 using blink::WebIDBKeyTypeString;
    159 using blink::WebIDBKeyPathType;
    160 using blink::WebIDBKeyPathTypeArray;
    161 using blink::WebIDBKeyPathTypeNull;
    162 using blink::WebIDBKeyPathTypeString;
    163 
    164 namespace content {
    165 
    166 // As most of the IndexedDBKeys and encoded values are short, we
    167 // initialize some Vectors with a default inline buffer size to reduce
    168 // the memory re-allocations when the Vectors are appended.
    169 static const size_t kDefaultInlineBufferSize = 32;
    170 
    171 static const unsigned char kIndexedDBKeyNullTypeByte = 0;
    172 static const unsigned char kIndexedDBKeyStringTypeByte = 1;
    173 static const unsigned char kIndexedDBKeyDateTypeByte = 2;
    174 static const unsigned char kIndexedDBKeyNumberTypeByte = 3;
    175 static const unsigned char kIndexedDBKeyArrayTypeByte = 4;
    176 static const unsigned char kIndexedDBKeyMinKeyTypeByte = 5;
    177 static const unsigned char kIndexedDBKeyBinaryTypeByte = 6;
    178 
    179 static const unsigned char kIndexedDBKeyPathTypeCodedByte1 = 0;
    180 static const unsigned char kIndexedDBKeyPathTypeCodedByte2 = 0;
    181 
    182 static const unsigned char kObjectStoreDataIndexId = 1;
    183 static const unsigned char kExistsEntryIndexId = 2;
    184 
    185 static const unsigned char kSchemaVersionTypeByte = 0;
    186 static const unsigned char kMaxDatabaseIdTypeByte = 1;
    187 static const unsigned char kDataVersionTypeByte = 2;
    188 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte =
    189     3;  // Insert before this and increment.
    190 static const unsigned char kDatabaseFreeListTypeByte = 100;
    191 static const unsigned char kDatabaseNameTypeByte = 201;
    192 
    193 static const unsigned char kObjectStoreMetaDataTypeByte = 50;
    194 static const unsigned char kIndexMetaDataTypeByte = 100;
    195 static const unsigned char kObjectStoreFreeListTypeByte = 150;
    196 static const unsigned char kIndexFreeListTypeByte = 151;
    197 static const unsigned char kObjectStoreNamesTypeByte = 200;
    198 static const unsigned char kIndexNamesKeyTypeByte = 201;
    199 
    200 static const unsigned char kObjectMetaDataTypeMaximum = 255;
    201 static const unsigned char kIndexMetaDataTypeMaximum = 255;
    202 
    203 const unsigned char kMinimumIndexId = 30;
    204 
    205 inline void EncodeIntSafely(int64 nParam, int64 max, std::string* into) {
    206   DCHECK_LE(nParam, max);
    207   return EncodeInt(nParam, into);
    208 }
    209 
    210 std::string MaxIDBKey() {
    211   std::string ret;
    212   EncodeByte(kIndexedDBKeyNullTypeByte, &ret);
    213   return ret;
    214 }
    215 
    216 std::string MinIDBKey() {
    217   std::string ret;
    218   EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret);
    219   return ret;
    220 }
    221 
    222 void EncodeByte(unsigned char value, std::string* into) {
    223   into->push_back(value);
    224 }
    225 
    226 void EncodeBool(bool value, std::string* into) {
    227   into->push_back(value ? 1 : 0);
    228 }
    229 
    230 void EncodeInt(int64 value, std::string* into) {
    231 #ifndef NDEBUG
    232   // Exercised by unit tests in debug only.
    233   DCHECK_GE(value, 0);
    234 #endif
    235   uint64 n = static_cast<uint64>(value);
    236 
    237   do {
    238     unsigned char c = n;
    239     into->push_back(c);
    240     n >>= 8;
    241   } while (n);
    242 }
    243 
    244 void EncodeVarInt(int64 value, std::string* into) {
    245 #ifndef NDEBUG
    246   // Exercised by unit tests in debug only.
    247   DCHECK_GE(value, 0);
    248 #endif
    249   uint64 n = static_cast<uint64>(value);
    250 
    251   do {
    252     unsigned char c = n & 0x7f;
    253     n >>= 7;
    254     if (n)
    255       c |= 0x80;
    256     into->push_back(c);
    257   } while (n);
    258 }
    259 
    260 void EncodeString(const base::string16& value, std::string* into) {
    261   if (value.empty())
    262     return;
    263   // Backing store is UTF-16BE, convert from host endianness.
    264   size_t length = value.length();
    265   size_t current = into->size();
    266   into->resize(into->size() + length * sizeof(char16));
    267 
    268   const char16* src = value.c_str();
    269   char16* dst = reinterpret_cast<char16*>(&*into->begin() + current);
    270   for (unsigned i = 0; i < length; ++i)
    271     *dst++ = htons(*src++);
    272 }
    273 
    274 void EncodeBinary(const std::string& value, std::string* into) {
    275   EncodeVarInt(value.length(), into);
    276   into->append(value.begin(), value.end());
    277   DCHECK(into->size() >= value.size());
    278 }
    279 
    280 void EncodeStringWithLength(const base::string16& value, std::string* into) {
    281   EncodeVarInt(value.length(), into);
    282   EncodeString(value, into);
    283 }
    284 
    285 void EncodeDouble(double value, std::string* into) {
    286   // This always has host endianness.
    287   const char* p = reinterpret_cast<char*>(&value);
    288   into->insert(into->end(), p, p + sizeof(value));
    289 }
    290 
    291 void EncodeIDBKey(const IndexedDBKey& value, std::string* into) {
    292   size_t previous_size = into->size();
    293   DCHECK(value.IsValid());
    294   switch (value.type()) {
    295     case WebIDBKeyTypeNull:
    296     case WebIDBKeyTypeInvalid:
    297     case WebIDBKeyTypeMin:
    298     default: {
    299       NOTREACHED();
    300       EncodeByte(kIndexedDBKeyNullTypeByte, into);
    301       return;
    302     }
    303     case WebIDBKeyTypeArray: {
    304       EncodeByte(kIndexedDBKeyArrayTypeByte, into);
    305       size_t length = value.array().size();
    306       EncodeVarInt(length, into);
    307       for (size_t i = 0; i < length; ++i)
    308         EncodeIDBKey(value.array()[i], into);
    309       DCHECK_GT(into->size(), previous_size);
    310       return;
    311     }
    312     case WebIDBKeyTypeBinary: {
    313       EncodeByte(kIndexedDBKeyBinaryTypeByte, into);
    314       EncodeBinary(value.binary(), into);
    315       DCHECK_GT(into->size(), previous_size);
    316       return;
    317     }
    318     case WebIDBKeyTypeString: {
    319       EncodeByte(kIndexedDBKeyStringTypeByte, into);
    320       EncodeStringWithLength(value.string(), into);
    321       DCHECK_GT(into->size(), previous_size);
    322       return;
    323     }
    324     case WebIDBKeyTypeDate: {
    325       EncodeByte(kIndexedDBKeyDateTypeByte, into);
    326       EncodeDouble(value.date(), into);
    327       DCHECK_EQ(static_cast<size_t>(9),
    328                 static_cast<size_t>(into->size() - previous_size));
    329       return;
    330     }
    331     case WebIDBKeyTypeNumber: {
    332       EncodeByte(kIndexedDBKeyNumberTypeByte, into);
    333       EncodeDouble(value.number(), into);
    334       DCHECK_EQ(static_cast<size_t>(9),
    335                 static_cast<size_t>(into->size() - previous_size));
    336       return;
    337     }
    338   }
    339 
    340   NOTREACHED();
    341 }
    342 
    343 void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into) {
    344   // May be typed, or may be a raw string. An invalid leading
    345   // byte is used to identify typed coding. New records are
    346   // always written as typed.
    347   EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into);
    348   EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into);
    349   EncodeByte(static_cast<char>(value.type()), into);
    350   switch (value.type()) {
    351     case WebIDBKeyPathTypeNull:
    352       break;
    353     case WebIDBKeyPathTypeString: {
    354       EncodeStringWithLength(value.string(), into);
    355       break;
    356     }
    357     case WebIDBKeyPathTypeArray: {
    358       const std::vector<base::string16>& array = value.array();
    359       size_t count = array.size();
    360       EncodeVarInt(count, into);
    361       for (size_t i = 0; i < count; ++i) {
    362         EncodeStringWithLength(array[i], into);
    363       }
    364       break;
    365     }
    366   }
    367 }
    368 
    369 bool DecodeByte(StringPiece* slice, unsigned char* value) {
    370   if (slice->empty())
    371     return false;
    372 
    373   *value = (*slice)[0];
    374   slice->remove_prefix(1);
    375   return true;
    376 }
    377 
    378 bool DecodeBool(StringPiece* slice, bool* value) {
    379   if (slice->empty())
    380     return false;
    381 
    382   *value = !!(*slice)[0];
    383   slice->remove_prefix(1);
    384   return true;
    385 }
    386 
    387 bool DecodeInt(StringPiece* slice, int64* value) {
    388   if (slice->empty())
    389     return false;
    390 
    391   StringPiece::const_iterator it = slice->begin();
    392   int shift = 0;
    393   int64 ret = 0;
    394   while (it != slice->end()) {
    395     unsigned char c = *it++;
    396     ret |= static_cast<int64>(c) << shift;
    397     shift += 8;
    398   }
    399   *value = ret;
    400   slice->remove_prefix(it - slice->begin());
    401   return true;
    402 }
    403 
    404 bool DecodeVarInt(StringPiece* slice, int64* value) {
    405   if (slice->empty())
    406     return false;
    407 
    408   StringPiece::const_iterator it = slice->begin();
    409   int shift = 0;
    410   int64 ret = 0;
    411   do {
    412     if (it == slice->end())
    413       return false;
    414 
    415     unsigned char c = *it;
    416     ret |= static_cast<int64>(c & 0x7f) << shift;
    417     shift += 7;
    418   } while (*it++ & 0x80);
    419   *value = ret;
    420   slice->remove_prefix(it - slice->begin());
    421   return true;
    422 }
    423 
    424 bool DecodeString(StringPiece* slice, base::string16* value) {
    425   if (slice->empty()) {
    426     value->clear();
    427     return true;
    428   }
    429 
    430   // Backing store is UTF-16BE, convert to host endianness.
    431   DCHECK(!(slice->size() % sizeof(char16)));
    432   size_t length = slice->size() / sizeof(char16);
    433   base::string16 decoded;
    434   decoded.reserve(length);
    435   const char16* encoded = reinterpret_cast<const char16*>(slice->begin());
    436   for (unsigned i = 0; i < length; ++i)
    437     decoded.push_back(ntohs(*encoded++));
    438 
    439   *value = decoded;
    440   slice->remove_prefix(length * sizeof(char16));
    441   return true;
    442 }
    443 
    444 bool DecodeStringWithLength(StringPiece* slice, base::string16* value) {
    445   if (slice->empty())
    446     return false;
    447 
    448   int64 length = 0;
    449   if (!DecodeVarInt(slice, &length) || length < 0)
    450     return false;
    451   size_t bytes = length * sizeof(char16);
    452   if (slice->size() < bytes)
    453     return false;
    454 
    455   StringPiece subpiece(slice->begin(), bytes);
    456   slice->remove_prefix(bytes);
    457   if (!DecodeString(&subpiece, value))
    458     return false;
    459 
    460   return true;
    461 }
    462 
    463 bool DecodeBinary(StringPiece* slice, std::string* value) {
    464   if (slice->empty())
    465     return false;
    466 
    467   int64 length = 0;
    468   if (!DecodeVarInt(slice, &length) || length < 0)
    469     return false;
    470   size_t size = length;
    471   if (slice->size() < size)
    472     return false;
    473 
    474   value->assign(slice->begin(), size);
    475   slice->remove_prefix(size);
    476   return true;
    477 }
    478 
    479 bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
    480   if (slice->empty())
    481     return false;
    482 
    483   unsigned char type = (*slice)[0];
    484   slice->remove_prefix(1);
    485 
    486   switch (type) {
    487     case kIndexedDBKeyNullTypeByte:
    488       *value = make_scoped_ptr(new IndexedDBKey());
    489       return true;
    490 
    491     case kIndexedDBKeyArrayTypeByte: {
    492       int64 length = 0;
    493       if (!DecodeVarInt(slice, &length) || length < 0)
    494         return false;
    495       IndexedDBKey::KeyArray array;
    496       while (length--) {
    497         scoped_ptr<IndexedDBKey> key;
    498         if (!DecodeIDBKey(slice, &key))
    499           return false;
    500         array.push_back(*key);
    501       }
    502       *value = make_scoped_ptr(new IndexedDBKey(array));
    503       return true;
    504     }
    505     case kIndexedDBKeyBinaryTypeByte: {
    506       std::string binary;
    507       if (!DecodeBinary(slice, &binary))
    508         return false;
    509       *value = make_scoped_ptr(new IndexedDBKey(binary));
    510       return true;
    511     }
    512     case kIndexedDBKeyStringTypeByte: {
    513       base::string16 s;
    514       if (!DecodeStringWithLength(slice, &s))
    515         return false;
    516       *value = make_scoped_ptr(new IndexedDBKey(s));
    517       return true;
    518     }
    519     case kIndexedDBKeyDateTypeByte: {
    520       double d;
    521       if (!DecodeDouble(slice, &d))
    522         return false;
    523       *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate));
    524       return true;
    525     }
    526     case kIndexedDBKeyNumberTypeByte: {
    527       double d;
    528       if (!DecodeDouble(slice, &d))
    529         return false;
    530       *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeNumber));
    531       return true;
    532     }
    533   }
    534 
    535   NOTREACHED();
    536   return false;
    537 }
    538 
    539 bool DecodeDouble(StringPiece* slice, double* value) {
    540   if (slice->size() < sizeof(*value))
    541     return false;
    542 
    543   memcpy(value, slice->begin(), sizeof(*value));
    544   slice->remove_prefix(sizeof(*value));
    545   return true;
    546 }
    547 
    548 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
    549   // May be typed, or may be a raw string. An invalid leading
    550   // byte sequence is used to identify typed coding. New records are
    551   // always written as typed.
    552   if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 ||
    553       (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) {
    554     base::string16 s;
    555     if (!DecodeString(slice, &s))
    556       return false;
    557     *value = IndexedDBKeyPath(s);
    558     return true;
    559   }
    560 
    561   slice->remove_prefix(2);
    562   DCHECK(!slice->empty());
    563   WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]);
    564   slice->remove_prefix(1);
    565 
    566   switch (type) {
    567     case WebIDBKeyPathTypeNull:
    568       DCHECK(slice->empty());
    569       *value = IndexedDBKeyPath();
    570       return true;
    571     case WebIDBKeyPathTypeString: {
    572       base::string16 string;
    573       if (!DecodeStringWithLength(slice, &string))
    574         return false;
    575       DCHECK(slice->empty());
    576       *value = IndexedDBKeyPath(string);
    577       return true;
    578     }
    579     case WebIDBKeyPathTypeArray: {
    580       std::vector<base::string16> array;
    581       int64 count;
    582       if (!DecodeVarInt(slice, &count))
    583         return false;
    584       DCHECK_GE(count, 0);
    585       while (count--) {
    586         base::string16 string;
    587         if (!DecodeStringWithLength(slice, &string))
    588           return false;
    589         array.push_back(string);
    590       }
    591       DCHECK(slice->empty());
    592       *value = IndexedDBKeyPath(array);
    593       return true;
    594     }
    595   }
    596   NOTREACHED();
    597   return false;
    598 }
    599 
    600 bool ConsumeEncodedIDBKey(StringPiece* slice) {
    601   unsigned char type = (*slice)[0];
    602   slice->remove_prefix(1);
    603 
    604   switch (type) {
    605     case kIndexedDBKeyNullTypeByte:
    606     case kIndexedDBKeyMinKeyTypeByte:
    607       return true;
    608     case kIndexedDBKeyArrayTypeByte: {
    609       int64 length;
    610       if (!DecodeVarInt(slice, &length))
    611         return false;
    612       while (length--) {
    613         if (!ConsumeEncodedIDBKey(slice))
    614           return false;
    615       }
    616       return true;
    617     }
    618     case kIndexedDBKeyBinaryTypeByte: {
    619       int64 length = 0;
    620       if (!DecodeVarInt(slice, &length) || length < 0)
    621         return false;
    622       if (slice->size() < static_cast<size_t>(length))
    623         return false;
    624       slice->remove_prefix(length);
    625       return true;
    626     }
    627     case kIndexedDBKeyStringTypeByte: {
    628       int64 length = 0;
    629       if (!DecodeVarInt(slice, &length) || length < 0)
    630         return false;
    631       if (slice->size() < static_cast<size_t>(length) * sizeof(char16))
    632         return false;
    633       slice->remove_prefix(length * sizeof(char16));
    634       return true;
    635     }
    636     case kIndexedDBKeyDateTypeByte:
    637     case kIndexedDBKeyNumberTypeByte:
    638       if (slice->size() < sizeof(double))
    639         return false;
    640       slice->remove_prefix(sizeof(double));
    641       return true;
    642   }
    643   NOTREACHED();
    644   return false;
    645 }
    646 
    647 bool ExtractEncodedIDBKey(StringPiece* slice, std::string* result) {
    648   const char* start = slice->begin();
    649   if (!ConsumeEncodedIDBKey(slice))
    650     return false;
    651 
    652   if (result)
    653     result->assign(start, slice->begin());
    654   return true;
    655 }
    656 
    657 static WebIDBKeyType KeyTypeByteToKeyType(unsigned char type) {
    658   switch (type) {
    659     case kIndexedDBKeyNullTypeByte:
    660       return WebIDBKeyTypeInvalid;
    661     case kIndexedDBKeyArrayTypeByte:
    662       return WebIDBKeyTypeArray;
    663     case kIndexedDBKeyBinaryTypeByte:
    664       return WebIDBKeyTypeBinary;
    665     case kIndexedDBKeyStringTypeByte:
    666       return WebIDBKeyTypeString;
    667     case kIndexedDBKeyDateTypeByte:
    668       return WebIDBKeyTypeDate;
    669     case kIndexedDBKeyNumberTypeByte:
    670       return WebIDBKeyTypeNumber;
    671     case kIndexedDBKeyMinKeyTypeByte:
    672       return WebIDBKeyTypeMin;
    673   }
    674 
    675   NOTREACHED();
    676   return WebIDBKeyTypeInvalid;
    677 }
    678 
    679 int CompareEncodedStringsWithLength(StringPiece* slice1,
    680                                     StringPiece* slice2,
    681                                     bool* ok) {
    682   int64 len1, len2;
    683   if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
    684     *ok = false;
    685     return 0;
    686   }
    687   DCHECK_GE(len1, 0);
    688   DCHECK_GE(len2, 0);
    689   if (len1 < 0 || len2 < 0) {
    690     *ok = false;
    691     return 0;
    692   }
    693   DCHECK_GE(slice1->size(), len1 * sizeof(char16));
    694   DCHECK_GE(slice2->size(), len2 * sizeof(char16));
    695   if (slice1->size() < len1 * sizeof(char16) ||
    696       slice2->size() < len2 * sizeof(char16)) {
    697     *ok = false;
    698     return 0;
    699   }
    700 
    701   // Extract the string data, and advance the passed slices.
    702   StringPiece string1(slice1->begin(), len1 * sizeof(char16));
    703   StringPiece string2(slice2->begin(), len2 * sizeof(char16));
    704   slice1->remove_prefix(len1 * sizeof(char16));
    705   slice2->remove_prefix(len2 * sizeof(char16));
    706 
    707   *ok = true;
    708   // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
    709   return string1.compare(string2);
    710 }
    711 
    712 int CompareEncodedBinary(StringPiece* slice1,
    713                          StringPiece* slice2,
    714                          bool* ok) {
    715   int64 len1, len2;
    716   if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
    717     *ok = false;
    718     return 0;
    719   }
    720   DCHECK_GE(len1, 0);
    721   DCHECK_GE(len2, 0);
    722   if (len1 < 0 || len2 < 0) {
    723     *ok = false;
    724     return 0;
    725   }
    726   size_t size1 = len1;
    727   size_t size2 = len2;
    728 
    729   DCHECK_GE(slice1->size(), size1);
    730   DCHECK_GE(slice2->size(), size2);
    731   if (slice1->size() < size1 || slice2->size() < size2) {
    732     *ok = false;
    733     return 0;
    734   }
    735 
    736   // Extract the binary data, and advance the passed slices.
    737   StringPiece binary1(slice1->begin(), size1);
    738   StringPiece binary2(slice2->begin(), size2);
    739   slice1->remove_prefix(size1);
    740   slice2->remove_prefix(size2);
    741 
    742   *ok = true;
    743   // This is the same as a memcmp()
    744   return binary1.compare(binary2);
    745 }
    746 
    747 static int CompareInts(int64 a, int64 b) {
    748 #ifndef NDEBUG
    749   // Exercised by unit tests in debug only.
    750   DCHECK_GE(a, 0);
    751   DCHECK_GE(b, 0);
    752 #endif
    753   int64 diff = a - b;
    754   if (diff < 0)
    755     return -1;
    756   if (diff > 0)
    757     return 1;
    758   return 0;
    759 }
    760 
    761 static inline int CompareSizes(size_t a, size_t b) {
    762   if (a > b)
    763     return 1;
    764   if (b > a)
    765     return -1;
    766   return 0;
    767 }
    768 
    769 static int CompareTypes(WebIDBKeyType a, WebIDBKeyType b) { return b - a; }
    770 
    771 int CompareEncodedIDBKeys(StringPiece* slice_a,
    772                           StringPiece* slice_b,
    773                           bool* ok) {
    774   DCHECK(!slice_a->empty());
    775   DCHECK(!slice_b->empty());
    776   *ok = true;
    777   unsigned char type_a = (*slice_a)[0];
    778   unsigned char type_b = (*slice_b)[0];
    779   slice_a->remove_prefix(1);
    780   slice_b->remove_prefix(1);
    781 
    782   if (int x = CompareTypes(KeyTypeByteToKeyType(type_a),
    783                            KeyTypeByteToKeyType(type_b)))
    784     return x;
    785 
    786   switch (type_a) {
    787     case kIndexedDBKeyNullTypeByte:
    788     case kIndexedDBKeyMinKeyTypeByte:
    789       // Null type or max type; no payload to compare.
    790       return 0;
    791     case kIndexedDBKeyArrayTypeByte: {
    792       int64 length_a, length_b;
    793       if (!DecodeVarInt(slice_a, &length_a) ||
    794           !DecodeVarInt(slice_b, &length_b)) {
    795         *ok = false;
    796         return 0;
    797       }
    798       for (int64 i = 0; i < length_a && i < length_b; ++i) {
    799         int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
    800         if (!*ok || result)
    801           return result;
    802       }
    803       return length_a - length_b;
    804     }
    805     case kIndexedDBKeyBinaryTypeByte:
    806       return CompareEncodedBinary(slice_a, slice_b, ok);
    807     case kIndexedDBKeyStringTypeByte:
    808       return CompareEncodedStringsWithLength(slice_a, slice_b, ok);
    809     case kIndexedDBKeyDateTypeByte:
    810     case kIndexedDBKeyNumberTypeByte: {
    811       double d, e;
    812       if (!DecodeDouble(slice_a, &d) || !DecodeDouble(slice_b, &e)) {
    813         *ok = false;
    814         return 0;
    815       }
    816       if (d < e)
    817         return -1;
    818       if (d > e)
    819         return 1;
    820       return 0;
    821     }
    822   }
    823 
    824   NOTREACHED();
    825   return 0;
    826 }
    827 
    828 namespace {
    829 
    830 template <typename KeyType>
    831 int Compare(const StringPiece& a,
    832             const StringPiece& b,
    833             bool only_compare_index_keys,
    834             bool* ok) {
    835   KeyType key_a;
    836   KeyType key_b;
    837 
    838   StringPiece slice_a(a);
    839   if (!KeyType::Decode(&slice_a, &key_a)) {
    840     *ok = false;
    841     return 0;
    842   }
    843   StringPiece slice_b(b);
    844   if (!KeyType::Decode(&slice_b, &key_b)) {
    845     *ok = false;
    846     return 0;
    847   }
    848 
    849   *ok = true;
    850   return key_a.Compare(key_b);
    851 }
    852 
    853 template <typename KeyType>
    854 int CompareSuffix(StringPiece* a,
    855                   StringPiece* b,
    856                   bool only_compare_index_keys,
    857                   bool* ok) {
    858   NOTREACHED();
    859   return 0;
    860 }
    861 
    862 template <>
    863 int CompareSuffix<ExistsEntryKey>(StringPiece* slice_a,
    864                                   StringPiece* slice_b,
    865                                   bool only_compare_index_keys,
    866                                   bool* ok) {
    867   DCHECK(!slice_a->empty());
    868   DCHECK(!slice_b->empty());
    869   return CompareEncodedIDBKeys(slice_a, slice_b, ok);
    870 }
    871 
    872 template <>
    873 int CompareSuffix<ObjectStoreDataKey>(StringPiece* slice_a,
    874                                       StringPiece* slice_b,
    875                                       bool only_compare_index_keys,
    876                                       bool* ok) {
    877   return CompareEncodedIDBKeys(slice_a, slice_b, ok);
    878 }
    879 
    880 template <>
    881 int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
    882                                 StringPiece* slice_b,
    883                                 bool only_compare_index_keys,
    884                                 bool* ok) {
    885   // index key
    886   int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
    887   if (!*ok || result)
    888     return result;
    889   if (only_compare_index_keys)
    890     return 0;
    891 
    892   // sequence number [optional]
    893   int64 sequence_number_a = -1;
    894   int64 sequence_number_b = -1;
    895   if (!slice_a->empty() && !DecodeVarInt(slice_a, &sequence_number_a))
    896       return 0;
    897   if (!slice_b->empty() && !DecodeVarInt(slice_b, &sequence_number_b))
    898       return 0;
    899 
    900   if (slice_a->empty() || slice_b->empty())
    901     return CompareSizes(slice_a->size(), slice_b->size());
    902 
    903   // primary key [optional]
    904   result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
    905   if (!*ok || result)
    906     return result;
    907 
    908   return CompareInts(sequence_number_a, sequence_number_b);
    909 }
    910 
    911 int Compare(const StringPiece& a,
    912             const StringPiece& b,
    913             bool only_compare_index_keys,
    914             bool* ok) {
    915   StringPiece slice_a(a);
    916   StringPiece slice_b(b);
    917   KeyPrefix prefix_a;
    918   KeyPrefix prefix_b;
    919   bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
    920   bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
    921   DCHECK(ok_a);
    922   DCHECK(ok_b);
    923   if (!ok_a || !ok_b) {
    924     *ok = false;
    925     return 0;
    926   }
    927 
    928   *ok = true;
    929   if (int x = prefix_a.Compare(prefix_b))
    930     return x;
    931 
    932   switch (prefix_a.type()) {
    933     case KeyPrefix::GLOBAL_METADATA: {
    934       DCHECK(!slice_a.empty());
    935       DCHECK(!slice_b.empty());
    936 
    937       unsigned char type_byte_a;
    938       if (!DecodeByte(&slice_a, &type_byte_a)) {
    939         *ok = false;
    940         return 0;
    941       }
    942 
    943       unsigned char type_byte_b;
    944       if (!DecodeByte(&slice_b, &type_byte_b)) {
    945         *ok = false;
    946         return 0;
    947       }
    948 
    949       if (int x = type_byte_a - type_byte_b)
    950         return x;
    951       if (type_byte_a < kMaxSimpleGlobalMetaDataTypeByte)
    952         return 0;
    953 
    954       // Compare<> is used (which re-decodes the prefix) rather than an
    955       // specialized CompareSuffix<> because metadata is relatively uncommon
    956       // in the database.
    957 
    958       if (type_byte_a == kDatabaseFreeListTypeByte) {
    959         // TODO(jsbell): No need to pass only_compare_index_keys through here.
    960         return Compare<DatabaseFreeListKey>(a, b, only_compare_index_keys, ok);
    961       }
    962       if (type_byte_a == kDatabaseNameTypeByte) {
    963         return Compare<DatabaseNameKey>(
    964             a, b, /*only_compare_index_keys*/ false, ok);
    965       }
    966       break;
    967     }
    968 
    969     case KeyPrefix::DATABASE_METADATA: {
    970       DCHECK(!slice_a.empty());
    971       DCHECK(!slice_b.empty());
    972 
    973       unsigned char type_byte_a;
    974       if (!DecodeByte(&slice_a, &type_byte_a)) {
    975         *ok = false;
    976         return 0;
    977       }
    978 
    979       unsigned char type_byte_b;
    980       if (!DecodeByte(&slice_b, &type_byte_b)) {
    981         *ok = false;
    982         return 0;
    983       }
    984 
    985       if (int x = type_byte_a - type_byte_b)
    986         return x;
    987       if (type_byte_a < DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE)
    988         return 0;
    989 
    990       // Compare<> is used (which re-decodes the prefix) rather than an
    991       // specialized CompareSuffix<> because metadata is relatively uncommon
    992       // in the database.
    993 
    994       if (type_byte_a == kObjectStoreMetaDataTypeByte) {
    995         // TODO(jsbell): No need to pass only_compare_index_keys through here.
    996         return Compare<ObjectStoreMetaDataKey>(
    997             a, b, only_compare_index_keys, ok);
    998       }
    999       if (type_byte_a == kIndexMetaDataTypeByte) {
   1000         return Compare<IndexMetaDataKey>(
   1001             a, b, /*only_compare_index_keys*/ false, ok);
   1002       }
   1003       if (type_byte_a == kObjectStoreFreeListTypeByte) {
   1004         return Compare<ObjectStoreFreeListKey>(
   1005             a, b, only_compare_index_keys, ok);
   1006       }
   1007       if (type_byte_a == kIndexFreeListTypeByte) {
   1008         return Compare<IndexFreeListKey>(
   1009             a, b, /*only_compare_index_keys*/ false, ok);
   1010       }
   1011       if (type_byte_a == kObjectStoreNamesTypeByte) {
   1012         // TODO(jsbell): No need to pass only_compare_index_keys through here.
   1013         return Compare<ObjectStoreNamesKey>(
   1014             a, b, only_compare_index_keys, ok);
   1015       }
   1016       if (type_byte_a == kIndexNamesKeyTypeByte) {
   1017         return Compare<IndexNamesKey>(
   1018             a, b, /*only_compare_index_keys*/ false, ok);
   1019       }
   1020       break;
   1021     }
   1022 
   1023     case KeyPrefix::OBJECT_STORE_DATA: {
   1024       // Provide a stable ordering for invalid data.
   1025       if (slice_a.empty() || slice_b.empty())
   1026         return CompareSizes(slice_a.size(), slice_b.size());
   1027 
   1028       return CompareSuffix<ObjectStoreDataKey>(
   1029           &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
   1030     }
   1031 
   1032     case KeyPrefix::EXISTS_ENTRY: {
   1033       // Provide a stable ordering for invalid data.
   1034       if (slice_a.empty() || slice_b.empty())
   1035         return CompareSizes(slice_a.size(), slice_b.size());
   1036 
   1037       return CompareSuffix<ExistsEntryKey>(
   1038           &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
   1039     }
   1040 
   1041     case KeyPrefix::INDEX_DATA: {
   1042       // Provide a stable ordering for invalid data.
   1043       if (slice_a.empty() || slice_b.empty())
   1044         return CompareSizes(slice_a.size(), slice_b.size());
   1045 
   1046       return CompareSuffix<IndexDataKey>(
   1047           &slice_a, &slice_b, only_compare_index_keys, ok);
   1048     }
   1049 
   1050     case KeyPrefix::INVALID_TYPE:
   1051       break;
   1052   }
   1053 
   1054   NOTREACHED();
   1055   *ok = false;
   1056   return 0;
   1057 }
   1058 
   1059 }  // namespace
   1060 
   1061 int Compare(const StringPiece& a,
   1062             const StringPiece& b,
   1063             bool only_compare_index_keys) {
   1064   bool ok;
   1065   int result = Compare(a, b, only_compare_index_keys, &ok);
   1066   DCHECK(ok);
   1067   if (!ok)
   1068     return 0;
   1069   return result;
   1070 }
   1071 
   1072 KeyPrefix::KeyPrefix()
   1073     : database_id_(INVALID_TYPE),
   1074       object_store_id_(INVALID_TYPE),
   1075       index_id_(INVALID_TYPE) {}
   1076 
   1077 KeyPrefix::KeyPrefix(int64 database_id)
   1078     : database_id_(database_id), object_store_id_(0), index_id_(0) {
   1079   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
   1080 }
   1081 
   1082 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
   1083     : database_id_(database_id),
   1084       object_store_id_(object_store_id),
   1085       index_id_(0) {
   1086   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
   1087   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
   1088 }
   1089 
   1090 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
   1091     : database_id_(database_id),
   1092       object_store_id_(object_store_id),
   1093       index_id_(index_id) {
   1094   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
   1095   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
   1096   DCHECK(KeyPrefix::IsValidIndexId(index_id));
   1097 }
   1098 
   1099 KeyPrefix::KeyPrefix(enum Type type,
   1100                      int64 database_id,
   1101                      int64 object_store_id,
   1102                      int64 index_id)
   1103     : database_id_(database_id),
   1104       object_store_id_(object_store_id),
   1105       index_id_(index_id) {
   1106   DCHECK_EQ(type, INVALID_TYPE);
   1107   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
   1108   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
   1109 }
   1110 
   1111 KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64 database_id,
   1112                                             int64 object_store_id,
   1113                                             int64 index_id) {
   1114   DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
   1115   DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
   1116   DCHECK(index_id);
   1117   return KeyPrefix(INVALID_TYPE, database_id, object_store_id, index_id);
   1118 }
   1119 
   1120 bool KeyPrefix::IsValidDatabaseId(int64 database_id) {
   1121   return (database_id > 0) && (database_id < KeyPrefix::kMaxDatabaseId);
   1122 }
   1123 
   1124 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id) {
   1125   return (object_store_id > 0) &&
   1126          (object_store_id < KeyPrefix::kMaxObjectStoreId);
   1127 }
   1128 
   1129 bool KeyPrefix::IsValidIndexId(int64 index_id) {
   1130   return (index_id >= kMinimumIndexId) && (index_id < KeyPrefix::kMaxIndexId);
   1131 }
   1132 
   1133 bool KeyPrefix::Decode(StringPiece* slice, KeyPrefix* result) {
   1134   unsigned char first_byte;
   1135   if (!DecodeByte(slice, &first_byte))
   1136     return false;
   1137 
   1138   size_t database_id_bytes = ((first_byte >> 5) & 0x7) + 1;
   1139   size_t object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1;
   1140   size_t index_id_bytes = (first_byte & 0x3) + 1;
   1141 
   1142   if (database_id_bytes + object_store_id_bytes + index_id_bytes >
   1143       slice->size())
   1144     return false;
   1145 
   1146   {
   1147     StringPiece tmp(slice->begin(), database_id_bytes);
   1148     if (!DecodeInt(&tmp, &result->database_id_))
   1149       return false;
   1150   }
   1151   slice->remove_prefix(database_id_bytes);
   1152   {
   1153     StringPiece tmp(slice->begin(), object_store_id_bytes);
   1154     if (!DecodeInt(&tmp, &result->object_store_id_))
   1155       return false;
   1156   }
   1157   slice->remove_prefix(object_store_id_bytes);
   1158   {
   1159     StringPiece tmp(slice->begin(), index_id_bytes);
   1160     if (!DecodeInt(&tmp, &result->index_id_))
   1161       return false;
   1162   }
   1163   slice->remove_prefix(index_id_bytes);
   1164   return true;
   1165 }
   1166 
   1167 std::string KeyPrefix::EncodeEmpty() {
   1168   const std::string result(4, 0);
   1169   DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
   1170   return result;
   1171 }
   1172 
   1173 std::string KeyPrefix::Encode() const {
   1174   DCHECK(database_id_ != kInvalidId);
   1175   DCHECK(object_store_id_ != kInvalidId);
   1176   DCHECK(index_id_ != kInvalidId);
   1177   return EncodeInternal(database_id_, object_store_id_, index_id_);
   1178 }
   1179 
   1180 std::string KeyPrefix::EncodeInternal(int64 database_id,
   1181                                       int64 object_store_id,
   1182                                       int64 index_id) {
   1183   std::string database_id_string;
   1184   std::string object_store_id_string;
   1185   std::string index_id_string;
   1186 
   1187   EncodeIntSafely(database_id, kMaxDatabaseId, &database_id_string);
   1188   EncodeIntSafely(object_store_id, kMaxObjectStoreId, &object_store_id_string);
   1189   EncodeIntSafely(index_id, kMaxIndexId, &index_id_string);
   1190 
   1191   DCHECK(database_id_string.size() <= kMaxDatabaseIdSizeBytes);
   1192   DCHECK(object_store_id_string.size() <= kMaxObjectStoreIdSizeBytes);
   1193   DCHECK(index_id_string.size() <= kMaxIndexIdSizeBytes);
   1194 
   1195   unsigned char first_byte =
   1196       (database_id_string.size() - 1) << (kMaxObjectStoreIdSizeBits +
   1197                                           kMaxIndexIdSizeBits) |
   1198       (object_store_id_string.size() - 1) << kMaxIndexIdSizeBits |
   1199       (index_id_string.size() - 1);
   1200   COMPILE_ASSERT(kMaxDatabaseIdSizeBits + kMaxObjectStoreIdSizeBits +
   1201                          kMaxIndexIdSizeBits ==
   1202                      sizeof(first_byte) * 8,
   1203                  CANT_ENCODE_IDS);
   1204   std::string ret;
   1205   ret.reserve(kDefaultInlineBufferSize);
   1206   ret.push_back(first_byte);
   1207   ret.append(database_id_string);
   1208   ret.append(object_store_id_string);
   1209   ret.append(index_id_string);
   1210 
   1211   DCHECK_LE(ret.size(), kDefaultInlineBufferSize);
   1212   return ret;
   1213 }
   1214 
   1215 int KeyPrefix::Compare(const KeyPrefix& other) const {
   1216   DCHECK(database_id_ != kInvalidId);
   1217   DCHECK(object_store_id_ != kInvalidId);
   1218   DCHECK(index_id_ != kInvalidId);
   1219 
   1220   if (database_id_ != other.database_id_)
   1221     return CompareInts(database_id_, other.database_id_);
   1222   if (object_store_id_ != other.object_store_id_)
   1223     return CompareInts(object_store_id_, other.object_store_id_);
   1224   if (index_id_ != other.index_id_)
   1225     return CompareInts(index_id_, other.index_id_);
   1226   return 0;
   1227 }
   1228 
   1229 KeyPrefix::Type KeyPrefix::type() const {
   1230   DCHECK(database_id_ != kInvalidId);
   1231   DCHECK(object_store_id_ != kInvalidId);
   1232   DCHECK(index_id_ != kInvalidId);
   1233 
   1234   if (!database_id_)
   1235     return GLOBAL_METADATA;
   1236   if (!object_store_id_)
   1237     return DATABASE_METADATA;
   1238   if (index_id_ == kObjectStoreDataIndexId)
   1239     return OBJECT_STORE_DATA;
   1240   if (index_id_ == kExistsEntryIndexId)
   1241     return EXISTS_ENTRY;
   1242   if (index_id_ >= kMinimumIndexId)
   1243     return INDEX_DATA;
   1244 
   1245   NOTREACHED();
   1246   return INVALID_TYPE;
   1247 }
   1248 
   1249 std::string SchemaVersionKey::Encode() {
   1250   std::string ret = KeyPrefix::EncodeEmpty();
   1251   ret.push_back(kSchemaVersionTypeByte);
   1252   return ret;
   1253 }
   1254 
   1255 std::string MaxDatabaseIdKey::Encode() {
   1256   std::string ret = KeyPrefix::EncodeEmpty();
   1257   ret.push_back(kMaxDatabaseIdTypeByte);
   1258   return ret;
   1259 }
   1260 
   1261 std::string DataVersionKey::Encode() {
   1262   std::string ret = KeyPrefix::EncodeEmpty();
   1263   ret.push_back(kDataVersionTypeByte);
   1264   return ret;
   1265 }
   1266 
   1267 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
   1268 
   1269 bool DatabaseFreeListKey::Decode(StringPiece* slice,
   1270                                  DatabaseFreeListKey* result) {
   1271   KeyPrefix prefix;
   1272   if (!KeyPrefix::Decode(slice, &prefix))
   1273     return false;
   1274   DCHECK(!prefix.database_id_);
   1275   DCHECK(!prefix.object_store_id_);
   1276   DCHECK(!prefix.index_id_);
   1277   unsigned char type_byte = 0;
   1278   if (!DecodeByte(slice, &type_byte))
   1279     return false;
   1280   DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte);
   1281   if (!DecodeVarInt(slice, &result->database_id_))
   1282     return false;
   1283   return true;
   1284 }
   1285 
   1286 std::string DatabaseFreeListKey::Encode(int64 database_id) {
   1287   std::string ret = KeyPrefix::EncodeEmpty();
   1288   ret.push_back(kDatabaseFreeListTypeByte);
   1289   EncodeVarInt(database_id, &ret);
   1290   return ret;
   1291 }
   1292 
   1293 std::string DatabaseFreeListKey::EncodeMaxKey() {
   1294   return Encode(std::numeric_limits<int64>::max());
   1295 }
   1296 
   1297 int64 DatabaseFreeListKey::DatabaseId() const {
   1298   DCHECK_GE(database_id_, 0);
   1299   return database_id_;
   1300 }
   1301 
   1302 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey& other) const {
   1303   DCHECK_GE(database_id_, 0);
   1304   return CompareInts(database_id_, other.database_id_);
   1305 }
   1306 
   1307 bool DatabaseNameKey::Decode(StringPiece* slice, DatabaseNameKey* result) {
   1308   KeyPrefix prefix;
   1309   if (!KeyPrefix::Decode(slice, &prefix))
   1310     return false;
   1311   DCHECK(!prefix.database_id_);
   1312   DCHECK(!prefix.object_store_id_);
   1313   DCHECK(!prefix.index_id_);
   1314   unsigned char type_byte = 0;
   1315   if (!DecodeByte(slice, &type_byte))
   1316     return false;
   1317   DCHECK_EQ(type_byte, kDatabaseNameTypeByte);
   1318   if (!DecodeStringWithLength(slice, &result->origin_))
   1319     return false;
   1320   if (!DecodeStringWithLength(slice, &result->database_name_))
   1321     return false;
   1322   return true;
   1323 }
   1324 
   1325 std::string DatabaseNameKey::Encode(const std::string& origin_identifier,
   1326                                     const base::string16& database_name) {
   1327   std::string ret = KeyPrefix::EncodeEmpty();
   1328   ret.push_back(kDatabaseNameTypeByte);
   1329   EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret);
   1330   EncodeStringWithLength(database_name, &ret);
   1331   return ret;
   1332 }
   1333 
   1334 std::string DatabaseNameKey::EncodeMinKeyForOrigin(
   1335     const std::string& origin_identifier) {
   1336   return Encode(origin_identifier, base::string16());
   1337 }
   1338 
   1339 std::string DatabaseNameKey::EncodeStopKeyForOrigin(
   1340     const std::string& origin_identifier) {
   1341   // just after origin in collation order
   1342   return EncodeMinKeyForOrigin(origin_identifier + '\x01');
   1343 }
   1344 
   1345 int DatabaseNameKey::Compare(const DatabaseNameKey& other) {
   1346   if (int x = origin_.compare(other.origin_))
   1347     return x;
   1348   return database_name_.compare(other.database_name_);
   1349 }
   1350 
   1351 std::string DatabaseMetaDataKey::Encode(int64 database_id,
   1352                                         MetaDataType meta_data_type) {
   1353   KeyPrefix prefix(database_id);
   1354   std::string ret = prefix.Encode();
   1355   ret.push_back(meta_data_type);
   1356   return ret;
   1357 }
   1358 
   1359 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
   1360     : object_store_id_(-1), meta_data_type_(-1) {}
   1361 
   1362 bool ObjectStoreMetaDataKey::Decode(StringPiece* slice,
   1363                                     ObjectStoreMetaDataKey* result) {
   1364   KeyPrefix prefix;
   1365   if (!KeyPrefix::Decode(slice, &prefix))
   1366     return false;
   1367   DCHECK(prefix.database_id_);
   1368   DCHECK(!prefix.object_store_id_);
   1369   DCHECK(!prefix.index_id_);
   1370   unsigned char type_byte = 0;
   1371   if (!DecodeByte(slice, &type_byte))
   1372     return false;
   1373   DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte);
   1374   if (!DecodeVarInt(slice, &result->object_store_id_))
   1375     return false;
   1376   DCHECK(result->object_store_id_);
   1377   if (!DecodeByte(slice, &result->meta_data_type_))
   1378     return false;
   1379   return true;
   1380 }
   1381 
   1382 std::string ObjectStoreMetaDataKey::Encode(int64 database_id,
   1383                                            int64 object_store_id,
   1384                                            unsigned char meta_data_type) {
   1385   KeyPrefix prefix(database_id);
   1386   std::string ret = prefix.Encode();
   1387   ret.push_back(kObjectStoreMetaDataTypeByte);
   1388   EncodeVarInt(object_store_id, &ret);
   1389   ret.push_back(meta_data_type);
   1390   return ret;
   1391 }
   1392 
   1393 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id) {
   1394   return Encode(database_id,
   1395                 std::numeric_limits<int64>::max(),
   1396                 kObjectMetaDataTypeMaximum);
   1397 }
   1398 
   1399 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id,
   1400                                                  int64 object_store_id) {
   1401   return Encode(database_id, object_store_id, kObjectMetaDataTypeMaximum);
   1402 }
   1403 
   1404 int64 ObjectStoreMetaDataKey::ObjectStoreId() const {
   1405   DCHECK_GE(object_store_id_, 0);
   1406   return object_store_id_;
   1407 }
   1408 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
   1409   return meta_data_type_;
   1410 }
   1411 
   1412 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey& other) {
   1413   DCHECK_GE(object_store_id_, 0);
   1414   if (int x = CompareInts(object_store_id_, other.object_store_id_))
   1415     return x;
   1416   return meta_data_type_ - other.meta_data_type_;
   1417 }
   1418 
   1419 IndexMetaDataKey::IndexMetaDataKey()
   1420     : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
   1421 
   1422 bool IndexMetaDataKey::Decode(StringPiece* slice, IndexMetaDataKey* result) {
   1423   KeyPrefix prefix;
   1424   if (!KeyPrefix::Decode(slice, &prefix))
   1425     return false;
   1426   DCHECK(prefix.database_id_);
   1427   DCHECK(!prefix.object_store_id_);
   1428   DCHECK(!prefix.index_id_);
   1429   unsigned char type_byte = 0;
   1430   if (!DecodeByte(slice, &type_byte))
   1431     return false;
   1432   DCHECK_EQ(type_byte, kIndexMetaDataTypeByte);
   1433   if (!DecodeVarInt(slice, &result->object_store_id_))
   1434     return false;
   1435   if (!DecodeVarInt(slice, &result->index_id_))
   1436     return false;
   1437   if (!DecodeByte(slice, &result->meta_data_type_))
   1438     return false;
   1439   return true;
   1440 }
   1441 
   1442 std::string IndexMetaDataKey::Encode(int64 database_id,
   1443                                      int64 object_store_id,
   1444                                      int64 index_id,
   1445                                      unsigned char meta_data_type) {
   1446   KeyPrefix prefix(database_id);
   1447   std::string ret = prefix.Encode();
   1448   ret.push_back(kIndexMetaDataTypeByte);
   1449   EncodeVarInt(object_store_id, &ret);
   1450   EncodeVarInt(index_id, &ret);
   1451   EncodeByte(meta_data_type, &ret);
   1452   return ret;
   1453 }
   1454 
   1455 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
   1456                                            int64 object_store_id) {
   1457   return Encode(database_id,
   1458                 object_store_id,
   1459                 std::numeric_limits<int64>::max(),
   1460                 kIndexMetaDataTypeMaximum);
   1461 }
   1462 
   1463 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
   1464                                            int64 object_store_id,
   1465                                            int64 index_id) {
   1466   return Encode(
   1467       database_id, object_store_id, index_id, kIndexMetaDataTypeMaximum);
   1468 }
   1469 
   1470 int IndexMetaDataKey::Compare(const IndexMetaDataKey& other) {
   1471   DCHECK_GE(object_store_id_, 0);
   1472   DCHECK_GE(index_id_, 0);
   1473 
   1474   if (int x = CompareInts(object_store_id_, other.object_store_id_))
   1475     return x;
   1476   if (int x = CompareInts(index_id_, other.index_id_))
   1477     return x;
   1478   return meta_data_type_ - other.meta_data_type_;
   1479 }
   1480 
   1481 int64 IndexMetaDataKey::IndexId() const {
   1482   DCHECK_GE(index_id_, 0);
   1483   return index_id_;
   1484 }
   1485 
   1486 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
   1487 
   1488 bool ObjectStoreFreeListKey::Decode(StringPiece* slice,
   1489                                     ObjectStoreFreeListKey* result) {
   1490   KeyPrefix prefix;
   1491   if (!KeyPrefix::Decode(slice, &prefix))
   1492     return false;
   1493   DCHECK(prefix.database_id_);
   1494   DCHECK(!prefix.object_store_id_);
   1495   DCHECK(!prefix.index_id_);
   1496   unsigned char type_byte = 0;
   1497   if (!DecodeByte(slice, &type_byte))
   1498     return false;
   1499   DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte);
   1500   if (!DecodeVarInt(slice, &result->object_store_id_))
   1501     return false;
   1502   return true;
   1503 }
   1504 
   1505 std::string ObjectStoreFreeListKey::Encode(int64 database_id,
   1506                                            int64 object_store_id) {
   1507   KeyPrefix prefix(database_id);
   1508   std::string ret = prefix.Encode();
   1509   ret.push_back(kObjectStoreFreeListTypeByte);
   1510   EncodeVarInt(object_store_id, &ret);
   1511   return ret;
   1512 }
   1513 
   1514 std::string ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id) {
   1515   return Encode(database_id, std::numeric_limits<int64>::max());
   1516 }
   1517 
   1518 int64 ObjectStoreFreeListKey::ObjectStoreId() const {
   1519   DCHECK_GE(object_store_id_, 0);
   1520   return object_store_id_;
   1521 }
   1522 
   1523 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey& other) {
   1524   // TODO(jsbell): It may seem strange that we're not comparing database id's,
   1525   // but that comparison will have been made earlier.
   1526   // We should probably make this more clear, though...
   1527   DCHECK_GE(object_store_id_, 0);
   1528   return CompareInts(object_store_id_, other.object_store_id_);
   1529 }
   1530 
   1531 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
   1532 
   1533 bool IndexFreeListKey::Decode(StringPiece* slice, IndexFreeListKey* result) {
   1534   KeyPrefix prefix;
   1535   if (!KeyPrefix::Decode(slice, &prefix))
   1536     return false;
   1537   DCHECK(prefix.database_id_);
   1538   DCHECK(!prefix.object_store_id_);
   1539   DCHECK(!prefix.index_id_);
   1540   unsigned char type_byte = 0;
   1541   if (!DecodeByte(slice, &type_byte))
   1542     return false;
   1543   DCHECK_EQ(type_byte, kIndexFreeListTypeByte);
   1544   if (!DecodeVarInt(slice, &result->object_store_id_))
   1545     return false;
   1546   if (!DecodeVarInt(slice, &result->index_id_))
   1547     return false;
   1548   return true;
   1549 }
   1550 
   1551 std::string IndexFreeListKey::Encode(int64 database_id,
   1552                                      int64 object_store_id,
   1553                                      int64 index_id) {
   1554   KeyPrefix prefix(database_id);
   1555   std::string ret = prefix.Encode();
   1556   ret.push_back(kIndexFreeListTypeByte);
   1557   EncodeVarInt(object_store_id, &ret);
   1558   EncodeVarInt(index_id, &ret);
   1559   return ret;
   1560 }
   1561 
   1562 std::string IndexFreeListKey::EncodeMaxKey(int64 database_id,
   1563                                            int64 object_store_id) {
   1564   return Encode(
   1565       database_id, object_store_id, std::numeric_limits<int64>::max());
   1566 }
   1567 
   1568 int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
   1569   DCHECK_GE(object_store_id_, 0);
   1570   DCHECK_GE(index_id_, 0);
   1571   if (int x = CompareInts(object_store_id_, other.object_store_id_))
   1572     return x;
   1573   return CompareInts(index_id_, other.index_id_);
   1574 }
   1575 
   1576 int64 IndexFreeListKey::ObjectStoreId() const {
   1577   DCHECK_GE(object_store_id_, 0);
   1578   return object_store_id_;
   1579 }
   1580 
   1581 int64 IndexFreeListKey::IndexId() const {
   1582   DCHECK_GE(index_id_, 0);
   1583   return index_id_;
   1584 }
   1585 
   1586 // TODO(jsbell): We never use this to look up object store ids,
   1587 // because a mapping is kept in the IndexedDBDatabase. Can the
   1588 // mapping become unreliable?  Can we remove this?
   1589 bool ObjectStoreNamesKey::Decode(StringPiece* slice,
   1590                                  ObjectStoreNamesKey* result) {
   1591   KeyPrefix prefix;
   1592   if (!KeyPrefix::Decode(slice, &prefix))
   1593     return false;
   1594   DCHECK(prefix.database_id_);
   1595   DCHECK(!prefix.object_store_id_);
   1596   DCHECK(!prefix.index_id_);
   1597   unsigned char type_byte = 0;
   1598   if (!DecodeByte(slice, &type_byte))
   1599     return false;
   1600   DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte);
   1601   if (!DecodeStringWithLength(slice, &result->object_store_name_))
   1602     return false;
   1603   return true;
   1604 }
   1605 
   1606 std::string ObjectStoreNamesKey::Encode(
   1607     int64 database_id,
   1608     const base::string16& object_store_name) {
   1609   KeyPrefix prefix(database_id);
   1610   std::string ret = prefix.Encode();
   1611   ret.push_back(kObjectStoreNamesTypeByte);
   1612   EncodeStringWithLength(object_store_name, &ret);
   1613   return ret;
   1614 }
   1615 
   1616 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) {
   1617   return object_store_name_.compare(other.object_store_name_);
   1618 }
   1619 
   1620 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
   1621 
   1622 // TODO(jsbell): We never use this to look up index ids, because a mapping
   1623 // is kept at a higher level.
   1624 bool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
   1625   KeyPrefix prefix;
   1626   if (!KeyPrefix::Decode(slice, &prefix))
   1627     return false;
   1628   DCHECK(prefix.database_id_);
   1629   DCHECK(!prefix.object_store_id_);
   1630   DCHECK(!prefix.index_id_);
   1631   unsigned char type_byte = 0;
   1632   if (!DecodeByte(slice, &type_byte))
   1633     return false;
   1634   DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte);
   1635   if (!DecodeVarInt(slice, &result->object_store_id_))
   1636     return false;
   1637   if (!DecodeStringWithLength(slice, &result->index_name_))
   1638     return false;
   1639   return true;
   1640 }
   1641 
   1642 std::string IndexNamesKey::Encode(int64 database_id,
   1643                                   int64 object_store_id,
   1644                                   const base::string16& index_name) {
   1645   KeyPrefix prefix(database_id);
   1646   std::string ret = prefix.Encode();
   1647   ret.push_back(kIndexNamesKeyTypeByte);
   1648   EncodeVarInt(object_store_id, &ret);
   1649   EncodeStringWithLength(index_name, &ret);
   1650   return ret;
   1651 }
   1652 
   1653 int IndexNamesKey::Compare(const IndexNamesKey& other) {
   1654   DCHECK_GE(object_store_id_, 0);
   1655   if (int x = CompareInts(object_store_id_, other.object_store_id_))
   1656     return x;
   1657   return index_name_.compare(other.index_name_);
   1658 }
   1659 
   1660 ObjectStoreDataKey::ObjectStoreDataKey() {}
   1661 ObjectStoreDataKey::~ObjectStoreDataKey() {}
   1662 
   1663 bool ObjectStoreDataKey::Decode(StringPiece* slice,
   1664                                 ObjectStoreDataKey* result) {
   1665   KeyPrefix prefix;
   1666   if (!KeyPrefix::Decode(slice, &prefix))
   1667     return false;
   1668   DCHECK(prefix.database_id_);
   1669   DCHECK(prefix.object_store_id_);
   1670   DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
   1671   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
   1672     return false;
   1673   return true;
   1674 }
   1675 
   1676 std::string ObjectStoreDataKey::Encode(int64 database_id,
   1677                                        int64 object_store_id,
   1678                                        const std::string encoded_user_key) {
   1679   KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
   1680       database_id, object_store_id, kSpecialIndexNumber));
   1681   std::string ret = prefix.Encode();
   1682   ret.append(encoded_user_key);
   1683 
   1684   return ret;
   1685 }
   1686 
   1687 std::string ObjectStoreDataKey::Encode(int64 database_id,
   1688                                        int64 object_store_id,
   1689                                        const IndexedDBKey& user_key) {
   1690   std::string encoded_key;
   1691   EncodeIDBKey(user_key, &encoded_key);
   1692   return Encode(database_id, object_store_id, encoded_key);
   1693 }
   1694 
   1695 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
   1696   scoped_ptr<IndexedDBKey> key;
   1697   StringPiece slice(encoded_user_key_);
   1698   if (!DecodeIDBKey(&slice, &key)) {
   1699     // TODO(jsbell): Return error.
   1700   }
   1701   return key.Pass();
   1702 }
   1703 
   1704 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
   1705 
   1706 ExistsEntryKey::ExistsEntryKey() {}
   1707 ExistsEntryKey::~ExistsEntryKey() {}
   1708 
   1709 bool ExistsEntryKey::Decode(StringPiece* slice, ExistsEntryKey* result) {
   1710   KeyPrefix prefix;
   1711   if (!KeyPrefix::Decode(slice, &prefix))
   1712     return false;
   1713   DCHECK(prefix.database_id_);
   1714   DCHECK(prefix.object_store_id_);
   1715   DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
   1716   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
   1717     return false;
   1718   return true;
   1719 }
   1720 
   1721 std::string ExistsEntryKey::Encode(int64 database_id,
   1722                                    int64 object_store_id,
   1723                                    const std::string& encoded_key) {
   1724   KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
   1725       database_id, object_store_id, kSpecialIndexNumber));
   1726   std::string ret = prefix.Encode();
   1727   ret.append(encoded_key);
   1728   return ret;
   1729 }
   1730 
   1731 std::string ExistsEntryKey::Encode(int64 database_id,
   1732                                    int64 object_store_id,
   1733                                    const IndexedDBKey& user_key) {
   1734   std::string encoded_key;
   1735   EncodeIDBKey(user_key, &encoded_key);
   1736   return Encode(database_id, object_store_id, encoded_key);
   1737 }
   1738 
   1739 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
   1740   scoped_ptr<IndexedDBKey> key;
   1741   StringPiece slice(encoded_user_key_);
   1742   if (!DecodeIDBKey(&slice, &key)) {
   1743     // TODO(jsbell): Return error.
   1744   }
   1745   return key.Pass();
   1746 }
   1747 
   1748 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
   1749 
   1750 IndexDataKey::IndexDataKey()
   1751     : database_id_(-1),
   1752       object_store_id_(-1),
   1753       index_id_(-1),
   1754       sequence_number_(-1) {}
   1755 
   1756 IndexDataKey::~IndexDataKey() {}
   1757 
   1758 bool IndexDataKey::Decode(StringPiece* slice, IndexDataKey* result) {
   1759   KeyPrefix prefix;
   1760   if (!KeyPrefix::Decode(slice, &prefix))
   1761     return false;
   1762   DCHECK(prefix.database_id_);
   1763   DCHECK(prefix.object_store_id_);
   1764   DCHECK_GE(prefix.index_id_, kMinimumIndexId);
   1765   result->database_id_ = prefix.database_id_;
   1766   result->object_store_id_ = prefix.object_store_id_;
   1767   result->index_id_ = prefix.index_id_;
   1768   result->sequence_number_ = -1;
   1769   result->encoded_primary_key_ = MinIDBKey();
   1770 
   1771   if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
   1772     return false;
   1773 
   1774   // [optional] sequence number
   1775   if (slice->empty())
   1776     return true;
   1777   if (!DecodeVarInt(slice, &result->sequence_number_))
   1778     return false;
   1779 
   1780   // [optional] primary key
   1781   if (slice->empty())
   1782     return true;
   1783   if (!ExtractEncodedIDBKey(slice, &result->encoded_primary_key_))
   1784     return false;
   1785   return true;
   1786 }
   1787 
   1788 std::string IndexDataKey::Encode(int64 database_id,
   1789                                  int64 object_store_id,
   1790                                  int64 index_id,
   1791                                  const std::string& encoded_user_key,
   1792                                  const std::string& encoded_primary_key,
   1793                                  int64 sequence_number) {
   1794   KeyPrefix prefix(database_id, object_store_id, index_id);
   1795   std::string ret = prefix.Encode();
   1796   ret.append(encoded_user_key);
   1797   EncodeVarInt(sequence_number, &ret);
   1798   ret.append(encoded_primary_key);
   1799   return ret;
   1800 }
   1801 
   1802 std::string IndexDataKey::Encode(int64 database_id,
   1803                                  int64 object_store_id,
   1804                                  int64 index_id,
   1805                                  const IndexedDBKey& user_key) {
   1806   std::string encoded_key;
   1807   EncodeIDBKey(user_key, &encoded_key);
   1808   return Encode(
   1809       database_id, object_store_id, index_id, encoded_key, MinIDBKey(), 0);
   1810 }
   1811 
   1812 std::string IndexDataKey::Encode(int64 database_id,
   1813                                  int64 object_store_id,
   1814                                  int64 index_id,
   1815                                  const IndexedDBKey& user_key,
   1816                                  const IndexedDBKey& user_primary_key) {
   1817   std::string encoded_key;
   1818   EncodeIDBKey(user_key, &encoded_key);
   1819   std::string encoded_primary_key;
   1820   EncodeIDBKey(user_primary_key, &encoded_primary_key);
   1821   return Encode(database_id,
   1822                 object_store_id,
   1823                 index_id,
   1824                 encoded_key,
   1825                 encoded_primary_key,
   1826                 0);
   1827 }
   1828 
   1829 std::string IndexDataKey::EncodeMinKey(int64 database_id,
   1830                                        int64 object_store_id,
   1831                                        int64 index_id) {
   1832   return Encode(
   1833       database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey(), 0);
   1834 }
   1835 
   1836 std::string IndexDataKey::EncodeMaxKey(int64 database_id,
   1837                                        int64 object_store_id,
   1838                                        int64 index_id) {
   1839   return Encode(database_id,
   1840                 object_store_id,
   1841                 index_id,
   1842                 MaxIDBKey(),
   1843                 MaxIDBKey(),
   1844                 std::numeric_limits<int64>::max());
   1845 }
   1846 
   1847 int64 IndexDataKey::DatabaseId() const {
   1848   DCHECK_GE(database_id_, 0);
   1849   return database_id_;
   1850 }
   1851 
   1852 int64 IndexDataKey::ObjectStoreId() const {
   1853   DCHECK_GE(object_store_id_, 0);
   1854   return object_store_id_;
   1855 }
   1856 
   1857 int64 IndexDataKey::IndexId() const {
   1858   DCHECK_GE(index_id_, 0);
   1859   return index_id_;
   1860 }
   1861 
   1862 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
   1863   scoped_ptr<IndexedDBKey> key;
   1864   StringPiece slice(encoded_user_key_);
   1865   if (!DecodeIDBKey(&slice, &key)) {
   1866     // TODO(jsbell): Return error.
   1867   }
   1868   return key.Pass();
   1869 }
   1870 
   1871 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
   1872   scoped_ptr<IndexedDBKey> key;
   1873   StringPiece slice(encoded_primary_key_);
   1874   if (!DecodeIDBKey(&slice, &key)) {
   1875     // TODO(jsbell): Return error.
   1876   }
   1877   return key.Pass();
   1878 }
   1879 
   1880 }  // namespace content
   1881