• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_
6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_
7 
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/strings/string16.h"
17 #include "base/strings/string_piece.h"
18 #include "content/common/indexed_db/indexed_db_key.h"
19 #include "content/common/indexed_db/indexed_db_key_path.h"
20 
21 namespace content {
22 
23 CONTENT_EXPORT extern const unsigned char kMinimumIndexId;
24 
25 CONTENT_EXPORT std::string MaxIDBKey();
26 CONTENT_EXPORT std::string MinIDBKey();
27 
28 // DatabaseId, BlobKey
29 typedef std::pair<int64_t, int64_t> BlobJournalEntryType;
30 typedef std::vector<BlobJournalEntryType> BlobJournalType;
31 
32 CONTENT_EXPORT void EncodeByte(unsigned char value, std::string* into);
33 CONTENT_EXPORT void EncodeBool(bool value, std::string* into);
34 CONTENT_EXPORT void EncodeInt(int64 value, std::string* into);
35 CONTENT_EXPORT void EncodeVarInt(int64 value, std::string* into);
36 CONTENT_EXPORT void EncodeString(const base::string16& value,
37                                  std::string* into);
38 CONTENT_EXPORT void EncodeStringWithLength(const base::string16& value,
39                                            std::string* into);
40 CONTENT_EXPORT void EncodeBinary(const std::string& value, std::string* into);
41 CONTENT_EXPORT void EncodeDouble(double value, std::string* into);
42 CONTENT_EXPORT void EncodeIDBKey(const IndexedDBKey& value, std::string* into);
43 CONTENT_EXPORT void EncodeIDBKeyPath(const IndexedDBKeyPath& value,
44                                      std::string* into);
45 CONTENT_EXPORT void EncodeBlobJournal(const BlobJournalType& journal,
46                                       std::string* into);
47 
48 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeByte(base::StringPiece* slice,
49                                                   unsigned char* value);
50 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBool(base::StringPiece* slice,
51                                                   bool* value);
52 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeInt(base::StringPiece* slice,
53                                                  int64* value);
54 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeVarInt(base::StringPiece* slice,
55                                                     int64* value);
56 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeString(base::StringPiece* slice,
57                                                     base::string16* value);
58 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeStringWithLength(
59     base::StringPiece* slice,
60     base::string16* value);
61 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBinary(base::StringPiece* slice,
62                                                     std::string* value);
63 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeDouble(base::StringPiece* slice,
64                                                     double* value);
65 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKey(
66     base::StringPiece* slice,
67     scoped_ptr<IndexedDBKey>* value);
68 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKeyPath(
69     base::StringPiece* slice,
70     IndexedDBKeyPath* value);
71 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBlobJournal(
72     base::StringPiece* slice,
73     BlobJournalType* journal);
74 
75 CONTENT_EXPORT int CompareEncodedStringsWithLength(base::StringPiece* slice1,
76                                                    base::StringPiece* slice2,
77                                                    bool* ok);
78 
79 CONTENT_EXPORT WARN_UNUSED_RESULT bool ExtractEncodedIDBKey(
80     base::StringPiece* slice,
81     std::string* result);
82 
83 CONTENT_EXPORT int CompareEncodedIDBKeys(base::StringPiece* slice1,
84                                          base::StringPiece* slice2,
85                                          bool* ok);
86 
87 CONTENT_EXPORT int Compare(const base::StringPiece& a,
88                            const base::StringPiece& b,
89                            bool index_keys);
90 
91 class KeyPrefix {
92  public:
93   KeyPrefix();
94   explicit KeyPrefix(int64 database_id);
95   KeyPrefix(int64 database_id, int64 object_store_id);
96   KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id);
97   static KeyPrefix CreateWithSpecialIndex(int64 database_id,
98                                           int64 object_store_id,
99                                           int64 index_id);
100 
101   static bool Decode(base::StringPiece* slice, KeyPrefix* result);
102   std::string Encode() const;
103   static std::string EncodeEmpty();
104   int Compare(const KeyPrefix& other) const;
105 
106   // These are serialized to disk; any new items must be appended, and none can
107   // be deleted.
108   enum Type {
109     GLOBAL_METADATA,
110     DATABASE_METADATA,
111     OBJECT_STORE_DATA,
112     EXISTS_ENTRY,
113     INDEX_DATA,
114     INVALID_TYPE,
115     BLOB_ENTRY
116   };
117 
118   static const size_t kMaxDatabaseIdSizeBits = 3;
119   static const size_t kMaxObjectStoreIdSizeBits = 3;
120   static const size_t kMaxIndexIdSizeBits = 2;
121 
122   static const size_t kMaxDatabaseIdSizeBytes =
123       1ULL << kMaxDatabaseIdSizeBits;  // 8
124   static const size_t kMaxObjectStoreIdSizeBytes =
125       1ULL << kMaxObjectStoreIdSizeBits;                                   // 8
126   static const size_t kMaxIndexIdSizeBytes = 1ULL << kMaxIndexIdSizeBits;  // 4
127 
128   static const size_t kMaxDatabaseIdBits =
129       kMaxDatabaseIdSizeBytes * 8 - 1;  // 63
130   static const size_t kMaxObjectStoreIdBits =
131       kMaxObjectStoreIdSizeBytes * 8 - 1;                              // 63
132   static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1;  // 31
133 
134   static const int64 kMaxDatabaseId =
135       (1ULL << kMaxDatabaseIdBits) - 1;  // max signed int64
136   static const int64 kMaxObjectStoreId =
137       (1ULL << kMaxObjectStoreIdBits) - 1;  // max signed int64
138   static const int64 kMaxIndexId =
139       (1ULL << kMaxIndexIdBits) - 1;  // max signed int32
140 
141   CONTENT_EXPORT static bool IsValidDatabaseId(int64 database_id);
142   static bool IsValidObjectStoreId(int64 index_id);
143   static bool IsValidIndexId(int64 index_id);
ValidIds(int64 database_id,int64 object_store_id,int64 index_id)144   static bool ValidIds(int64 database_id,
145                        int64 object_store_id,
146                        int64 index_id) {
147     return IsValidDatabaseId(database_id) &&
148            IsValidObjectStoreId(object_store_id) && IsValidIndexId(index_id);
149   }
ValidIds(int64 database_id,int64 object_store_id)150   static bool ValidIds(int64 database_id, int64 object_store_id) {
151     return IsValidDatabaseId(database_id) &&
152            IsValidObjectStoreId(object_store_id);
153   }
154 
155   Type type() const;
156 
157   int64 database_id_;
158   int64 object_store_id_;
159   int64 index_id_;
160 
161   static const int64 kInvalidId = -1;
162 
163  private:
164   static std::string EncodeInternal(int64 database_id,
165                                     int64 object_store_id,
166                                     int64 index_id);
167   // Special constructor for CreateWithSpecialIndex()
168   KeyPrefix(enum Type,
169             int64 database_id,
170             int64 object_store_id,
171             int64 index_id);
172 };
173 
174 class SchemaVersionKey {
175  public:
176   CONTENT_EXPORT static std::string Encode();
177 };
178 
179 class MaxDatabaseIdKey {
180  public:
181   CONTENT_EXPORT static std::string Encode();
182 };
183 
184 class DataVersionKey {
185  public:
186   static std::string Encode();
187 };
188 
189 class BlobJournalKey {
190  public:
191   static std::string Encode();
192 };
193 
194 class LiveBlobJournalKey {
195  public:
196   static std::string Encode();
197 };
198 
199 class DatabaseFreeListKey {
200  public:
201   DatabaseFreeListKey();
202   static bool Decode(base::StringPiece* slice, DatabaseFreeListKey* result);
203   CONTENT_EXPORT static std::string Encode(int64 database_id);
204   static CONTENT_EXPORT std::string EncodeMaxKey();
205   int64 DatabaseId() const;
206   int Compare(const DatabaseFreeListKey& other) const;
207 
208  private:
209   int64 database_id_;
210 };
211 
212 class DatabaseNameKey {
213  public:
214   static bool Decode(base::StringPiece* slice, DatabaseNameKey* result);
215   CONTENT_EXPORT static std::string Encode(const std::string& origin_identifier,
216                                            const base::string16& database_name);
217   static std::string EncodeMinKeyForOrigin(
218       const std::string& origin_identifier);
219   static std::string EncodeStopKeyForOrigin(
220       const std::string& origin_identifier);
origin()221   base::string16 origin() const { return origin_; }
database_name()222   base::string16 database_name() const { return database_name_; }
223   int Compare(const DatabaseNameKey& other);
224 
225  private:
226   base::string16 origin_;  // TODO(jsbell): Store encoded strings, or just
227                            // pointers.
228   base::string16 database_name_;
229 };
230 
231 class DatabaseMetaDataKey {
232  public:
233   enum MetaDataType {
234     ORIGIN_NAME = 0,
235     DATABASE_NAME = 1,
236     USER_VERSION = 2,
237     MAX_OBJECT_STORE_ID = 3,
238     USER_INT_VERSION = 4,
239     BLOB_KEY_GENERATOR_CURRENT_NUMBER = 5,
240     MAX_SIMPLE_METADATA_TYPE = 6
241   };
242 
243   CONTENT_EXPORT static const int64 kAllBlobsKey;
244   static const int64 kBlobKeyGeneratorInitialNumber;
245   // All keys <= 0 are invalid.  This one's just a convenient example.
246   static const int64 kInvalidBlobKey;
247 
248   static bool IsValidBlobKey(int64 blobKey);
249   CONTENT_EXPORT static std::string Encode(int64 database_id,
250                                            MetaDataType type);
251 };
252 
253 class ObjectStoreMetaDataKey {
254  public:
255   enum MetaDataType {
256     NAME = 0,
257     KEY_PATH = 1,
258     AUTO_INCREMENT = 2,
259     EVICTABLE = 3,
260     LAST_VERSION = 4,
261     MAX_INDEX_ID = 5,
262     HAS_KEY_PATH = 6,
263     KEY_GENERATOR_CURRENT_NUMBER = 7
264   };
265 
266   ObjectStoreMetaDataKey();
267   static bool Decode(base::StringPiece* slice, ObjectStoreMetaDataKey* result);
268   CONTENT_EXPORT static std::string Encode(int64 database_id,
269                                            int64 object_store_id,
270                                            unsigned char meta_data_type);
271   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id);
272   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
273                                                  int64 object_store_id);
274   int64 ObjectStoreId() const;
275   unsigned char MetaDataType() const;
276   int Compare(const ObjectStoreMetaDataKey& other);
277 
278  private:
279   int64 object_store_id_;
280   unsigned char meta_data_type_;
281 };
282 
283 class IndexMetaDataKey {
284  public:
285   enum MetaDataType {
286     NAME = 0,
287     UNIQUE = 1,
288     KEY_PATH = 2,
289     MULTI_ENTRY = 3
290   };
291 
292   IndexMetaDataKey();
293   static bool Decode(base::StringPiece* slice, IndexMetaDataKey* result);
294   CONTENT_EXPORT static std::string Encode(int64 database_id,
295                                            int64 object_store_id,
296                                            int64 index_id,
297                                            unsigned char meta_data_type);
298   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
299                                                  int64 object_store_id);
300   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
301                                                  int64 object_store_id,
302                                                  int64 index_id);
303   int Compare(const IndexMetaDataKey& other);
304   int64 IndexId() const;
meta_data_type()305   unsigned char meta_data_type() const { return meta_data_type_; }
306 
307  private:
308   int64 object_store_id_;
309   int64 index_id_;
310   unsigned char meta_data_type_;
311 };
312 
313 class ObjectStoreFreeListKey {
314  public:
315   ObjectStoreFreeListKey();
316   static bool Decode(base::StringPiece* slice, ObjectStoreFreeListKey* result);
317   CONTENT_EXPORT static std::string Encode(int64 database_id,
318                                            int64 object_store_id);
319   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id);
320   int64 ObjectStoreId() const;
321   int Compare(const ObjectStoreFreeListKey& other);
322 
323  private:
324   int64 object_store_id_;
325 };
326 
327 class IndexFreeListKey {
328  public:
329   IndexFreeListKey();
330   static bool Decode(base::StringPiece* slice, IndexFreeListKey* result);
331   CONTENT_EXPORT static std::string Encode(int64 database_id,
332                                            int64 object_store_id,
333                                            int64 index_id);
334   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
335                                                  int64 object_store_id);
336   int Compare(const IndexFreeListKey& other);
337   int64 ObjectStoreId() const;
338   int64 IndexId() const;
339 
340  private:
341   int64 object_store_id_;
342   int64 index_id_;
343 };
344 
345 class ObjectStoreNamesKey {
346  public:
347   // TODO(jsbell): We never use this to look up object store ids,
348   // because a mapping is kept in the IndexedDBDatabase. Can the
349   // mapping become unreliable?  Can we remove this?
350   static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result);
351   CONTENT_EXPORT static std::string Encode(
352       int64 database_id,
353       const base::string16& object_store_name);
354   int Compare(const ObjectStoreNamesKey& other);
object_store_name()355   base::string16 object_store_name() const { return object_store_name_; }
356 
357  private:
358   // TODO(jsbell): Store the encoded string, or just pointers to it.
359   base::string16 object_store_name_;
360 };
361 
362 class IndexNamesKey {
363  public:
364   IndexNamesKey();
365   // TODO(jsbell): We never use this to look up index ids, because a mapping
366   // is kept at a higher level.
367   static bool Decode(base::StringPiece* slice, IndexNamesKey* result);
368   CONTENT_EXPORT static std::string Encode(int64 database_id,
369                                            int64 object_store_id,
370                                            const base::string16& index_name);
371   int Compare(const IndexNamesKey& other);
index_name()372   base::string16 index_name() const { return index_name_; }
373 
374  private:
375   int64 object_store_id_;
376   base::string16 index_name_;
377 };
378 
379 class ObjectStoreDataKey {
380  public:
381   static bool Decode(base::StringPiece* slice, ObjectStoreDataKey* result);
382   CONTENT_EXPORT static std::string Encode(int64 database_id,
383                                            int64 object_store_id,
384                                            const std::string encoded_user_key);
385   static std::string Encode(int64 database_id,
386                             int64 object_store_id,
387                             const IndexedDBKey& user_key);
388   scoped_ptr<IndexedDBKey> user_key() const;
389   static const int64 kSpecialIndexNumber;
390   ObjectStoreDataKey();
391   ~ObjectStoreDataKey();
392 
393  private:
394   std::string encoded_user_key_;
395 };
396 
397 class ExistsEntryKey {
398  public:
399   ExistsEntryKey();
400   ~ExistsEntryKey();
401 
402   static bool Decode(base::StringPiece* slice, ExistsEntryKey* result);
403   CONTENT_EXPORT static std::string Encode(int64 database_id,
404                                            int64 object_store_id,
405                                            const std::string& encoded_key);
406   static std::string Encode(int64 database_id,
407                             int64 object_store_id,
408                             const IndexedDBKey& user_key);
409   scoped_ptr<IndexedDBKey> user_key() const;
410 
411   static const int64 kSpecialIndexNumber;
412 
413  private:
414   std::string encoded_user_key_;
415   DISALLOW_COPY_AND_ASSIGN(ExistsEntryKey);
416 };
417 
418 class BlobEntryKey {
419  public:
BlobEntryKey()420   BlobEntryKey() : database_id_(0), object_store_id_(0) {}
421   static bool Decode(base::StringPiece* slice, BlobEntryKey* result);
422   static bool FromObjectStoreDataKey(base::StringPiece* slice,
423                                      BlobEntryKey* result);
424   static std::string ReencodeToObjectStoreDataKey(base::StringPiece* slice);
425   static std::string EncodeMinKeyForObjectStore(int64 database_id,
426                                                 int64 object_store_id);
427   static std::string EncodeStopKeyForObjectStore(int64 database_id,
428                                                  int64 object_store_id);
429   static std::string Encode(int64 database_id,
430                             int64 object_store_id,
431                             const IndexedDBKey& user_key);
432   std::string Encode() const;
database_id()433   int64 database_id() const { return database_id_; }
object_store_id()434   int64 object_store_id() const { return object_store_id_; }
435 
436   static const int64 kSpecialIndexNumber;
437 
438  private:
439   static std::string Encode(int64 database_id,
440                             int64 object_store_id,
441                             const std::string& encoded_user_key);
442   int64 database_id_;
443   int64 object_store_id_;
444   // This is the user's ObjectStoreDataKey, not the BlobEntryKey itself.
445   std::string encoded_user_key_;
446 };
447 
448 class IndexDataKey {
449  public:
450   IndexDataKey();
451   ~IndexDataKey();
452   static bool Decode(base::StringPiece* slice, IndexDataKey* result);
453   CONTENT_EXPORT static std::string Encode(
454       int64 database_id,
455       int64 object_store_id,
456       int64 index_id,
457       const std::string& encoded_user_key,
458       const std::string& encoded_primary_key,
459       int64 sequence_number);
460   static std::string Encode(int64 database_id,
461                             int64 object_store_id,
462                             int64 index_id,
463                             const IndexedDBKey& user_key);
464   static std::string Encode(int64 database_id,
465                             int64 object_store_id,
466                             int64 index_id,
467                             const IndexedDBKey& user_key,
468                             const IndexedDBKey& user_primary_key);
469   static std::string EncodeMinKey(int64 database_id,
470                                   int64 object_store_id,
471                                   int64 index_id);
472   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
473                                                  int64 object_store_id,
474                                                  int64 index_id);
475   int64 DatabaseId() const;
476   int64 ObjectStoreId() const;
477   int64 IndexId() const;
478   scoped_ptr<IndexedDBKey> user_key() const;
479   scoped_ptr<IndexedDBKey> primary_key() const;
480 
481  private:
482   int64 database_id_;
483   int64 object_store_id_;
484   int64 index_id_;
485   std::string encoded_user_key_;
486   std::string encoded_primary_key_;
487   int64 sequence_number_;
488 
489   DISALLOW_COPY_AND_ASSIGN(IndexDataKey);
490 };
491 
492 }  // namespace content
493 
494 #endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_
495