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