12daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch/* 22daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved. 32daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 42daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Redistribution and use in source and binary forms, with or without 52daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * modification, are permitted provided that the following conditions 62daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * are met: 72daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 82daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 1. Redistributions of source code must retain the above copyright 92daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * notice, this list of conditions and the following disclaimer. 102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright 112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * notice, this list of conditions and the following disclaimer in the 122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * documentation and/or other materials provided with the distribution. 132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch */ 252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "config.h" 272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "IDBLevelDBBackingStore.h" 282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(INDEXED_DATABASE) 302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(LEVELDB) 312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "Assertions.h" 332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "FileSystem.h" 342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "IDBFactoryBackendImpl.h" 352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "IDBKeyRange.h" 362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBComparator.h" 372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBDatabase.h" 382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBIterator.h" 392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBSlice.h" 402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "SecurityOrigin.h" 412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#ifndef INT64_MAX 432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// FIXME: We shouldn't need to rely on these macros. 442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define INT64_MAX 0x7fffffffffffffffLL 452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#ifndef INT32_MAX 472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define INT32_MAX 0x7fffffffL 482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// LevelDB stores key/value pairs. Keys and values are strings of bytes, normally of type Vector<char>. 512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// The keys in the backing store are variable-length tuples with different types 532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 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. 542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// The prefix makes sure that data for a specific database, object store, and index are grouped together. The locality is important for performance: common 552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 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 562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// meta-data only requires one seek. 572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Each key type has a class (in square brackets below) which knows how to encode, decode, and compare that key type. 592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Global meta-data have keys with prefix (0,0,0), followed by a type byte: 612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <0, 0, 0, 0> => IndexedDB/LevelDB schema version (0 for now) [SchemaVersionKey] 632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <0, 0, 0, 1> => The maximum database id ever allocated [MaxDatabaseIdKey] 642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <0, 0, 0, 100, database id> => Existence implies the database id is in the free list [DatabaseFreeListKey] 652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <0, 0, 0, 201, utf16 origin name, utf16 database name> => Database id [DatabaseNameKey] 662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Database meta-data: 692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Again, the prefix is followed by a type byte. 712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 0> => utf16 origin name [DatabaseMetaDataKey] 732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 1> => utf16 database name [DatabaseMetaDataKey] 742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 2> => utf16 user version data [DatabaseMetaDataKey] 752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 3> => maximum object store id ever allocated [DatabaseMetaDataKey] 762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Object store meta-data: 792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 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). 812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 50, object store id, 0> => utf16 object store name [ObjectStoreMetaDataKey] 832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 50, object store id, 1> => utf16 key path [ObjectStoreMetaDataKey] 842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 50, object store id, 2> => has auto increment [ObjectStoreMetaDataKey] 852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 50, object store id, 3> => is evictable [ObjectStoreMetaDataKey] 862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 50, object store id, 4> => last "version" number [ObjectStoreMetaDataKey] 872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 50, object store id, 5> => maximum index id ever allocated [ObjectStoreMetaDataKey] 882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Index meta-data: 912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// The prefix is followed by a type byte, then two variable-length integers, and then another type byte. 932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 100, object store id, index id, 0> => utf16 index name [IndexMetaDataKey] 952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 100, object store id, index id, 1> => are index keys unique [IndexMetaDataKey] 962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 100, object store id, index id, 2> => utf16 key path [IndexMetaDataKey] 972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Other object store and index meta-data: 1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 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. 1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 150, object store id> => existence implies the object store id is in the free list [ObjectStoreFreeListKey] 1042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 151, object store id, index id> => existence implies the index id is in the free list [IndexFreeListKey] 1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 200, utf16 object store name> => object store id [ObjectStoreNamesKey] 1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, 0, 0, 201, object store id, utf16 index name> => index id [IndexNamesKey] 1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Object store data: 1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// The prefix is followed by a type byte. The user key is an encoded IDBKey. 1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, object store id, 1, user key> => "version", serialized script value [ObjectStoreDataKey] 1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// "Exists" entry: 1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// The prefix is followed by a type byte. The user key is an encoded IDBKey. 1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, object store id, 2, user key> => "version" [ExistsEntryKey] 1212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Index data: 1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// The prefix is followed by a type byte. The user key is an encoded IDBKey. The sequence number is a variable length integer. 1262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// <database id, object store id, index id, user key, sequence number> => "version", user key [IndexDataKey] 1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// 1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// (The sequence number is used to allow two entries with the same user key 1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// in non-unique indexes. The "version" field is used to weed out stale 1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// index data. Whenever new object store data is inserted, it gets a new 1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// "version" number, and new index data is written with this number. When 1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// the index is used for look-ups, entries are validated against the 1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// "exists" entries, and records with old "version" numbers are deleted 1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// when they are encountered in getPrimaryKeyViaIndex, 1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// IndexCursorImpl::loadCurrentRow, and IndexKeyCursorImpl::loadCurrentRow). 1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIDBKeyNullTypeByte = 0; 1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIDBKeyStringTypeByte = 1; 1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIDBKeyDateTypeByte = 2; 1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIDBKeyNumberTypeByte = 3; 1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIDBKeyMinKeyTypeByte = 4; 1432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kMinimumIndexId = 30; 1452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kObjectStoreDataIndexId = 1; 1462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kExistsEntryIndexId = 2; 1472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kSchemaVersionTypeByte = 0; 1492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kMaxDatabaseIdTypeByte = 1; 1502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kDatabaseFreeListTypeByte = 100; 1512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kDatabaseNameTypeByte = 201; 1522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kObjectStoreMetaDataTypeByte = 50; 1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIndexMetaDataTypeByte = 100; 1552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kObjectStoreFreeListTypeByte = 150; 1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIndexFreeListTypeByte = 151; 1572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kObjectStoreNamesTypeByte = 200; 1582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const unsigned char kIndexNamesKeyTypeByte = 201; 1592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace WebCore { 1612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeByte(unsigned char c) 1632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> v; 1652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch v.append(c); 1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return v; 1672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 1682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> maxIDBKey() 1702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encodeByte(kIDBKeyNullTypeByte); 1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> minIDBKey() 1752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encodeByte(kIDBKeyMinKeyTypeByte); 1772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 1782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeInt(int64_t n) 1802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(n >= 0); 1822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret; // FIXME: Size this at creation. 1832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch do { 1852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char c = n; 1862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(c); 1872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch n >>= 8; 1882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } while (n); 1892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 1912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 1922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int64_t decodeInt(const char* begin, const char* end) 1942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 1952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(begin <= end); 1962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t ret = 0; 1972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (begin < end) { 1992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char c = *begin++; 2002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret = (ret << 8) | c; 2012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 2022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 2042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeVarInt(int64_t n) 2072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret; // FIXME: Size this at creation. 2092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch do { 2112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char c = n & 0x7f; 2122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch n >>= 7; 2132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (n) 2142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch c |= 128; 2152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(c); 2162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } while (n); 2172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 2192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const char* decodeVarInt(const char *p, const char* limit, int64_t& foundInt) 2222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(limit >= p); 2242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundInt = 0; 2252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch do { 2272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p >= limit) 2282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 2292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundInt = (foundInt << 7) | (*p & 0x7f); 2312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } while (*p++ & 128); 2322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 2332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeString(const String& s) 2362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret; // FIXME: Size this at creation. 2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (unsigned i = 0; i < s.length(); ++i) { 2402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch UChar u = s[i]; 2412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char hi = u >> 8; 2422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char lo = u; 2432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(hi); 2442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(lo); 2452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 2462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 2482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic String decodeString(const char* p, const char* end) 2512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(end >= p); 2532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!((end - p) % 2)); 2542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch size_t len = (end - p) / 2; 2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<UChar> vector(len); 2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (size_t i = 0; i < len; ++i) { 2592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char hi = *p++; 2602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char lo = *p++; 2612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch vector[i] = (hi << 8) | lo; 2632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 2642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return String::adopt(vector); 2662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeStringWithLength(const String& s) 2692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = encodeVarInt(s.length()); 2712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeString(s)); 2722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 2732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const char* decodeStringWithLength(const char* p, const char* limit, String& foundString) 2762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(limit >= p); 2782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t len; 2792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, len); 2802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 2812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 2822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p + len * 2 > limit) 2832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 2842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundString = decodeString(p, p + len * 2); 2862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p += len * 2; 2872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeDouble(double x) 2912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: It would be nice if we could be byte order independent. 2932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = reinterpret_cast<char*>(&x); 2942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> v; 2952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch v.append(p, sizeof(x)); 2962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(v.size() == sizeof(x)); 2972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return v; 2982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 2992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const char* decodeDouble(const char* p, const char* limit, double* d) 3012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 3022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p + sizeof(*d) > limit) 3032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch char* x = reinterpret_cast<char*>(d); 3062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (size_t i = 0; i < sizeof(*d); ++i) 3072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *x++ = *p++; 3082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 3092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 3102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> encodeIDBKey(const IDBKey& key) 3122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 3132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret; 3142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch switch (key.type()) { 3162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case IDBKey::NullType: 3172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encodeByte(kIDBKeyNullTypeByte); 3182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case IDBKey::StringType: 3192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret = encodeByte(kIDBKeyStringTypeByte); 3202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeStringWithLength(key.string())); 3212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 3222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case IDBKey::DateType: 3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret = encodeByte(kIDBKeyDateTypeByte); 3242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeDouble(key.date())); 3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ret.size() == 9); 3262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 3272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case IDBKey::NumberType: 3282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret = encodeByte(kIDBKeyNumberTypeByte); 3292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeDouble(key.number())); 3302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ret.size() == 9); 3312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 3322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 3332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 3352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return Vector<char>(); 3362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 3372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey) 3392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 3402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(limit >= p); 3412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p >= limit) 3422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char type = *p++; 3452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String s; 3462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch double d; 3472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch switch (type) { 3492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyNullTypeByte: 3502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Null. 3512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey = IDBKey::createNull(); 3522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 3532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyStringTypeByte: 3542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // String. 3552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeStringWithLength(p, limit, s); 3562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 3572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey = IDBKey::createString(s); 3592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 3602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyDateTypeByte: 3612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Date. 3622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeDouble(p, limit, &d); 3632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 3642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey = IDBKey::createDate(d); 3662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 3672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyNumberTypeByte: 3682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Number. 3692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeDouble(p, limit, &d); 3702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 3712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey = IDBKey::createNumber(d); 3732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 3742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 3752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 3772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 3792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result) 3812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 3822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = start; 3832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p >= limit) 3842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 3852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char type = *p++; 3872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t stringLen; 3892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch switch (type) { 3912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyNullTypeByte: 3922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyMinKeyTypeByte: 3932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *result = encodeByte(type); 3942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 3952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyStringTypeByte: 3962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // String. 3972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, stringLen); 3982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 3992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p + stringLen * 2 > limit) 4012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->clear(); 4032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->append(start, p - start + stringLen * 2); 4042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p + stringLen * 2; 4052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyDateTypeByte: 4062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyNumberTypeByte: 4072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Date or number. 4082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p + sizeof(double) > limit) 4092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->clear(); 4112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->append(start, 1 + sizeof(double)); 4122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p + sizeof(double); 4132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 4142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 4152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 4172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB) 4192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 4202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(keyA.size() >= 1); 4212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(keyB.size() >= 1); 4222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = keyA.data(); 4242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* limitA = p + keyA.size(); 4252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* q = keyB.data(); 4262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* limitB = q + keyB.size(); 4272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeA = *p++; 4292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeB = *q++; 4302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String s, t; 4322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch double d, e; 4332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = typeB - typeA) // FIXME: Note the subtleness! 4352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 4362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch switch (typeA) { 4382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyNullTypeByte: 4392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyMinKeyTypeByte: 4402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Null type or max type; no payload to compare. 4412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyStringTypeByte: 4432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // String type. 4442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeStringWithLength(p, limitA, s); // FIXME: Compare without actually decoding the String! 4452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 4462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch q = decodeStringWithLength(q, limitB, t); 4472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 4482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return codePointCompare(s, t); 4492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyDateTypeByte: 4502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case kIDBKeyNumberTypeByte: 4512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Date or number. 4522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeDouble(p, limitA, &d); 4532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 4542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch q = decodeDouble(q, limitB, &e); 4552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 4562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (d < e) 4572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return -1; 4582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (d > e) 4592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 1; 4602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 4622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 4642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 4652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 4662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool getInt(LevelDBDatabase* db, const Vector<char>& key, int64_t& foundInt) 4682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 4692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> result; 4702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!db->get(key, result)) 4712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 4722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundInt = decodeInt(result.begin(), result.end()); 4742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 4752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 4762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool putInt(LevelDBDatabase* db, const Vector<char>& key, int64_t value) 4782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 4792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return db->put(key, encodeInt(value)); 4802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 4812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool getString(LevelDBDatabase* db, const Vector<char>& key, String& foundString) 4832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 4842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> result; 4852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!db->get(key, result)) 4862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 4872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundString = decodeString(result.begin(), result.end()); 4892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 4902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 4912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool putString(LevelDBDatabase* db, const Vector<char> key, const String& value) 4932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 4942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!db->put(key, encodeString(value))) 4952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 4962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 4972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 4982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 4992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace { 5002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass KeyPrefix { 5012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 5022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix() 5032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_databaseId(kInvalidType) 5042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_objectStoreId(kInvalidType) 5052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_indexId(kInvalidType) 5062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 5072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix(int64_t databaseId, int64_t objectStoreId, int64_t indexId) 5102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_databaseId(databaseId) 5112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_objectStoreId(objectStoreId) 5122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_indexId(indexId) 5132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 5142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, KeyPrefix* result) 5172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 5182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (start == limit) 5192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 5202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char firstByte = *start++; 5222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int databaseIdBytes = ((firstByte >> 5) & 0x7) + 1; 5242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int objectStoreIdBytes = ((firstByte >> 2) & 0x7) + 1; 5252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int indexIdBytes = (firstByte & 0x3) + 1; 5262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (start + databaseIdBytes + objectStoreIdBytes + indexIdBytes > limit) 5282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 5292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_databaseId = decodeInt(start, start + databaseIdBytes); 5312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch start += databaseIdBytes; 5322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_objectStoreId = decodeInt(start, start + objectStoreIdBytes); 5332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch start += objectStoreIdBytes; 5342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_indexId = decodeInt(start, start + indexIdBytes); 5352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch start += indexIdBytes; 5362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return start; 5382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> encode() const 5412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 5422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId != kInvalidId); 5432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId != kInvalidId); 5442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId != kInvalidId); 5452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> databaseIdString = encodeInt(m_databaseId); 5472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> objectStoreIdString = encodeInt(m_objectStoreId); 5482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> indexIdString = encodeInt(m_indexId); 5492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(databaseIdString.size() <= 8); 5512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(objectStoreIdString.size() <= 8); 5522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(indexIdString.size() <= 4); 5532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char firstByte = (databaseIdString.size() - 1) << 5 | (objectStoreIdString.size() - 1) << 2 | (indexIdString.size() - 1); 5562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret; 5572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(firstByte); 5582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(databaseIdString); 5592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(objectStoreIdString); 5602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(indexIdString); 5612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 5632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const KeyPrefix& other) const 5662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 5672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId != kInvalidId); 5682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId != kInvalidId); 5692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId != kInvalidId); 5702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_databaseId != other.m_databaseId) 5722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_databaseId - other.m_databaseId; 5732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_objectStoreId != other.m_objectStoreId) 5742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_objectStoreId - other.m_objectStoreId; 5752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_indexId != other.m_indexId) 5762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_indexId - other.m_indexId; 5772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 5782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 5792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch enum Type { 5812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kGlobalMetaData, 5822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kDatabaseMetaData, 5832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kObjectStoreData, 5842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kExistsEntry, 5852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kIndexData, 5862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kInvalidType 5872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch }; 5882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Type type() const 5902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 5912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId != kInvalidId); 5922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId != kInvalidId); 5932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId != kInvalidId); 5942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_databaseId) 5962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return kGlobalMetaData; 5972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_objectStoreId) 5982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return kDatabaseMetaData; 5992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_indexId == kObjectStoreDataIndexId) 6002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return kObjectStoreData; 6012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_indexId == kExistsEntryIndexId) 6022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return kExistsEntry; 6032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_indexId >= kMinimumIndexId) 6042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return kIndexData; 6052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 6072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return kInvalidType; 6082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_databaseId; 6112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 6122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_indexId; 6132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const int64_t kInvalidId = -1; 6152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 6162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass SchemaVersionKey { 6182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 6192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode() 6202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(0, 0, 0); 6222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 6232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kSchemaVersionTypeByte)); 6242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 6252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 6272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass MaxDatabaseIdKey { 6292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 6302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode() 6312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(0, 0, 0); 6332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 6342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kMaxDatabaseIdTypeByte)); 6352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 6362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 6382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass DatabaseFreeListKey { 6402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 6412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch DatabaseFreeListKey() 6422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_databaseId(-1) 6432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, DatabaseFreeListKey* result) 6472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 6492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = KeyPrefix::decode(start, limit, &prefix); 6502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 6512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 6522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_databaseId); 6532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 6542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 6552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 6562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 6572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 6582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kDatabaseFreeListTypeByte); 6592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 6602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 6612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeVarInt(p, limit, result->m_databaseId); 6622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId) 6652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(0, 0, 0); 6672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 6682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kDatabaseFreeListTypeByte)); 6692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(databaseId)); 6702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 6712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t databaseId() const 6742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId >= 0); 6762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_databaseId; 6772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const DatabaseFreeListKey& other) const 6802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId >= 0); 6822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_databaseId - other.m_databaseId; 6832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 6862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_databaseId; 6872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 6882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass DatabaseNameKey { 6902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 6912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, DatabaseNameKey* result) 6922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 6932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 6942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 6952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 6962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 6972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_databaseId); 6982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 6992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 7002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 7012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 7032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kDatabaseNameTypeByte); 7042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 7052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeStringWithLength(p, limit, result->m_origin); 7072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 7082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeStringWithLength(p, limit, result->m_databaseName); 7102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(const String& origin, const String& databaseName) 7132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(0, 0, 0); 7152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 7162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kDatabaseNameTypeByte)); 7172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeStringWithLength(origin)); 7182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeStringWithLength(databaseName)); 7192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 7202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String origin() const { return m_origin; } 7232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String databaseName() const { return m_databaseName; } 7242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const DatabaseNameKey& other) 7262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = codePointCompare(m_origin, other.m_origin)) 7282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 7292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return codePointCompare(m_databaseName, other.m_databaseName); 7302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 7332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String m_origin; // FIXME: Store encoded strings, or just pointers. 7342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String m_databaseName; 7352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 7362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass DatabaseMetaDataKey { 7382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 7392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch enum MetaDataType { 7402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kOriginName = 0, 7412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kDatabaseName = 1, 7422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kUserVersion = 2, 7432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch kMaxObjectStoreId = 3 7442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch }; 7452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, MetaDataType metaDataType) 7472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 7492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 7502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(metaDataType)); 7512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 7522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 7542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ObjectStoreMetaDataKey { 7562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 7572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreMetaDataKey() 7582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_objectStoreId(-1) 7592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_metaDataType(-1) 7602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result) 7642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 7662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 7672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 7682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 7702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 7712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 7722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 7732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 7752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kObjectStoreMetaDataTypeByte); 7762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 7772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, result->m_objectStoreId); 7792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 7802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(result->m_objectStoreId); 7822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 7832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 7842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeVarInt(p, limit, result->m_metaDataType); 7852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t metaDataType) 7882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 7902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 7912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kObjectStoreMetaDataTypeByte)); 7922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(objectStoreId)); 7932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(metaDataType)); 7942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 7952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId() const 7982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 7992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 8002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_objectStoreId; 8012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t metaDataType() const 8032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_metaDataType >= 0); 8052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_metaDataType; 8062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const ObjectStoreMetaDataKey& other) 8092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 8112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_metaDataType >= 0); 8122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = m_objectStoreId - other.m_objectStoreId) 8132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; // FIXME: Is this cast safe? I.e., will it preserve the sign? 8142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_metaDataType - other.m_metaDataType; 8152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 8182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 8192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_metaDataType; // FIXME: Make this a byte. 8202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 8212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass IndexMetaDataKey { 8232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 8242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexMetaDataKey() 8252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_objectStoreId(-1) 8262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_indexId(-1) 8272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_metaDataType(0) 8282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, IndexMetaDataKey* result) 8322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 8342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 8352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 8362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 8372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 8382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 8392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 8402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 8412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 8422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 8432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kIndexMetaDataTypeByte); 8442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 8452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 8462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, result->m_objectStoreId); 8472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 8482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 8492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, result->m_indexId); 8502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 8512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 8522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 8532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 8542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_metaDataType = *p++; 8552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 8562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, unsigned char metaDataType) 8592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 8612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 8622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kIndexMetaDataTypeByte)); 8632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(objectStoreId)); 8642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(indexId)); 8652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(metaDataType)); 8662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 8672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const IndexMetaDataKey& other) 8702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 8722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId >= 0); 8732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = m_objectStoreId - other.m_objectStoreId) 8752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 8762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = m_indexId - other.m_indexId) 8772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 8782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_metaDataType - other.m_metaDataType; 8792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexId() const 8822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 8832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId >= 0); 8842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_indexId; 8852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 8862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char metaDataType() const { return m_metaDataType; } 8882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 8902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 8912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_indexId; 8922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char m_metaDataType; 8932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 8942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 8952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ObjectStoreFreeListKey { 8962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 8972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreFreeListKey() 8982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_objectStoreId(-1) 8992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, ObjectStoreFreeListKey* result) 9032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 9052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = KeyPrefix::decode(start, limit, &prefix); 9062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 9072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 9092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 9102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 9112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 9122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 9142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kObjectStoreFreeListTypeByte); 9152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 9162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeVarInt(p, limit, result->m_objectStoreId); 9182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId) 9212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 9232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 9242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kObjectStoreFreeListTypeByte)); 9252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(objectStoreId)); 9262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 9272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId() const 9302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 9322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_objectStoreId; 9332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const ObjectStoreFreeListKey& other) 9362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: It may seem strange that we're not comparing database id's, 9382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // but that comparison will have been made earlier. 9392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // We should probably make this more clear, though... 9402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 9412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_objectStoreId - other.m_objectStoreId; 9422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 9452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 9462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 9472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass IndexFreeListKey { 9492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 9502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexFreeListKey() 9512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_objectStoreId(-1) 9522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_indexId(-1) 9532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, IndexFreeListKey* result) 9572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 9592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 9602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 9612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 9632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 9642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 9652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 9662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 9682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kIndexFreeListTypeByte); 9692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 9702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, result->m_objectStoreId); 9722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 9732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 9742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeVarInt(p, limit, result->m_indexId); 9752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId) 9782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 9802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 9812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kIndexFreeListTypeByte)); 9822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(objectStoreId)); 9832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(indexId)); 9842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 9852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const IndexFreeListKey& other) 9882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 9902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId >= 0); 9912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = m_objectStoreId - other.m_objectStoreId) 9922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 9932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_indexId - other.m_indexId; 9942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 9952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId() const 9972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 9982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 9992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_objectStoreId; 10002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexId() const 10032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId >= 0); 10052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_indexId; 10062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 10092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 10102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_indexId; 10112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 10122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ObjectStoreNamesKey { 10142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 10152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: We never use this to look up object store ids, because a mapping 10162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // is kept in the IDBDatabaseBackendImpl. Can the mapping become unreliable? 10172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Can we remove this? 10182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, ObjectStoreNamesKey* result) 10192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 10212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 10222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 10232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 10242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 10252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 10262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 10272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 10282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 10292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 10302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kObjectStoreNamesTypeByte); 10312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeStringWithLength(p, limit, result->m_objectStoreName); 10322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, const String& objectStoreName) 10352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 10372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 10382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kSchemaVersionTypeByte)); 10392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kObjectStoreNamesTypeByte)); 10402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeStringWithLength(objectStoreName)); 10412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 10422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const ObjectStoreNamesKey& other) 10452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return codePointCompare(m_objectStoreName, other.m_objectStoreName); 10472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String objectStoreName() const { return m_objectStoreName; } 10502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 10522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String m_objectStoreName; // FIXME: Store the encoded string, or just pointers to it. 10532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 10542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass IndexNamesKey { 10562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 10572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexNamesKey() 10582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_objectStoreId(-1) 10592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: We never use this to look up index ids, because a mapping 10632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // is kept at a higher level. 10642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, IndexNamesKey* result) 10652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 10672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 10682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 10692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 10702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 10712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_objectStoreId); 10722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!prefix.m_indexId); 10732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 10742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 10752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByte = *p++; 10762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(typeByte, typeByte == kIndexNamesKeyTypeByte); 10772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) 10782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 10792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = decodeVarInt(p, limit, result->m_objectStoreId); 10802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 10812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 10822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeStringWithLength(p, limit, result->m_indexName); 10832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const String& indexName) 10862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, 0, 0); 10882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 10892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeByte(kIndexNamesKeyTypeByte)); 10902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(objectStoreId)); 10912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeStringWithLength(indexName)); 10922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 10932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const IndexNamesKey& other) 10962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 10972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 10982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = m_objectStoreId - other.m_objectStoreId) 10992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 11002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return codePointCompare(m_indexName, other.m_indexName); 11012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String indexName() const { return m_indexName; } 11042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 11062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 11072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String m_indexName; 11082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 11092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ObjectStoreDataKey { 11112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 11122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* end, ObjectStoreDataKey* result) 11132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 11152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, end, &prefix); 11162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 11172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 11182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 11192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_objectStoreId); 11202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_indexId == kSpecialIndexNumber); 11212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == end) 11222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 11232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return extractEncodedIDBKey(p, end, &result->m_encodedUserKey); 11242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char> encodedUserKey) 11272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, objectStoreId, kSpecialIndexNumber); 11292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 11302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodedUserKey); 11312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 11332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey) 11362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encode(databaseId, objectStoreId, encodeIDBKey(userKey)); 11382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const ObjectStoreDataKey& other) 11412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey); 11432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch PassRefPtr<IDBKey> userKey() const 11462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> key; 11482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key); 11492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return key; 11502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const int64_t kSpecialIndexNumber = kObjectStoreDataIndexId; 11532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 11552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_encodedUserKey; 11562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 11572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ExistsEntryKey { 11592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 11602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* end, ExistsEntryKey* result) 11612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 11632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, end, &prefix); 11642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 11652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 11662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 11672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_objectStoreId); 11682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_indexId == kSpecialIndexNumber); 11692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == end) 11702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 11712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return extractEncodedIDBKey(p, end, &result->m_encodedUserKey); 11722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char>& encodedKey) 11752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, objectStoreId, kSpecialIndexNumber); 11772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 11782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodedKey); 11792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 11802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey) 11832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encode(databaseId, objectStoreId, encodeIDBKey(userKey)); 11852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const ExistsEntryKey& other) 11882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey); 11902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch PassRefPtr<IDBKey> userKey() const 11932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 11942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> key; 11952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key); 11962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return key; 11972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 11982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 11992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const int64_t kSpecialIndexNumber = kExistsEntryIndexId; 12002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 12022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_encodedUserKey; 12032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 12042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass IndexDataKey { 12062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 12072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexDataKey() 12082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_databaseId(-1) 12092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_objectStoreId(-1) 12102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_indexId(-1) 12112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_sequenceNumber(-1) 12122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static const char* decode(const char* start, const char* limit, IndexDataKey* result) 12162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix; 12182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = KeyPrefix::decode(start, limit, &prefix); 12192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 12202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 12212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_databaseId); 12222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_objectStoreId); 12232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(prefix.m_indexId >= kMinimumIndexId); 12242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_databaseId = prefix.m_databaseId; 12252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_objectStoreId = prefix.m_objectStoreId; 12262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_indexId = prefix.m_indexId; 12272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = extractEncodedIDBKey(p, limit, &result->m_encodedUserKey); 12282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 12292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 12302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (p == limit) { 12312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch result->m_sequenceNumber = -1; // FIXME: We should change it so that all keys have a sequence number. Shouldn't need to handle this case. 12322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return p; 12332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeVarInt(p, limit, result->m_sequenceNumber); 12352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const Vector<char>& encodedUserKey, int64_t sequenceNumber) 12382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefix(databaseId, objectStoreId, indexId); 12402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> ret = prefix.encode(); 12412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodedUserKey); 12422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret.append(encodeVarInt(sequenceNumber)); 12432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 12442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& userKey, int64_t sequenceNumber) 12472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encode(databaseId, objectStoreId, indexId, encodeIDBKey(userKey), sequenceNumber); 12492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId) 12522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return encode(databaseId, objectStoreId, INT32_MAX, maxIDBKey(), INT64_MAX); 12542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int compare(const IndexDataKey& other, bool ignoreSequenceNumber) 12572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId >= 0); 12592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 12602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId >= 0); 12612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey)) 12622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 12632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ignoreSequenceNumber) 12642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 12652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_sequenceNumber - other.m_sequenceNumber; 12662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t databaseId() const 12692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_databaseId >= 0); 12712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_databaseId; 12722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId() const 12752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_objectStoreId >= 0); 12772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_objectStoreId; 12782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexId() const 12812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_indexId >= 0); 12832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_indexId; 12842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch PassRefPtr<IDBKey> userKey() const 12872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 12882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> key; 12892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key); 12902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return key; 12912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 12922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 12932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 12942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_databaseId; 12952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 12962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_indexId; 12972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_encodedUserKey; 12982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_sequenceNumber; 12992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 13002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace { 13022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochtemplate<typename KeyType> 13032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochint decodeAndCompare(const LevelDBSlice& a, const LevelDBSlice& b) 13042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 13052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyType keyA; 13062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyType keyB; 13072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* ptrA = KeyType::decode(a.begin(), a.end(), &keyA); 13092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ptrA, ptrA); 13102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* ptrB = KeyType::decode(b.begin(), b.end(), &keyB); 13112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ptrB, ptrB); 13122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return keyA.compare(keyB); 13142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 13152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 13162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int realCompare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys = false) 13182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 13192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* ptrA = a.begin(); 13202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* ptrB = b.begin(); 13212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* endA = a.end(); 13222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* endB = b.end(); 13232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefixA; 13252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch KeyPrefix prefixB; 13262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ptrA = KeyPrefix::decode(ptrA, endA, &prefixA); 13282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ptrB = KeyPrefix::decode(ptrB, endB, &prefixB); 13292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrA); 13302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrB); 13312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = prefixA.compare(prefixB)) 13332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 13342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (prefixA.type() == KeyPrefix::kGlobalMetaData) { 13362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrA != endA); 13372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrB != endB); 13382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByteA = *ptrA++; 13402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByteB = *ptrB++; 13412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = typeByteA - typeByteB) 13432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 13442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA <= 1) 13462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 13472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kDatabaseFreeListTypeByte) 13482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<DatabaseFreeListKey>(a, b); 13492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kDatabaseNameTypeByte) 13502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<DatabaseNameKey>(a, b); 13512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 13522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (prefixA.type() == KeyPrefix::kDatabaseMetaData) { 13542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrA != endA); 13552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrB != endB); 13562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByteA = *ptrA++; 13582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned char typeByteB = *ptrB++; 13592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (int x = typeByteA - typeByteB) 13612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return x; 13622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA <= 3) 13642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 13652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kObjectStoreMetaDataTypeByte) 13672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<ObjectStoreMetaDataKey>(a, b); 13682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kIndexMetaDataTypeByte) 13692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<IndexMetaDataKey>(a, b); 13702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kObjectStoreFreeListTypeByte) 13712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<ObjectStoreFreeListKey>(a, b); 13722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kIndexFreeListTypeByte) 13732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<IndexFreeListKey>(a, b); 13742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kObjectStoreNamesTypeByte) 13752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<ObjectStoreNamesKey>(a, b); 13762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (typeByteA == kIndexNamesKeyTypeByte) 13772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<IndexNamesKey>(a, b); 13782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 13802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 13812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 13822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (prefixA.type() == KeyPrefix::kObjectStoreData) { 13842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrA == endA && ptrB == endB) 13852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 13862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrA == endA) 13872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return -1; 13882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrB == endB) 13892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 1; // FIXME: This case of non-existing user keys should not have to be handled this way. 13902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 13912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<ObjectStoreDataKey>(a, b); 13922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 13932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (prefixA.type() == KeyPrefix::kExistsEntry) { 13942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrA == endA && ptrB == endB) 13952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 13962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrA == endA) 13972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return -1; 13982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrB == endB) 13992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 1; // FIXME: This case of non-existing user keys should not have to be handled this way. 14002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeAndCompare<ExistsEntryKey>(a, b); 14022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 14032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (prefixA.type() == KeyPrefix::kIndexData) { 14042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrA == endA && ptrB == endB) 14052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 14062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrA == endA) 14072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return -1; 14082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (ptrB == endB) 14092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 1; // FIXME: This case of non-existing user keys should not have to be handled this way. 14102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexDataKey indexDataKeyA; 14122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexDataKey indexDataKeyB; 14132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ptrA = IndexDataKey::decode(a.begin(), endA, &indexDataKeyA); 14152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ptrB = IndexDataKey::decode(b.begin(), endB, &indexDataKeyB); 14162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrA); 14172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(ptrB); 14182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ignoreSequenceNumber = indexKeys; 14202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return indexDataKeyA.compare(indexDataKeyB, ignoreSequenceNumber); 14212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 14222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 14242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 14252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int compareKeys(const LevelDBSlice& a, const LevelDBSlice& b) 14282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 14292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return realCompare(a, b); 14302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int compareIndexKeys(const LevelDBSlice& a, const LevelDBSlice& b) 14332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 14342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return realCompare(a, b, true); 14352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass Comparator : public LevelDBComparator { 14382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 14392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual int compare(const LevelDBSlice& a, const LevelDBSlice& b) const { return realCompare(a, b); } 14402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual const char* name() const { return "idb_cmp1"; } 14412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 14422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool setUpMetadata(LevelDBDatabase* db) 14452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 14462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> metaDataKey = SchemaVersionKey::encode(); 14472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t schemaVersion; 14492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!getInt(db, metaDataKey, schemaVersion)) { 14502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch schemaVersion = 0; 14512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!putInt(db, metaDataKey, schemaVersion)) 14522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 14532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 14542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: Eventually, we'll need to be able to transition between schemas. 14562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (schemaVersion) 14572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; // Don't know what to do with this version. 14582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 14602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochIDBLevelDBBackingStore::IDBLevelDBBackingStore(String identifier, IDBFactoryBackendImpl* factory, LevelDBDatabase* db) 14632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_identifier(identifier) 14642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_factory(factory) 14652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_db(db) 14662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 14672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_factory->addIDBBackingStore(identifier, this); 14682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochIDBLevelDBBackingStore::~IDBLevelDBBackingStore() 14712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 14722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_factory->removeIDBBackingStore(m_identifier); 14732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 14742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBBackingStore> IDBLevelDBBackingStore::open(SecurityOrigin* securityOrigin, const String& pathBaseArg, int64_t maximumSize, const String& fileIdentifier, IDBFactoryBackendImpl* factory) 14762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 14772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String pathBase = pathBaseArg; 14782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (pathBase.isEmpty()) { 14802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); // FIXME: We need to handle this case for incognito and DumpRenderTree. 14812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 14822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 14832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!makeAllDirectories(pathBase)) { 14852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Unable to create IndexedDB database path %s", pathBase.utf8().data()); 14862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 14872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 14882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: We should eventually use the same LevelDB database for all origins. 14892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb.leveldb"); 14902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBComparator> comparator(new Comparator()); 14922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LevelDBDatabase* db = LevelDBDatabase::open(path, comparator.get()); 14932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!db) 14942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 14952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: Handle comparator name changes. 14972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBLevelDBBackingStore> backingStore(adoptRef(new IDBLevelDBBackingStore(fileIdentifier, factory, db))); 14992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch backingStore->m_comparator = comparator.release(); 15002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!setUpMetadata(backingStore->m_db.get())) 15022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 15032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return backingStore.release(); 15052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 15062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::extractIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId) 15082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 15092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> key = DatabaseNameKey::encode(m_identifier, name); 15102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = getInt(m_db.get(), key, foundId); 15122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) 15132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 15142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = getString(m_db.get(), DatabaseMetaDataKey::encode(foundId, DatabaseMetaDataKey::kUserVersion), foundVersion); 15162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) 15172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 15182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 15202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 15212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int64_t getNewDatabaseId(LevelDBDatabase* db) 15232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 15242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> freeListStartKey = DatabaseFreeListKey::encode(0); 15252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> freeListStopKey = DatabaseFreeListKey::encode(INT64_MAX); 15262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(db->newIterator()); 15282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(freeListStartKey); it->isValid() && compareKeys(it->key(), freeListStopKey) < 0; it->next()) { 15292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = it->key().begin(); 15302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *limit = it->key().end(); 15312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch DatabaseFreeListKey freeListKey; 15332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = DatabaseFreeListKey::decode(p, limit, &freeListKey); 15342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 15352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = db->remove(it->key()); 15372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ok, ok); 15382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return freeListKey.databaseId(); 15402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 15412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // If we got here, there was no free-list. 15432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t maxDatabaseId = -1; 15442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!getInt(db, MaxDatabaseIdKey::encode(), maxDatabaseId)) 15452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch maxDatabaseId = 0; 15462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(maxDatabaseId >= 0); 15482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t databaseId = maxDatabaseId + 1; 15502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = putInt(db, MaxDatabaseIdKey::encode(), databaseId); 15512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ok, ok); 15522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return databaseId; 15542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 15562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::setIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId, bool invalidRowId) 15582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 15592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (invalidRowId) { 15602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch rowId = getNewDatabaseId(m_db.get()); 15612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> key = DatabaseNameKey::encode(m_identifier, name); 15632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!putInt(m_db.get(), key, rowId)) 15642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 15652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 15662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!putString(m_db.get(), DatabaseMetaDataKey::encode(rowId, DatabaseMetaDataKey::kUserVersion), version)) 15682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 15692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 15712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 15722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags) 15742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 15752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1, 0); 15762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> stopKey = ObjectStoreMetaDataKey::encode(databaseId, INT64_MAX, 0); 15772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(m_db->newIterator()); 15792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 15802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = it->key().begin(); 15812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *limit = it->key().end(); 15822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreMetaDataKey metaDataKey; 15842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey); 15852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 15862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId = metaDataKey.objectStoreId(); 15882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String objectStoreName = decodeString(it->value().begin(), it->value().end()); 15902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); 15922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 15932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 15942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 15952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 15962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String keyPath = decodeString(it->value().begin(), it->value().end()); 15972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 15982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); 15992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 16002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 16022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool autoIncrement = *it->value().begin(); 16042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); // Is evicatble. 16062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 16072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 16092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); // Last version. 16122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 16132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 16152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); // Maxium index id allocated. 16182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 16192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 16212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundIds.append(objectStoreId); 16242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundNames.append(objectStoreName); 16252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKeyPaths.append(keyPath); 16262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundAutoIncrementFlags.append(autoIncrement); 16272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 16292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int64_t getNewObjectStoreId(LevelDBDatabase* db, int64_t databaseId) 16312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 16322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> freeListStartKey = ObjectStoreFreeListKey::encode(databaseId, 0); 16332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> freeListStopKey = ObjectStoreFreeListKey::encode(databaseId, INT64_MAX); 16342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(db->newIterator()); 16362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(freeListStartKey); it->isValid() && compareKeys(it->key(), freeListStopKey) < 0; it->next()) { 16372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = it->key().begin(); 16382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* limit = it->key().end(); 16392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreFreeListKey freeListKey; 16412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = ObjectStoreFreeListKey::decode(p, limit, &freeListKey); 16422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 16432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = db->remove(it->key()); 16452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ok, ok); 16462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return freeListKey.objectStoreId(); 16482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t maxObjectStoreId; 16512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::kMaxObjectStoreId); 16522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!getInt(db, maxObjectStoreIdKey, maxObjectStoreId)) 16532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch maxObjectStoreId = 0; 16542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId = maxObjectStoreId + 1; 16562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = putInt(db, maxObjectStoreIdKey, objectStoreId); 16572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ok, ok); 16582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return objectStoreId; 16602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 16612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId) 16632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 16642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreId = getNewObjectStoreId(m_db.get(), databaseId); 16652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0); 16672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 1); 16682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 2); 16692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 3); 16702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4); 16712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5); 16722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name); 16732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = putString(m_db.get(), nameKey, name); 16752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 16762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 16782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putString(m_db.get(), keyPathKey, keyPath); 16812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 16822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 16842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putInt(m_db.get(), autoIncrementKey, autoIncrement); 16872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 16882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 16902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putInt(m_db.get(), evictableKey, false); 16932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 16942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 16952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 16962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 16972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 16982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putInt(m_db.get(), lastVersionKey, 1); 16992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 17002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 17012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 17022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putInt(m_db.get(), maxIndexIdKey, kMinimumIndexId); 17052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 17062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 17072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 17082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putInt(m_db.get(), namesKey, objectStoreId); 17112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 17122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 17132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 17142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch assignedObjectStoreId = objectStoreId; 17172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 17192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool deleteRange(LevelDBDatabase* db, const Vector<char>& begin, const Vector<char>& end) 17222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: LevelDB may be able to provide a bulk operation that we can do first. 17242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(db->newIterator()); 17252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(begin); it->isValid() && compareKeys(it->key(), end) < 0; it->next()) { 17262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!db->remove(it->key())) 17272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 17282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 17312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid IDBLevelDBBackingStore::deleteObjectStore(int64_t databaseId, int64_t objectStoreId) 17342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String objectStoreName; 17362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch getString(m_db.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName); 17372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!deleteRange(m_db.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6))) 17392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; // FIXME: Report error. 17402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch putString(m_db.get(), ObjectStoreFreeListKey::encode(databaseId, objectStoreId), ""); 17422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_db->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName)); 17432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!deleteRange(m_db.get(), IndexFreeListKey::encode(databaseId, objectStoreId, 0), IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX))) 17452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; // FIXME: Report error. 17462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!deleteRange(m_db.get(), IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0), IndexMetaDataKey::encode(databaseId, objectStoreId, INT64_MAX, 0))) 17472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; // FIXME: Report error. 17482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch clearObjectStore(databaseId, objectStoreId); 17502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochString IDBLevelDBBackingStore::getObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key) 17532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 17552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> data; 17562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->get(leveldbKey, data)) 17582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return String(); 17592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version; 17612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = decodeVarInt(data.begin(), data.end(), version); 17622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 17632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return String(); 17642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch (void) version; 17652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeString(p, data.end()); 17672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace { 17702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass LevelDBRecordIdentifier : public IDBBackingStore::ObjectStoreRecordIdentifier { 17712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 17722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static PassRefPtr<LevelDBRecordIdentifier> create(const Vector<char>& primaryKey, int64_t version) { return adoptRef(new LevelDBRecordIdentifier(primaryKey, version)); } 17732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static PassRefPtr<LevelDBRecordIdentifier> create() { return adoptRef(new LevelDBRecordIdentifier()); } 17742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual bool isValid() const { return m_primaryKey.isEmpty(); } 17762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> primaryKey() const { return m_primaryKey; } 17772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void setPrimaryKey(const Vector<char>& primaryKey) { m_primaryKey = primaryKey; } 17782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version() const { return m_version; } 17792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void setVersion(int64_t version) { m_version = version; } 17802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 17822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LevelDBRecordIdentifier(const Vector<char>& primaryKey, int64_t version) : m_primaryKey(primaryKey), m_version(version) { ASSERT(!primaryKey.isEmpty()); } 17832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LevelDBRecordIdentifier() : m_primaryKey(), m_version(-1) {} 17842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_primaryKey; // FIXME: Make it more clear that this is the *encoded* version of the key. 17862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_version; 17872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 17882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 17892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int64_t getNewVersionNumber(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId) 17912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 17922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4); 17932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t lastVersion = -1; 17952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!getInt(db, lastVersionKey, lastVersion)) 17962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lastVersion = 0; 17972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(lastVersion >= 0); 17992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version = lastVersion + 1; 18012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = putInt(db, lastVersionKey, version); 18022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ok, ok); 18032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(version > lastVersion); // FIXME: Think about how we want to handle the overflow scenario. 18052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return version; 18072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const String& value, ObjectStoreRecordIdentifier* recordIdentifier) 18102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 18112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version = getNewVersionNumber(m_db.get(), databaseId, objectStoreId); 18122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> objectStoredataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 18132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> v; 18152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch v.append(encodeVarInt(version)); 18162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch v.append(encodeString(value)); 18172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->put(objectStoredataKey, v)) 18192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 18202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> existsEntryKey = ExistsEntryKey::encode(databaseId, objectStoreId, key); 18222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->put(existsEntryKey, encodeInt(version))) 18232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 18242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<LevelDBRecordIdentifier*>(recordIdentifier); 18262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch levelDBRecordIdentifier->setPrimaryKey(encodeIDBKey(key)); 18272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch levelDBRecordIdentifier->setVersion(version); 18282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 18292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid IDBLevelDBBackingStore::clearObjectStore(int64_t databaseId, int64_t objectStoreId) 18322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 18332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> startKey = KeyPrefix(databaseId, objectStoreId, 0).encode(); 18342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> stopKey = KeyPrefix(databaseId, objectStoreId + 1, 0).encode(); 18352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch deleteRange(m_db.get(), startKey, stopKey); 18372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> IDBLevelDBBackingStore::createInvalidRecordIdentifier() 18402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 18412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return LevelDBRecordIdentifier::create(); 18422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid IDBLevelDBBackingStore::deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier* recordIdentifier) 18452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 18462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier); 18472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> key = ObjectStoreDataKey::encode(databaseId, objectStoreId, levelDBRecordIdentifier->primaryKey()); 18482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_db->remove(key); 18492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochdouble IDBLevelDBBackingStore::nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) 18522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 18532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); 18542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); 18552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(m_db->newIterator()); 18572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int maxNumericKey = 0; 18592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: Be more efficient: seek to something after the object store data, then reverse. 18612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 18632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = it->key().begin(); 18642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *limit = it->key().end(); 18652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreDataKey dataKey; 18672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = ObjectStoreDataKey::decode(p, limit, &dataKey); 18682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 18692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (dataKey.userKey()->type() == IDBKey::NumberType) { 18712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t n = static_cast<int64_t>(dataKey.userKey()->number()); 18722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (n > maxNumericKey) 18732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch maxNumericKey = n; 18742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 18752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 18762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return maxNumericKey + 1; 18782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, ObjectStoreRecordIdentifier* foundRecordIdentifier) 18812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 18822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 18832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> data; 18842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->get(leveldbKey, data)) 18862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 18872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version; 18892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!decodeVarInt(data.begin(), data.end(), version)) 18902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 18912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<LevelDBRecordIdentifier*>(foundRecordIdentifier); 18932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch levelDBRecordIdentifier->setPrimaryKey(encodeIDBKey(key)); 18942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch levelDBRecordIdentifier->setVersion(version); 18952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 18962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 18972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 18982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback& callback) 18992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 19002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); 19012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); 19022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(m_db->newIterator()); 19042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 19052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = it->key().begin(); 19062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *limit = it->key().end(); 19072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreDataKey dataKey; 19082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = ObjectStoreDataKey::decode(p, limit, &dataKey); 19092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 19102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> primaryKey = dataKey.userKey(); 19122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version; 19142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* q = decodeVarInt(it->value().begin(), it->value().end(), version); 19152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!q) 19162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 19172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<LevelDBRecordIdentifier> ri = LevelDBRecordIdentifier::create(encodeIDBKey(*primaryKey), version); 19192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String idbValue = decodeString(q, it->value().end()); 19202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch callback.callback(ri.get(), idbValue); 19222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 19232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 19252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 19262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid IDBLevelDBBackingStore::getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundUniqueFlags) 19282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 19292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> startKey = IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0); 19302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> stopKey = IndexMetaDataKey::encode(databaseId, objectStoreId + 1, 0, 0); 19312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(m_db->newIterator()); 19332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 19342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = it->key().begin(); 19352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* limit = it->key().end(); 19362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexMetaDataKey metaDataKey; 19382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = IndexMetaDataKey::decode(p, limit, &metaDataKey); 19392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 19402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexId = metaDataKey.indexId(); 19422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(!metaDataKey.metaDataType()); 19432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String indexName = decodeString(it->value().begin(), it->value().end()); 19452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); 19462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 19472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 19482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 19492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 19502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool indexUnique = *it->value().begin(); 19522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); 19532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 19542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 19552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 19562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 19572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String keyPath = decodeString(it->value().begin(), it->value().end()); 19592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundIds.append(indexId); 19612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundNames.append(indexName); 19622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKeyPaths.append(keyPath); 19632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundUniqueFlags.append(indexUnique); 19642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 19652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 19662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic int64_t getNewIndexId(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId) 19682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 19692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> startKey = IndexFreeListKey::encode(databaseId, objectStoreId, 0); 19702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> stopKey = IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX); 19712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(db->newIterator()); 19732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { 19742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = it->key().begin(); 19752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* limit = it->key().end(); 19762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexFreeListKey freeListKey; 19782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = IndexFreeListKey::decode(p, limit, &freeListKey); 19792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 19802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = db->remove(it->key()); 19822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_UNUSED(ok, ok); 19832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(freeListKey.indexId() >= kMinimumIndexId); 19852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return freeListKey.indexId(); 19862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 19872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t maxIndexId; 19892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5); 19902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!getInt(db, maxIndexIdKey, maxIndexId)) 19912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch maxIndexId = kMinimumIndexId; 19922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexId = maxIndexId + 1; 19942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = putInt(db, maxIndexIdKey, indexId); 19952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) 19962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 19972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 19982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return indexId; 19992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const String& keyPath, bool isUnique, int64_t& indexId) 20022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch indexId = getNewIndexId(m_db.get(), databaseId, objectStoreId); 20042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0); 20062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> uniqueKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 1); 20072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 2); 20082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool ok = putString(m_db.get(), nameKey, name); 20102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 20112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 20122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 20132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 20142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putInt(m_db.get(), uniqueKey, isUnique); 20162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 20172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 20182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 20192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 20202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ok = putString(m_db.get(), keyPathKey, keyPath); 20222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!ok) { 20232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_ERROR("Internal Indexed DB error."); 20242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 20252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 20262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 20282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid IDBLevelDBBackingStore::deleteIndex(int64_t, int64_t, int64_t) 20312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); // FIXME: Implement and add layout test. 20332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 20342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, const ObjectStoreRecordIdentifier* recordIdentifier) 20372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(indexId >= kMinimumIndexId); 20392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier); 20402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const int64_t globalSequenceNumber = getNewVersionNumber(m_db.get(), databaseId, objectStoreId); 20422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> indexDataKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, globalSequenceNumber); 20432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> data; 20452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch data.append(encodeVarInt(levelDBRecordIdentifier->version())); 20462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch data.append(levelDBRecordIdentifier->primaryKey()); 20472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return m_db->put(indexDataKey, data); 20492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool findGreatestKeyLessThan(LevelDBDatabase* db, const Vector<char>& target, Vector<char>& foundKey) 20522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(db->newIterator()); 20542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->seek(target); 20552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) { 20572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->seekToLast(); 20582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) 20592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 20602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 20612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (compareIndexKeys(it->key(), target) >= 0) { 20632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->prev(); 20642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) 20652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 20662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 20672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey.clear(); 20692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey.append(it->key().begin(), it->key().end() - it->key().begin()); 20702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 20712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::deleteIndexDataForRecord(int64_t, int64_t, int64_t, const ObjectStoreRecordIdentifier*) 20742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: This isn't needed since we invalidate index data via the version number mechanism. 20762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 20772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochString IDBLevelDBBackingStore::getObjectViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key) 20802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> primaryKey = getPrimaryKeyViaIndex(databaseId, objectStoreId, indexId, key); 20822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!primaryKey) 20832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return String(); 20842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return getObjectStoreRecord(databaseId, objectStoreId, *primaryKey); 20862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool versionExists(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey) 20892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 20902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> key = ExistsEntryKey::encode(databaseId, objectStoreId, encodedPrimaryKey); 20912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> data; 20922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!db->get(key, data)) 20942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 20952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return decodeInt(data.begin(), data.end()) == version; 20972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 20982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 20992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBKey> IDBLevelDBBackingStore::getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key) 21002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 21012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> leveldbKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, 0); 21022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(m_db->newIterator()); 21032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->seek(leveldbKey); 21042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (;;) { 21062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) 21072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 21082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (compareIndexKeys(it->key(), leveldbKey) > 0) 21092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 21102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version; 21122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = decodeVarInt(it->value().begin(), it->value().end(), version); 21132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 21142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 21152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> encodedPrimaryKey; 21162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch encodedPrimaryKey.append(p, it->value().end() - p); 21172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!versionExists(m_db.get(), databaseId, objectStoreId, version, encodedPrimaryKey)) { 21192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Delete stale index data entry and continue. 21202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_db->remove(it->key()); 21212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); 21222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 21232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 21242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> primaryKey; 21262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch decodeIDBKey(encodedPrimaryKey.begin(), encodedPrimaryKey.end(), primaryKey); 21272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return primaryKey.release(); 21282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 21292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 21302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IDBLevelDBBackingStore::keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key) 21322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 21332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const Vector<char> levelDBKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, 0); 21342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(m_db->newIterator()); 21352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool found = false; 21372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->seek(levelDBKey); 21392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (it->isValid() && !compareIndexKeys(it->key(), levelDBKey)) 21402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch found = true; 21412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return found; 21432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 21442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace { 21462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass CursorImplCommon : public IDBBackingStore::Cursor { 21472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 21482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // IDBBackingStore::Cursor 21492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual bool continueFunction(const IDBKey*); 21502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBKey> key() { return m_currentKey; } 21512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBKey> primaryKey() { return m_currentKey; } 21522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual String value() = 0; 21532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() = 0; // FIXME: I don't think this is actually used, so drop it. 21542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual int64_t indexDataId() = 0; 21552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual bool loadCurrentRow() = 0; 21572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool firstSeek(); 21582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprotected: 21602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CursorImplCommon(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 21612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : m_db(db) 21622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_lowKey(lowKey) 21632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_lowOpen(lowOpen) 21642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_highKey(highKey) 21652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_highOpen(highOpen) 21662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_forward(forward) 21672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 21682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 21692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual ~CursorImplCommon() {} 21702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LevelDBDatabase* m_db; 21722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> m_iterator; 21732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_lowKey; 21742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool m_lowOpen; 21752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_highKey; 21762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool m_highOpen; 21772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool m_forward; 21782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> m_currentKey; 21792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 21802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool CursorImplCommon::firstSeek() 21822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 21832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator = m_db->newIterator(); 21842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward) 21862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->seek(m_lowKey); 21872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else 21882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->seek(m_highKey); 21892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (;;) { 21912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_iterator->isValid()) 21922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 21932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 21942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward && m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) >= 0) 21952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 21962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward && !m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) > 0) 21972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 21982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_forward && m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) <= 0) 21992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_forward && !m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) < 0) 22012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward && m_lowOpen) { 22042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // lowKey not included in the range. 22052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (compareIndexKeys(m_iterator->key(), m_lowKey) <= 0) { 22062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->next(); 22072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_forward && m_highOpen) { 22112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // highKey not included in the range. 22122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (compareIndexKeys(m_iterator->key(), m_highKey) >= 0) { 22132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->prev(); 22142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!loadCurrentRow()) { 22192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward) 22202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->next(); 22212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else 22222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->prev(); 22232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 22272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 22292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool CursorImplCommon::continueFunction(const IDBKey* key) 22312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 22322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: This shares a lot of code with firstSeek. 22332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (;;) { 22352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward) 22362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->next(); 22372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else 22382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_iterator->prev(); 22392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_iterator->isValid()) 22412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> trash; 22442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->get(m_iterator->key(), trash)) 22452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward && m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) >= 0) // high key not included in range 22482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward && !m_highOpen && compareIndexKeys(m_iterator->key(), m_highKey) > 0) 22502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_forward && m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) <= 0) // low key not included in range 22522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_forward && !m_lowOpen && compareIndexKeys(m_iterator->key(), m_lowKey) < 0) 22542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 22552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!loadCurrentRow()) 22572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (key) { 22602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_forward) { 22612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_currentKey->isLessThan(key)) 22622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 22642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (key->isLessThan(m_currentKey.get())) 22652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; 22662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: Obey the uniqueness constraint (and test for it!) 22702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 22722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 22752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 22762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ObjectStoreCursorImpl : public CursorImplCommon { 22782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 22792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static PassRefPtr<ObjectStoreCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 22802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 22812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return adoptRef(new ObjectStoreCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward)); 22822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // CursorImplCommon 22852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual String value() { return m_currentValue; } 22862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; } 22872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual int64_t indexDataId() { ASSERT_NOT_REACHED(); return 0; } 22882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual bool loadCurrentRow(); 22892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 22912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 22922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward) 22932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 22942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 22952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String m_currentValue; 22972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 22982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool ObjectStoreCursorImpl::loadCurrentRow() 23002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 23012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = m_iterator->key().begin(); 23022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* keyLimit = m_iterator->key().end(); 23032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ObjectStoreDataKey objectStoreDataKey; 23052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = ObjectStoreDataKey::decode(p, keyLimit, &objectStoreDataKey); 23062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(p); 23072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!p) 23082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_currentKey = objectStoreDataKey.userKey(); 23112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t version; 23132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* q = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), version); 23142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 23152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!q) 23162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch (void) version; 23182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_currentValue = decodeString(q, m_iterator->value().end()); 23202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 23222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 23232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass IndexKeyCursorImpl : public CursorImplCommon { 23252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 23262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static PassRefPtr<IndexKeyCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 23272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 23282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return adoptRef(new IndexKeyCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward)); 23292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 23302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // CursorImplCommon 23322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual String value() { ASSERT_NOT_REACHED(); return String(); } 23332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBKey> primaryKey() { return m_primaryKey; } 23342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; } 23352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual int64_t indexDataId() { ASSERT_NOT_REACHED(); return 0; } 23362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual bool loadCurrentRow(); 23372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 23392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexKeyCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 23402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward) 23412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 23422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 23432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> m_primaryKey; 23452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 23462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IndexKeyCursorImpl::loadCurrentRow() 23482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 23492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* p = m_iterator->key().begin(); 23502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* keyLimit = m_iterator->key().end(); 23512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexDataKey indexDataKey; 23522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = IndexDataKey::decode(p, keyLimit, &indexDataKey); 23532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_currentKey = indexDataKey.userKey(); 23552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexDataVersion; 23572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* q = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), indexDataVersion); 23582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 23592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!q) 23602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch q = decodeIDBKey(q, m_iterator->value().end(), m_primaryKey); 23632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 23642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!q) 23652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> primaryLevelDBKey = ObjectStoreDataKey::encode(indexDataKey.databaseId(), indexDataKey.objectStoreId(), *m_primaryKey); 23682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> result; 23702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->get(primaryLevelDBKey, result)) 23712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreDataVersion; 23742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* t = decodeVarInt(result.begin(), result.end(), objectStoreDataVersion); 23752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(t); 23762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!t) 23772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (objectStoreDataVersion != indexDataVersion) { // FIXME: This is probably not very well covered by the layout tests. 23802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_db->remove(m_iterator->key()); 23812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 23822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 23832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 23852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 23862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass IndexCursorImpl : public CursorImplCommon { 23882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 23892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch static PassRefPtr<IndexCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 23902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 23912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return adoptRef(new IndexCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward)); 23922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 23932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 23942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // CursorImplCommon 23952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual String value() { return m_value; } 23962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBKey> primaryKey() { return m_primaryKey; } 23972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; } 23982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual int64_t indexDataId() { ASSERT_NOT_REACHED(); return 0; } 23992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool loadCurrentRow(); 24002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate: 24022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward) 24032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward) 24042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch { 24052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 24062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBKey> m_primaryKey; 24082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String m_value; 24092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> m_primaryLevelDBKey; 24102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 24112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool IndexCursorImpl::loadCurrentRow() 24132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 24142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *p = m_iterator->key().begin(); 24152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *limit = m_iterator->key().end(); 24162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch IndexDataKey indexDataKey; 24182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch p = IndexDataKey::decode(p, limit, &indexDataKey); 24192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_currentKey = indexDataKey.userKey(); 24212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *q = m_iterator->value().begin(); 24232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char *valueLimit = m_iterator->value().end(); 24242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t indexDataVersion; 24262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch q = decodeVarInt(q, valueLimit, indexDataVersion); 24272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 24282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!q) 24292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch q = decodeIDBKey(q, valueLimit, m_primaryKey); 24312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(q); 24322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!q) 24332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_primaryLevelDBKey = ObjectStoreDataKey::encode(indexDataKey.databaseId(), indexDataKey.objectStoreId(), *m_primaryKey); 24362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> result; 24382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_db->get(m_primaryLevelDBKey, result)) 24392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t objectStoreDataVersion; 24422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const char* t = decodeVarInt(result.begin(), result.end(), objectStoreDataVersion); 24432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(t); 24442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!t) 24452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (objectStoreDataVersion != indexDataVersion) { 24482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_db->remove(m_iterator->key()); 24492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 24512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_value = decodeString(t, result.end()); 24532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 24542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 24552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 24572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool findLastIndexKeyEqualTo(LevelDBDatabase* db, const Vector<char>& target, Vector<char>& foundKey) 24592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 24602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch OwnPtr<LevelDBIterator> it(db->newIterator()); 24612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->seek(target); 24622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->isValid()) 24642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return false; 24652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch while (it->isValid() && !compareIndexKeys(it->key(), target)) { 24672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey.clear(); 24682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch foundKey.append(it->key().begin(), it->key().end() - it->key().begin()); 24692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch it->next(); 24702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 24712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 24732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 24742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openObjectStoreCursor(int64_t databaseId, int64_t objectStoreId, const IDBKeyRange* range, IDBCursor::Direction direction) 24762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 24772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool lowerBound = range && range->lower(); 24782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool upperBound = range && range->upper(); 24792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool forward = (direction == IDBCursor::NEXT_NO_DUPLICATE || direction == IDBCursor::NEXT); 24802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool lowerOpen, upperOpen; 24822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> startKey, stopKey; 24832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!lowerBound) { 24852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); 24862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lowerOpen = true; // Not included. 24872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 24882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, *range->lower()); 24892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lowerOpen = range->lowerOpen(); 24902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 24912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!upperBound) { 24932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); 24942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = true; // Not included. 24952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 24962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!forward) { // We need a key that exists. 24972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey)) 24982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 24992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = false; 25002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 25022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, *range->upper()); 25032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = range->upperOpen(); 25042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<ObjectStoreCursorImpl> cursor = ObjectStoreCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward); 25072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!cursor->firstSeek()) 25082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return cursor.release(); 25112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 25122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openIndexKeyCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IDBCursor::Direction direction) 25142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 25152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool lowerBound = range && range->lower(); 25162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool upperBound = range && range->upper(); 25172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool forward = (direction == IDBCursor::NEXT_NO_DUPLICATE || direction == IDBCursor::NEXT); 25182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool lowerOpen, upperOpen; 25202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> startKey, stopKey; 25212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!lowerBound) { 25232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, minIDBKey(), 0); 25242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lowerOpen = false; // Included. 25252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 25262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->lower(), 0); 25272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lowerOpen = range->lowerOpen(); 25282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!upperBound) { 25312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, maxIDBKey(), 0); 25322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = false; // Included. 25332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!forward) { // We need a key that exists. 25352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey)) 25362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = false; 25382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 25402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper(), 0); 25412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!findLastIndexKeyEqualTo(m_db.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys. 25422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = range->upperOpen(); 25442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IndexKeyCursorImpl> cursor = IndexKeyCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward); 25472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!cursor->firstSeek()) 25482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return cursor.release(); 25512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 25522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openIndexCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IDBCursor::Direction direction) 25542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 25552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool lowerBound = range && range->lower(); 25562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool upperBound = range && range->upper(); 25572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool forward = (direction == IDBCursor::NEXT_NO_DUPLICATE || direction == IDBCursor::NEXT); 25582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool lowerOpen, upperOpen; 25602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<char> startKey, stopKey; 25612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!lowerBound) { 25632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, minIDBKey(), 0); 25642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lowerOpen = false; // Included. 25652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 25662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch startKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->lower(), 0); 25672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch lowerOpen = range->lowerOpen(); 25682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!upperBound) { 25712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, maxIDBKey(), 0); 25722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = false; // Included. 25732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!forward) { // We need a key that exists. 25752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey)) 25762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = false; 25782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else { 25802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper(), 0); 25812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!findLastIndexKeyEqualTo(m_db.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys. 25822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch upperOpen = range->upperOpen(); 25842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 25852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IndexCursorImpl> cursor = IndexCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward); 25872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!cursor->firstSeek()) 25882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return 0; 25892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return cursor.release(); 25912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 25922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 25932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace { 25942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass DummyTransaction : public IDBBackingStore::Transaction { 25952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic: 25962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual void begin() {} 25972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual void commit() {} 25982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual void rollback() {} 25992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 26002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 26012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 26022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBBackingStore::Transaction> IDBLevelDBBackingStore::createTransaction() 26032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 26042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: We need to implement a transaction abstraction that allows for roll-backs, and write tests for it. 26052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return adoptRef(new DummyTransaction()); 26062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 26072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 26082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// FIXME: deleteDatabase should be part of IDBBackingStore. 26092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 26102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} // namespace WebCore 26112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 26122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif // ENABLE(LEVELDB) 26132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif // ENABLE(INDEXED_DATABASE) 2614