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 // These are serialized to disk; any new items must be appended, and none can 94 // be deleted. 95 enum Type { 96 GLOBAL_METADATA, 97 DATABASE_METADATA, 98 OBJECT_STORE_DATA, 99 EXISTS_ENTRY, 100 INDEX_DATA, 101 INVALID_TYPE, 102 BLOB_ENTRY 103 }; 104 105 static const size_t kMaxDatabaseIdSizeBits = 3; 106 static const size_t kMaxObjectStoreIdSizeBits = 3; 107 static const size_t kMaxIndexIdSizeBits = 2; 108 109 static const size_t kMaxDatabaseIdSizeBytes = 110 1ULL << kMaxDatabaseIdSizeBits; // 8 111 static const size_t kMaxObjectStoreIdSizeBytes = 112 1ULL << kMaxObjectStoreIdSizeBits; // 8 113 static const size_t kMaxIndexIdSizeBytes = 1ULL << kMaxIndexIdSizeBits; // 4 114 115 static const size_t kMaxDatabaseIdBits = 116 kMaxDatabaseIdSizeBytes * 8 - 1; // 63 117 static const size_t kMaxObjectStoreIdBits = 118 kMaxObjectStoreIdSizeBytes * 8 - 1; // 63 119 static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1; // 31 120 121 static const int64 kMaxDatabaseId = 122 (1ULL << kMaxDatabaseIdBits) - 1; // max signed int64 123 static const int64 kMaxObjectStoreId = 124 (1ULL << kMaxObjectStoreIdBits) - 1; // max signed int64 125 static const int64 kMaxIndexId = 126 (1ULL << kMaxIndexIdBits) - 1; // max signed int32 127 128 static const int64 kInvalidId = -1; 129 130 KeyPrefix(); 131 explicit KeyPrefix(int64 database_id); 132 KeyPrefix(int64 database_id, int64 object_store_id); 133 KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id); 134 static KeyPrefix CreateWithSpecialIndex(int64 database_id, 135 int64 object_store_id, 136 int64 index_id); 137 138 static bool Decode(base::StringPiece* slice, KeyPrefix* result); 139 std::string Encode() const; 140 static std::string EncodeEmpty(); 141 int Compare(const KeyPrefix& other) const; 142 143 CONTENT_EXPORT static bool IsValidDatabaseId(int64 database_id); 144 static bool IsValidObjectStoreId(int64 index_id); 145 static bool IsValidIndexId(int64 index_id); 146 static bool ValidIds(int64 database_id, 147 int64 object_store_id, 148 int64 index_id) { 149 return IsValidDatabaseId(database_id) && 150 IsValidObjectStoreId(object_store_id) && IsValidIndexId(index_id); 151 } 152 static bool ValidIds(int64 database_id, int64 object_store_id) { 153 return IsValidDatabaseId(database_id) && 154 IsValidObjectStoreId(object_store_id); 155 } 156 157 Type type() const; 158 159 int64 database_id_; 160 int64 object_store_id_; 161 int64 index_id_; 162 163 private: 164 // Special constructor for CreateWithSpecialIndex() 165 KeyPrefix(enum Type, 166 int64 database_id, 167 int64 object_store_id, 168 int64 index_id); 169 170 static std::string EncodeInternal(int64 database_id, 171 int64 object_store_id, 172 int64 index_id); 173 }; 174 175 class SchemaVersionKey { 176 public: 177 CONTENT_EXPORT static std::string Encode(); 178 }; 179 180 class MaxDatabaseIdKey { 181 public: 182 CONTENT_EXPORT static std::string Encode(); 183 }; 184 185 class DataVersionKey { 186 public: 187 static std::string Encode(); 188 }; 189 190 class BlobJournalKey { 191 public: 192 static std::string Encode(); 193 }; 194 195 class LiveBlobJournalKey { 196 public: 197 static std::string Encode(); 198 }; 199 200 class DatabaseFreeListKey { 201 public: 202 DatabaseFreeListKey(); 203 static bool Decode(base::StringPiece* slice, DatabaseFreeListKey* result); 204 CONTENT_EXPORT static std::string Encode(int64 database_id); 205 static CONTENT_EXPORT std::string EncodeMaxKey(); 206 int64 DatabaseId() const; 207 int Compare(const DatabaseFreeListKey& other) const; 208 209 private: 210 int64 database_id_; 211 }; 212 213 class DatabaseNameKey { 214 public: 215 static bool Decode(base::StringPiece* slice, DatabaseNameKey* result); 216 CONTENT_EXPORT static std::string Encode(const std::string& origin_identifier, 217 const base::string16& database_name); 218 static std::string EncodeMinKeyForOrigin( 219 const std::string& origin_identifier); 220 static std::string EncodeStopKeyForOrigin( 221 const std::string& origin_identifier); 222 base::string16 origin() const { return origin_; } 223 base::string16 database_name() const { return database_name_; } 224 int Compare(const DatabaseNameKey& other); 225 226 private: 227 base::string16 origin_; // TODO(jsbell): Store encoded strings, or just 228 // pointers. 229 base::string16 database_name_; 230 }; 231 232 class DatabaseMetaDataKey { 233 public: 234 enum MetaDataType { 235 ORIGIN_NAME = 0, 236 DATABASE_NAME = 1, 237 USER_VERSION = 2, 238 MAX_OBJECT_STORE_ID = 3, 239 USER_INT_VERSION = 4, 240 BLOB_KEY_GENERATOR_CURRENT_NUMBER = 5, 241 MAX_SIMPLE_METADATA_TYPE = 6 242 }; 243 244 CONTENT_EXPORT static const int64 kAllBlobsKey; 245 static const int64 kBlobKeyGeneratorInitialNumber; 246 // All keys <= 0 are invalid. This one's just a convenient example. 247 static const int64 kInvalidBlobKey; 248 249 static bool IsValidBlobKey(int64 blobKey); 250 CONTENT_EXPORT static std::string Encode(int64 database_id, 251 MetaDataType type); 252 }; 253 254 class ObjectStoreMetaDataKey { 255 public: 256 enum MetaDataType { 257 NAME = 0, 258 KEY_PATH = 1, 259 AUTO_INCREMENT = 2, 260 EVICTABLE = 3, 261 LAST_VERSION = 4, 262 MAX_INDEX_ID = 5, 263 HAS_KEY_PATH = 6, 264 KEY_GENERATOR_CURRENT_NUMBER = 7 265 }; 266 267 ObjectStoreMetaDataKey(); 268 static bool Decode(base::StringPiece* slice, ObjectStoreMetaDataKey* result); 269 CONTENT_EXPORT static std::string Encode(int64 database_id, 270 int64 object_store_id, 271 unsigned char meta_data_type); 272 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id); 273 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, 274 int64 object_store_id); 275 int64 ObjectStoreId() const; 276 unsigned char MetaDataType() const; 277 int Compare(const ObjectStoreMetaDataKey& other); 278 279 private: 280 int64 object_store_id_; 281 unsigned char meta_data_type_; 282 }; 283 284 class IndexMetaDataKey { 285 public: 286 enum MetaDataType { 287 NAME = 0, 288 UNIQUE = 1, 289 KEY_PATH = 2, 290 MULTI_ENTRY = 3 291 }; 292 293 IndexMetaDataKey(); 294 static bool Decode(base::StringPiece* slice, IndexMetaDataKey* result); 295 CONTENT_EXPORT static std::string Encode(int64 database_id, 296 int64 object_store_id, 297 int64 index_id, 298 unsigned char meta_data_type); 299 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, 300 int64 object_store_id); 301 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, 302 int64 object_store_id, 303 int64 index_id); 304 int Compare(const IndexMetaDataKey& other); 305 int64 IndexId() const; 306 unsigned char meta_data_type() const { return meta_data_type_; } 307 308 private: 309 int64 object_store_id_; 310 int64 index_id_; 311 unsigned char meta_data_type_; 312 }; 313 314 class ObjectStoreFreeListKey { 315 public: 316 ObjectStoreFreeListKey(); 317 static bool Decode(base::StringPiece* slice, ObjectStoreFreeListKey* result); 318 CONTENT_EXPORT static std::string Encode(int64 database_id, 319 int64 object_store_id); 320 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id); 321 int64 ObjectStoreId() const; 322 int Compare(const ObjectStoreFreeListKey& other); 323 324 private: 325 int64 object_store_id_; 326 }; 327 328 class IndexFreeListKey { 329 public: 330 IndexFreeListKey(); 331 static bool Decode(base::StringPiece* slice, IndexFreeListKey* result); 332 CONTENT_EXPORT static std::string Encode(int64 database_id, 333 int64 object_store_id, 334 int64 index_id); 335 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, 336 int64 object_store_id); 337 int Compare(const IndexFreeListKey& other); 338 int64 ObjectStoreId() const; 339 int64 IndexId() const; 340 341 private: 342 int64 object_store_id_; 343 int64 index_id_; 344 }; 345 346 class ObjectStoreNamesKey { 347 public: 348 // TODO(jsbell): We never use this to look up object store ids, 349 // because a mapping is kept in the IndexedDBDatabase. Can the 350 // mapping become unreliable? Can we remove this? 351 static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result); 352 CONTENT_EXPORT static std::string Encode( 353 int64 database_id, 354 const base::string16& object_store_name); 355 int Compare(const ObjectStoreNamesKey& other); 356 base::string16 object_store_name() const { return object_store_name_; } 357 358 private: 359 // TODO(jsbell): Store the encoded string, or just pointers to it. 360 base::string16 object_store_name_; 361 }; 362 363 class IndexNamesKey { 364 public: 365 IndexNamesKey(); 366 // TODO(jsbell): We never use this to look up index ids, because a mapping 367 // is kept at a higher level. 368 static bool Decode(base::StringPiece* slice, IndexNamesKey* result); 369 CONTENT_EXPORT static std::string Encode(int64 database_id, 370 int64 object_store_id, 371 const base::string16& index_name); 372 int Compare(const IndexNamesKey& other); 373 base::string16 index_name() const { return index_name_; } 374 375 private: 376 int64 object_store_id_; 377 base::string16 index_name_; 378 }; 379 380 class ObjectStoreDataKey { 381 public: 382 static const int64 kSpecialIndexNumber; 383 384 ObjectStoreDataKey(); 385 ~ObjectStoreDataKey(); 386 387 static bool Decode(base::StringPiece* slice, ObjectStoreDataKey* result); 388 CONTENT_EXPORT static std::string Encode(int64 database_id, 389 int64 object_store_id, 390 const std::string encoded_user_key); 391 static std::string Encode(int64 database_id, 392 int64 object_store_id, 393 const IndexedDBKey& user_key); 394 scoped_ptr<IndexedDBKey> user_key() const; 395 private: 396 std::string encoded_user_key_; 397 }; 398 399 class ExistsEntryKey { 400 public: 401 ExistsEntryKey(); 402 ~ExistsEntryKey(); 403 404 static bool Decode(base::StringPiece* slice, ExistsEntryKey* result); 405 CONTENT_EXPORT static std::string Encode(int64 database_id, 406 int64 object_store_id, 407 const std::string& encoded_key); 408 static std::string Encode(int64 database_id, 409 int64 object_store_id, 410 const IndexedDBKey& user_key); 411 scoped_ptr<IndexedDBKey> user_key() const; 412 413 private: 414 static const int64 kSpecialIndexNumber; 415 416 std::string encoded_user_key_; 417 DISALLOW_COPY_AND_ASSIGN(ExistsEntryKey); 418 }; 419 420 class BlobEntryKey { 421 public: 422 BlobEntryKey() : database_id_(0), object_store_id_(0) {} 423 static bool Decode(base::StringPiece* slice, BlobEntryKey* result); 424 static bool FromObjectStoreDataKey(base::StringPiece* slice, 425 BlobEntryKey* result); 426 static std::string ReencodeToObjectStoreDataKey(base::StringPiece* slice); 427 static std::string EncodeMinKeyForObjectStore(int64 database_id, 428 int64 object_store_id); 429 static std::string EncodeStopKeyForObjectStore(int64 database_id, 430 int64 object_store_id); 431 static std::string Encode(int64 database_id, 432 int64 object_store_id, 433 const IndexedDBKey& user_key); 434 std::string Encode() const; 435 int64 database_id() const { return database_id_; } 436 int64 object_store_id() const { return object_store_id_; } 437 438 private: 439 static const int64 kSpecialIndexNumber; 440 441 static std::string Encode(int64 database_id, 442 int64 object_store_id, 443 const std::string& encoded_user_key); 444 int64 database_id_; 445 int64 object_store_id_; 446 // This is the user's ObjectStoreDataKey, not the BlobEntryKey itself. 447 std::string encoded_user_key_; 448 }; 449 450 class IndexDataKey { 451 public: 452 IndexDataKey(); 453 ~IndexDataKey(); 454 static bool Decode(base::StringPiece* slice, IndexDataKey* result); 455 CONTENT_EXPORT static std::string Encode( 456 int64 database_id, 457 int64 object_store_id, 458 int64 index_id, 459 const std::string& encoded_user_key, 460 const std::string& encoded_primary_key, 461 int64 sequence_number); 462 static std::string Encode(int64 database_id, 463 int64 object_store_id, 464 int64 index_id, 465 const IndexedDBKey& user_key); 466 static std::string Encode(int64 database_id, 467 int64 object_store_id, 468 int64 index_id, 469 const IndexedDBKey& user_key, 470 const IndexedDBKey& user_primary_key); 471 static std::string EncodeMinKey(int64 database_id, 472 int64 object_store_id, 473 int64 index_id); 474 CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id, 475 int64 object_store_id, 476 int64 index_id); 477 int64 DatabaseId() const; 478 int64 ObjectStoreId() const; 479 int64 IndexId() const; 480 scoped_ptr<IndexedDBKey> user_key() const; 481 scoped_ptr<IndexedDBKey> primary_key() const; 482 483 private: 484 int64 database_id_; 485 int64 object_store_id_; 486 int64 index_id_; 487 std::string encoded_user_key_; 488 std::string encoded_primary_key_; 489 int64 sequence_number_; 490 491 DISALLOW_COPY_AND_ASSIGN(IndexDataKey); 492 }; 493 494 } // namespace content 495 496 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_LEVELDB_CODING_H_ 497