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