| OLD | NEW |
| (Empty) |
| 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 #include "content/browser/indexed_db/indexed_db_index_writer.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/utf_string_conversions.h" | |
| 9 #include "content/browser/indexed_db/indexed_db_backing_store.h" | |
| 10 #include "content/browser/indexed_db/indexed_db_tracing.h" | |
| 11 #include "content/browser/indexed_db/indexed_db_transaction.h" | |
| 12 #include "content/common/indexed_db/indexed_db_key.h" | |
| 13 #include "content/common/indexed_db/indexed_db_key_path.h" | |
| 14 #include "content/common/indexed_db/indexed_db_key_range.h" | |
| 15 | |
| 16 namespace content { | |
| 17 | |
| 18 IndexedDBObjectStoreImpl::IndexWriter::IndexWriter( | |
| 19 const IndexedDBIndexMetadata& index_metadata) | |
| 20 : index_metadata_(index_metadata) {} | |
| 21 | |
| 22 IndexedDBObjectStoreImpl::IndexWriter::IndexWriter( | |
| 23 const IndexedDBIndexMetadata& index_metadata, | |
| 24 const IndexedDBDatabase::IndexKeys& index_keys) | |
| 25 : index_metadata_(index_metadata), index_keys_(index_keys) {} | |
| 26 | |
| 27 IndexedDBObjectStoreImpl::IndexWriter::~IndexWriter() {} | |
| 28 | |
| 29 bool IndexedDBObjectStoreImpl::IndexWriter::VerifyIndexKeys( | |
| 30 IndexedDBBackingStore* backing_store, | |
| 31 IndexedDBBackingStore::Transaction* transaction, | |
| 32 int64 database_id, | |
| 33 int64 object_store_id, | |
| 34 int64 index_id, | |
| 35 bool* can_add_keys, | |
| 36 const IndexedDBKey& primary_key, | |
| 37 string16* error_message) const { | |
| 38 *can_add_keys = false; | |
| 39 for (size_t i = 0; i < index_keys_.size(); ++i) { | |
| 40 bool ok = AddingKeyAllowed(backing_store, | |
| 41 transaction, | |
| 42 database_id, | |
| 43 object_store_id, | |
| 44 index_id, | |
| 45 (index_keys_)[i], | |
| 46 primary_key, | |
| 47 can_add_keys); | |
| 48 if (!ok) | |
| 49 return false; | |
| 50 if (!*can_add_keys) { | |
| 51 if (error_message) | |
| 52 *error_message = ASCIIToUTF16("Unable to add key to index '") + | |
| 53 index_metadata_.name + | |
| 54 ASCIIToUTF16("': at least one key does not satisfy " | |
| 55 "the uniqueness requirements."); | |
| 56 return true; | |
| 57 } | |
| 58 } | |
| 59 *can_add_keys = true; | |
| 60 return true; | |
| 61 } | |
| 62 | |
| 63 void IndexedDBObjectStoreImpl::IndexWriter::WriteIndexKeys( | |
| 64 const IndexedDBBackingStore::RecordIdentifier& record_identifier, | |
| 65 IndexedDBBackingStore* backing_store, | |
| 66 IndexedDBBackingStore::Transaction* transaction, | |
| 67 int64 database_id, | |
| 68 int64 object_store_id) const { | |
| 69 int64 index_id = index_metadata_.id; | |
| 70 for (size_t i = 0; i < index_keys_.size(); ++i) { | |
| 71 bool ok = backing_store->PutIndexDataForRecord(transaction, | |
| 72 database_id, | |
| 73 object_store_id, | |
| 74 index_id, | |
| 75 index_keys_[i], | |
| 76 record_identifier); | |
| 77 // This should have already been verified as a valid write during | |
| 78 // verify_index_keys. | |
| 79 DCHECK(ok); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 bool IndexedDBObjectStoreImpl::IndexWriter::AddingKeyAllowed( | |
| 84 IndexedDBBackingStore* backing_store, | |
| 85 IndexedDBBackingStore::Transaction* transaction, | |
| 86 int64 database_id, | |
| 87 int64 object_store_id, | |
| 88 int64 index_id, | |
| 89 const IndexedDBKey& index_key, | |
| 90 const IndexedDBKey& primary_key, | |
| 91 bool* allowed) const { | |
| 92 *allowed = false; | |
| 93 if (!index_metadata_.unique) { | |
| 94 *allowed = true; | |
| 95 return true; | |
| 96 } | |
| 97 | |
| 98 scoped_ptr<IndexedDBKey> found_primary_key; | |
| 99 bool found = false; | |
| 100 bool ok = backing_store->KeyExistsInIndex(transaction, | |
| 101 database_id, | |
| 102 object_store_id, | |
| 103 index_id, | |
| 104 index_key, | |
| 105 &found_primary_key, | |
| 106 found); | |
| 107 if (!ok) | |
| 108 return false; | |
| 109 if (!found || | |
| 110 (primary_key.IsValid() && found_primary_key->IsEqual(primary_key))) | |
| 111 *allowed = true; | |
| 112 return true; | |
| 113 } | |
| 114 | |
| 115 bool IndexedDBObjectStoreImpl::MakeIndexWriters( | |
| 116 scoped_refptr<IndexedDBTransaction> transaction, | |
| 117 IndexedDBBackingStore* backing_store, | |
| 118 int64 database_id, | |
| 119 const IndexedDBObjectStoreMetadata& object_store, | |
| 120 const IndexedDBKey& primary_key, // makes a copy | |
| 121 bool key_was_generated, | |
| 122 const std::vector<int64>& index_ids, | |
| 123 const std::vector<IndexedDBDatabase::IndexKeys>& index_keys, | |
| 124 ScopedVector<IndexWriter>* index_writers, | |
| 125 string16* error_message, | |
| 126 bool* completed) { | |
| 127 DCHECK_EQ(index_ids.size(), index_keys.size()); | |
| 128 *completed = false; | |
| 129 | |
| 130 std::map<int64, IndexedDBDatabase::IndexKeys> index_key_map; | |
| 131 for (size_t i = 0; i < index_ids.size(); ++i) | |
| 132 index_key_map[index_ids[i]] = index_keys[i]; | |
| 133 | |
| 134 for (IndexedDBObjectStoreMetadata::IndexMap::const_iterator it = | |
| 135 object_store.indexes.begin(); | |
| 136 it != object_store.indexes.end(); | |
| 137 ++it) { | |
| 138 const IndexedDBIndexMetadata& index = it->second; | |
| 139 | |
| 140 IndexedDBDatabase::IndexKeys keys = index_key_map[it->first]; | |
| 141 // If the object_store is using auto_increment, then any indexes with an | |
| 142 // identical key_path need to also use the primary (generated) key as a key. | |
| 143 if (key_was_generated && (index.key_path == object_store.key_path)) | |
| 144 keys.push_back(primary_key); | |
| 145 | |
| 146 scoped_ptr<IndexWriter> index_writer(new IndexWriter(index, keys)); | |
| 147 bool can_add_keys = false; | |
| 148 bool backing_store_success = | |
| 149 index_writer->VerifyIndexKeys(backing_store, | |
| 150 transaction->BackingStoreTransaction(), | |
| 151 database_id, | |
| 152 object_store.id, | |
| 153 index.id, | |
| 154 &can_add_keys, | |
| 155 primary_key, | |
| 156 error_message); | |
| 157 if (!backing_store_success) | |
| 158 return false; | |
| 159 if (!can_add_keys) | |
| 160 return true; | |
| 161 | |
| 162 index_writers->push_back(index_writer.release()); | |
| 163 } | |
| 164 | |
| 165 *completed = true; | |
| 166 return true; | |
| 167 } | |
| 168 | |
| 169 } // namespace content | |
| OLD | NEW |