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