Home | History | Annotate | Download | only in indexed_db
      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   // These are serialized to disk; any new items must be appended, and none can
     94   // be deleted.
     95   enum Type {
     96     GLOBAL_METADATA,
     97     DATABASE_METADATA,
     98     OBJECT_STORE_DATA,
     99     EXISTS_ENTRY,
    100     INDEX_DATA,
    101     INVALID_TYPE,
    102     BLOB_ENTRY
    103   };
    104 
    105   static const size_t kMaxDatabaseIdSizeBits = 3;
    106   static const size_t kMaxObjectStoreIdSizeBits = 3;
    107   static const size_t kMaxIndexIdSizeBits = 2;
    108 
    109   static const size_t kMaxDatabaseIdSizeBytes =
    110       1ULL << kMaxDatabaseIdSizeBits;  // 8
    111   static const size_t kMaxObjectStoreIdSizeBytes =
    112       1ULL << kMaxObjectStoreIdSizeBits;                                   // 8
    113   static const size_t kMaxIndexIdSizeBytes = 1ULL << kMaxIndexIdSizeBits;  // 4
    114 
    115   static const size_t kMaxDatabaseIdBits =
    116       kMaxDatabaseIdSizeBytes * 8 - 1;  // 63
    117   static const size_t kMaxObjectStoreIdBits =
    118       kMaxObjectStoreIdSizeBytes * 8 - 1;                              // 63
    119   static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1;  // 31
    120 
    121   static const int64 kMaxDatabaseId =
    122       (1ULL << kMaxDatabaseIdBits) - 1;  // max signed int64
    123   static const int64 kMaxObjectStoreId =
    124       (1ULL << kMaxObjectStoreIdBits) - 1;  // max signed int64
    125   static const int64 kMaxIndexId =
    126       (1ULL << kMaxIndexIdBits) - 1;  // max signed int32
    127 
    128   static const int64 kInvalidId = -1;
    129 
    130   KeyPrefix();
    131   explicit KeyPrefix(int64 database_id);
    132   KeyPrefix(int64 database_id, int64 object_store_id);
    133   KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id);
    134   static KeyPrefix CreateWithSpecialIndex(int64 database_id,
    135                                           int64 object_store_id,
    136                                           int64 index_id);
    137 
    138   static bool Decode(base::StringPiece* slice, KeyPrefix* result);
    139   std::string Encode() const;
    140   static std::string EncodeEmpty();
    141   int Compare(const KeyPrefix& other) const;
    142 
    143   CONTENT_EXPORT static bool IsValidDatabaseId(int64 database_id);
    144   static bool IsValidObjectStoreId(int64 index_id);
    145   static bool IsValidIndexId(int64 index_id);
    146   static bool ValidIds(int64 database_id,
    147                        int64 object_store_id,
    148                        int64 index_id) {
    149     return IsValidDatabaseId(database_id) &&
    150            IsValidObjectStoreId(object_store_id) && IsValidIndexId(index_id);
    151   }
    152   static bool ValidIds(int64 database_id, int64 object_store_id) {
    153     return IsValidDatabaseId(database_id) &&
    154            IsValidObjectStoreId(object_store_id);
    155   }
    156 
    157   Type type() const;
    158 
    159   int64 database_id_;
    160   int64 object_store_id_;
    161   int64 index_id_;
    162 
    163  private:
    164   // Special constructor for CreateWithSpecialIndex()
    165   KeyPrefix(enum Type,
    166             int64 database_id,
    167             int64 object_store_id,
    168             int64 index_id);
    169 
    170   static std::string EncodeInternal(int64 database_id,
    171                                     int64 object_store_id,
    172                                     int64 index_id);
    173 };
    174 
    175 class SchemaVersionKey {
    176  public:
    177   CONTENT_EXPORT static std::string Encode();
    178 };
    179 
    180 class MaxDatabaseIdKey {
    181  public:
    182   CONTENT_EXPORT static std::string Encode();
    183 };
    184 
    185 class DataVersionKey {
    186  public:
    187   static std::string Encode();
    188 };
    189 
    190 class BlobJournalKey {
    191  public:
    192   static std::string Encode();
    193 };
    194 
    195 class LiveBlobJournalKey {
    196  public:
    197   static std::string Encode();
    198 };
    199 
    200 class DatabaseFreeListKey {
    201  public:
    202   DatabaseFreeListKey();
    203   static bool Decode(base::StringPiece* slice, DatabaseFreeListKey* result);
    204   CONTENT_EXPORT static std::string Encode(int64 database_id);
    205   static CONTENT_EXPORT std::string EncodeMaxKey();
    206   int64 DatabaseId() const;
    207   int Compare(const DatabaseFreeListKey& other) const;
    208 
    209  private:
    210   int64 database_id_;
    211 };
    212 
    213 class DatabaseNameKey {
    214  public:
    215   static bool Decode(base::StringPiece* slice, DatabaseNameKey* result);
    216   CONTENT_EXPORT static std::string Encode(const std::string& origin_identifier,
    217                                            const base::string16& database_name);
    218   static std::string EncodeMinKeyForOrigin(
    219       const std::string& origin_identifier);
    220   static std::string EncodeStopKeyForOrigin(
    221       const std::string& origin_identifier);
    222   base::string16 origin() const { return origin_; }
    223   base::string16 database_name() const { return database_name_; }
    224   int Compare(const DatabaseNameKey& other);
    225 
    226  private:
    227   base::string16 origin_;  // TODO(jsbell): Store encoded strings, or just
    228                            // pointers.
    229   base::string16 database_name_;
    230 };
    231 
    232 class DatabaseMetaDataKey {
    233  public:
    234   enum MetaDataType {
    235     ORIGIN_NAME = 0,
    236     DATABASE_NAME = 1,
    237     USER_VERSION = 2,
    238     MAX_OBJECT_STORE_ID = 3,
    239     USER_INT_VERSION = 4,
    240     BLOB_KEY_GENERATOR_CURRENT_NUMBER = 5,
    241     MAX_SIMPLE_METADATA_TYPE = 6
    242   };
    243 
    244   CONTENT_EXPORT static const int64 kAllBlobsKey;
    245   static const int64 kBlobKeyGeneratorInitialNumber;
    246   // All keys <= 0 are invalid.  This one's just a convenient example.
    247   static const int64 kInvalidBlobKey;
    248 
    249   static bool IsValidBlobKey(int64 blobKey);
    250   CONTENT_EXPORT static std::string Encode(int64 database_id,
    251                                            MetaDataType type);
    252 };
    253 
    254 class ObjectStoreMetaDataKey {
    255  public:
    256   enum MetaDataType {
    257     NAME = 0,
    258     KEY_PATH = 1,
    259     AUTO_INCREMENT = 2,
    260     EVICTABLE = 3,
    261     LAST_VERSION = 4,
    262     MAX_INDEX_ID = 5,
    263     HAS_KEY_PATH = 6,
    264     KEY_GENERATOR_CURRENT_NUMBER = 7
    265   };
    266 
    267   ObjectStoreMetaDataKey();
    268   static bool Decode(base::StringPiece* slice, ObjectStoreMetaDataKey* result);
    269   CONTENT_EXPORT static std::string Encode(int64 database_id,
    270                                            int64 object_store_id,
    271                                            unsigned char meta_data_type);
    272   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id);
    273   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
    274                                                  int64 object_store_id);
    275   int64 ObjectStoreId() const;
    276   unsigned char MetaDataType() const;
    277   int Compare(const ObjectStoreMetaDataKey& other);
    278 
    279  private:
    280   int64 object_store_id_;
    281   unsigned char meta_data_type_;
    282 };
    283 
    284 class IndexMetaDataKey {
    285  public:
    286   enum MetaDataType {
    287     NAME = 0,
    288     UNIQUE = 1,
    289     KEY_PATH = 2,
    290     MULTI_ENTRY = 3
    291   };
    292 
    293   IndexMetaDataKey();
    294   static bool Decode(base::StringPiece* slice, IndexMetaDataKey* result);
    295   CONTENT_EXPORT static std::string Encode(int64 database_id,
    296                                            int64 object_store_id,
    297                                            int64 index_id,
    298                                            unsigned char meta_data_type);
    299   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
    300                                                  int64 object_store_id);
    301   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
    302                                                  int64 object_store_id,
    303                                                  int64 index_id);
    304   int Compare(const IndexMetaDataKey& other);
    305   int64 IndexId() const;
    306   unsigned char meta_data_type() const { return meta_data_type_; }
    307 
    308  private:
    309   int64 object_store_id_;
    310   int64 index_id_;
    311   unsigned char meta_data_type_;
    312 };
    313 
    314 class ObjectStoreFreeListKey {
    315  public:
    316   ObjectStoreFreeListKey();
    317   static bool Decode(base::StringPiece* slice, ObjectStoreFreeListKey* result);
    318   CONTENT_EXPORT static std::string Encode(int64 database_id,
    319                                            int64 object_store_id);
    320   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id);
    321   int64 ObjectStoreId() const;
    322   int Compare(const ObjectStoreFreeListKey& other);
    323 
    324  private:
    325   int64 object_store_id_;
    326 };
    327 
    328 class IndexFreeListKey {
    329  public:
    330   IndexFreeListKey();
    331   static bool Decode(base::StringPiece* slice, IndexFreeListKey* result);
    332   CONTENT_EXPORT static std::string Encode(int64 database_id,
    333                                            int64 object_store_id,
    334                                            int64 index_id);
    335   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
    336                                                  int64 object_store_id);
    337   int Compare(const IndexFreeListKey& other);
    338   int64 ObjectStoreId() const;
    339   int64 IndexId() const;
    340 
    341  private:
    342   int64 object_store_id_;
    343   int64 index_id_;
    344 };
    345 
    346 class ObjectStoreNamesKey {
    347  public:
    348   // TODO(jsbell): We never use this to look up object store ids,
    349   // because a mapping is kept in the IndexedDBDatabase. Can the
    350   // mapping become unreliable?  Can we remove this?
    351   static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result);
    352   CONTENT_EXPORT static std::string Encode(
    353       int64 database_id,
    354       const base::string16& object_store_name);
    355   int Compare(const ObjectStoreNamesKey& other);
    356   base::string16 object_store_name() const { return object_store_name_; }
    357 
    358  private:
    359   // TODO(jsbell): Store the encoded string, or just pointers to it.
    360   base::string16 object_store_name_;
    361 };
    362 
    363 class IndexNamesKey {
    364  public:
    365   IndexNamesKey();
    366   // TODO(jsbell): We never use this to look up index ids, because a mapping
    367   // is kept at a higher level.
    368   static bool Decode(base::StringPiece* slice, IndexNamesKey* result);
    369   CONTENT_EXPORT static std::string Encode(int64 database_id,
    370                                            int64 object_store_id,
    371                                            const base::string16& index_name);
    372   int Compare(const IndexNamesKey& other);
    373   base::string16 index_name() const { return index_name_; }
    374 
    375  private:
    376   int64 object_store_id_;
    377   base::string16 index_name_;
    378 };
    379 
    380 class ObjectStoreDataKey {
    381  public:
    382   static const int64 kSpecialIndexNumber;
    383 
    384   ObjectStoreDataKey();
    385   ~ObjectStoreDataKey();
    386 
    387   static bool Decode(base::StringPiece* slice, ObjectStoreDataKey* result);
    388   CONTENT_EXPORT static std::string Encode(int64 database_id,
    389                                            int64 object_store_id,
    390                                            const std::string encoded_user_key);
    391   static std::string Encode(int64 database_id,
    392                             int64 object_store_id,
    393                             const IndexedDBKey& user_key);
    394   scoped_ptr<IndexedDBKey> user_key() const;
    395  private:
    396   std::string encoded_user_key_;
    397 };
    398 
    399 class ExistsEntryKey {
    400  public:
    401   ExistsEntryKey();
    402   ~ExistsEntryKey();
    403 
    404   static bool Decode(base::StringPiece* slice, ExistsEntryKey* result);
    405   CONTENT_EXPORT static std::string Encode(int64 database_id,
    406                                            int64 object_store_id,
    407                                            const std::string& encoded_key);
    408   static std::string Encode(int64 database_id,
    409                             int64 object_store_id,
    410                             const IndexedDBKey& user_key);
    411   scoped_ptr<IndexedDBKey> user_key() const;
    412 
    413  private:
    414   static const int64 kSpecialIndexNumber;
    415 
    416   std::string encoded_user_key_;
    417   DISALLOW_COPY_AND_ASSIGN(ExistsEntryKey);
    418 };
    419 
    420 class BlobEntryKey {
    421  public:
    422   BlobEntryKey() : database_id_(0), object_store_id_(0) {}
    423   static bool Decode(base::StringPiece* slice, BlobEntryKey* result);
    424   static bool FromObjectStoreDataKey(base::StringPiece* slice,
    425                                      BlobEntryKey* result);
    426   static std::string ReencodeToObjectStoreDataKey(base::StringPiece* slice);
    427   static std::string EncodeMinKeyForObjectStore(int64 database_id,
    428                                                 int64 object_store_id);
    429   static std::string EncodeStopKeyForObjectStore(int64 database_id,
    430                                                  int64 object_store_id);
    431   static std::string Encode(int64 database_id,
    432                             int64 object_store_id,
    433                             const IndexedDBKey& user_key);
    434   std::string Encode() const;
    435   int64 database_id() const { return database_id_; }
    436   int64 object_store_id() const { return object_store_id_; }
    437 
    438  private:
    439   static const int64 kSpecialIndexNumber;
    440 
    441   static std::string Encode(int64 database_id,
    442                             int64 object_store_id,
    443                             const std::string& encoded_user_key);
    444   int64 database_id_;
    445   int64 object_store_id_;
    446   // This is the user's ObjectStoreDataKey, not the BlobEntryKey itself.
    447   std::string encoded_user_key_;
    448 };
    449 
    450 class IndexDataKey {
    451  public:
    452   IndexDataKey();
    453   ~IndexDataKey();
    454   static bool Decode(base::StringPiece* slice, IndexDataKey* result);
    455   CONTENT_EXPORT static std::string Encode(
    456       int64 database_id,
    457       int64 object_store_id,
    458       int64 index_id,
    459       const std::string& encoded_user_key,
    460       const std::string& encoded_primary_key,
    461       int64 sequence_number);
    462   static std::string Encode(int64 database_id,
    463                             int64 object_store_id,
    464                             int64 index_id,
    465                             const IndexedDBKey& user_key);
    466   static std::string Encode(int64 database_id,
    467                             int64 object_store_id,
    468                             int64 index_id,
    469                             const IndexedDBKey& user_key,
    470                             const IndexedDBKey& user_primary_key);
    471   static std::string EncodeMinKey(int64 database_id,
    472                                   int64 object_store_id,
    473                                   int64 index_id);
    474   CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
    475                                                  int64 object_store_id,
    476                                                  int64 index_id);
    477   int64 DatabaseId() const;
    478   int64 ObjectStoreId() const;
    479   int64 IndexId() const;
    480   scoped_ptr<IndexedDBKey> user_key() const;
    481   scoped_ptr<IndexedDBKey> primary_key() const;
    482 
    483  private:
    484   int64 database_id_;
    485   int64 object_store_id_;
    486   int64 index_id_;
    487   std::string encoded_user_key_;
    488   std::string encoded_primary_key_;
    489   int64 sequence_number_;
    490 
    491   DISALLOW_COPY_AND_ASSIGN(IndexDataKey);
    492 };
    493 
    494 }  // namespace content
    495 
    496 #endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_
    497