1 /* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "IDBLevelDBBackingStore.h" 28 29 #if ENABLE(INDEXED_DATABASE) 30 #if ENABLE(LEVELDB) 31 32 #include "Assertions.h" 33 #include "FileSystem.h" 34 #include "IDBFactoryBackendImpl.h" 35 #include "IDBKeyRange.h" 36 #include "LevelDBComparator.h" 37 #include "LevelDBDatabase.h" 38 #include "LevelDBIterator.h" 39 #include "LevelDBSlice.h" 40 #include "SecurityOrigin.h" 41 42 #ifndef INT64_MAX 43 // FIXME: We shouldn't need to rely on these macros. 44 #define INT64_MAX 0x7fffffffffffffffLL 45 #endif 46 #ifndef INT32_MAX 47 #define INT32_MAX 0x7fffffffL 48 #endif 49 50 // LevelDB stores key/value pairs. Keys and values are strings of bytes, normally of type Vector<char>. 51 // 52 // The keys in the backing store are variable-length tuples with different types 53 // of fields. Each key in the backing store starts with a ternary prefix: (database id, object store id, index id). For each, 0 is reserved for meta-data. 54 // The prefix makes sure that data for a specific database, object store, and index are grouped together. The locality is important for performance: common 55 // operations should only need a minimal number of seek operations. For example, all the meta-data for a database is grouped together so that reading that 56 // meta-data only requires one seek. 57 // 58 // Each key type has a class (in square brackets below) which knows how to encode, decode, and compare that key type. 59 // 60 // Global meta-data have keys with prefix (0,0,0), followed by a type byte: 61 // 62 // <0, 0, 0, 0> => IndexedDB/LevelDB schema version (0 for now) [SchemaVersionKey] 63 // <0, 0, 0, 1> => The maximum database id ever allocated [MaxDatabaseIdKey] 64 // <0, 0, 0, 100, database id> => Existence implies the database id is in the free list [DatabaseFreeListKey] 65 // <0, 0, 0, 201, utf16 origin name, utf16 database name> => Database id [DatabaseNameKey] 66 // 67 // 68 // Database meta-data: 69 // 70 // Again, the prefix is followed by a type byte. 71 // 72 // <database id, 0, 0, 0> => utf16 origin name [DatabaseMetaDataKey] 73 // <database id, 0, 0, 1> => utf16 database name [DatabaseMetaDataKey] 74 // <database id, 0, 0, 2> => utf16 user version data [DatabaseMetaDataKey] 75 // <database id, 0, 0, 3> => maximum object store id ever allocated [DatabaseMetaDataKey] 76 // 77 // 78 // Object store meta-data: 79 // 80 // The prefix is followed by a type byte, then a variable-length integer, and then another variable-length integer (FIXME: this should be a byte). 81 // 82 // <database id, 0, 0, 50, object store id, 0> => utf16 object store name [ObjectStoreMetaDataKey] 83 // <database id, 0, 0, 50, object store id, 1> => utf16 key path [ObjectStoreMetaDataKey] 84 // <database id, 0, 0, 50, object store id, 2> => has auto increment [ObjectStoreMetaDataKey] 85 // <database id, 0, 0, 50, object store id, 3> => is evictable [ObjectStoreMetaDataKey] 86 // <database id, 0, 0, 50, object store id, 4> => last "version" number [ObjectStoreMetaDataKey] 87 // <database id, 0, 0, 50, object store id, 5> => maximum index id ever allocated [ObjectStoreMetaDataKey] 88 // 89 // 90 // Index meta-data: 91 // 92 // The prefix is followed by a type byte, then two variable-length integers, and then another type byte. 93 // 94 // <database id, 0, 0, 100, object store id, index id, 0> => utf16 index name [IndexMetaDataKey] 95 // <database id, 0, 0, 100, object store id, index id, 1> => are index keys unique [IndexMetaDataKey] 96 // <database id, 0, 0, 100, object store id, index id, 2> => utf16 key path [IndexMetaDataKey] 97 // 98 // 99 // Other object store and index meta-data: 100 // 101 // The prefix is followed by a type byte. The object store and index id are variable length integers, the utf16 strings are variable length strings. 102 // 103 // <database id, 0, 0, 150, object store id> => existence implies the object store id is in the free list [ObjectStoreFreeListKey] 104 // <database id, 0, 0, 151, object store id, index id> => existence implies the index id is in the free list [IndexFreeListKey] 105 // <database id, 0, 0, 200, utf16 object store name> => object store id [ObjectStoreNamesKey] 106 // <database id, 0, 0, 201, object store id, utf16 index name> => index id [IndexNamesKey] 107 // 108 // 109 // Object store data: 110 // 111 // The prefix is followed by a type byte. The user key is an encoded IDBKey. 112 // 113 // <database id, object store id, 1, user key> => "version", serialized script value [ObjectStoreDataKey] 114 // 115 // 116 // "Exists" entry: 117 // 118 // The prefix is followed by a type byte. The user key is an encoded IDBKey. 119 // 120 // <database id, object store id, 2, user key> => "version" [ExistsEntryKey] 121 // 122 // 123 // Index data: 124 // 125 // The prefix is followed by a type byte. The user key is an encoded IDBKey. The sequence number is a variable length integer. 126 // 127 // <database id, object store id, index id, user key, sequence number> => "version", user key [IndexDataKey] 128 // 129 // (The sequence number is used to allow two entries with the same user key 130 // in non-unique indexes. The "version" field is used to weed out stale 131 // index data. Whenever new object store data is inserted, it gets a new 132 // "version" number, and new index data is written with this number. When 133 // the index is used for look-ups, entries are validated against the 134 // "exists" entries, and records with old "version" numbers are deleted 135 // when they are encountered in getPrimaryKeyViaIndex, 136 // IndexCursorImpl::loadCurrentRow, and IndexKeyCursorImpl::loadCurrentRow). 137 138 static const unsigned char kIDBKeyNullTypeByte = 0; 139 static const unsigned char kIDBKeyStringTypeByte = 1; 140 static const unsigned char kIDBKeyDateTypeByte = 2; 141 static const unsigned char kIDBKeyNumberTypeByte = 3; 142 static const unsigned char kIDBKeyMinKeyTypeByte = 4; 143 144 static const unsigned char kMinimumIndexId = 30; 145 static const unsigned char kObjectStoreDataIndexId = 1; 146 static const unsigned char kExistsEntryIndexId = 2; 147 148 static const unsigned char kSchemaVersionTypeByte = 0; 149 static const unsigned char kMaxDatabaseIdTypeByte = 1; 150 static const unsigned char kDatabaseFreeListTypeByte = 100; 151 static const unsigned char kDatabaseNameTypeByte = 201; 152 153 static const unsigned char kObjectStoreMetaDataTypeByte = 50; 154 static const unsigned char kIndexMetaDataTypeByte = 100; 155 static const unsigned char kObjectStoreFreeListTypeByte = 150; 156 static const unsigned char kIndexFreeListTypeByte = 151; 157 static const unsigned char kObjectStoreNamesTypeByte = 200; 158 static const unsigned char kIndexNamesKeyTypeByte = 201; 159 160 namespace WebCore { 161 162 static Vector<char> encodeByte(unsigned char c) 163 { 164 Vector<char> v; 165 v.append(c); 166 return v; 167 } 168 169 static Vector<char> maxIDBKey() 170 { 171 return encodeByte(kIDBKeyNullTypeByte); 172 } 173 174 static Vector<char> minIDBKey() 175 { 176 return encodeByte(kIDBKeyMinKeyTypeByte); 177 } 178 179 static Vector<char> encodeInt(int64_t n) 180 { 181 ASSERT(n >= 0); 182 Vector<char> ret; // FIXME: Size this at creation. 183 184 do { 185 unsigned char c = n; 186 ret.append(c); 187 n >>= 8; 188 } while (n); 189 190 return ret; 191 } 192 193 static int64_t decodeInt(const char* begin, const char* end) 194 { 195 ASSERT(begin <= end); 196 int64_t ret = 0; 197 198 while (begin < end) { 199 unsigned char c = *begin++; 200 ret = (ret << 8) | c; 201 } 202 203 return ret; 204 } 205 206 static Vector<char> encodeVarInt(int64_t n) 207 { 208 Vector<char> ret; // FIXME: Size this at creation. 209 210 do { 211 unsigned char c = n & 0x7f; 212 n >>= 7; 213 if (n) 214 c |= 128; 215 ret.append(c); 216 } while (n); 217 218 return ret; 219 } 220 221 static const char* decodeVarInt(const char *p, const char* limit, int64_t& foundInt) 222 { 223 ASSERT(limit >= p); 224 foundInt = 0; 225 226 do { 227 if (p >= limit) 228 return 0; 229 230 foundInt = (foundInt << 7) | (*p & 0x7f); 231 } while (*p++ & 128); 232 return p; 233 } 234 235 static Vector<char> encodeString(const String& s) 236 { 237 Vector<char> ret; // FIXME: Size this at creation. 238 239 for (unsigned i = 0; i < s.length(); ++i) { 240 UChar u = s[i]; 241 unsigned char hi = u >> 8; 242 unsigned char lo = u; 243 ret.append(hi); 244 ret.append(lo); 245 } 246 247 return ret; 248 } 249 250 static String decodeString(const char* p, const char* end) 251 { 252 ASSERT(end >= p); 253 ASSERT(!((end - p) % 2)); 254 255 size_t len = (end - p) / 2; 256 Vector<UChar> vector(len); 257 258 for (size_t i = 0; i < len; ++i) { 259 unsigned char hi = *p++; 260 unsigned char lo = *p++; 261 262 vector[i] = (hi << 8) | lo; 263 } 264 265 return String::adopt(vector); 266 } 267 268 static Vector<char> encodeStringWithLength(const String& s) 269 { 270 Vector<char> ret = encodeVarInt(s.length()); 271 ret.append(encodeString(s)); 272 return ret; 273 } 274 275 static const char* decodeStringWithLength(const char* p, const char* limit, String& foundString) 276 { 277 ASSERT(limit >= p); 278 int64_t len; 279 p = decodeVarInt(p, limit, len); 280 if (!p) 281 return 0; 282 if (p + len * 2 > limit) 283 return 0; 284 285 foundString = decodeString(p, p + len * 2); 286 p += len * 2; 287 return p; 288 } 289 290 static Vector<char> encodeDouble(double x) 291 { 292 // FIXME: It would be nice if we could be byte order independent. 293 const char* p = reinterpret_cast<char*>(&x); 294 Vector<char> v; 295 v.append(p, sizeof(x)); 296 ASSERT(v.size() == sizeof(x)); 297 return v; 298 } 299 300 static const char* decodeDouble(const char* p, const char* limit, double* d) 301 { 302 if (p + sizeof(*d) > limit) 303 return 0; 304 305 char* x = reinterpret_cast<char*>(d); 306 for (size_t i = 0; i < sizeof(*d); ++i) 307 *x++ = *p++; 308 return p; 309 } 310 311 static Vector<char> encodeIDBKey(const IDBKey& key) 312 { 313 Vector<char> ret; 314 315 switch (key.type()) { 316 case IDBKey::NullType: 317 return encodeByte(kIDBKeyNullTypeByte); 318 case IDBKey::StringType: 319 ret = encodeByte(kIDBKeyStringTypeByte); 320 ret.append(encodeStringWithLength(key.string())); 321 return ret; 322 case IDBKey::DateType: 323 ret = encodeByte(kIDBKeyDateTypeByte); 324 ret.append(encodeDouble(key.date())); 325 ASSERT(ret.size() == 9); 326 return ret; 327 case IDBKey::NumberType: 328 ret = encodeByte(kIDBKeyNumberTypeByte); 329 ret.append(encodeDouble(key.number())); 330 ASSERT(ret.size() == 9); 331 return ret; 332 } 333 334 ASSERT_NOT_REACHED(); 335 return Vector<char>(); 336 } 337 338 static const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey) 339 { 340 ASSERT(limit >= p); 341 if (p >= limit) 342 return 0; 343 344 unsigned char type = *p++; 345 String s; 346 double d; 347 348 switch (type) { 349 case kIDBKeyNullTypeByte: 350 // Null. 351 foundKey = IDBKey::createNull(); 352 return p; 353 case kIDBKeyStringTypeByte: 354 // String. 355 p = decodeStringWithLength(p, limit, s); 356 if (!p) 357 return 0; 358 foundKey = IDBKey::createString(s); 359 return p; 360 case kIDBKeyDateTypeByte: 361 // Date. 362 p = decodeDouble(p, limit, &d); 363 if (!p) 364 return 0; 365 foundKey = IDBKey::createDate(d); 366 return p; 367 case kIDBKeyNumberTypeByte: 368 // Number. 369 p = decodeDouble(p, limit, &d); 370 if (!p) 371 return 0; 372 foundKey = IDBKey::createNumber(d); 373 return p; 374 } 375 376 ASSERT_NOT_REACHED(); 377 return 0; 378 } 379 380 static const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result) 381 { 382 const char* p = start; 383 if (p >= limit) 384 return 0; 385 386 unsigned char type = *p++; 387 388 int64_t stringLen; 389 390 switch (type) { 391 case kIDBKeyNullTypeByte: 392 case kIDBKeyMinKeyTypeByte: 393 *result = encodeByte(type); 394 return p; 395 case kIDBKeyStringTypeByte: 396 // String. 397 p = decodeVarInt(p, limit, stringLen); 398 if (!p) 399 return 0; 400 if (p + stringLen * 2 > limit) 401 return 0; 402 result->clear(); 403 result->append(start, p - start + stringLen * 2); 404 return p + stringLen * 2; 405 case kIDBKeyDateTypeByte: 406 case kIDBKeyNumberTypeByte: 407 // Date or number. 408 if (p + sizeof(double) > limit) 409 return 0; 410 result->clear(); 411 result->append(start, 1 + sizeof(double)); 412 return p + sizeof(double); 413 } 414 ASSERT_NOT_REACHED(); 415 return 0; 416 } 417 418 static int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB) 419 { 420 ASSERT(keyA.size() >= 1); 421 ASSERT(keyB.size() >= 1); 422 423 const char* p = keyA.data(); 424 const char* limitA = p + keyA.size(); 425 const char* q = keyB.data(); 426 const char* limitB = q + keyB.size(); 427 428 unsigned char typeA = *p++; 429 unsigned char typeB = *q++; 430 431 String s, t; 432 double d, e; 433 434 if (int x = typeB - typeA) // FIXME: Note the subtleness! 435 return x; 436 437 switch (typeA) { 438 case kIDBKeyNullTypeByte: 439 case kIDBKeyMinKeyTypeByte: 440 // Null type or max type; no payload to compare. 441 return 0; 442 case kIDBKeyStringTypeByte: 443 // String type. 444 p = decodeStringWithLength(p, limitA, s); // FIXME: Compare without actually decoding the String! 445 ASSERT(p); 446 q = decodeStringWithLength(q, limitB, t); 447 ASSERT(q); 448 return codePointCompare(s, t); 449 case kIDBKeyDateTypeByte: 450 case kIDBKeyNumberTypeByte: 451 // Date or number. 452 p = decodeDouble(p, limitA, &d); 453 ASSERT(p); 454 q = decodeDouble(q, limitB, &e); 455 ASSERT(q); 456 if (d < e) 457 return -1; 458 if (d > e) 459 return 1; 460 return 0; 461 } 462 463 ASSERT_NOT_REACHED(); 464 return 0; 465 } 466 467 static bool getInt(LevelDBDatabase* db, const Vector<char>& key, int64_t& foundInt) 468 { 469 Vector<char> result; 470 if (!db->get(key, result)) 471 return false; 472 473 foundInt = decodeInt(result.begin(), result.end()); 474 return true; 475 } 476 477 static bool putInt(LevelDBDatabase* db, const Vector<char>& key, int64_t value) 478 { 479 return db->put(key, encodeInt(value)); 480 } 481 482 static bool getString(LevelDBDatabase* db, const Vector<char>& key, String& foundString) 483 { 484 Vector<char> result; 485 if (!db->get(key, result)) 486 return false; 487 488 foundString = decodeString(result.begin(), result.end()); 489 return true; 490 } 491 492 static bool putString(LevelDBDatabase* db, const Vector<char> key, const String& value) 493 { 494 if (!db->put(key, encodeString(value))) 495 return false; 496 return true; 497 } 498 499 namespace { 500 class KeyPrefix { 501 public: 502 KeyPrefix() 503 : m_databaseId(kInvalidType) 504 , m_objectStoreId(kInvalidType) 505 , m_indexId(kInvalidType) 506 { 507 } 508 509 KeyPrefix(int64_t databaseId, int64_t objectStoreId, int64_t indexId) 510 : m_databaseId(databaseId) 511 , m_objectStoreId(objectStoreId) 512 , m_indexId(indexId) 513 { 514 } 515 516 static const char* decode(const char* start, const char* limit, KeyPrefix* result) 517 { 518 if (start == limit) 519 return 0; 520 521 unsigned char firstByte = *start++; 522 523 int databaseIdBytes = ((firstByte >> 5) & 0x7) + 1; 524 int objectStoreIdBytes = ((firstByte >> 2) & 0x7) + 1; 525 int indexIdBytes = (firstByte & 0x3) + 1; 526 527 if (start + databaseIdBytes + objectStoreIdBytes + indexIdBytes > limit) 528 return 0; 529 530 result->m_databaseId = decodeInt(start, start + databaseIdBytes); 531 start += databaseIdBytes; 532 result->m_objectStoreId = decodeInt(start, start + objectStoreIdBytes); 533 start += objectStoreIdBytes; 534 result->m_indexId = decodeInt(start, start + indexIdBytes); 535 start += indexIdBytes; 536 537 return start; 538 } 539 540 Vector<char> encode() const 541 { 542 ASSERT(m_databaseId != kInvalidId); 543 ASSERT(m_objectStoreId != kInvalidId); 544 ASSERT(m_indexId != kInvalidId); 545 546 Vector<char> databaseIdString = encodeInt(m_databaseId); 547 Vector<char> objectStoreIdString = encodeInt(m_objectStoreId); 548 Vector<char> indexIdString = encodeInt(m_indexId); 549 550 ASSERT(databaseIdString.size() <= 8); 551 ASSERT(objectStoreIdString.size() <= 8); 552 ASSERT(indexIdString.size() <= 4); 553 554 555 unsigned char firstByte = (databaseIdString.size() - 1) << 5 | (objectStoreIdString.size() - 1) << 2 | (indexIdString.size() - 1); 556 Vector<char> ret; 557 ret.append(firstByte); 558 ret.append(databaseIdString); 559 ret.append(objectStoreIdString); 560 ret.append(indexIdString); 561 562 return ret; 563 } 564 565 int compare(const KeyPrefix& other) const 566 { 567 ASSERT(m_databaseId != kInvalidId); 568 ASSERT(m_objectStoreId != kInvalidId); 569 ASSERT(m_indexId != kInvalidId); 570 571 if (m_databaseId != other.m_databaseId) 572 return m_databaseId - other.m_databaseId; 573 if (m_objectStoreId != other.m_objectStoreId) 574 return m_objectStoreId - other.m_objectStoreId; 575 if (m_indexId != other.m_indexId) 576 return m_indexId - other.m_indexId; 577 return 0; 578 } 579 580 enum Type { 581 kGlobalMetaData, 582 kDatabaseMetaData, 583 kObjectStoreData, 584 kExistsEntry, 585 kIndexData, 586 kInvalidType 587 }; 588 589 Type type() const 590 { 591 ASSERT(m_databaseId != kInvalidId); 592 ASSERT(m_objectStoreId != kInvalidId); 593 ASSERT(m_indexId != kInvalidId); 594 595 if (!m_databaseId) 596 return kGlobalMetaData; 597 if (!m_objectStoreId) 598 return kDatabaseMetaData; 599 if (m_indexId == kObjectStoreDataIndexId) 600 return kObjectStoreData; 601 if (m_indexId == kExistsEntryIndexId) 602 return kExistsEntry; 603 if (m_indexId >= kMinimumIndexId) 604 return kIndexData; 605 606 ASSERT_NOT_REACHED(); 607 return kInvalidType; 608 } 609 610 int64_t m_databaseId; 611 int64_t m_objectStoreId; 612 int64_t m_indexId; 613 614 static const int64_t kInvalidId = -1; 615 }; 616 617 class SchemaVersionKey { 618 public: 619 static Vector<char> encode() 620 { 621 KeyPrefix prefix(0, 0, 0); 622 Vector<char> ret = prefix.encode(); 623 ret.append(encodeByte(kSchemaVersionTypeByte)); 624 return ret; 625 } 626 }; 627 628 class MaxDatabaseIdKey { 629 public: 630 static Vector<char> encode() 631 { 632 KeyPrefix prefix(0, 0, 0); 633 Vector<char> ret = prefix.encode(); 634 ret.append(encodeByte(kMaxDatabaseIdTypeByte)); 635 return ret; 636 } 637 }; 638 639 class DatabaseFreeListKey { 640 public: 641 DatabaseFreeListKey() 642 : m_databaseId(-1) 643 { 644 } 645 646 static const char* decode(const char* start, const char* limit, DatabaseFreeListKey* result) 647 { 648 KeyPrefix prefix; 649 const char *p = KeyPrefix::decode(start, limit, &prefix); 650 if (!p) 651 return 0; 652 ASSERT(!prefix.m_databaseId); 653 ASSERT(!prefix.m_objectStoreId); 654 ASSERT(!prefix.m_indexId); 655 if (p == limit) 656 return 0; 657 unsigned char typeByte = *p++; 658 ASSERT_UNUSED(typeByte, typeByte == kDatabaseFreeListTypeByte); 659 if (p == limit) 660 return 0; 661 return decodeVarInt(p, limit, result->m_databaseId); 662 } 663 664 static Vector<char> encode(int64_t databaseId) 665 { 666 KeyPrefix prefix(0, 0, 0); 667 Vector<char> ret = prefix.encode(); 668 ret.append(encodeByte(kDatabaseFreeListTypeByte)); 669 ret.append(encodeVarInt(databaseId)); 670 return ret; 671 } 672 673 int64_t databaseId() const 674 { 675 ASSERT(m_databaseId >= 0); 676 return m_databaseId; 677 } 678 679 int compare(const DatabaseFreeListKey& other) const 680 { 681 ASSERT(m_databaseId >= 0); 682 return m_databaseId - other.m_databaseId; 683 } 684 685 private: 686 int64_t m_databaseId; 687 }; 688 689 class DatabaseNameKey { 690 public: 691 static const char* decode(const char* start, const char* limit, DatabaseNameKey* result) 692 { 693 KeyPrefix prefix; 694 const char* p = KeyPrefix::decode(start, limit, &prefix); 695 if (!p) 696 return p; 697 ASSERT(!prefix.m_databaseId); 698 ASSERT(!prefix.m_objectStoreId); 699 ASSERT(!prefix.m_indexId); 700 if (p == limit) 701 return 0; 702 unsigned char typeByte = *p++; 703 ASSERT_UNUSED(typeByte, typeByte == kDatabaseNameTypeByte); 704 if (p == limit) 705 return 0; 706 p = decodeStringWithLength(p, limit, result->m_origin); 707 if (!p) 708 return 0; 709 return decodeStringWithLength(p, limit, result->m_databaseName); 710 } 711 712 static Vector<char> encode(const String& origin, const String& databaseName) 713 { 714 KeyPrefix prefix(0, 0, 0); 715 Vector<char> ret = prefix.encode(); 716 ret.append(encodeByte(kDatabaseNameTypeByte)); 717 ret.append(encodeStringWithLength(origin)); 718 ret.append(encodeStringWithLength(databaseName)); 719 return ret; 720 } 721 722 String origin() const { return m_origin; } 723 String databaseName() const { return m_databaseName; } 724 725 int compare(const DatabaseNameKey& other) 726 { 727 if (int x = codePointCompare(m_origin, other.m_origin)) 728 return x; 729 return codePointCompare(m_databaseName, other.m_databaseName); 730 } 731 732 private: 733 String m_origin; // FIXME: Store encoded strings, or just pointers. 734 String m_databaseName; 735 }; 736 737 class DatabaseMetaDataKey { 738 public: 739 enum MetaDataType { 740 kOriginName = 0, 741 kDatabaseName = 1, 742 kUserVersion = 2, 743 kMaxObjectStoreId = 3 744 }; 745 746 static Vector<char> encode(int64_t databaseId, MetaDataType metaDataType) 747 { 748 KeyPrefix prefix(databaseId, 0, 0); 749 Vector<char> ret = prefix.encode(); 750 ret.append(encodeByte(metaDataType)); 751 return ret; 752 } 753 }; 754 755 class ObjectStoreMetaDataKey { 756 public: 757 ObjectStoreMetaDataKey() 758 : m_objectStoreId(-1) 759 , m_metaDataType(-1) 760 { 761 } 762 763 static const char* decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result) 764 { 765 KeyPrefix prefix; 766 const char* p = KeyPrefix::decode(start, limit, &prefix); 767 if (!p) 768 return 0; 769 ASSERT(prefix.m_databaseId); 770 ASSERT(!prefix.m_objectStoreId); 771 ASSERT(!prefix.m_indexId); 772 if (p == limit) 773 return 0; 774 unsigned char typeByte = *p++; 775 ASSERT_UNUSED(typeByte, typeByte == kObjectStoreMetaDataTypeByte); 776 if (p == limit) 777 return 0; 778 p = decodeVarInt(p, limit, result->m_objectStoreId); 779 if (!p) 780 return 0; 781 ASSERT(result->m_objectStoreId); 782 if (p == limit) 783 return 0; 784 return decodeVarInt(p, limit, result->m_metaDataType); 785 } 786 787 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t metaDataType) 788 { 789 KeyPrefix prefix(databaseId, 0, 0); 790 Vector<char> ret = prefix.encode(); 791 ret.append(encodeByte(kObjectStoreMetaDataTypeByte)); 792 ret.append(encodeVarInt(objectStoreId)); 793 ret.append(encodeVarInt(metaDataType)); 794 return ret; 795 } 796 797 int64_t objectStoreId() const 798 { 799 ASSERT(m_objectStoreId >= 0); 800 return m_objectStoreId; 801 } 802 int64_t metaDataType() const 803 { 804 ASSERT(m_metaDataType >= 0); 805 return m_metaDataType; 806 } 807 808 int compare(const ObjectStoreMetaDataKey& other) 809 { 810 ASSERT(m_objectStoreId >= 0); 811 ASSERT(m_metaDataType >= 0); 812 if (int x = m_objectStoreId - other.m_objectStoreId) 813 return x; // FIXME: Is this cast safe? I.e., will it preserve the sign? 814 return m_metaDataType - other.m_metaDataType; 815 } 816 817 private: 818 int64_t m_objectStoreId; 819 int64_t m_metaDataType; // FIXME: Make this a byte. 820 }; 821 822 class IndexMetaDataKey { 823 public: 824 IndexMetaDataKey() 825 : m_objectStoreId(-1) 826 , m_indexId(-1) 827 , m_metaDataType(0) 828 { 829 } 830 831 static const char* decode(const char* start, const char* limit, IndexMetaDataKey* result) 832 { 833 KeyPrefix prefix; 834 const char* p = KeyPrefix::decode(start, limit, &prefix); 835 if (!p) 836 return 0; 837 ASSERT(prefix.m_databaseId); 838 ASSERT(!prefix.m_objectStoreId); 839 ASSERT(!prefix.m_indexId); 840 if (p == limit) 841 return 0; 842 unsigned char typeByte = *p++; 843 ASSERT_UNUSED(typeByte, typeByte == kIndexMetaDataTypeByte); 844 if (p == limit) 845 return 0; 846 p = decodeVarInt(p, limit, result->m_objectStoreId); 847 if (!p) 848 return 0; 849 p = decodeVarInt(p, limit, result->m_indexId); 850 if (!p) 851 return 0; 852 if (p == limit) 853 return 0; 854 result->m_metaDataType = *p++; 855 return p; 856 } 857 858 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, unsigned char metaDataType) 859 { 860 KeyPrefix prefix(databaseId, 0, 0); 861 Vector<char> ret = prefix.encode(); 862 ret.append(encodeByte(kIndexMetaDataTypeByte)); 863 ret.append(encodeVarInt(objectStoreId)); 864 ret.append(encodeVarInt(indexId)); 865 ret.append(encodeByte(metaDataType)); 866 return ret; 867 } 868 869 int compare(const IndexMetaDataKey& other) 870 { 871 ASSERT(m_objectStoreId >= 0); 872 ASSERT(m_indexId >= 0); 873 874 if (int x = m_objectStoreId - other.m_objectStoreId) 875 return x; 876 if (int x = m_indexId - other.m_indexId) 877 return x; 878 return m_metaDataType - other.m_metaDataType; 879 } 880 881 int64_t indexId() const 882 { 883 ASSERT(m_indexId >= 0); 884 return m_indexId; 885 } 886 887 unsigned char metaDataType() const { return m_metaDataType; } 888 889 private: 890 int64_t m_objectStoreId; 891 int64_t m_indexId; 892 unsigned char m_metaDataType; 893 }; 894 895 class ObjectStoreFreeListKey { 896 public: 897 ObjectStoreFreeListKey() 898 : m_objectStoreId(-1) 899 { 900 } 901 902 static const char* decode(const char* start, const char* limit, ObjectStoreFreeListKey* result) 903 { 904 KeyPrefix prefix; 905 const char *p = KeyPrefix::decode(start, limit, &prefix); 906 if (!p) 907 return 0; 908 ASSERT(prefix.m_databaseId); 909 ASSERT(!prefix.m_objectStoreId); 910 ASSERT(!prefix.m_indexId); 911 if (p == limit) 912 return 0; 913 unsigned char typeByte = *p++; 914 ASSERT_UNUSED(typeByte, typeByte == kObjectStoreFreeListTypeByte); 915 if (p == limit) 916 return 0; 917 return decodeVarInt(p, limit, result->m_objectStoreId); 918 } 919 920 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId) 921 { 922 KeyPrefix prefix(databaseId, 0, 0); 923 Vector<char> ret = prefix.encode(); 924 ret.append(encodeByte(kObjectStoreFreeListTypeByte)); 925 ret.append(encodeVarInt(objectStoreId)); 926 return ret; 927 } 928 929 int64_t objectStoreId() const 930 { 931 ASSERT(m_objectStoreId >= 0); 932 return m_objectStoreId; 933 } 934 935 int compare(const ObjectStoreFreeListKey& other) 936 { 937 // FIXME: It may seem strange that we're not comparing database id's, 938 // but that comparison will have been made earlier. 939 // We should probably make this more clear, though... 940 ASSERT(m_objectStoreId >= 0); 941 return m_objectStoreId - other.m_objectStoreId; 942 } 943 944 private: 945 int64_t m_objectStoreId; 946 }; 947 948 class IndexFreeListKey { 949 public: 950 IndexFreeListKey() 951 : m_objectStoreId(-1) 952 , m_indexId(-1) 953 { 954 } 955 956 static const char* decode(const char* start, const char* limit, IndexFreeListKey* result) 957 { 958 KeyPrefix prefix; 959 const char* p = KeyPrefix::decode(start, limit, &prefix); 960 if (!p) 961 return 0; 962 ASSERT(prefix.m_databaseId); 963 ASSERT(!prefix.m_objectStoreId); 964 ASSERT(!prefix.m_indexId); 965 if (p == limit) 966 return 0; 967 unsigned char typeByte = *p++; 968 ASSERT_UNUSED(typeByte, typeByte == kIndexFreeListTypeByte); 969 if (p == limit) 970 return 0; 971 p = decodeVarInt(p, limit, result->m_objectStoreId); 972 if (!p) 973 return 0; 974 return decodeVarInt(p, limit, result->m_indexId); 975 } 976 977 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId) 978 { 979 KeyPrefix prefix(databaseId, 0, 0); 980 Vector<char> ret = prefix.encode(); 981 ret.append(encodeByte(kIndexFreeListTypeByte)); 982 ret.append(encodeVarInt(objectStoreId)); 983 ret.append(encodeVarInt(indexId)); 984 return ret; 985 } 986 987 int compare(const IndexFreeListKey& other) 988 { 989 ASSERT(m_objectStoreId >= 0); 990 ASSERT(m_indexId >= 0); 991 if (int x = m_objectStoreId - other.m_objectStoreId) 992 return x; 993 return m_indexId - other.m_indexId; 994 } 995 996 int64_t objectStoreId() const 997 { 998 ASSERT(m_objectStoreId >= 0); 999 return m_objectStoreId; 1000 } 1001 1002 int64_t indexId() const 1003 { 1004 ASSERT(m_indexId >= 0); 1005 return m_indexId; 1006 } 1007 1008 private: 1009 int64_t m_objectStoreId; 1010 int64_t m_indexId; 1011 }; 1012 1013 class ObjectStoreNamesKey { 1014 public: 1015 // FIXME: We never use this to look up object store ids, because a mapping 1016 // is kept in the IDBDatabaseBackendImpl. Can the mapping become unreliable? 1017 // Can we remove this? 1018 static const char* decode(const char* start, const char* limit, ObjectStoreNamesKey* result) 1019 { 1020 KeyPrefix prefix; 1021 const char* p = KeyPrefix::decode(start, limit, &prefix); 1022 if (!p) 1023 return 0; 1024 ASSERT(prefix.m_databaseId); 1025 ASSERT(!prefix.m_objectStoreId); 1026 ASSERT(!prefix.m_indexId); 1027 if (p == limit) 1028 return 0; 1029 unsigned char typeByte = *p++; 1030 ASSERT_UNUSED(typeByte, typeByte == kObjectStoreNamesTypeByte); 1031 return decodeStringWithLength(p, limit, result->m_objectStoreName); 1032 } 1033 1034 static Vector<char> encode(int64_t databaseId, const String& objectStoreName) 1035 { 1036 KeyPrefix prefix(databaseId, 0, 0); 1037 Vector<char> ret = prefix.encode(); 1038 ret.append(encodeByte(kSchemaVersionTypeByte)); 1039 ret.append(encodeByte(kObjectStoreNamesTypeByte)); 1040 ret.append(encodeStringWithLength(objectStoreName)); 1041 return ret; 1042 } 1043 1044 int compare(const ObjectStoreNamesKey& other) 1045 { 1046 return codePointCompare(m_objectStoreName, other.m_objectStoreName); 1047 } 1048 1049 String objectStoreName() const { return m_objectStoreName; } 1050 1051 private: 1052 String m_objectStoreName; // FIXME: Store the encoded string, or just pointers to it. 1053 }; 1054 1055 class IndexNamesKey { 1056 public: 1057 IndexNamesKey() 1058 : m_objectStoreId(-1) 1059 { 1060 } 1061 1062 // FIXME: We never use this to look up index ids, because a mapping 1063 // is kept at a higher level. 1064 static const char* decode(const char* start, const char* limit, IndexNamesKey* result) 1065 { 1066 KeyPrefix prefix; 1067 const char* p = KeyPrefix::decode(start, limit, &prefix); 1068 if (!p) 1069 return 0; 1070 ASSERT(prefix.m_databaseId); 1071 ASSERT(!prefix.m_objectStoreId); 1072 ASSERT(!prefix.m_indexId); 1073 if (p == limit) 1074 return 0; 1075 unsigned char typeByte = *p++; 1076 ASSERT_UNUSED(typeByte, typeByte == kIndexNamesKeyTypeByte); 1077 if (p == limit) 1078 return 0; 1079 p = decodeVarInt(p, limit, result->m_objectStoreId); 1080 if (!p) 1081 return 0; 1082 return decodeStringWithLength(p, limit, result->m_indexName); 1083 } 1084 1085 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const String& indexName) 1086 { 1087 KeyPrefix prefix(databaseId, 0, 0); 1088 Vector<char> ret = prefix.encode(); 1089 ret.append(encodeByte(kIndexNamesKeyTypeByte)); 1090 ret.append(encodeVarInt(objectStoreId)); 1091 ret.append(encodeStringWithLength(indexName)); 1092 return ret; 1093 } 1094 1095 int compare(const IndexNamesKey& other) 1096 { 1097 ASSERT(m_objectStoreId >= 0); 1098 if (int x = m_objectStoreId - other.m_objectStoreId) 1099 return x; 1100 return codePointCompare(m_indexName, other.m_indexName); 1101 } 1102 1103 String indexName() const { return m_indexName; } 1104 1105 private: 1106 int64_t m_objectStoreId; 1107 String m_indexName; 1108 }; 1109 1110 class ObjectStoreDataKey { 1111 public: 1112 static const char* decode(const char* start, const char* end, ObjectStoreDataKey* result) 1113 { 1114 KeyPrefix prefix; 1115 const char* p = KeyPrefix::decode(start, end, &prefix); 1116 if (!p) 1117 return 0; 1118 ASSERT(prefix.m_databaseId); 1119 ASSERT(prefix.m_objectStoreId); 1120 ASSERT(prefix.m_indexId == kSpecialIndexNumber); 1121 if (p == end) 1122 return 0; 1123 return extractEncodedIDBKey(p, end, &result->m_encodedUserKey); 1124 } 1125 1126 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char> encodedUserKey) 1127 { 1128 KeyPrefix prefix(databaseId, objectStoreId, kSpecialIndexNumber); 1129 Vector<char> ret = prefix.encode(); 1130 ret.append(encodedUserKey); 1131 1132 return ret; 1133 } 1134 1135 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey) 1136 { 1137 return encode(databaseId, objectStoreId, encodeIDBKey(userKey)); 1138 } 1139 1140 int compare(const ObjectStoreDataKey& other) 1141 { 1142 return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey); 1143 } 1144 1145 PassRefPtr<IDBKey> userKey() const 1146 { 1147 RefPtr<IDBKey> key; 1148 decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key); 1149 return key; 1150 } 1151 1152 static const int64_t kSpecialIndexNumber = kObjectStoreDataIndexId; 1153 1154 private: 1155 Vector<char> m_encodedUserKey; 1156 }; 1157 1158 class ExistsEntryKey { 1159 public: 1160 static const char* decode(const char* start, const char* end, ExistsEntryKey* result) 1161 { 1162 KeyPrefix prefix; 1163 const char* p = KeyPrefix::decode(start, end, &prefix); 1164 if (!p) 1165 return 0; 1166 ASSERT(prefix.m_databaseId); 1167 ASSERT(prefix.m_objectStoreId); 1168 ASSERT(prefix.m_indexId == kSpecialIndexNumber); 1169 if (p == end) 1170 return 0; 1171 return extractEncodedIDBKey(p, end, &result->m_encodedUserKey); 1172 } 1173 1174 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char>& encodedKey) 1175 { 1176 KeyPrefix prefix(databaseId, objectStoreId, kSpecialIndexNumber); 1177 Vector<char> ret = prefix.encode(); 1178 ret.append(encodedKey); 1179 return ret; 1180 } 1181 1182 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey) 1183 { 1184 return encode(databaseId, objectStoreId, encodeIDBKey(userKey)); 1185 } 1186 1187 int compare(const ExistsEntryKey& other) 1188 { 1189 return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey); 1190 } 1191 1192 PassRefPtr<IDBKey> userKey() const 1193 { 1194 RefPtr<IDBKey> key; 1195 decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key); 1196 return key; 1197 } 1198 1199 static const int64_t kSpecialIndexNumber = kExistsEntryIndexId; 1200 1201 private: 1202 Vector<char> m_encodedUserKey; 1203 }; 1204 1205 class IndexDataKey { 1206 public: 1207 IndexDataKey() 1208 : m_databaseId(-1) 1209 , m_objectStoreId(-1) 1210 , m_indexId(-1) 1211 , m_sequenceNumber(-1) 1212 { 1213 } 1214 1215 static const char* decode(const char* start, const char* limit, IndexDataKey* result) 1216 { 1217 KeyPrefix prefix; 1218 const char* p = KeyPrefix::decode(start, limit, &prefix); 1219 if (!p) 1220 return 0; 1221 ASSERT(prefix.m_databaseId); 1222 ASSERT(prefix.m_objectStoreId); 1223 ASSERT(prefix.m_indexId >= kMinimumIndexId); 1224 result->m_databaseId = prefix.m_databaseId; 1225 result->m_objectStoreId = prefix.m_objectStoreId; 1226 result->m_indexId = prefix.m_indexId; 1227 p = extractEncodedIDBKey(p, limit, &result->m_encodedUserKey); 1228 if (!p) 1229 return 0; 1230 if (p == limit) { 1231 result->m_sequenceNumber = -1; // FIXME: We should change it so that all keys have a sequence number. Shouldn't need to handle this case. 1232 return p; 1233 } 1234 return decodeVarInt(p, limit, result->m_sequenceNumber); 1235 } 1236 1237 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const Vector<char>& encodedUserKey, int64_t sequenceNumber) 1238 { 1239 KeyPrefix prefix(databaseId, objectStoreId, indexId); 1240 Vector<char> ret = prefix.encode(); 1241 ret.append(encodedUserKey); 1242 ret.append(encodeVarInt(sequenceNumber)); 1243 return ret; 1244 } 1245 1246 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& userKey, int64_t sequenceNumber) 1247 { 1248 return encode(databaseId, objectStoreId, indexId, encodeIDBKey(userKey), sequenceNumber); 1249 } 1250 1251 static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId) 1252 { 1253 return encode(databaseId, objectStoreId, INT32_MAX, maxIDBKey(), INT64_MAX); 1254 } 1255 1256 int compare(const IndexDataKey& other, bool ignoreSequenceNumber) 1257 { 1258 ASSERT(m_databaseId >= 0); 1259 ASSERT(m_objectStoreId >= 0); 1260 ASSERT(m_indexId >= 0); 1261 if (int x = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey)) 1262 return x; 1263 if (ignoreSequenceNumber) 1264 return 0; 1265 return m_sequenceNumber - other.m_sequenceNumber; 1266 } 1267 1268 int64_t databaseId() const 1269 { 1270 ASSERT(m_databaseId >= 0); 1271 return m_databaseId; 1272 } 1273 1274 int64_t objectStoreId() const 1275 { 1276 ASSERT(m_objectStoreId >= 0); 1277 return m_objectStoreId; 1278 } 1279 1280 int64_t indexId() const 1281 { 1282 ASSERT(m_indexId >= 0); 1283 return m_indexId; 1284 } 1285 1286 PassRefPtr<IDBKey> userKey() const 1287 { 1288 RefPtr<IDBKey> key; 1289 decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key); 1290 return key; 1291 } 1292 1293 private: 1294 int64_t m_databaseId; 1295 int64_t m_objectStoreId; 1296 int64_t m_indexId; 1297 Vector<char> m_encodedUserKey; 1298 int64_t m_sequenceNumber; 1299 }; 1300 1301 namespace { 1302 template<typename KeyType> 1303 int decodeAndCompare(const LevelDBSlice& a, const LevelDBSlice& b) 1304 { 1305 KeyType keyA; 1306 KeyType keyB; 1307 1308 const char* ptrA = KeyType::decode(a.begin(), a.end(), &keyA); 1309 ASSERT_UNUSED(ptrA, ptrA); 1310 const char* ptrB = KeyType::decode(b.begin(), b.end(), &keyB); 1311 ASSERT_UNUSED(ptrB, ptrB); 1312 1313 return keyA.compare(keyB); 1314 } 1315 } 1316 1317 static int realCompare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys = false) 1318 { 1319 const char* ptrA = a.begin(); 1320 const char* ptrB = b.begin(); 1321 const char* endA = a.end(); 1322 const char* endB = b.end(); 1323 1324 KeyPrefix prefixA; 1325 KeyPrefix prefixB; 1326 1327 ptrA = KeyPrefix::decode(ptrA, endA, &prefixA); 1328 ptrB = KeyPrefix::decode(ptrB, endB, &prefixB); 1329 ASSERT(ptrA); 1330 ASSERT(ptrB); 1331 1332 if (int x = prefixA.compare(prefixB)) 1333 return x; 1334 1335 if (prefixA.type() == KeyPrefix::kGlobalMetaData) { 1336 ASSERT(ptrA != endA); 1337 ASSERT(ptrB != endB); 1338 1339 unsigned char typeByteA = *ptrA++; 1340 unsigned char typeByteB = *ptrB++; 1341 1342 if (int x = typeByteA - typeByteB) 1343 return x; 1344 1345 if (typeByteA <= 1) 1346 return 0; 1347 if (typeByteA == kDatabaseFreeListTypeByte) 1348 return decodeAndCompare<DatabaseFreeListKey>(a, b); 1349 if (typeByteA == kDatabaseNameTypeByte) 1350 return decodeAndCompare<DatabaseNameKey>(a, b); 1351 } 1352 1353 if (prefixA.type() == KeyPrefix::kDatabaseMetaData) { 1354 ASSERT(ptrA != endA); 1355 ASSERT(ptrB != endB); 1356 1357 unsigned char typeByteA = *ptrA++; 1358 unsigned char typeByteB = *ptrB++; 1359 1360 if (int x = typeByteA - typeByteB) 1361 return x; 1362 1363 if (typeByteA <= 3) 1364 return 0; 1365 1366 if (typeByteA == kObjectStoreMetaDataTypeByte) 1367 return decodeAndCompare<ObjectStoreMetaDataKey>(a, b); 1368 if (typeByteA == kIndexMetaDataTypeByte) 1369 return decodeAndCompare<IndexMetaDataKey>(a, b); 1370 if (typeByteA == kObjectStoreFreeListTypeByte) 1371 return decodeAndCompare<ObjectStoreFreeListKey>(a, b); 1372 if (typeByteA == kIndexFreeListTypeByte) 1373 return decodeAndCompare<IndexFreeListKey>(a, b); 1374 if (typeByteA == kObjectStoreNamesTypeByte) 1375 return decodeAndCompare<ObjectStoreNamesKey>(a, b); 1376 if (typeByteA == kIndexNamesKeyTypeByte) 1377 return decodeAndCompare<IndexNamesKey>(a, b); 1378 1379 return 0; 1380 ASSERT_NOT_REACHED(); 1381 } 1382 1383 if (prefixA.type() == KeyPrefix::kObjectStoreData) { 1384 if (ptrA == endA && ptrB == endB) 1385 return 0; 1386 if (ptrA == endA) 1387 return -1; 1388 if (ptrB == endB) 1389 return 1; // FIXME: This case of non-existing user keys should not have to be handled this way. 1390 1391 return decodeAndCompare<ObjectStoreDataKey>(a, b); 1392 } 1393 if (prefixA.type() == KeyPrefix::kExistsEntry) { 1394 if (ptrA == endA && ptrB == endB) 1395 return 0; 1396 if (ptrA == endA) 1397 return -1; 1398 if (ptrB == endB) 1399 return 1; // FIXME: This case of non-existing user keys should not have to be handled this way. 1400 1401 return decodeAndCompare<ExistsEntryKey>(a, b); 1402 } 1403 if (prefixA.type() == KeyPrefix::kIndexData) { 1404 if (ptrA == endA && ptrB == endB) 1405 return 0; 1406 if (ptrA == endA) 1407 return -1; 1408 if (ptrB == endB) 1409 return 1; // FIXME: This case of non-existing user keys should not have to be handled this way. 1410 1411 IndexDataKey indexDataKeyA; 1412 IndexDataKey indexDataKeyB; 1413 1414 ptrA = IndexDataKey::decode(a.begin(), endA, &indexDataKeyA); 1415 ptrB = IndexDataKey::decode(b.begin(), endB, &indexDataKeyB); 1416 ASSERT(ptrA); 1417 ASSERT(ptrB); 1418 1419 bool ignoreSequenceNumber = indexKeys; 1420 return indexDataKeyA.compare(indexDataKeyB, ignoreSequenceNumber); 1421 } 1422 1423 ASSERT_NOT_REACHED(); 1424 return 0; 1425 } 1426 1427 static int compareKeys(const LevelDBSlice& a, const LevelDBSlice& b) 1428 { 1429 return realCompare(a, b); 1430 } 1431 1432 static int compareIndexKeys(const LevelDBSlice& a, const LevelDBSlice& b) 1433 { 1434 return realCompare(a, b, true); 1435 } 1436 1437 class Comparator : public LevelDBComparator { 1438 public: 1439 virtual int compare(const LevelDBSlice& a, const LevelDBSlice& b) const { return realCompare(a, b); } 1440 virtual const char* name() const { return "idb_cmp1"; } 1441 }; 1442 } 1443 1444 static bool setUpMetadata(LevelDBDatabase* db) 1445 { 1446 const Vector<char> metaDataKey = SchemaVersionKey::encode(); 1447 1448 int64_t schemaVersion; 1449 if (!getInt(db, metaDataKey, schemaVersion)) { 1450 schemaVersion = 0; 1451 if (!putInt(db, metaDataKey, schemaVersion)) 1452 return false; 1453 } 1454 1455 // FIXME: Eventually, we'll need to be able to transition between schemas. 1456 if (schemaVersion) 1457 return false; // Don't know what to do with this version. 1458 1459 return true; 1460 } 1461 1462 IDBLevelDBBackingStore::IDBLevelDBBackingStore(String identifier, IDBFactoryBackendImpl* factory, LevelDBDatabase* db) 1463 : m_identifier(identifier) 1464 , m_factory(factory) 1465 , m_db(db) 1466 { 1467 m_factory->addIDBBackingStore(identifier, this); 1468 } 1469 1470 IDBLevelDBBackingStore::~IDBLevelDBBackingStore() 1471 { 1472 m_factory->removeIDBBackingStore(m_identifier); 1473 } 1474 1475 PassRefPtr<IDBBackingStore> IDBLevelDBBackingStore::open(SecurityOrigin* securityOrigin, const String& pathBaseArg, int64_t maximumSize, const String& fileIdentifier, IDBFactoryBackendImpl* factory) 1476 { 1477 String pathBase = pathBaseArg; 1478 1479 if (pathBase.isEmpty()) { 1480 ASSERT_NOT_REACHED(); // FIXME: We need to handle this case for incognito and DumpRenderTree. 1481 return 0; 1482 } 1483 1484 if (!makeAllDirectories(pathBase)) { 1485 LOG_ERROR("Unable to create IndexedDB database path %s", pathBase.utf8().data()); 1486 return 0; 1487 } 1488 // FIXME: We should eventually use the same LevelDB database for all origins. 1489 String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb.leveldb"); 1490 1491 OwnPtr<LevelDBComparator> comparator(new Comparator()); 1492 LevelDBDatabase* db = LevelDBDatabase::open(path, comparator.get()); 1493 if (!db) 1494 return 0; 1495 1496 // FIXME: Handle comparator name changes. 1497 1498 RefPtr<IDBLevelDBBackingStore> backingStore(adoptRef(new IDBLevelDBBackingStore(fileIdentifier, factory, db))); 1499 backingStore->m_comparator = comparator.release(); 1500 1501 if (!setUpMetadata(backingStore->m_db.get())) 1502 return 0; 1503 1504 return backingStore.release(); 1505 } 1506 1507 bool IDBLevelDBBackingStore::extractIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId) 1508 { 1509 const Vector<char> key = DatabaseNameKey::encode(m_identifier, name); 1510 1511 bool ok = getInt(m_db.get(), key, foundId); 1512 if (!ok) 1513 return false; 1514 1515 ok = getString(m_db.get(), DatabaseMetaDataKey::encode(foundId, DatabaseMetaDataKey::kUserVersion), foundVersion); 1516 if (!ok) 1517 return false; 1518 1519 return true; 1520 } 1521 1522 static int64_t getNewDatabaseId(LevelDBDatabase* db) 1523 { 1524 const Vector<char> freeListStartKey = DatabaseFreeListKey::encode(0); 1525 const Vector<char> freeListStopKey = DatabaseFreeListKey::encode(INT64_MAX); 1526 1527 OwnPtr<LevelDBIterator> it(db->newIterator()); 1528 for (it->seek(freeListStartKey); it->isValid() && compareKeys(it->key(), freeListStopKey) < 0; it->next()) { 1529 const char *p = it->key().begin(); 1530 const char *limit = it->key().end(); 1531 1532 DatabaseFreeListKey freeListKey; 1533 p = DatabaseFreeListKey::decode(p, limit, &freeListKey); 1534 ASSERT(p); 1535 1536 bool ok = db->remove(it->key()); 1537 ASSERT_UNUSED(ok, ok); 1538 1539 return freeListKey.databaseId(); 1540 } 1541 1542 // If we got here, there was no free-list. 1543 int64_t maxDatabaseId = -1; 1544 if (!getInt(db, MaxDatabaseIdKey::encode(), maxDatabaseId)) 1545 maxDatabaseId = 0; 1546 1547 ASSERT(maxDatabaseId >= 0); 1548 1549 int64_t databaseId = maxDatabaseId + 1; 1550 bool ok = putInt(db, MaxDatabaseIdKey::encode(), databaseId); 1551 ASSERT_UNUSED(ok, ok); 1552 1553 return databaseId; 1554 1555 } 1556 1557 bool IDBLevelDBBackingStore::setIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId, bool invalidRowId) 1558 { 1559 if (invalidRowId) { 1560 rowId = getNewDatabaseId(m_db.get()); 1561 1562 const Vector<char> key = DatabaseNameKey::encode(m_identifier, name); 1563 if (!putInt(m_db.get(), key, rowId)) 1564 return false; 1565 } 1566 1567 if (!putString(m_db.get(), DatabaseMetaDataKey::encode(rowId, DatabaseMetaDataKey::kUserVersion), version)) 1568 return false; 1569 1570 return true; 1571 } 1572 1573 void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags) 1574 { 1575 const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1, 0); 1576 const Vector<char> stopKey = ObjectStoreMetaDataKey::encode(databaseId, INT64_MAX, 0); 1577 1578 OwnPtr<LevelDBIterator> it(m_db->newIterator()); 1579 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 1580 const char *p = it->key().begin(); 1581 const char *limit = it->key().end(); 1582 1583 ObjectStoreMetaDataKey metaDataKey; 1584 p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey); 1585 ASSERT(p); 1586 1587 int64_t objectStoreId = metaDataKey.objectStoreId(); 1588 1589 String objectStoreName = decodeString(it->value().begin(), it->value().end()); 1590 1591 it->next(); 1592 if (!it->isValid()) { 1593 LOG_ERROR("Internal Indexed DB error."); 1594 return; 1595 } 1596 String keyPath = decodeString(it->value().begin(), it->value().end()); 1597 1598 it->next(); 1599 if (!it->isValid()) { 1600 LOG_ERROR("Internal Indexed DB error."); 1601 return; 1602 } 1603 bool autoIncrement = *it->value().begin(); 1604 1605 it->next(); // Is evicatble. 1606 if (!it->isValid()) { 1607 LOG_ERROR("Internal Indexed DB error."); 1608 return; 1609 } 1610 1611 it->next(); // Last version. 1612 if (!it->isValid()) { 1613 LOG_ERROR("Internal Indexed DB error."); 1614 return; 1615 } 1616 1617 it->next(); // Maxium index id allocated. 1618 if (!it->isValid()) { 1619 LOG_ERROR("Internal Indexed DB error."); 1620 return; 1621 } 1622 1623 foundIds.append(objectStoreId); 1624 foundNames.append(objectStoreName); 1625 foundKeyPaths.append(keyPath); 1626 foundAutoIncrementFlags.append(autoIncrement); 1627 } 1628 } 1629 1630 static int64_t getNewObjectStoreId(LevelDBDatabase* db, int64_t databaseId) 1631 { 1632 const Vector<char> freeListStartKey = ObjectStoreFreeListKey::encode(databaseId, 0); 1633 const Vector<char> freeListStopKey = ObjectStoreFreeListKey::encode(databaseId, INT64_MAX); 1634 1635 OwnPtr<LevelDBIterator> it(db->newIterator()); 1636 for (it->seek(freeListStartKey); it->isValid() && compareKeys(it->key(), freeListStopKey) < 0; it->next()) { 1637 const char* p = it->key().begin(); 1638 const char* limit = it->key().end(); 1639 1640 ObjectStoreFreeListKey freeListKey; 1641 p = ObjectStoreFreeListKey::decode(p, limit, &freeListKey); 1642 ASSERT(p); 1643 1644 bool ok = db->remove(it->key()); 1645 ASSERT_UNUSED(ok, ok); 1646 1647 return freeListKey.objectStoreId(); 1648 } 1649 1650 int64_t maxObjectStoreId; 1651 const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::kMaxObjectStoreId); 1652 if (!getInt(db, maxObjectStoreIdKey, maxObjectStoreId)) 1653 maxObjectStoreId = 0; 1654 1655 int64_t objectStoreId = maxObjectStoreId + 1; 1656 bool ok = putInt(db, maxObjectStoreIdKey, objectStoreId); 1657 ASSERT_UNUSED(ok, ok); 1658 1659 return objectStoreId; 1660 } 1661 1662 bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId) 1663 { 1664 int64_t objectStoreId = getNewObjectStoreId(m_db.get(), databaseId); 1665 1666 const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0); 1667 const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 1); 1668 const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 2); 1669 const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 3); 1670 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4); 1671 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5); 1672 const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name); 1673 1674 bool ok = putString(m_db.get(), nameKey, name); 1675 if (!ok) { 1676 LOG_ERROR("Internal Indexed DB error."); 1677 return false; 1678 } 1679 1680 ok = putString(m_db.get(), keyPathKey, keyPath); 1681 if (!ok) { 1682 LOG_ERROR("Internal Indexed DB error."); 1683 return false; 1684 } 1685 1686 ok = putInt(m_db.get(), autoIncrementKey, autoIncrement); 1687 if (!ok) { 1688 LOG_ERROR("Internal Indexed DB error."); 1689 return false; 1690 } 1691 1692 ok = putInt(m_db.get(), evictableKey, false); 1693 if (!ok) { 1694 LOG_ERROR("Internal Indexed DB error."); 1695 return false; 1696 } 1697 1698 ok = putInt(m_db.get(), lastVersionKey, 1); 1699 if (!ok) { 1700 LOG_ERROR("Internal Indexed DB error."); 1701 return false; 1702 } 1703 1704 ok = putInt(m_db.get(), maxIndexIdKey, kMinimumIndexId); 1705 if (!ok) { 1706 LOG_ERROR("Internal Indexed DB error."); 1707 return false; 1708 } 1709 1710 ok = putInt(m_db.get(), namesKey, objectStoreId); 1711 if (!ok) { 1712 LOG_ERROR("Internal Indexed DB error."); 1713 return false; 1714 } 1715 1716 assignedObjectStoreId = objectStoreId; 1717 1718 return true; 1719 } 1720 1721 static bool deleteRange(LevelDBDatabase* db, const Vector<char>& begin, const Vector<char>& end) 1722 { 1723 // FIXME: LevelDB may be able to provide a bulk operation that we can do first. 1724 OwnPtr<LevelDBIterator> it(db->newIterator()); 1725 for (it->seek(begin); it->isValid() && compareKeys(it->key(), end) < 0; it->next()) { 1726 if (!db->remove(it->key())) 1727 return false; 1728 } 1729 1730 return true; 1731 } 1732 1733 void IDBLevelDBBackingStore::deleteObjectStore(int64_t databaseId, int64_t objectStoreId) 1734 { 1735 String objectStoreName; 1736 getString(m_db.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName); 1737 1738 if (!deleteRange(m_db.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6))) 1739 return; // FIXME: Report error. 1740 1741 putString(m_db.get(), ObjectStoreFreeListKey::encode(databaseId, objectStoreId), ""); 1742 m_db->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName)); 1743 1744 if (!deleteRange(m_db.get(), IndexFreeListKey::encode(databaseId, objectStoreId, 0), IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX))) 1745 return; // FIXME: Report error. 1746 if (!deleteRange(m_db.get(), IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0), IndexMetaDataKey::encode(databaseId, objectStoreId, INT64_MAX, 0))) 1747 return; // FIXME: Report error. 1748 1749 clearObjectStore(databaseId, objectStoreId); 1750 } 1751 1752 String IDBLevelDBBackingStore::getObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key) 1753 { 1754 const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 1755 Vector<char> data; 1756 1757 if (!m_db->get(leveldbKey, data)) 1758 return String(); 1759 1760 int64_t version; 1761 const char* p = decodeVarInt(data.begin(), data.end(), version); 1762 if (!p) 1763 return String(); 1764 (void) version; 1765 1766 return decodeString(p, data.end()); 1767 } 1768 1769 namespace { 1770 class LevelDBRecordIdentifier : public IDBBackingStore::ObjectStoreRecordIdentifier { 1771 public: 1772 static PassRefPtr<LevelDBRecordIdentifier> create(const Vector<char>& primaryKey, int64_t version) { return adoptRef(new LevelDBRecordIdentifier(primaryKey, version)); } 1773 static PassRefPtr<LevelDBRecordIdentifier> create() { return adoptRef(new LevelDBRecordIdentifier()); } 1774 1775 virtual bool isValid() const { return m_primaryKey.isEmpty(); } 1776 Vector<char> primaryKey() const { return m_primaryKey; } 1777 void setPrimaryKey(const Vector<char>& primaryKey) { m_primaryKey = primaryKey; } 1778 int64_t version() const { return m_version; } 1779 void setVersion(int64_t version) { m_version = version; } 1780 1781 private: 1782 LevelDBRecordIdentifier(const Vector<char>& primaryKey, int64_t version) : m_primaryKey(primaryKey), m_version(version) { ASSERT(!primaryKey.isEmpty()); } 1783 LevelDBRecordIdentifier() : m_primaryKey(), m_version(-1) {} 1784 1785 Vector<char> m_primaryKey; // FIXME: Make it more clear that this is the *encoded* version of the key. 1786 int64_t m_version; 1787 }; 1788 } 1789 1790 static int64_t getNewVersionNumber(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId) 1791 { 1792 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4); 1793 1794 int64_t lastVersion = -1; 1795 if (!getInt(db, lastVersionKey, lastVersion)) 1796 lastVersion = 0; 1797 1798 ASSERT(lastVersion >= 0); 1799 1800 int64_t version = lastVersion + 1; 1801 bool ok = putInt(db, lastVersionKey, version); 1802 ASSERT_UNUSED(ok, ok); 1803 1804 ASSERT(version > lastVersion); // FIXME: Think about how we want to handle the overflow scenario. 1805 1806 return version; 1807 } 1808 1809 bool IDBLevelDBBackingStore::putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const String& value, ObjectStoreRecordIdentifier* recordIdentifier) 1810 { 1811 int64_t version = getNewVersionNumber(m_db.get(), databaseId, objectStoreId); 1812 const Vector<char> objectStoredataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 1813 1814 Vector<char> v; 1815 v.append(encodeVarInt(version)); 1816 v.append(encodeString(value)); 1817 1818 if (!m_db->put(objectStoredataKey, v)) 1819 return false; 1820 1821 const Vector<char> existsEntryKey = ExistsEntryKey::encode(databaseId, objectStoreId, key); 1822 if (!m_db->put(existsEntryKey, encodeInt(version))) 1823 return false; 1824 1825 LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<LevelDBRecordIdentifier*>(recordIdentifier); 1826 levelDBRecordIdentifier->setPrimaryKey(encodeIDBKey(key)); 1827 levelDBRecordIdentifier->setVersion(version); 1828 return true; 1829 } 1830 1831 void IDBLevelDBBackingStore::clearObjectStore(int64_t databaseId, int64_t objectStoreId) 1832 { 1833 const Vector<char> startKey = KeyPrefix(databaseId, objectStoreId, 0).encode(); 1834 const Vector<char> stopKey = KeyPrefix(databaseId, objectStoreId + 1, 0).encode(); 1835 1836 deleteRange(m_db.get(), startKey, stopKey); 1837 } 1838 1839 PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> IDBLevelDBBackingStore::createInvalidRecordIdentifier() 1840 { 1841 return LevelDBRecordIdentifier::create(); 1842 } 1843 1844 void IDBLevelDBBackingStore::deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier* recordIdentifier) 1845 { 1846 const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier); 1847 const Vector<char> key = ObjectStoreDataKey::encode(databaseId, objectStoreId, levelDBRecordIdentifier->primaryKey()); 1848 m_db->remove(key); 1849 } 1850 1851 double IDBLevelDBBackingStore::nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) 1852 { 1853 const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); 1854 const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); 1855 1856 OwnPtr<LevelDBIterator> it(m_db->newIterator()); 1857 1858 int maxNumericKey = 0; 1859 1860 // FIXME: Be more efficient: seek to something after the object store data, then reverse. 1861 1862 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 1863 const char *p = it->key().begin(); 1864 const char *limit = it->key().end(); 1865 1866 ObjectStoreDataKey dataKey; 1867 p = ObjectStoreDataKey::decode(p, limit, &dataKey); 1868 ASSERT(p); 1869 1870 if (dataKey.userKey()->type() == IDBKey::NumberType) { 1871 int64_t n = static_cast<int64_t>(dataKey.userKey()->number()); 1872 if (n > maxNumericKey) 1873 maxNumericKey = n; 1874 } 1875 } 1876 1877 return maxNumericKey + 1; 1878 } 1879 1880 bool IDBLevelDBBackingStore::keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, ObjectStoreRecordIdentifier* foundRecordIdentifier) 1881 { 1882 const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 1883 Vector<char> data; 1884 1885 if (!m_db->get(leveldbKey, data)) 1886 return false; 1887 1888 int64_t version; 1889 if (!decodeVarInt(data.begin(), data.end(), version)) 1890 return false; 1891 1892 LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<LevelDBRecordIdentifier*>(foundRecordIdentifier); 1893 levelDBRecordIdentifier->setPrimaryKey(encodeIDBKey(key)); 1894 levelDBRecordIdentifier->setVersion(version); 1895 return true; 1896 } 1897 1898 bool IDBLevelDBBackingStore::forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback& callback) 1899 { 1900 const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); 1901 const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); 1902 1903 OwnPtr<LevelDBIterator> it(m_db->newIterator()); 1904 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 1905 const char *p = it->key().begin(); 1906 const char *limit = it->key().end(); 1907 ObjectStoreDataKey dataKey; 1908 p = ObjectStoreDataKey::decode(p, limit, &dataKey); 1909 ASSERT(p); 1910 1911 RefPtr<IDBKey> primaryKey = dataKey.userKey(); 1912 1913 int64_t version; 1914 const char* q = decodeVarInt(it->value().begin(), it->value().end(), version); 1915 if (!q) 1916 return false; 1917 1918 RefPtr<LevelDBRecordIdentifier> ri = LevelDBRecordIdentifier::create(encodeIDBKey(*primaryKey), version); 1919 String idbValue = decodeString(q, it->value().end()); 1920 1921 callback.callback(ri.get(), idbValue); 1922 } 1923 1924 return true; 1925 } 1926 1927 void IDBLevelDBBackingStore::getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundUniqueFlags) 1928 { 1929 const Vector<char> startKey = IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0); 1930 const Vector<char> stopKey = IndexMetaDataKey::encode(databaseId, objectStoreId + 1, 0, 0); 1931 1932 OwnPtr<LevelDBIterator> it(m_db->newIterator()); 1933 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 1934 const char* p = it->key().begin(); 1935 const char* limit = it->key().end(); 1936 1937 IndexMetaDataKey metaDataKey; 1938 p = IndexMetaDataKey::decode(p, limit, &metaDataKey); 1939 ASSERT(p); 1940 1941 int64_t indexId = metaDataKey.indexId(); 1942 ASSERT(!metaDataKey.metaDataType()); 1943 1944 String indexName = decodeString(it->value().begin(), it->value().end()); 1945 it->next(); 1946 if (!it->isValid()) { 1947 LOG_ERROR("Internal Indexed DB error."); 1948 return; 1949 } 1950 1951 bool indexUnique = *it->value().begin(); 1952 it->next(); 1953 if (!it->isValid()) { 1954 LOG_ERROR("Internal Indexed DB error."); 1955 return; 1956 } 1957 1958 String keyPath = decodeString(it->value().begin(), it->value().end()); 1959 1960 foundIds.append(indexId); 1961 foundNames.append(indexName); 1962 foundKeyPaths.append(keyPath); 1963 foundUniqueFlags.append(indexUnique); 1964 } 1965 } 1966 1967 static int64_t getNewIndexId(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId) 1968 { 1969 const Vector<char> startKey = IndexFreeListKey::encode(databaseId, objectStoreId, 0); 1970 const Vector<char> stopKey = IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX); 1971 1972 OwnPtr<LevelDBIterator> it(db->newIterator()); 1973 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 1974 const char* p = it->key().begin(); 1975 const char* limit = it->key().end(); 1976 1977 IndexFreeListKey freeListKey; 1978 p = IndexFreeListKey::decode(p, limit, &freeListKey); 1979 ASSERT(p); 1980 1981 bool ok = db->remove(it->key()); 1982 ASSERT_UNUSED(ok, ok); 1983 1984 ASSERT(freeListKey.indexId() >= kMinimumIndexId); 1985 return freeListKey.indexId(); 1986 } 1987 1988 int64_t maxIndexId; 1989 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5); 1990 if (!getInt(db, maxIndexIdKey, maxIndexId)) 1991 maxIndexId = kMinimumIndexId; 1992 1993 int64_t indexId = maxIndexId + 1; 1994 bool ok = putInt(db, maxIndexIdKey, indexId); 1995 if (!ok) 1996 return false; 1997 1998 return indexId; 1999 } 2000 2001 bool IDBLevelDBBackingStore::createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const String& keyPath, bool isUnique, int64_t& indexId) 2002 { 2003 indexId = getNewIndexId(m_db.get(), databaseId, objectStoreId); 2004 2005 const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0); 2006 const Vector<char> uniqueKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 1); 2007 const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 2); 2008 2009 bool ok = putString(m_db.get(), nameKey, name); 2010 if (!ok) { 2011 LOG_ERROR("Internal Indexed DB error."); 2012 return false; 2013 } 2014 2015 ok = putInt(m_db.get(), uniqueKey, isUnique); 2016 if (!ok) { 2017 LOG_ERROR("Internal Indexed DB error."); 2018 return false; 2019 } 2020 2021 ok = putString(m_db.get(), keyPathKey, keyPath); 2022 if (!ok) { 2023 LOG_ERROR("Internal Indexed DB error."); 2024 return false; 2025 } 2026 2027 return true; 2028 } 2029 2030 void IDBLevelDBBackingStore::deleteIndex(int64_t, int64_t, int64_t) 2031 { 2032 ASSERT_NOT_REACHED(); // FIXME: Implement and add layout test. 2033 return; 2034 } 2035 2036 bool IDBLevelDBBackingStore::putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, const ObjectStoreRecordIdentifier* recordIdentifier) 2037 { 2038 ASSERT(indexId >= kMinimumIndexId); 2039 const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier); 2040 2041 const int64_t globalSequenceNumber = getNewVersionNumber(m_db.get(), databaseId, objectStoreId); 2042 const Vector<char> indexDataKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, globalSequenceNumber); 2043 2044 Vector<char> data; 2045 data.append(encodeVarInt(levelDBRecordIdentifier->version())); 2046 data.append(levelDBRecordIdentifier->primaryKey()); 2047 2048 return m_db->put(indexDataKey, data); 2049 } 2050 2051 static bool findGreatestKeyLessThan(LevelDBDatabase* db, const Vector<char>& target, Vector<char>& foundKey) 2052 { 2053 OwnPtr<LevelDBIterator> it(db->newIterator()); 2054 it->seek(target); 2055 2056 if (!it->isValid()) { 2057 it->seekToLast(); 2058 if (!it->isValid()) 2059 return false; 2060 } 2061 2062 while (compareIndexKeys(it->key(), target) >= 0) { 2063 it->prev(); 2064 if (!it->isValid()) 2065 return false; 2066 } 2067 2068 foundKey.clear(); 2069 foundKey.append(it->key().begin(), it->key().end() - it->key().begin()); 2070 return true; 2071 } 2072 2073 bool IDBLevelDBBackingStore::deleteIndexDataForRecord(int64_t, int64_t, int64_t, const ObjectStoreRecordIdentifier*) 2074 { 2075 // FIXME: This isn't needed since we invalidate index data via the version number mechanism. 2076 return true; 2077 } 2078 2079 String IDBLevelDBBackingStore::getObjectViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key) 2080 { 2081 RefPtr<IDBKey> primaryKey = getPrimaryKeyViaIndex(databaseId, objectStoreId, indexId, key); 2082 if (!primaryKey) 2083 return String(); 2084 2085 return getObjectStoreRecord(databaseId, objectStoreId, *primaryKey); 2086 } 2087 2088 static bool versionExists(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey) 2089 { 2090 const Vector<char> key = ExistsEntryKey::encode(databaseId, objectStoreId, encodedPrimaryKey); 2091 Vector<char> data; 2092 2093 if (!db->get(key, data)) 2094 return false; 2095 2096 return decodeInt(data.begin(), data.end()) == version; 2097 } 2098 2099 PassRefPtr<IDBKey> IDBLevelDBBackingStore::getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key) 2100 { 2101 const Vector<char> leveldbKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, 0); 2102 OwnPtr<LevelDBIterator> it(m_db->newIterator()); 2103 it->seek(leveldbKey); 2104 2105 for (;;) { 2106 if (!it->isValid()) 2107 return 0; 2108 if (compareIndexKeys(it->key(), leveldbKey) > 0) 2109 return 0; 2110 2111 int64_t version; 2112 const char* p = decodeVarInt(it->value().begin(), it->value().end(), version); 2113 if (!p) 2114 return 0; 2115 Vector<char> encodedPrimaryKey; 2116 encodedPrimaryKey.append(p, it->value().end() - p); 2117 2118 if (!versionExists(m_db.get(), databaseId, objectStoreId, version, encodedPrimaryKey)) { 2119 // Delete stale index data entry and continue. 2120 m_db->remove(it->key()); 2121 it->next(); 2122 continue; 2123 } 2124 2125 RefPtr<IDBKey> primaryKey; 2126 decodeIDBKey(encodedPrimaryKey.begin(), encodedPrimaryKey.end(), primaryKey); 2127 return primaryKey.release(); 2128 } 2129 } 2130 2131 bool IDBLevelDBBackingStore::keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key) 2132 { 2133 const Vector<char> levelDBKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, 0); 2134 OwnPtr<LevelDBIterator> it(m_db->newIterator()); 2135 2136 bool found = false; 2137 2138 it->seek(levelDBKey); 2139 if (it->isValid() && !compareIndexKeys(it->key(), levelDBKey)) 2140 found = true; 2141 2142 return found; 2143 } 2144 2145 namespace { 2146 class CursorImplCommon : public IDBBackingStore::Cursor { 2147 public: 2148 // IDBBackingStore::Cursor 2149 virtual bool continueFunction(const IDBKey*); 2150 virtual PassRefPtr<IDBKey> key() { return m_currentKey; } 2151 virtual PassRefPtr<IDBKey> primaryKey() { return m_currentKey; } 2152 virtual String value() = 0; 2153 virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() = 0; // FIXME: I don't think this is actually used, so drop it. 2154 virtual int64_t indexDataId() = 0; 2155 2156 virtual bool loadCurrentRow() = 0; 2157 bool firstSeek(); 2158 2159 protected: 2160 CursorImplCommon(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2161 : m_db(db) 2162 , m_lowKey(lowKey) 2163 , m_lowOpen(lowOpen) 2164 , m_highKey(highKey) 2165 , m_highOpen(highOpen) 2166 , m_forward(forward) 2167 { 2168 } 2169 virtual ~CursorImplCommon() {} 2170 2171 LevelDBDatabase* m_db; 2172 OwnPtr<LevelDBIterator> m_iterator; 2173 Vector<char> m_lowKey; 2174 bool m_lowOpen; 2175 Vector<char> m_highKey; 2176 bool m_highOpen; 2177 bool m_forward; 2178 RefPtr<IDBKey> m_currentKey; 2179 }; 2180 2181 bool CursorImplCommon::firstSeek() 2182 { 2183 m_iterator = m_db->newIterator(); 2184 2185 if (m_forward) 2186 m_iterator->seek(m_lowKey); 2187 else 2188 m_iterator->seek(m_highKey); 2189 2190 for (;;) { 2191 if (!m_iterator->isValid()) 2192 return false; 2193 2194 if (m_forward && m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) >= 0) 2195 return false; 2196 if (m_forward && !m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) > 0) 2197 return false; 2198 if (!m_forward && m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) <= 0) 2199 return false; 2200 if (!m_forward && !m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) < 0) 2201 return false; 2202 2203 if (m_forward && m_lowOpen) { 2204 // lowKey not included in the range. 2205 if (compareIndexKeys(m_iterator->key(), m_lowKey) <= 0) { 2206 m_iterator->next(); 2207 continue; 2208 } 2209 } 2210 if (!m_forward && m_highOpen) { 2211 // highKey not included in the range. 2212 if (compareIndexKeys(m_iterator->key(), m_highKey) >= 0) { 2213 m_iterator->prev(); 2214 continue; 2215 } 2216 } 2217 2218 if (!loadCurrentRow()) { 2219 if (m_forward) 2220 m_iterator->next(); 2221 else 2222 m_iterator->prev(); 2223 continue; 2224 } 2225 2226 return true; 2227 } 2228 } 2229 2230 bool CursorImplCommon::continueFunction(const IDBKey* key) 2231 { 2232 // FIXME: This shares a lot of code with firstSeek. 2233 2234 for (;;) { 2235 if (m_forward) 2236 m_iterator->next(); 2237 else 2238 m_iterator->prev(); 2239 2240 if (!m_iterator->isValid()) 2241 return false; 2242 2243 Vector<char> trash; 2244 if (!m_db->get(m_iterator->key(), trash)) 2245 continue; 2246 2247 if (m_forward && m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) >= 0) // high key not included in range 2248 return false; 2249 if (m_forward && !m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) > 0) 2250 return false; 2251 if (!m_forward && m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) <= 0) // low key not included in range 2252 return false; 2253 if (!m_forward && !m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) < 0) 2254 return false; 2255 2256 if (!loadCurrentRow()) 2257 continue; 2258 2259 if (key) { 2260 if (m_forward) { 2261 if (m_currentKey->isLessThan(key)) 2262 continue; 2263 } else { 2264 if (key->isLessThan(m_currentKey.get())) 2265 continue; 2266 } 2267 } 2268 2269 // FIXME: Obey the uniqueness constraint (and test for it!) 2270 2271 break; 2272 } 2273 2274 return true; 2275 } 2276 2277 class ObjectStoreCursorImpl : public CursorImplCommon { 2278 public: 2279 static PassRefPtr<ObjectStoreCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2280 { 2281 return adoptRef(new ObjectStoreCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward)); 2282 } 2283 2284 // CursorImplCommon 2285 virtual String value() { return m_currentValue; } 2286 virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; } 2287 virtual int64_t indexDataId() { ASSERT_NOT_REACHED(); return 0; } 2288 virtual bool loadCurrentRow(); 2289 2290 private: 2291 ObjectStoreCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2292 : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward) 2293 { 2294 } 2295 2296 String m_currentValue; 2297 }; 2298 2299 bool ObjectStoreCursorImpl::loadCurrentRow() 2300 { 2301 const char* p = m_iterator->key().begin(); 2302 const char* keyLimit = m_iterator->key().end(); 2303 2304 ObjectStoreDataKey objectStoreDataKey; 2305 p = ObjectStoreDataKey::decode(p, keyLimit, &objectStoreDataKey); 2306 ASSERT(p); 2307 if (!p) 2308 return false; 2309 2310 m_currentKey = objectStoreDataKey.userKey(); 2311 2312 int64_t version; 2313 const char* q = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), version); 2314 ASSERT(q); 2315 if (!q) 2316 return false; 2317 (void) version; 2318 2319 m_currentValue = decodeString(q, m_iterator->value().end()); 2320 2321 return true; 2322 } 2323 2324 class IndexKeyCursorImpl : public CursorImplCommon { 2325 public: 2326 static PassRefPtr<IndexKeyCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2327 { 2328 return adoptRef(new IndexKeyCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward)); 2329 } 2330 2331 // CursorImplCommon 2332 virtual String value() { ASSERT_NOT_REACHED(); return String(); } 2333 virtual PassRefPtr<IDBKey> primaryKey() { return m_primaryKey; } 2334 virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; } 2335 virtual int64_t indexDataId() { ASSERT_NOT_REACHED(); return 0; } 2336 virtual bool loadCurrentRow(); 2337 2338 private: 2339 IndexKeyCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2340 : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward) 2341 { 2342 } 2343 2344 RefPtr<IDBKey> m_primaryKey; 2345 }; 2346 2347 bool IndexKeyCursorImpl::loadCurrentRow() 2348 { 2349 const char* p = m_iterator->key().begin(); 2350 const char* keyLimit = m_iterator->key().end(); 2351 IndexDataKey indexDataKey; 2352 p = IndexDataKey::decode(p, keyLimit, &indexDataKey); 2353 2354 m_currentKey = indexDataKey.userKey(); 2355 2356 int64_t indexDataVersion; 2357 const char* q = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), indexDataVersion); 2358 ASSERT(q); 2359 if (!q) 2360 return false; 2361 2362 q = decodeIDBKey(q, m_iterator->value().end(), m_primaryKey); 2363 ASSERT(q); 2364 if (!q) 2365 return false; 2366 2367 Vector<char> primaryLevelDBKey = ObjectStoreDataKey::encode(indexDataKey.databaseId(), indexDataKey.objectStoreId(), *m_primaryKey); 2368 2369 Vector<char> result; 2370 if (!m_db->get(primaryLevelDBKey, result)) 2371 return false; 2372 2373 int64_t objectStoreDataVersion; 2374 const char* t = decodeVarInt(result.begin(), result.end(), objectStoreDataVersion); 2375 ASSERT(t); 2376 if (!t) 2377 return false; 2378 2379 if (objectStoreDataVersion != indexDataVersion) { // FIXME: This is probably not very well covered by the layout tests. 2380 m_db->remove(m_iterator->key()); 2381 return false; 2382 } 2383 2384 return true; 2385 } 2386 2387 class IndexCursorImpl : public CursorImplCommon { 2388 public: 2389 static PassRefPtr<IndexCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2390 { 2391 return adoptRef(new IndexCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward)); 2392 } 2393 2394 // CursorImplCommon 2395 virtual String value() { return m_value; } 2396 virtual PassRefPtr<IDBKey> primaryKey() { return m_primaryKey; } 2397 virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; } 2398 virtual int64_t indexDataId() { ASSERT_NOT_REACHED(); return 0; } 2399 bool loadCurrentRow(); 2400 2401 private: 2402 IndexCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 2403 : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward) 2404 { 2405 } 2406 2407 RefPtr<IDBKey> m_primaryKey; 2408 String m_value; 2409 Vector<char> m_primaryLevelDBKey; 2410 }; 2411 2412 bool IndexCursorImpl::loadCurrentRow() 2413 { 2414 const char *p = m_iterator->key().begin(); 2415 const char *limit = m_iterator->key().end(); 2416 2417 IndexDataKey indexDataKey; 2418 p = IndexDataKey::decode(p, limit, &indexDataKey); 2419 2420 m_currentKey = indexDataKey.userKey(); 2421 2422 const char *q = m_iterator->value().begin(); 2423 const char *valueLimit = m_iterator->value().end(); 2424 2425 int64_t indexDataVersion; 2426 q = decodeVarInt(q, valueLimit, indexDataVersion); 2427 ASSERT(q); 2428 if (!q) 2429 return false; 2430 q = decodeIDBKey(q, valueLimit, m_primaryKey); 2431 ASSERT(q); 2432 if (!q) 2433 return false; 2434 2435 m_primaryLevelDBKey = ObjectStoreDataKey::encode(indexDataKey.databaseId(), indexDataKey.objectStoreId(), *m_primaryKey); 2436 2437 Vector<char> result; 2438 if (!m_db->get(m_primaryLevelDBKey, result)) 2439 return false; 2440 2441 int64_t objectStoreDataVersion; 2442 const char* t = decodeVarInt(result.begin(), result.end(), objectStoreDataVersion); 2443 ASSERT(t); 2444 if (!t) 2445 return false; 2446 2447 if (objectStoreDataVersion != indexDataVersion) { 2448 m_db->remove(m_iterator->key()); 2449 return false; 2450 } 2451 2452 m_value = decodeString(t, result.end()); 2453 return true; 2454 } 2455 2456 } 2457 2458 static bool findLastIndexKeyEqualTo(LevelDBDatabase* db, const Vector<char>& target, Vector<char>& foundKey) 2459 { 2460 OwnPtr<LevelDBIterator> it(db->newIterator()); 2461 it->seek(target); 2462 2463 if (!it->isValid()) 2464 return false; 2465 2466 while (it->isValid() && !compareIndexKeys(it->key(), target)) { 2467 foundKey.clear(); 2468 foundKey.append(it->key().begin(), it->key().end() - it->key().begin()); 2469 it->next(); 2470 } 2471 2472 return true; 2473 } 2474 2475 PassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openObjectStoreCursor(int64_t databaseId, int64_t objectStoreId, const IDBKeyRange* range, IDBCursor::Direction direction) 2476 { 2477 bool lowerBound = range && range->lower(); 2478 bool upperBound = range && range->upper(); 2479 bool forward = (direction == IDBCursor::NEXT_NO_DUPLICATE || direction == IDBCursor::NEXT); 2480 2481 bool lowerOpen, upperOpen; 2482 Vector<char> startKey, stopKey; 2483 2484 if (!lowerBound) { 2485 startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); 2486 lowerOpen = true; // Not included. 2487 } else { 2488 startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, *range->lower()); 2489 lowerOpen = range->lowerOpen(); 2490 } 2491 2492 if (!upperBound) { 2493 stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); 2494 upperOpen = true; // Not included. 2495 2496 if (!forward) { // We need a key that exists. 2497 if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey)) 2498 return 0; 2499 upperOpen = false; 2500 } 2501 } else { 2502 stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, *range->upper()); 2503 upperOpen = range->upperOpen(); 2504 } 2505 2506 RefPtr<ObjectStoreCursorImpl> cursor = ObjectStoreCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward); 2507 if (!cursor->firstSeek()) 2508 return 0; 2509 2510 return cursor.release(); 2511 } 2512 2513 PassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openIndexKeyCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IDBCursor::Direction direction) 2514 { 2515 bool lowerBound = range && range->lower(); 2516 bool upperBound = range && range->upper(); 2517 bool forward = (direction == IDBCursor::NEXT_NO_DUPLICATE || direction == IDBCursor::NEXT); 2518 2519 bool lowerOpen, upperOpen; 2520 Vector<char> startKey, stopKey; 2521 2522 if (!lowerBound) { 2523 startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, minIDBKey(), 0); 2524 lowerOpen = false; // Included. 2525 } else { 2526 startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->lower(), 0); 2527 lowerOpen = range->lowerOpen(); 2528 } 2529 2530 if (!upperBound) { 2531 stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, maxIDBKey(), 0); 2532 upperOpen = false; // Included. 2533 2534 if (!forward) { // We need a key that exists. 2535 if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey)) 2536 return 0; 2537 upperOpen = false; 2538 } 2539 } else { 2540 stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper(), 0); 2541 if (!findLastIndexKeyEqualTo(m_db.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys. 2542 return 0; 2543 upperOpen = range->upperOpen(); 2544 } 2545 2546 RefPtr<IndexKeyCursorImpl> cursor = IndexKeyCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward); 2547 if (!cursor->firstSeek()) 2548 return 0; 2549 2550 return cursor.release(); 2551 } 2552 2553 PassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openIndexCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IDBCursor::Direction direction) 2554 { 2555 bool lowerBound = range && range->lower(); 2556 bool upperBound = range && range->upper(); 2557 bool forward = (direction == IDBCursor::NEXT_NO_DUPLICATE || direction == IDBCursor::NEXT); 2558 2559 bool lowerOpen, upperOpen; 2560 Vector<char> startKey, stopKey; 2561 2562 if (!lowerBound) { 2563 startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, minIDBKey(), 0); 2564 lowerOpen = false; // Included. 2565 } else { 2566 startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->lower(), 0); 2567 lowerOpen = range->lowerOpen(); 2568 } 2569 2570 if (!upperBound) { 2571 stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, maxIDBKey(), 0); 2572 upperOpen = false; // Included. 2573 2574 if (!forward) { // We need a key that exists. 2575 if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey)) 2576 return 0; 2577 upperOpen = false; 2578 } 2579 } else { 2580 stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper(), 0); 2581 if (!findLastIndexKeyEqualTo(m_db.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys. 2582 return 0; 2583 upperOpen = range->upperOpen(); 2584 } 2585 2586 RefPtr<IndexCursorImpl> cursor = IndexCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward); 2587 if (!cursor->firstSeek()) 2588 return 0; 2589 2590 return cursor.release(); 2591 } 2592 2593 namespace { 2594 class DummyTransaction : public IDBBackingStore::Transaction { 2595 public: 2596 virtual void begin() {} 2597 virtual void commit() {} 2598 virtual void rollback() {} 2599 }; 2600 } 2601 2602 PassRefPtr<IDBBackingStore::Transaction> IDBLevelDBBackingStore::createTransaction() 2603 { 2604 // FIXME: We need to implement a transaction abstraction that allows for roll-backs, and write tests for it. 2605 return adoptRef(new DummyTransaction()); 2606 } 2607 2608 // FIXME: deleteDatabase should be part of IDBBackingStore. 2609 2610 } // namespace WebCore 2611 2612 #endif // ENABLE(LEVELDB) 2613 #endif // ENABLE(INDEXED_DATABASE) 2614