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   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);
    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   }
    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);
    221   base::string16 origin() const { return origin_; }
    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;
    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);
    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);
    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:
    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;
    433   int64 database_id() const { return database_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