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