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 |