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