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