OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/indexed_db/indexed_db_database.h" | 5 #include "content/browser/indexed_db/indexed_db_database.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 | 264 |
265 void IndexedDBDatabase::CreateObjectStore(int64 transaction_id, | 265 void IndexedDBDatabase::CreateObjectStore(int64 transaction_id, |
266 int64 object_store_id, | 266 int64 object_store_id, |
267 const base::string16& name, | 267 const base::string16& name, |
268 const IndexedDBKeyPath& key_path, | 268 const IndexedDBKeyPath& key_path, |
269 bool auto_increment) { | 269 bool auto_increment) { |
270 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id); | 270 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id); |
271 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 271 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
272 if (!transaction) | 272 if (!transaction) |
273 return; | 273 return; |
274 DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); | 274 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
275 | 275 |
276 if (ContainsKey(metadata_.object_stores, object_store_id)) { | 276 if (ContainsKey(metadata_.object_stores, object_store_id)) { |
277 DLOG(ERROR) << "Invalid object_store_id"; | 277 DLOG(ERROR) << "Invalid object_store_id"; |
278 return; | 278 return; |
279 } | 279 } |
280 | 280 |
281 // Store creation is done synchronously, as it may be followed by | 281 // Store creation is done synchronously, as it may be followed by |
282 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys | 282 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys |
283 // may follow. | 283 // may follow. |
284 IndexedDBObjectStoreMetadata object_store_metadata( | 284 IndexedDBObjectStoreMetadata object_store_metadata( |
(...skipping 28 matching lines...) Expand all Loading... |
313 this, | 313 this, |
314 object_store_id)); | 314 object_store_id)); |
315 } | 315 } |
316 | 316 |
317 void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id, | 317 void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id, |
318 int64 object_store_id) { | 318 int64 object_store_id) { |
319 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id); | 319 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id); |
320 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 320 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
321 if (!transaction) | 321 if (!transaction) |
322 return; | 322 return; |
323 DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); | 323 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
324 | 324 |
325 if (!ValidateObjectStoreId(object_store_id)) | 325 if (!ValidateObjectStoreId(object_store_id)) |
326 return; | 326 return; |
327 | 327 |
328 transaction->ScheduleTask( | 328 transaction->ScheduleTask( |
329 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, | 329 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, |
330 this, | 330 this, |
331 object_store_id)); | 331 object_store_id)); |
332 } | 332 } |
333 | 333 |
334 void IndexedDBDatabase::CreateIndex(int64 transaction_id, | 334 void IndexedDBDatabase::CreateIndex(int64 transaction_id, |
335 int64 object_store_id, | 335 int64 object_store_id, |
336 int64 index_id, | 336 int64 index_id, |
337 const base::string16& name, | 337 const base::string16& name, |
338 const IndexedDBKeyPath& key_path, | 338 const IndexedDBKeyPath& key_path, |
339 bool unique, | 339 bool unique, |
340 bool multi_entry) { | 340 bool multi_entry) { |
341 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id); | 341 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id); |
342 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 342 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
343 if (!transaction) | 343 if (!transaction) |
344 return; | 344 return; |
345 DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); | 345 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
346 | 346 |
347 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) | 347 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) |
348 return; | 348 return; |
349 | 349 |
350 // Index creation is done synchronously since preemptive | 350 // Index creation is done synchronously since preemptive |
351 // OpenCursor/SetIndexKeys may follow. | 351 // OpenCursor/SetIndexKeys may follow. |
352 const IndexedDBIndexMetadata index_metadata( | 352 const IndexedDBIndexMetadata index_metadata( |
353 name, index_id, key_path, unique, multi_entry); | 353 name, index_id, key_path, unique, multi_entry); |
354 | 354 |
355 if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(), | 355 if (!backing_store_->CreateIndex(transaction->BackingStoreTransaction(), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 RemoveIndex(object_store_id, index_id); | 387 RemoveIndex(object_store_id, index_id); |
388 } | 388 } |
389 | 389 |
390 void IndexedDBDatabase::DeleteIndex(int64 transaction_id, | 390 void IndexedDBDatabase::DeleteIndex(int64 transaction_id, |
391 int64 object_store_id, | 391 int64 object_store_id, |
392 int64 index_id) { | 392 int64 index_id) { |
393 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); | 393 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); |
394 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 394 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
395 if (!transaction) | 395 if (!transaction) |
396 return; | 396 return; |
397 DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); | 397 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
398 | 398 |
399 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) | 399 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) |
400 return; | 400 return; |
401 | 401 |
402 transaction->ScheduleTask( | 402 transaction->ScheduleTask( |
403 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, | 403 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, |
404 this, | 404 this, |
405 object_store_id, | 405 object_store_id, |
406 index_id)); | 406 index_id)); |
407 } | 407 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 key = &key_range->lower(); | 528 key = &key_range->lower(); |
529 } else { | 529 } else { |
530 if (index_id == IndexedDBIndexMetadata::kInvalidId) { | 530 if (index_id == IndexedDBIndexMetadata::kInvalidId) { |
531 DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY); | 531 DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY); |
532 // ObjectStore Retrieval Operation | 532 // ObjectStore Retrieval Operation |
533 backing_store_cursor = backing_store_->OpenObjectStoreCursor( | 533 backing_store_cursor = backing_store_->OpenObjectStoreCursor( |
534 transaction->BackingStoreTransaction(), | 534 transaction->BackingStoreTransaction(), |
535 id(), | 535 id(), |
536 object_store_id, | 536 object_store_id, |
537 *key_range, | 537 *key_range, |
538 indexed_db::CURSOR_NEXT, | 538 blink::WebIDBCursorDirectionNext, |
539 &s); | 539 &s); |
540 } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { | 540 } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { |
541 // Index Value Retrieval Operation | 541 // Index Value Retrieval Operation |
542 backing_store_cursor = backing_store_->OpenIndexKeyCursor( | 542 backing_store_cursor = backing_store_->OpenIndexKeyCursor( |
543 transaction->BackingStoreTransaction(), | 543 transaction->BackingStoreTransaction(), |
544 id(), | 544 id(), |
545 object_store_id, | 545 object_store_id, |
546 index_id, | 546 index_id, |
547 *key_range, | 547 *key_range, |
548 indexed_db::CURSOR_NEXT, | 548 blink::WebIDBCursorDirectionNext, |
549 &s); | 549 &s); |
550 } else { | 550 } else { |
551 // Index Referenced Value Retrieval Operation | 551 // Index Referenced Value Retrieval Operation |
552 backing_store_cursor = backing_store_->OpenIndexCursor( | 552 backing_store_cursor = backing_store_->OpenIndexCursor( |
553 transaction->BackingStoreTransaction(), | 553 transaction->BackingStoreTransaction(), |
554 id(), | 554 id(), |
555 object_store_id, | 555 object_store_id, |
556 index_id, | 556 index_id, |
557 *key_range, | 557 *key_range, |
558 indexed_db::CURSOR_NEXT, | 558 blink::WebIDBCursorDirectionNext, |
559 &s); | 559 &s); |
560 } | 560 } |
561 | 561 |
562 if (!s.ok()) { | 562 if (!s.ok()) { |
563 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); | 563 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); |
564 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 564 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
565 "Internal error deleting data in range"); | 565 "Internal error deleting data in range"); |
566 if (leveldb_env::IsCorruption(s)) { | 566 if (leveldb_env::IsCorruption(s)) { |
567 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | 567 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), |
568 error); | 568 error); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 static_cast<int64>(floor(key.number())) + 1, | 705 static_cast<int64>(floor(key.number())) + 1, |
706 check_current); | 706 check_current); |
707 } | 707 } |
708 | 708 |
709 struct IndexedDBDatabase::PutOperationParams { | 709 struct IndexedDBDatabase::PutOperationParams { |
710 PutOperationParams() {} | 710 PutOperationParams() {} |
711 int64 object_store_id; | 711 int64 object_store_id; |
712 IndexedDBValue value; | 712 IndexedDBValue value; |
713 ScopedVector<webkit_blob::BlobDataHandle> handles; | 713 ScopedVector<webkit_blob::BlobDataHandle> handles; |
714 scoped_ptr<IndexedDBKey> key; | 714 scoped_ptr<IndexedDBKey> key; |
715 IndexedDBDatabase::PutMode put_mode; | 715 blink::WebIDBPutMode put_mode; |
716 scoped_refptr<IndexedDBCallbacks> callbacks; | 716 scoped_refptr<IndexedDBCallbacks> callbacks; |
717 std::vector<IndexKeys> index_keys; | 717 std::vector<IndexKeys> index_keys; |
718 | 718 |
719 private: | 719 private: |
720 DISALLOW_COPY_AND_ASSIGN(PutOperationParams); | 720 DISALLOW_COPY_AND_ASSIGN(PutOperationParams); |
721 }; | 721 }; |
722 | 722 |
723 void IndexedDBDatabase::Put(int64 transaction_id, | 723 void IndexedDBDatabase::Put(int64 transaction_id, |
724 int64 object_store_id, | 724 int64 object_store_id, |
725 IndexedDBValue* value, | 725 IndexedDBValue* value, |
726 ScopedVector<webkit_blob::BlobDataHandle>* handles, | 726 ScopedVector<webkit_blob::BlobDataHandle>* handles, |
727 scoped_ptr<IndexedDBKey> key, | 727 scoped_ptr<IndexedDBKey> key, |
728 PutMode put_mode, | 728 blink::WebIDBPutMode put_mode, |
729 scoped_refptr<IndexedDBCallbacks> callbacks, | 729 scoped_refptr<IndexedDBCallbacks> callbacks, |
730 const std::vector<IndexKeys>& index_keys) { | 730 const std::vector<IndexKeys>& index_keys) { |
731 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id); | 731 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id); |
732 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 732 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
733 if (!transaction) | 733 if (!transaction) |
734 return; | 734 return; |
735 DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); | 735 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
736 | 736 |
737 if (!ValidateObjectStoreId(object_store_id)) | 737 if (!ValidateObjectStoreId(object_store_id)) |
738 return; | 738 return; |
739 | 739 |
740 DCHECK(key); | 740 DCHECK(key); |
741 DCHECK(value); | 741 DCHECK(value); |
742 scoped_ptr<PutOperationParams> params(new PutOperationParams()); | 742 scoped_ptr<PutOperationParams> params(new PutOperationParams()); |
743 params->object_store_id = object_store_id; | 743 params->object_store_id = object_store_id; |
744 params->value.swap(*value); | 744 params->value.swap(*value); |
745 params->handles.swap(*handles); | 745 params->handles.swap(*handles); |
746 params->key = key.Pass(); | 746 params->key = key.Pass(); |
747 params->put_mode = put_mode; | 747 params->put_mode = put_mode; |
748 params->callbacks = callbacks; | 748 params->callbacks = callbacks; |
749 params->index_keys = index_keys; | 749 params->index_keys = index_keys; |
750 transaction->ScheduleTask(base::Bind( | 750 transaction->ScheduleTask(base::Bind( |
751 &IndexedDBDatabase::PutOperation, this, base::Passed(¶ms))); | 751 &IndexedDBDatabase::PutOperation, this, base::Passed(¶ms))); |
752 } | 752 } |
753 | 753 |
754 void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params, | 754 void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params, |
755 IndexedDBTransaction* transaction) { | 755 IndexedDBTransaction* transaction) { |
756 IDB_TRACE1("IndexedDBDatabase::PutOperation", "txn.id", transaction->id()); | 756 IDB_TRACE1("IndexedDBDatabase::PutOperation", "txn.id", transaction->id()); |
757 DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); | 757 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
758 bool key_was_generated = false; | 758 bool key_was_generated = false; |
759 | 759 |
760 DCHECK(metadata_.object_stores.find(params->object_store_id) != | 760 DCHECK(metadata_.object_stores.find(params->object_store_id) != |
761 metadata_.object_stores.end()); | 761 metadata_.object_stores.end()); |
762 const IndexedDBObjectStoreMetadata& object_store = | 762 const IndexedDBObjectStoreMetadata& object_store = |
763 metadata_.object_stores[params->object_store_id]; | 763 metadata_.object_stores[params->object_store_id]; |
764 DCHECK(object_store.auto_increment || params->key->IsValid()); | 764 DCHECK(object_store.auto_increment || params->key->IsValid()); |
765 | 765 |
766 scoped_ptr<IndexedDBKey> key; | 766 scoped_ptr<IndexedDBKey> key; |
767 if (params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && | 767 if (params->put_mode != blink::WebIDBPutModeCursorUpdate && |
768 object_store.auto_increment && !params->key->IsValid()) { | 768 object_store.auto_increment && !params->key->IsValid()) { |
769 scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey( | 769 scoped_ptr<IndexedDBKey> auto_inc_key = GenerateKey( |
770 backing_store_.get(), transaction, id(), params->object_store_id); | 770 backing_store_.get(), transaction, id(), params->object_store_id); |
771 key_was_generated = true; | 771 key_was_generated = true; |
772 if (!auto_inc_key->IsValid()) { | 772 if (!auto_inc_key->IsValid()) { |
773 params->callbacks->OnError( | 773 params->callbacks->OnError( |
774 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, | 774 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, |
775 "Maximum key generator value reached.")); | 775 "Maximum key generator value reached.")); |
776 return; | 776 return; |
777 } | 777 } |
778 key = auto_inc_key.Pass(); | 778 key = auto_inc_key.Pass(); |
779 } else { | 779 } else { |
780 key = params->key.Pass(); | 780 key = params->key.Pass(); |
781 } | 781 } |
782 | 782 |
783 DCHECK(key->IsValid()); | 783 DCHECK(key->IsValid()); |
784 | 784 |
785 IndexedDBBackingStore::RecordIdentifier record_identifier; | 785 IndexedDBBackingStore::RecordIdentifier record_identifier; |
786 if (params->put_mode == IndexedDBDatabase::ADD_ONLY) { | 786 if (params->put_mode == blink::WebIDBPutModeAddOnly) { |
787 bool found = false; | 787 bool found = false; |
788 leveldb::Status s = backing_store_->KeyExistsInObjectStore( | 788 leveldb::Status s = backing_store_->KeyExistsInObjectStore( |
789 transaction->BackingStoreTransaction(), | 789 transaction->BackingStoreTransaction(), |
790 id(), | 790 id(), |
791 params->object_store_id, | 791 params->object_store_id, |
792 *key, | 792 *key, |
793 &record_identifier, | 793 &record_identifier, |
794 &found); | 794 &found); |
795 if (!s.ok()) { | 795 if (!s.ok()) { |
796 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 796 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 for (size_t i = 0; i < index_writers.size(); ++i) { | 858 for (size_t i = 0; i < index_writers.size(); ++i) { |
859 IndexWriter* index_writer = index_writers[i]; | 859 IndexWriter* index_writer = index_writers[i]; |
860 index_writer->WriteIndexKeys(record_identifier, | 860 index_writer->WriteIndexKeys(record_identifier, |
861 backing_store_.get(), | 861 backing_store_.get(), |
862 transaction->BackingStoreTransaction(), | 862 transaction->BackingStoreTransaction(), |
863 id(), | 863 id(), |
864 params->object_store_id); | 864 params->object_store_id); |
865 } | 865 } |
866 | 866 |
867 if (object_store.auto_increment && | 867 if (object_store.auto_increment && |
868 params->put_mode != IndexedDBDatabase::CURSOR_UPDATE && | 868 params->put_mode != blink::WebIDBPutModeCursorUpdate && |
869 key->type() == WebIDBKeyTypeNumber) { | 869 key->type() == WebIDBKeyTypeNumber) { |
870 leveldb::Status s = UpdateKeyGenerator(backing_store_.get(), | 870 leveldb::Status s = UpdateKeyGenerator(backing_store_.get(), |
871 transaction, | 871 transaction, |
872 id(), | 872 id(), |
873 params->object_store_id, | 873 params->object_store_id, |
874 *key, | 874 *key, |
875 !key_was_generated); | 875 !key_was_generated); |
876 if (!s.ok()) { | 876 if (!s.ok()) { |
877 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 877 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
878 "Internal error updating key generator."); | 878 "Internal error updating key generator."); |
879 params->callbacks->OnError(error); | 879 params->callbacks->OnError(error); |
880 if (leveldb_env::IsCorruption(s)) | 880 if (leveldb_env::IsCorruption(s)) |
881 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | 881 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), |
882 error); | 882 error); |
883 return; | 883 return; |
884 } | 884 } |
885 } | 885 } |
886 | 886 |
887 params->callbacks->OnSuccess(*key); | 887 params->callbacks->OnSuccess(*key); |
888 } | 888 } |
889 | 889 |
890 void IndexedDBDatabase::SetIndexKeys(int64 transaction_id, | 890 void IndexedDBDatabase::SetIndexKeys(int64 transaction_id, |
891 int64 object_store_id, | 891 int64 object_store_id, |
892 scoped_ptr<IndexedDBKey> primary_key, | 892 scoped_ptr<IndexedDBKey> primary_key, |
893 const std::vector<IndexKeys>& index_keys) { | 893 const std::vector<IndexKeys>& index_keys) { |
894 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); | 894 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); |
895 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 895 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
896 if (!transaction) | 896 if (!transaction) |
897 return; | 897 return; |
898 DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); | 898 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
899 | 899 |
900 // TODO(alecflett): This method could be asynchronous, but we need to | 900 // TODO(alecflett): This method could be asynchronous, but we need to |
901 // evaluate if it's worth the extra complexity. | 901 // evaluate if it's worth the extra complexity. |
902 IndexedDBBackingStore::RecordIdentifier record_identifier; | 902 IndexedDBBackingStore::RecordIdentifier record_identifier; |
903 bool found = false; | 903 bool found = false; |
904 leveldb::Status s = backing_store_->KeyExistsInObjectStore( | 904 leveldb::Status s = backing_store_->KeyExistsInObjectStore( |
905 transaction->BackingStoreTransaction(), | 905 transaction->BackingStoreTransaction(), |
906 metadata_.id, | 906 metadata_.id, |
907 object_store_id, | 907 object_store_id, |
908 *primary_key, | 908 *primary_key, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 } | 963 } |
964 } | 964 } |
965 | 965 |
966 void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, | 966 void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, |
967 int64, | 967 int64, |
968 const std::vector<int64>& index_ids) { | 968 const std::vector<int64>& index_ids) { |
969 IDB_TRACE1("IndexedDBDatabase::SetIndexesReady", "txn.id", transaction_id); | 969 IDB_TRACE1("IndexedDBDatabase::SetIndexesReady", "txn.id", transaction_id); |
970 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 970 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
971 if (!transaction) | 971 if (!transaction) |
972 return; | 972 return; |
973 DCHECK_EQ(transaction->mode(), indexed_db::TRANSACTION_VERSION_CHANGE); | 973 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
974 | 974 |
975 transaction->ScheduleTask( | 975 transaction->ScheduleTask( |
976 IndexedDBDatabase::PREEMPTIVE_TASK, | 976 blink::WebIDBTaskTypePreemptive, |
977 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, | 977 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, |
978 this, | 978 this, |
979 index_ids.size())); | 979 index_ids.size())); |
980 } | 980 } |
981 | 981 |
982 void IndexedDBDatabase::SetIndexesReadyOperation( | 982 void IndexedDBDatabase::SetIndexesReadyOperation( |
983 size_t index_count, | 983 size_t index_count, |
984 IndexedDBTransaction* transaction) { | 984 IndexedDBTransaction* transaction) { |
985 IDB_TRACE1("IndexedDBDatabase::SetIndexesReadyOperation", | 985 IDB_TRACE1("IndexedDBDatabase::SetIndexesReadyOperation", |
986 "txn.id", | 986 "txn.id", |
987 transaction->id()); | 987 transaction->id()); |
988 for (size_t i = 0; i < index_count; ++i) | 988 for (size_t i = 0; i < index_count; ++i) |
989 transaction->DidCompletePreemptiveEvent(); | 989 transaction->DidCompletePreemptiveEvent(); |
990 } | 990 } |
991 | 991 |
992 struct IndexedDBDatabase::OpenCursorOperationParams { | 992 struct IndexedDBDatabase::OpenCursorOperationParams { |
993 OpenCursorOperationParams() {} | 993 OpenCursorOperationParams() {} |
994 int64 object_store_id; | 994 int64 object_store_id; |
995 int64 index_id; | 995 int64 index_id; |
996 scoped_ptr<IndexedDBKeyRange> key_range; | 996 scoped_ptr<IndexedDBKeyRange> key_range; |
997 indexed_db::CursorDirection direction; | 997 blink::WebIDBCursorDirection direction; |
998 indexed_db::CursorType cursor_type; | 998 indexed_db::CursorType cursor_type; |
999 IndexedDBDatabase::TaskType task_type; | 999 blink::WebIDBTaskType task_type; |
1000 scoped_refptr<IndexedDBCallbacks> callbacks; | 1000 scoped_refptr<IndexedDBCallbacks> callbacks; |
1001 | 1001 |
1002 private: | 1002 private: |
1003 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); | 1003 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); |
1004 }; | 1004 }; |
1005 | 1005 |
1006 void IndexedDBDatabase::OpenCursor( | 1006 void IndexedDBDatabase::OpenCursor( |
1007 int64 transaction_id, | 1007 int64 transaction_id, |
1008 int64 object_store_id, | 1008 int64 object_store_id, |
1009 int64 index_id, | 1009 int64 index_id, |
1010 scoped_ptr<IndexedDBKeyRange> key_range, | 1010 scoped_ptr<IndexedDBKeyRange> key_range, |
1011 indexed_db::CursorDirection direction, | 1011 blink::WebIDBCursorDirection direction, |
1012 bool key_only, | 1012 bool key_only, |
1013 TaskType task_type, | 1013 blink::WebIDBTaskType task_type, |
1014 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1014 scoped_refptr<IndexedDBCallbacks> callbacks) { |
1015 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id); | 1015 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id); |
1016 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 1016 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
1017 if (!transaction) | 1017 if (!transaction) |
1018 return; | 1018 return; |
1019 | 1019 |
1020 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 1020 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) |
1021 return; | 1021 return; |
1022 | 1022 |
1023 scoped_ptr<OpenCursorOperationParams> params(new OpenCursorOperationParams()); | 1023 scoped_ptr<OpenCursorOperationParams> params(new OpenCursorOperationParams()); |
(...skipping 12 matching lines...) Expand all Loading... |
1036 void IndexedDBDatabase::OpenCursorOperation( | 1036 void IndexedDBDatabase::OpenCursorOperation( |
1037 scoped_ptr<OpenCursorOperationParams> params, | 1037 scoped_ptr<OpenCursorOperationParams> params, |
1038 IndexedDBTransaction* transaction) { | 1038 IndexedDBTransaction* transaction) { |
1039 IDB_TRACE1( | 1039 IDB_TRACE1( |
1040 "IndexedDBDatabase::OpenCursorOperation", "txn.id", transaction->id()); | 1040 "IndexedDBDatabase::OpenCursorOperation", "txn.id", transaction->id()); |
1041 | 1041 |
1042 // The frontend has begun indexing, so this pauses the transaction | 1042 // The frontend has begun indexing, so this pauses the transaction |
1043 // until the indexing is complete. This can't happen any earlier | 1043 // until the indexing is complete. This can't happen any earlier |
1044 // because we don't want to switch to early mode in case multiple | 1044 // because we don't want to switch to early mode in case multiple |
1045 // indexes are being created in a row, with Put()'s in between. | 1045 // indexes are being created in a row, with Put()'s in between. |
1046 if (params->task_type == IndexedDBDatabase::PREEMPTIVE_TASK) | 1046 if (params->task_type == blink::WebIDBTaskTypePreemptive) |
1047 transaction->AddPreemptiveEvent(); | 1047 transaction->AddPreemptiveEvent(); |
1048 | 1048 |
1049 leveldb::Status s; | 1049 leveldb::Status s; |
1050 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; | 1050 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; |
1051 if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { | 1051 if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { |
1052 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { | 1052 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { |
1053 DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); | 1053 DCHECK_EQ(params->task_type, blink::WebIDBTaskTypeNormal); |
1054 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( | 1054 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( |
1055 transaction->BackingStoreTransaction(), | 1055 transaction->BackingStoreTransaction(), |
1056 id(), | 1056 id(), |
1057 params->object_store_id, | 1057 params->object_store_id, |
1058 *params->key_range, | 1058 *params->key_range, |
1059 params->direction, | 1059 params->direction, |
1060 &s); | 1060 &s); |
1061 } else { | 1061 } else { |
1062 backing_store_cursor = backing_store_->OpenObjectStoreCursor( | 1062 backing_store_cursor = backing_store_->OpenObjectStoreCursor( |
1063 transaction->BackingStoreTransaction(), | 1063 transaction->BackingStoreTransaction(), |
1064 id(), | 1064 id(), |
1065 params->object_store_id, | 1065 params->object_store_id, |
1066 *params->key_range, | 1066 *params->key_range, |
1067 params->direction, | 1067 params->direction, |
1068 &s); | 1068 &s); |
1069 } | 1069 } |
1070 } else { | 1070 } else { |
1071 DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); | 1071 DCHECK_EQ(params->task_type, blink::WebIDBTaskTypeNormal); |
1072 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { | 1072 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { |
1073 backing_store_cursor = backing_store_->OpenIndexKeyCursor( | 1073 backing_store_cursor = backing_store_->OpenIndexKeyCursor( |
1074 transaction->BackingStoreTransaction(), | 1074 transaction->BackingStoreTransaction(), |
1075 id(), | 1075 id(), |
1076 params->object_store_id, | 1076 params->object_store_id, |
1077 params->index_id, | 1077 params->index_id, |
1078 *params->key_range, | 1078 *params->key_range, |
1079 params->direction, | 1079 params->direction, |
1080 &s); | 1080 &s); |
1081 } else { | 1081 } else { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 uint32 count = 0; | 1146 uint32 count = 0; |
1147 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; | 1147 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; |
1148 | 1148 |
1149 leveldb::Status s; | 1149 leveldb::Status s; |
1150 if (index_id == IndexedDBIndexMetadata::kInvalidId) { | 1150 if (index_id == IndexedDBIndexMetadata::kInvalidId) { |
1151 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( | 1151 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( |
1152 transaction->BackingStoreTransaction(), | 1152 transaction->BackingStoreTransaction(), |
1153 id(), | 1153 id(), |
1154 object_store_id, | 1154 object_store_id, |
1155 *key_range, | 1155 *key_range, |
1156 indexed_db::CURSOR_NEXT, | 1156 blink::WebIDBCursorDirectionNext, |
1157 &s); | 1157 &s); |
1158 } else { | 1158 } else { |
1159 backing_store_cursor = backing_store_->OpenIndexKeyCursor( | 1159 backing_store_cursor = backing_store_->OpenIndexKeyCursor( |
1160 transaction->BackingStoreTransaction(), | 1160 transaction->BackingStoreTransaction(), |
1161 id(), | 1161 id(), |
1162 object_store_id, | 1162 object_store_id, |
1163 index_id, | 1163 index_id, |
1164 *key_range, | 1164 *key_range, |
1165 indexed_db::CURSOR_NEXT, | 1165 blink::WebIDBCursorDirectionNext, |
1166 &s); | 1166 &s); |
1167 } | 1167 } |
1168 if (!s.ok()) { | 1168 if (!s.ok()) { |
1169 DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); | 1169 DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); |
1170 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 1170 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
1171 "Internal error performing count operation"); | 1171 "Internal error performing count operation"); |
1172 if (leveldb_env::IsCorruption(s)) { | 1172 if (leveldb_env::IsCorruption(s)) { |
1173 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | 1173 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), |
1174 error); | 1174 error); |
1175 } | 1175 } |
(...skipping 14 matching lines...) Expand all Loading... |
1190 | 1190 |
1191 void IndexedDBDatabase::DeleteRange( | 1191 void IndexedDBDatabase::DeleteRange( |
1192 int64 transaction_id, | 1192 int64 transaction_id, |
1193 int64 object_store_id, | 1193 int64 object_store_id, |
1194 scoped_ptr<IndexedDBKeyRange> key_range, | 1194 scoped_ptr<IndexedDBKeyRange> key_range, |
1195 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1195 scoped_refptr<IndexedDBCallbacks> callbacks) { |
1196 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); | 1196 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); |
1197 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 1197 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
1198 if (!transaction) | 1198 if (!transaction) |
1199 return; | 1199 return; |
1200 DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); | 1200 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
1201 | 1201 |
1202 if (!ValidateObjectStoreId(object_store_id)) | 1202 if (!ValidateObjectStoreId(object_store_id)) |
1203 return; | 1203 return; |
1204 | 1204 |
1205 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, | 1205 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, |
1206 this, | 1206 this, |
1207 object_store_id, | 1207 object_store_id, |
1208 base::Passed(&key_range), | 1208 base::Passed(&key_range), |
1209 callbacks)); | 1209 callbacks)); |
1210 } | 1210 } |
(...skipping 25 matching lines...) Expand all Loading... |
1236 callbacks->OnSuccess(); | 1236 callbacks->OnSuccess(); |
1237 } | 1237 } |
1238 | 1238 |
1239 void IndexedDBDatabase::Clear(int64 transaction_id, | 1239 void IndexedDBDatabase::Clear(int64 transaction_id, |
1240 int64 object_store_id, | 1240 int64 object_store_id, |
1241 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1241 scoped_refptr<IndexedDBCallbacks> callbacks) { |
1242 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); | 1242 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); |
1243 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 1243 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
1244 if (!transaction) | 1244 if (!transaction) |
1245 return; | 1245 return; |
1246 DCHECK_NE(transaction->mode(), indexed_db::TRANSACTION_READ_ONLY); | 1246 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
1247 | 1247 |
1248 if (!ValidateObjectStoreId(object_store_id)) | 1248 if (!ValidateObjectStoreId(object_store_id)) |
1249 return; | 1249 return; |
1250 | 1250 |
1251 transaction->ScheduleTask(base::Bind( | 1251 transaction->ScheduleTask(base::Bind( |
1252 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); | 1252 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); |
1253 } | 1253 } |
1254 | 1254 |
1255 void IndexedDBDatabase::ClearOperation( | 1255 void IndexedDBDatabase::ClearOperation( |
1256 int64 object_store_id, | 1256 int64 object_store_id, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 new PendingSuccessCall(callbacks, connection.get(), version)); | 1340 new PendingSuccessCall(callbacks, connection.get(), version)); |
1341 callbacks->OnUpgradeNeeded(old_version, connection.Pass(), metadata()); | 1341 callbacks->OnUpgradeNeeded(old_version, connection.Pass(), metadata()); |
1342 } | 1342 } |
1343 | 1343 |
1344 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, | 1344 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, |
1345 bool committed) { | 1345 bool committed) { |
1346 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); | 1346 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); |
1347 DCHECK_EQ(transactions_[transaction->id()], transaction); | 1347 DCHECK_EQ(transactions_[transaction->id()], transaction); |
1348 transactions_.erase(transaction->id()); | 1348 transactions_.erase(transaction->id()); |
1349 | 1349 |
1350 if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { | 1350 if (transaction->mode() == blink::WebIDBTransactionModeVersionChange) { |
1351 if (pending_second_half_open_) { | 1351 if (pending_second_half_open_) { |
1352 if (committed) { | 1352 if (committed) { |
1353 DCHECK_EQ(pending_second_half_open_->version(), metadata_.int_version); | 1353 DCHECK_EQ(pending_second_half_open_->version(), metadata_.int_version); |
1354 DCHECK(metadata_.id != kInvalidId); | 1354 DCHECK(metadata_.id != kInvalidId); |
1355 | 1355 |
1356 // Connection was already minted for OnUpgradeNeeded callback. | 1356 // Connection was already minted for OnUpgradeNeeded callback. |
1357 scoped_ptr<IndexedDBConnection> connection; | 1357 scoped_ptr<IndexedDBConnection> connection; |
1358 pending_second_half_open_->callbacks()->OnSuccess(connection.Pass(), | 1358 pending_second_half_open_->callbacks()->OnSuccess(connection.Pass(), |
1359 this->metadata()); | 1359 this->metadata()); |
1360 } else { | 1360 } else { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 OpenConnection(pending_open_calls.front()); | 1441 OpenConnection(pending_open_calls.front()); |
1442 pending_open_calls.pop_front(); | 1442 pending_open_calls.pop_front(); |
1443 } | 1443 } |
1444 } | 1444 } |
1445 } | 1445 } |
1446 | 1446 |
1447 void IndexedDBDatabase::CreateTransaction( | 1447 void IndexedDBDatabase::CreateTransaction( |
1448 int64 transaction_id, | 1448 int64 transaction_id, |
1449 IndexedDBConnection* connection, | 1449 IndexedDBConnection* connection, |
1450 const std::vector<int64>& object_store_ids, | 1450 const std::vector<int64>& object_store_ids, |
1451 uint16 mode) { | 1451 blink::WebIDBTransactionMode mode) { |
1452 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); | 1452 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); |
1453 DCHECK(connections_.count(connection)); | 1453 DCHECK(connections_.count(connection)); |
1454 DCHECK(transactions_.find(transaction_id) == transactions_.end()); | 1454 DCHECK(transactions_.find(transaction_id) == transactions_.end()); |
1455 if (transactions_.find(transaction_id) != transactions_.end()) | 1455 if (transactions_.find(transaction_id) != transactions_.end()) |
1456 return; | 1456 return; |
1457 | 1457 |
1458 // The transaction will add itself to this database's coordinator, which | 1458 // The transaction will add itself to this database's coordinator, which |
1459 // manages the lifetime of the object. | 1459 // manages the lifetime of the object. |
1460 TransactionCreated(new IndexedDBTransaction( | 1460 TransactionCreated(new IndexedDBTransaction( |
1461 transaction_id, | 1461 transaction_id, |
1462 connection->callbacks(), | 1462 connection->callbacks(), |
1463 std::set<int64>(object_store_ids.begin(), object_store_ids.end()), | 1463 std::set<int64>(object_store_ids.begin(), object_store_ids.end()), |
1464 static_cast<indexed_db::TransactionMode>(mode), | 1464 mode, |
1465 this, | 1465 this, |
1466 new IndexedDBBackingStore::Transaction(backing_store_))); | 1466 new IndexedDBBackingStore::Transaction(backing_store_))); |
1467 } | 1467 } |
1468 | 1468 |
1469 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { | 1469 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { |
1470 transactions_[transaction->id()] = transaction; | 1470 transactions_[transaction->id()] = transaction; |
1471 } | 1471 } |
1472 | 1472 |
1473 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { | 1473 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { |
1474 return !pending_delete_calls_.empty() || | 1474 return !pending_delete_calls_.empty() || |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1607 void IndexedDBDatabase::RunVersionChangeTransactionFinal( | 1607 void IndexedDBDatabase::RunVersionChangeTransactionFinal( |
1608 scoped_refptr<IndexedDBCallbacks> callbacks, | 1608 scoped_refptr<IndexedDBCallbacks> callbacks, |
1609 scoped_ptr<IndexedDBConnection> connection, | 1609 scoped_ptr<IndexedDBConnection> connection, |
1610 int64 transaction_id, | 1610 int64 transaction_id, |
1611 int64 requested_version) { | 1611 int64 requested_version) { |
1612 | 1612 |
1613 std::vector<int64> object_store_ids; | 1613 std::vector<int64> object_store_ids; |
1614 CreateTransaction(transaction_id, | 1614 CreateTransaction(transaction_id, |
1615 connection.get(), | 1615 connection.get(), |
1616 object_store_ids, | 1616 object_store_ids, |
1617 indexed_db::TRANSACTION_VERSION_CHANGE); | 1617 blink::WebIDBTransactionModeVersionChange); |
1618 | 1618 |
1619 transactions_[transaction_id]->ScheduleTask( | 1619 transactions_[transaction_id]->ScheduleTask( |
1620 base::Bind(&IndexedDBDatabase::VersionChangeOperation, | 1620 base::Bind(&IndexedDBDatabase::VersionChangeOperation, |
1621 this, | 1621 this, |
1622 requested_version, | 1622 requested_version, |
1623 callbacks, | 1623 callbacks, |
1624 base::Passed(&connection))); | 1624 base::Passed(&connection))); |
1625 DCHECK(!pending_second_half_open_); | 1625 DCHECK(!pending_second_half_open_); |
1626 } | 1626 } |
1627 | 1627 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 IndexedDBTransaction* transaction) { | 1760 IndexedDBTransaction* transaction) { |
1761 DCHECK(!transaction); | 1761 DCHECK(!transaction); |
1762 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", | 1762 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", |
1763 "txn.id", | 1763 "txn.id", |
1764 transaction->id()); | 1764 transaction->id()); |
1765 metadata_.version = previous_version; | 1765 metadata_.version = previous_version; |
1766 metadata_.int_version = previous_int_version; | 1766 metadata_.int_version = previous_int_version; |
1767 } | 1767 } |
1768 | 1768 |
1769 } // namespace content | 1769 } // namespace content |
OLD | NEW |