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