|  | // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_ | 
|  | #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/logging.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/memory/ref_counted.h" | 
|  | #include "base/strings/string16.h" | 
|  | #include "base/strings/string_piece.h" | 
|  | #include "content/common/content_export.h" | 
|  | #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" | 
|  | #include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h" | 
|  |  | 
|  | namespace content { | 
|  |  | 
|  | namespace indexed_db { | 
|  | // 0 - Initial version. | 
|  | // 1 - Adds UserIntVersion to DatabaseMetaData. | 
|  | // 2 - Adds DataVersion to to global metadata. | 
|  | // 3 - Adds metadata needed for blob support. | 
|  | const constexpr int64_t kLatestKnownSchemaVersion = 3; | 
|  | }  // namespace indexed_db | 
|  |  | 
|  | CONTENT_EXPORT extern const unsigned char kMinimumIndexId; | 
|  |  | 
|  | CONTENT_EXPORT std::string MaxIDBKey(); | 
|  | CONTENT_EXPORT std::string MinIDBKey(); | 
|  |  | 
|  | // DatabaseId, BlobKey | 
|  | typedef std::pair<int64_t, int64_t> BlobJournalEntryType; | 
|  | typedef std::vector<BlobJournalEntryType> BlobJournalType; | 
|  |  | 
|  | CONTENT_EXPORT void EncodeByte(unsigned char value, std::string* into); | 
|  | CONTENT_EXPORT void EncodeBool(bool value, std::string* into); | 
|  | CONTENT_EXPORT void EncodeInt(int64_t value, std::string* into); | 
|  | CONTENT_EXPORT void EncodeVarInt(int64_t value, std::string* into); | 
|  | CONTENT_EXPORT void EncodeString(const base::string16& value, | 
|  | std::string* into); | 
|  | CONTENT_EXPORT void EncodeStringWithLength(const base::string16& value, | 
|  | std::string* into); | 
|  | CONTENT_EXPORT void EncodeBinary(const std::string& value, std::string* into); | 
|  | CONTENT_EXPORT void EncodeDouble(double value, std::string* into); | 
|  | CONTENT_EXPORT void EncodeIDBKey(const blink::IndexedDBKey& value, | 
|  | std::string* into); | 
|  | CONTENT_EXPORT void EncodeIDBKeyPath(const blink::IndexedDBKeyPath& value, | 
|  | std::string* into); | 
|  | CONTENT_EXPORT void EncodeBlobJournal(const BlobJournalType& journal, | 
|  | std::string* into); | 
|  |  | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeByte(base::StringPiece* slice, | 
|  | unsigned char* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBool(base::StringPiece* slice, | 
|  | bool* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeInt(base::StringPiece* slice, | 
|  | int64_t* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeVarInt(base::StringPiece* slice, | 
|  | int64_t* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeString(base::StringPiece* slice, | 
|  | base::string16* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeStringWithLength( | 
|  | base::StringPiece* slice, | 
|  | base::string16* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBinary(base::StringPiece* slice, | 
|  | std::string* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeDouble(base::StringPiece* slice, | 
|  | double* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKey( | 
|  | base::StringPiece* slice, | 
|  | std::unique_ptr<blink::IndexedDBKey>* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKeyPath( | 
|  | base::StringPiece* slice, | 
|  | blink::IndexedDBKeyPath* value); | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBlobJournal( | 
|  | base::StringPiece* slice, | 
|  | BlobJournalType* journal); | 
|  |  | 
|  | CONTENT_EXPORT int CompareEncodedStringsWithLength(base::StringPiece* slice1, | 
|  | base::StringPiece* slice2, | 
|  | bool* ok); | 
|  |  | 
|  | CONTENT_EXPORT WARN_UNUSED_RESULT bool ExtractEncodedIDBKey( | 
|  | base::StringPiece* slice, | 
|  | std::string* result); | 
|  |  | 
|  | CONTENT_EXPORT int CompareEncodedIDBKeys(base::StringPiece* slice1, | 
|  | base::StringPiece* slice2, | 
|  | bool* ok); | 
|  |  | 
|  | CONTENT_EXPORT int Compare(const base::StringPiece& a, | 
|  | const base::StringPiece& b, | 
|  | bool index_keys); | 
|  |  | 
|  | CONTENT_EXPORT int CompareKeys(const base::StringPiece& a, | 
|  | const base::StringPiece& b); | 
|  |  | 
|  | CONTENT_EXPORT int CompareIndexKeys(const base::StringPiece& a, | 
|  | const base::StringPiece& b); | 
|  |  | 
|  | class KeyPrefix { | 
|  | public: | 
|  | // These are serialized to disk; any new items must be appended, and none can | 
|  | // be deleted. | 
|  | enum Type { | 
|  | GLOBAL_METADATA = 0, | 
|  | DATABASE_METADATA = 1, | 
|  | OBJECT_STORE_DATA = 2, | 
|  | EXISTS_ENTRY = 3, | 
|  | INDEX_DATA = 4, | 
|  | INVALID_TYPE = 5, | 
|  | BLOB_ENTRY = 6 | 
|  | }; | 
|  |  | 
|  | static const size_t kMaxDatabaseIdSizeBits = 3; | 
|  | static const size_t kMaxObjectStoreIdSizeBits = 3; | 
|  | static const size_t kMaxIndexIdSizeBits = 2; | 
|  |  | 
|  | static const size_t kMaxDatabaseIdSizeBytes = | 
|  | 1ULL << kMaxDatabaseIdSizeBits;  // 8 | 
|  | static const size_t kMaxObjectStoreIdSizeBytes = | 
|  | 1ULL << kMaxObjectStoreIdSizeBits;                                   // 8 | 
|  | static const size_t kMaxIndexIdSizeBytes = 1ULL << kMaxIndexIdSizeBits;  // 4 | 
|  |  | 
|  | static const size_t kMaxDatabaseIdBits = | 
|  | kMaxDatabaseIdSizeBytes * 8 - 1;  // 63 | 
|  | static const size_t kMaxObjectStoreIdBits = | 
|  | kMaxObjectStoreIdSizeBytes * 8 - 1;                              // 63 | 
|  | static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1;  // 31 | 
|  |  | 
|  | static const int64_t kMaxDatabaseId = | 
|  | (1ULL << kMaxDatabaseIdBits) - 1;  // max signed int64_t | 
|  | static const int64_t kMaxObjectStoreId = | 
|  | (1ULL << kMaxObjectStoreIdBits) - 1;  // max signed int64_t | 
|  | static const int64_t kMaxIndexId = | 
|  | (1ULL << kMaxIndexIdBits) - 1;  // max signed int32_t | 
|  |  | 
|  | static const int64_t kInvalidId = -1; | 
|  |  | 
|  | KeyPrefix(); | 
|  | explicit KeyPrefix(int64_t database_id); | 
|  | KeyPrefix(int64_t database_id, int64_t object_store_id); | 
|  | KeyPrefix(int64_t database_id, int64_t object_store_id, int64_t index_id); | 
|  | static KeyPrefix CreateWithSpecialIndex(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  |  | 
|  | static bool Decode(base::StringPiece* slice, KeyPrefix* result); | 
|  | std::string Encode() const; | 
|  | static std::string EncodeEmpty(); | 
|  | int Compare(const KeyPrefix& other) const; | 
|  |  | 
|  | CONTENT_EXPORT static bool IsValidDatabaseId(int64_t database_id); | 
|  | static bool IsValidObjectStoreId(int64_t index_id); | 
|  | static bool IsValidIndexId(int64_t index_id); | 
|  | static bool ValidIds(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id) { | 
|  | return IsValidDatabaseId(database_id) && | 
|  | IsValidObjectStoreId(object_store_id) && IsValidIndexId(index_id); | 
|  | } | 
|  | static bool ValidIds(int64_t database_id, int64_t object_store_id) { | 
|  | return IsValidDatabaseId(database_id) && | 
|  | IsValidObjectStoreId(object_store_id); | 
|  | } | 
|  |  | 
|  | Type type() const; | 
|  |  | 
|  | int64_t database_id_; | 
|  | int64_t object_store_id_; | 
|  | int64_t index_id_; | 
|  |  | 
|  | private: | 
|  | // Special constructor for CreateWithSpecialIndex() | 
|  | KeyPrefix(enum Type, | 
|  | int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  |  | 
|  | static std::string EncodeInternal(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  | }; | 
|  |  | 
|  | class SchemaVersionKey { | 
|  | public: | 
|  | CONTENT_EXPORT static std::string Encode(); | 
|  | }; | 
|  |  | 
|  | class MaxDatabaseIdKey { | 
|  | public: | 
|  | CONTENT_EXPORT static std::string Encode(); | 
|  | }; | 
|  |  | 
|  | class DataVersionKey { | 
|  | public: | 
|  | static std::string Encode(); | 
|  | }; | 
|  |  | 
|  | class BlobJournalKey { | 
|  | public: | 
|  | static std::string Encode(); | 
|  | }; | 
|  |  | 
|  | class LiveBlobJournalKey { | 
|  | public: | 
|  | static std::string Encode(); | 
|  | }; | 
|  |  | 
|  | class EarliestSweepKey { | 
|  | public: | 
|  | static std::string Encode(); | 
|  | }; | 
|  |  | 
|  | class DatabaseFreeListKey { | 
|  | public: | 
|  | DatabaseFreeListKey(); | 
|  | static bool Decode(base::StringPiece* slice, DatabaseFreeListKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id); | 
|  | static CONTENT_EXPORT std::string EncodeMaxKey(); | 
|  | int64_t DatabaseId() const; | 
|  | int Compare(const DatabaseFreeListKey& other) const; | 
|  |  | 
|  | private: | 
|  | int64_t database_id_; | 
|  | }; | 
|  |  | 
|  | class DatabaseNameKey { | 
|  | public: | 
|  | static bool Decode(base::StringPiece* slice, DatabaseNameKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(const std::string& origin_identifier, | 
|  | const base::string16& database_name); | 
|  | static std::string EncodeMinKeyForOrigin( | 
|  | const std::string& origin_identifier); | 
|  | static std::string EncodeStopKeyForOrigin( | 
|  | const std::string& origin_identifier); | 
|  | base::string16 origin() const { return origin_; } | 
|  | base::string16 database_name() const { return database_name_; } | 
|  | int Compare(const DatabaseNameKey& other); | 
|  |  | 
|  | private: | 
|  | base::string16 origin_;  // TODO(jsbell): Store encoded strings, or just | 
|  | // pointers. | 
|  | base::string16 database_name_; | 
|  | }; | 
|  |  | 
|  | class DatabaseMetaDataKey { | 
|  | public: | 
|  | enum MetaDataType { | 
|  | ORIGIN_NAME = 0, | 
|  | DATABASE_NAME = 1, | 
|  | USER_STRING_VERSION = 2,  // Obsolete | 
|  | MAX_OBJECT_STORE_ID = 3, | 
|  | USER_VERSION = 4, | 
|  | BLOB_KEY_GENERATOR_CURRENT_NUMBER = 5, | 
|  | MAX_SIMPLE_METADATA_TYPE = 6 | 
|  | }; | 
|  |  | 
|  | CONTENT_EXPORT static const int64_t kAllBlobsKey; | 
|  | static const int64_t kBlobKeyGeneratorInitialNumber; | 
|  | // All keys <= 0 are invalid.  This one's just a convenient example. | 
|  | static const int64_t kInvalidBlobKey; | 
|  |  | 
|  | static bool IsValidBlobKey(int64_t blob_key); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | MetaDataType type); | 
|  | }; | 
|  |  | 
|  | class ObjectStoreMetaDataKey { | 
|  | public: | 
|  | enum MetaDataType { | 
|  | NAME = 0, | 
|  | KEY_PATH = 1, | 
|  | AUTO_INCREMENT = 2, | 
|  | EVICTABLE = 3, | 
|  | LAST_VERSION = 4, | 
|  | MAX_INDEX_ID = 5, | 
|  | HAS_KEY_PATH = 6, | 
|  | KEY_GENERATOR_CURRENT_NUMBER = 7 | 
|  | }; | 
|  |  | 
|  | // From the IndexedDB specification. | 
|  | static const int64_t kKeyGeneratorInitialNumber; | 
|  |  | 
|  | ObjectStoreMetaDataKey(); | 
|  | static bool Decode(base::StringPiece* slice, ObjectStoreMetaDataKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | unsigned char meta_data_type); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id, | 
|  | int64_t object_store_id); | 
|  | int64_t ObjectStoreId() const; | 
|  | unsigned char MetaDataType() const; | 
|  | int Compare(const ObjectStoreMetaDataKey& other); | 
|  |  | 
|  | private: | 
|  | int64_t object_store_id_; | 
|  | unsigned char meta_data_type_; | 
|  | }; | 
|  |  | 
|  | class IndexMetaDataKey { | 
|  | public: | 
|  | enum MetaDataType { | 
|  | NAME = 0, | 
|  | UNIQUE = 1, | 
|  | KEY_PATH = 2, | 
|  | MULTI_ENTRY = 3 | 
|  | }; | 
|  |  | 
|  | IndexMetaDataKey(); | 
|  | static bool Decode(base::StringPiece* slice, IndexMetaDataKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id, | 
|  | unsigned char meta_data_type); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id, | 
|  | int64_t object_store_id); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  | int Compare(const IndexMetaDataKey& other); | 
|  | int64_t IndexId() const; | 
|  | unsigned char meta_data_type() const { return meta_data_type_; } | 
|  |  | 
|  | private: | 
|  | int64_t object_store_id_; | 
|  | int64_t index_id_; | 
|  | unsigned char meta_data_type_; | 
|  | }; | 
|  |  | 
|  | class ObjectStoreFreeListKey { | 
|  | public: | 
|  | ObjectStoreFreeListKey(); | 
|  | static bool Decode(base::StringPiece* slice, ObjectStoreFreeListKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id); | 
|  | int64_t ObjectStoreId() const; | 
|  | int Compare(const ObjectStoreFreeListKey& other); | 
|  |  | 
|  | private: | 
|  | int64_t object_store_id_; | 
|  | }; | 
|  |  | 
|  | class IndexFreeListKey { | 
|  | public: | 
|  | IndexFreeListKey(); | 
|  | static bool Decode(base::StringPiece* slice, IndexFreeListKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id, | 
|  | int64_t object_store_id); | 
|  | int Compare(const IndexFreeListKey& other); | 
|  | int64_t ObjectStoreId() const; | 
|  | int64_t IndexId() const; | 
|  |  | 
|  | private: | 
|  | int64_t object_store_id_; | 
|  | int64_t index_id_; | 
|  | }; | 
|  |  | 
|  | class ObjectStoreNamesKey { | 
|  | public: | 
|  | // TODO(jsbell): We never use this to look up object store ids, | 
|  | // because a mapping is kept in the IndexedDBDatabase. Can the | 
|  | // mapping become unreliable?  Can we remove this? | 
|  | static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result); | 
|  | CONTENT_EXPORT static std::string Encode( | 
|  | int64_t database_id, | 
|  | const base::string16& object_store_name); | 
|  | int Compare(const ObjectStoreNamesKey& other); | 
|  | base::string16 object_store_name() const { return object_store_name_; } | 
|  |  | 
|  | private: | 
|  | // TODO(jsbell): Store the encoded string, or just pointers to it. | 
|  | base::string16 object_store_name_; | 
|  | }; | 
|  |  | 
|  | class IndexNamesKey { | 
|  | public: | 
|  | IndexNamesKey(); | 
|  | // TODO(jsbell): We never use this to look up index ids, because a mapping | 
|  | // is kept at a higher level. | 
|  | static bool Decode(base::StringPiece* slice, IndexNamesKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const base::string16& index_name); | 
|  | int Compare(const IndexNamesKey& other); | 
|  | base::string16 index_name() const { return index_name_; } | 
|  |  | 
|  | private: | 
|  | int64_t object_store_id_; | 
|  | base::string16 index_name_; | 
|  | }; | 
|  |  | 
|  | class ObjectStoreDataKey { | 
|  | public: | 
|  | static const int64_t kSpecialIndexNumber; | 
|  |  | 
|  | ObjectStoreDataKey(); | 
|  | ~ObjectStoreDataKey(); | 
|  |  | 
|  | static bool Decode(base::StringPiece* slice, ObjectStoreDataKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const std::string encoded_user_key); | 
|  | static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const blink::IndexedDBKey& user_key); | 
|  | std::unique_ptr<blink::IndexedDBKey> user_key() const; | 
|  |  | 
|  | private: | 
|  | std::string encoded_user_key_; | 
|  | }; | 
|  |  | 
|  | class ExistsEntryKey { | 
|  | public: | 
|  | ExistsEntryKey(); | 
|  | ~ExistsEntryKey(); | 
|  |  | 
|  | static bool Decode(base::StringPiece* slice, ExistsEntryKey* result); | 
|  | CONTENT_EXPORT static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const std::string& encoded_key); | 
|  | static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const blink::IndexedDBKey& user_key); | 
|  | std::unique_ptr<blink::IndexedDBKey> user_key() const; | 
|  |  | 
|  | private: | 
|  | static const int64_t kSpecialIndexNumber; | 
|  |  | 
|  | std::string encoded_user_key_; | 
|  | DISALLOW_COPY_AND_ASSIGN(ExistsEntryKey); | 
|  | }; | 
|  |  | 
|  | class BlobEntryKey { | 
|  | public: | 
|  | BlobEntryKey() : database_id_(0), object_store_id_(0) {} | 
|  | static bool Decode(base::StringPiece* slice, BlobEntryKey* result); | 
|  | static bool FromObjectStoreDataKey(base::StringPiece* slice, | 
|  | BlobEntryKey* result); | 
|  | static std::string ReencodeToObjectStoreDataKey(base::StringPiece* slice); | 
|  | static std::string EncodeMinKeyForObjectStore(int64_t database_id, | 
|  | int64_t object_store_id); | 
|  | static std::string EncodeStopKeyForObjectStore(int64_t database_id, | 
|  | int64_t object_store_id); | 
|  | static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const blink::IndexedDBKey& user_key); | 
|  | std::string Encode() const; | 
|  | int64_t database_id() const { return database_id_; } | 
|  | int64_t object_store_id() const { return object_store_id_; } | 
|  |  | 
|  | private: | 
|  | static const int64_t kSpecialIndexNumber; | 
|  |  | 
|  | static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | const std::string& encoded_user_key); | 
|  | int64_t database_id_; | 
|  | int64_t object_store_id_; | 
|  | // This is the user's ObjectStoreDataKey, not the BlobEntryKey itself. | 
|  | std::string encoded_user_key_; | 
|  | }; | 
|  |  | 
|  | class IndexDataKey { | 
|  | public: | 
|  | CONTENT_EXPORT IndexDataKey(); | 
|  | CONTENT_EXPORT IndexDataKey(IndexDataKey&& other); | 
|  | CONTENT_EXPORT ~IndexDataKey(); | 
|  | CONTENT_EXPORT static bool Decode(base::StringPiece* slice, | 
|  | IndexDataKey* result); | 
|  | CONTENT_EXPORT static std::string Encode( | 
|  | int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id, | 
|  | const std::string& encoded_user_key, | 
|  | const std::string& encoded_primary_key, | 
|  | int64_t sequence_number); | 
|  | static std::string Encode(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id, | 
|  | const blink::IndexedDBKey& user_key); | 
|  | CONTENT_EXPORT static std::string Encode( | 
|  | int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id, | 
|  | const blink::IndexedDBKey& user_key, | 
|  | const blink::IndexedDBKey& user_primary_key); | 
|  | CONTENT_EXPORT static std::string EncodeMinKey(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  | CONTENT_EXPORT static std::string EncodeMaxKey(int64_t database_id, | 
|  | int64_t object_store_id, | 
|  | int64_t index_id); | 
|  | int64_t DatabaseId() const; | 
|  | int64_t ObjectStoreId() const; | 
|  | int64_t IndexId() const; | 
|  | std::unique_ptr<blink::IndexedDBKey> user_key() const; | 
|  | std::unique_ptr<blink::IndexedDBKey> primary_key() const; | 
|  |  | 
|  | CONTENT_EXPORT std::string Encode() const; | 
|  |  | 
|  | private: | 
|  | int64_t database_id_; | 
|  | int64_t object_store_id_; | 
|  | int64_t index_id_; | 
|  | std::string encoded_user_key_; | 
|  | std::string encoded_primary_key_; | 
|  | int64_t sequence_number_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(IndexDataKey); | 
|  | }; | 
|  |  | 
|  | }  // namespace content | 
|  |  | 
|  | #endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_ |