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