Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: content/browser/indexed_db/indexed_db_factory_impl.cc

Issue 1841553002: IndexedDB: Use url::Origin rather than GURL for representing origins (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@origin-idb
Patch Set: Rebased Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_factory_impl.h" 5 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "content/browser/indexed_db/indexed_db_backing_store.h" 15 #include "content/browser/indexed_db/indexed_db_backing_store.h"
16 #include "content/browser/indexed_db/indexed_db_context_impl.h" 16 #include "content/browser/indexed_db/indexed_db_context_impl.h"
17 #include "content/browser/indexed_db/indexed_db_database_error.h" 17 #include "content/browser/indexed_db/indexed_db_database_error.h"
18 #include "content/browser/indexed_db/indexed_db_tracing.h" 18 #include "content/browser/indexed_db/indexed_db_tracing.h"
19 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" 19 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h"
20 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" 20 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h"
21 #include "third_party/leveldatabase/env_chromium.h" 21 #include "third_party/leveldatabase/env_chromium.h"
22 22
23 using base::ASCIIToUTF16; 23 using base::ASCIIToUTF16;
24 using url::Origin;
24 25
25 namespace content { 26 namespace content {
26 27
27 const int64_t kBackingStoreGracePeriodMs = 2000; 28 const int64_t kBackingStoreGracePeriodMs = 2000;
28 29
29 IndexedDBFactoryImpl::IndexedDBFactoryImpl(IndexedDBContextImpl* context) 30 IndexedDBFactoryImpl::IndexedDBFactoryImpl(IndexedDBContextImpl* context)
30 : context_(context) { 31 : context_(context) {
31 } 32 }
32 33
33 IndexedDBFactoryImpl::~IndexedDBFactoryImpl() { 34 IndexedDBFactoryImpl::~IndexedDBFactoryImpl() {
(...skipping 23 matching lines...) Expand all
57 DCHECK(!database_map_.find(identifier)->second->backing_store()); 58 DCHECK(!database_map_.find(identifier)->second->backing_store());
58 59
59 RemoveDatabaseFromMaps(identifier); 60 RemoveDatabaseFromMaps(identifier);
60 61
61 // No grace period on a forced-close, as the initiator is 62 // No grace period on a forced-close, as the initiator is
62 // assuming the backing store will be released once all 63 // assuming the backing store will be released once all
63 // connections are closed. 64 // connections are closed.
64 ReleaseBackingStore(identifier.first, forced_close); 65 ReleaseBackingStore(identifier.first, forced_close);
65 } 66 }
66 67
67 void IndexedDBFactoryImpl::ReleaseBackingStore(const GURL& origin_url, 68 void IndexedDBFactoryImpl::ReleaseBackingStore(const Origin& origin,
68 bool immediate) { 69 bool immediate) {
69 if (immediate) { 70 if (immediate) {
70 IndexedDBBackingStoreMap::iterator it = 71 IndexedDBBackingStoreMap::iterator it =
71 backing_stores_with_active_blobs_.find(origin_url); 72 backing_stores_with_active_blobs_.find(origin);
72 if (it != backing_stores_with_active_blobs_.end()) { 73 if (it != backing_stores_with_active_blobs_.end()) {
73 it->second->active_blob_registry()->ForceShutdown(); 74 it->second->active_blob_registry()->ForceShutdown();
74 backing_stores_with_active_blobs_.erase(it); 75 backing_stores_with_active_blobs_.erase(it);
75 } 76 }
76 } 77 }
77 78
78 // Only close if this is the last reference. 79 // Only close if this is the last reference.
79 if (!HasLastBackingStoreReference(origin_url)) 80 if (!HasLastBackingStoreReference(origin))
80 return; 81 return;
81 82
82 // If this factory does hold the last reference to the backing store, it can 83 // If this factory does hold the last reference to the backing store, it can
83 // be closed - but unless requested to close it immediately, keep it around 84 // be closed - but unless requested to close it immediately, keep it around
84 // for a short period so that a re-open is fast. 85 // for a short period so that a re-open is fast.
85 if (immediate) { 86 if (immediate) {
86 CloseBackingStore(origin_url); 87 CloseBackingStore(origin);
87 return; 88 return;
88 } 89 }
89 90
90 // Start a timer to close the backing store, unless something else opens it 91 // Start a timer to close the backing store, unless something else opens it
91 // in the mean time. 92 // in the mean time.
92 DCHECK(!backing_store_map_[origin_url]->close_timer()->IsRunning()); 93 DCHECK(!backing_store_map_[origin]->close_timer()->IsRunning());
93 backing_store_map_[origin_url]->close_timer()->Start( 94 backing_store_map_[origin]->close_timer()->Start(
94 FROM_HERE, 95 FROM_HERE, base::TimeDelta::FromMilliseconds(kBackingStoreGracePeriodMs),
95 base::TimeDelta::FromMilliseconds(kBackingStoreGracePeriodMs), 96 base::Bind(&IndexedDBFactoryImpl::MaybeCloseBackingStore, this, origin));
96 base::Bind(
97 &IndexedDBFactoryImpl::MaybeCloseBackingStore, this, origin_url));
98 } 97 }
99 98
100 void IndexedDBFactoryImpl::MaybeCloseBackingStore(const GURL& origin_url) { 99 void IndexedDBFactoryImpl::MaybeCloseBackingStore(const Origin& origin) {
101 // Another reference may have opened since the maybe-close was posted, so it 100 // Another reference may have opened since the maybe-close was posted, so it
102 // is necessary to check again. 101 // is necessary to check again.
103 if (HasLastBackingStoreReference(origin_url)) 102 if (HasLastBackingStoreReference(origin))
104 CloseBackingStore(origin_url); 103 CloseBackingStore(origin);
105 } 104 }
106 105
107 void IndexedDBFactoryImpl::CloseBackingStore(const GURL& origin_url) { 106 void IndexedDBFactoryImpl::CloseBackingStore(const Origin& origin) {
108 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); 107 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin);
109 DCHECK(it != backing_store_map_.end()); 108 DCHECK(it != backing_store_map_.end());
110 // Stop the timer (if it's running) - this may happen if the timer was started 109 // Stop the timer (if it's running) - this may happen if the timer was started
111 // and then a forced close occurs. 110 // and then a forced close occurs.
112 it->second->close_timer()->Stop(); 111 it->second->close_timer()->Stop();
113 backing_store_map_.erase(it); 112 backing_store_map_.erase(it);
114 } 113 }
115 114
116 bool IndexedDBFactoryImpl::HasLastBackingStoreReference( 115 bool IndexedDBFactoryImpl::HasLastBackingStoreReference(
117 const GURL& origin_url) const { 116 const Origin& origin) const {
118 IndexedDBBackingStore* ptr; 117 IndexedDBBackingStore* ptr;
119 { 118 {
120 // Scope so that the implicit scoped_refptr<> is freed. 119 // Scope so that the implicit scoped_refptr<> is freed.
121 IndexedDBBackingStoreMap::const_iterator it = 120 IndexedDBBackingStoreMap::const_iterator it =
122 backing_store_map_.find(origin_url); 121 backing_store_map_.find(origin);
123 DCHECK(it != backing_store_map_.end()); 122 DCHECK(it != backing_store_map_.end());
124 ptr = it->second.get(); 123 ptr = it->second.get();
125 } 124 }
126 return ptr->HasOneRef(); 125 return ptr->HasOneRef();
127 } 126 }
128 127
129 void IndexedDBFactoryImpl::ForceClose(const GURL& origin_url) { 128 void IndexedDBFactoryImpl::ForceClose(const Origin& origin) {
130 OriginDBs range = GetOpenDatabasesForOrigin(origin_url); 129 OriginDBs range = GetOpenDatabasesForOrigin(origin);
131 130
132 while (range.first != range.second) { 131 while (range.first != range.second) {
133 IndexedDBDatabase* db = range.first->second; 132 IndexedDBDatabase* db = range.first->second;
134 ++range.first; 133 ++range.first;
135 db->ForceClose(); 134 db->ForceClose();
136 } 135 }
137 136
138 if (backing_store_map_.find(origin_url) != backing_store_map_.end()) 137 if (backing_store_map_.find(origin) != backing_store_map_.end())
139 ReleaseBackingStore(origin_url, true /* immediate */); 138 ReleaseBackingStore(origin, true /* immediate */);
140 } 139 }
141 140
142 void IndexedDBFactoryImpl::ContextDestroyed() { 141 void IndexedDBFactoryImpl::ContextDestroyed() {
143 // Timers on backing stores hold a reference to this factory. When the 142 // Timers on backing stores hold a reference to this factory. When the
144 // context (which nominally owns this factory) is destroyed during thread 143 // context (which nominally owns this factory) is destroyed during thread
145 // termination the timers must be stopped so that this factory and the 144 // termination the timers must be stopped so that this factory and the
146 // stores can be disposed of. 145 // stores can be disposed of.
147 for (const auto& it : backing_store_map_) 146 for (const auto& it : backing_store_map_)
148 it.second->close_timer()->Stop(); 147 it.second->close_timer()->Stop();
149 backing_store_map_.clear(); 148 backing_store_map_.clear();
150 backing_stores_with_active_blobs_.clear(); 149 backing_stores_with_active_blobs_.clear();
151 context_ = NULL; 150 context_ = NULL;
152 } 151 }
153 152
154 void IndexedDBFactoryImpl::ReportOutstandingBlobs(const GURL& origin_url, 153 void IndexedDBFactoryImpl::ReportOutstandingBlobs(const Origin& origin,
155 bool blobs_outstanding) { 154 bool blobs_outstanding) {
156 if (!context_) 155 if (!context_)
157 return; 156 return;
158 if (blobs_outstanding) { 157 if (blobs_outstanding) {
159 DCHECK(!backing_stores_with_active_blobs_.count(origin_url)); 158 DCHECK(!backing_stores_with_active_blobs_.count(origin));
160 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); 159 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin);
161 if (it != backing_store_map_.end()) 160 if (it != backing_store_map_.end())
162 backing_stores_with_active_blobs_.insert(*it); 161 backing_stores_with_active_blobs_.insert(*it);
163 else 162 else
164 DCHECK(false); 163 DCHECK(false);
165 } else { 164 } else {
166 IndexedDBBackingStoreMap::iterator it = 165 IndexedDBBackingStoreMap::iterator it =
167 backing_stores_with_active_blobs_.find(origin_url); 166 backing_stores_with_active_blobs_.find(origin);
168 if (it != backing_stores_with_active_blobs_.end()) { 167 if (it != backing_stores_with_active_blobs_.end()) {
169 backing_stores_with_active_blobs_.erase(it); 168 backing_stores_with_active_blobs_.erase(it);
170 ReleaseBackingStore(origin_url, false /* immediate */); 169 ReleaseBackingStore(origin, false /* immediate */);
171 } 170 }
172 } 171 }
173 } 172 }
174 173
175 void IndexedDBFactoryImpl::GetDatabaseNames( 174 void IndexedDBFactoryImpl::GetDatabaseNames(
176 scoped_refptr<IndexedDBCallbacks> callbacks, 175 scoped_refptr<IndexedDBCallbacks> callbacks,
177 const url::Origin& origin, 176 const Origin& origin,
178 const base::FilePath& data_directory, 177 const base::FilePath& data_directory,
179 net::URLRequestContext* request_context) { 178 net::URLRequestContext* request_context) {
180 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); 179 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames");
181 // TODO(dgrogan): Plumb data_loss back to script eventually? 180 // TODO(dgrogan): Plumb data_loss back to script eventually?
182 blink::WebIDBDataLoss data_loss; 181 blink::WebIDBDataLoss data_loss;
183 std::string data_loss_message; 182 std::string data_loss_message;
184 bool disk_full; 183 bool disk_full;
185 GURL origin_url(origin.Serialize());
186 leveldb::Status s; 184 leveldb::Status s;
187 // TODO(cmumford): Handle this error 185 // TODO(cmumford): Handle this error
188 scoped_refptr<IndexedDBBackingStore> backing_store = 186 scoped_refptr<IndexedDBBackingStore> backing_store =
189 OpenBackingStore(origin_url, 187 OpenBackingStore(origin, data_directory, request_context, &data_loss,
190 data_directory, 188 &data_loss_message, &disk_full, &s);
191 request_context,
192 &data_loss,
193 &data_loss_message,
194 &disk_full,
195 &s);
196 if (!backing_store.get()) { 189 if (!backing_store.get()) {
197 callbacks->OnError( 190 callbacks->OnError(
198 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 191 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
199 "Internal error opening backing store for " 192 "Internal error opening backing store for "
200 "indexedDB.webkitGetDatabaseNames.")); 193 "indexedDB.webkitGetDatabaseNames."));
201 return; 194 return;
202 } 195 }
203 196
204 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); 197 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s);
205 if (!s.ok()) { 198 if (!s.ok()) {
206 DLOG(ERROR) << "Internal error getting database names"; 199 DLOG(ERROR) << "Internal error getting database names";
207 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 200 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
208 "Internal error opening backing store for " 201 "Internal error opening backing store for "
209 "indexedDB.webkitGetDatabaseNames."); 202 "indexedDB.webkitGetDatabaseNames.");
210 callbacks->OnError(error); 203 callbacks->OnError(error);
211 backing_store = NULL; 204 backing_store = NULL;
212 if (s.IsCorruption()) 205 if (s.IsCorruption())
213 HandleBackingStoreCorruption(origin_url, error); 206 HandleBackingStoreCorruption(origin, error);
214 return; 207 return;
215 } 208 }
216 callbacks->OnSuccess(names); 209 callbacks->OnSuccess(names);
217 backing_store = NULL; 210 backing_store = NULL;
218 ReleaseBackingStore(origin_url, false /* immediate */); 211 ReleaseBackingStore(origin, false /* immediate */);
219 } 212 }
220 213
221 void IndexedDBFactoryImpl::DeleteDatabase( 214 void IndexedDBFactoryImpl::DeleteDatabase(
222 const base::string16& name, 215 const base::string16& name,
223 net::URLRequestContext* request_context, 216 net::URLRequestContext* request_context,
224 scoped_refptr<IndexedDBCallbacks> callbacks, 217 scoped_refptr<IndexedDBCallbacks> callbacks,
225 const url::Origin& origin, 218 const Origin& origin,
226 const base::FilePath& data_directory) { 219 const base::FilePath& data_directory) {
227 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); 220 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase");
228 GURL origin_url(origin.Serialize()); 221 IndexedDBDatabase::Identifier unique_identifier(origin, name);
229 IndexedDBDatabase::Identifier unique_identifier(origin_url, name);
230 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); 222 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier);
231 if (it != database_map_.end()) { 223 if (it != database_map_.end()) {
232 // If there are any connections to the database, directly delete the 224 // If there are any connections to the database, directly delete the
233 // database. 225 // database.
234 it->second->DeleteDatabase(callbacks); 226 it->second->DeleteDatabase(callbacks);
235 return; 227 return;
236 } 228 }
237 229
238 // TODO(dgrogan): Plumb data_loss back to script eventually? 230 // TODO(dgrogan): Plumb data_loss back to script eventually?
239 blink::WebIDBDataLoss data_loss; 231 blink::WebIDBDataLoss data_loss;
240 std::string data_loss_message; 232 std::string data_loss_message;
241 bool disk_full = false; 233 bool disk_full = false;
242 leveldb::Status s; 234 leveldb::Status s;
243 scoped_refptr<IndexedDBBackingStore> backing_store = 235 scoped_refptr<IndexedDBBackingStore> backing_store =
244 OpenBackingStore(origin_url, 236 OpenBackingStore(origin, data_directory, request_context, &data_loss,
245 data_directory, 237 &data_loss_message, &disk_full, &s);
246 request_context,
247 &data_loss,
248 &data_loss_message,
249 &disk_full,
250 &s);
251 if (!backing_store.get()) { 238 if (!backing_store.get()) {
252 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 239 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
253 ASCIIToUTF16( 240 ASCIIToUTF16(
254 "Internal error opening backing store " 241 "Internal error opening backing store "
255 "for indexedDB.deleteDatabase.")); 242 "for indexedDB.deleteDatabase."));
256 callbacks->OnError(error); 243 callbacks->OnError(error);
257 if (s.IsCorruption()) { 244 if (s.IsCorruption()) {
258 HandleBackingStoreCorruption(origin_url, error); 245 HandleBackingStoreCorruption(origin, error);
259 } 246 }
260 return; 247 return;
261 } 248 }
262 249
263 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); 250 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s);
264 if (!s.ok()) { 251 if (!s.ok()) {
265 DLOG(ERROR) << "Internal error getting database names"; 252 DLOG(ERROR) << "Internal error getting database names";
266 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 253 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
267 "Internal error opening backing store for " 254 "Internal error opening backing store for "
268 "indexedDB.deleteDatabase."); 255 "indexedDB.deleteDatabase.");
269 callbacks->OnError(error); 256 callbacks->OnError(error);
270 backing_store = NULL; 257 backing_store = NULL;
271 if (s.IsCorruption()) 258 if (s.IsCorruption())
272 HandleBackingStoreCorruption(origin_url, error); 259 HandleBackingStoreCorruption(origin, error);
273 return; 260 return;
274 } 261 }
275 if (!ContainsValue(names, name)) { 262 if (!ContainsValue(names, name)) {
276 const int64_t version = 0; 263 const int64_t version = 0;
277 callbacks->OnSuccess(version); 264 callbacks->OnSuccess(version);
278 backing_store = NULL; 265 backing_store = NULL;
279 ReleaseBackingStore(origin_url, false /* immediate */); 266 ReleaseBackingStore(origin, false /* immediate */);
280 return; 267 return;
281 } 268 }
282 269
283 scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create( 270 scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create(
284 name, backing_store.get(), this, unique_identifier, &s); 271 name, backing_store.get(), this, unique_identifier, &s);
285 if (!database.get()) { 272 if (!database.get()) {
286 IndexedDBDatabaseError error( 273 IndexedDBDatabaseError error(
287 blink::WebIDBDatabaseExceptionUnknownError, 274 blink::WebIDBDatabaseExceptionUnknownError,
288 ASCIIToUTF16( 275 ASCIIToUTF16(
289 "Internal error creating database backend for " 276 "Internal error creating database backend for "
290 "indexedDB.deleteDatabase.")); 277 "indexedDB.deleteDatabase."));
291 callbacks->OnError(error); 278 callbacks->OnError(error);
292 if (s.IsCorruption()) { 279 if (s.IsCorruption()) {
293 backing_store = NULL; 280 backing_store = NULL;
294 HandleBackingStoreCorruption(origin_url, error); 281 HandleBackingStoreCorruption(origin, error);
295 } 282 }
296 return; 283 return;
297 } 284 }
298 285
299 database_map_[unique_identifier] = database.get(); 286 database_map_[unique_identifier] = database.get();
300 origin_dbs_.insert(std::make_pair(origin_url, database.get())); 287 origin_dbs_.insert(std::make_pair(origin, database.get()));
301 database->DeleteDatabase(callbacks); 288 database->DeleteDatabase(callbacks);
302 RemoveDatabaseFromMaps(unique_identifier); 289 RemoveDatabaseFromMaps(unique_identifier);
303 database = NULL; 290 database = NULL;
304 backing_store = NULL; 291 backing_store = NULL;
305 ReleaseBackingStore(origin_url, false /* immediate */); 292 ReleaseBackingStore(origin, false /* immediate */);
306 } 293 }
307 294
308 void IndexedDBFactoryImpl::DatabaseDeleted( 295 void IndexedDBFactoryImpl::DatabaseDeleted(
309 const IndexedDBDatabase::Identifier& identifier) { 296 const IndexedDBDatabase::Identifier& identifier) {
310 // NULL after ContextDestroyed() called, and in some unit tests. 297 // NULL after ContextDestroyed() called, and in some unit tests.
311 if (!context_) 298 if (!context_)
312 return; 299 return;
313 context_->DatabaseDeleted(identifier.first); 300 context_->DatabaseDeleted(identifier.first);
314 } 301 }
315 302
316 void IndexedDBFactoryImpl::HandleBackingStoreFailure(const GURL& origin_url) { 303 void IndexedDBFactoryImpl::HandleBackingStoreFailure(const Origin& origin) {
317 // NULL after ContextDestroyed() called, and in some unit tests. 304 // NULL after ContextDestroyed() called, and in some unit tests.
318 if (!context_) 305 if (!context_)
319 return; 306 return;
320 context_->ForceClose(origin_url, 307 context_->ForceClose(origin,
321 IndexedDBContextImpl::FORCE_CLOSE_BACKING_STORE_FAILURE); 308 IndexedDBContextImpl::FORCE_CLOSE_BACKING_STORE_FAILURE);
322 } 309 }
323 310
324 void IndexedDBFactoryImpl::HandleBackingStoreCorruption( 311 void IndexedDBFactoryImpl::HandleBackingStoreCorruption(
325 const GURL& origin_url, 312 const Origin& origin,
326 const IndexedDBDatabaseError& error) { 313 const IndexedDBDatabaseError& error) {
327 // Make a copy of origin_url as this is likely a reference to a member of a 314 // Make a copy of origin as this is likely a reference to a member of a
328 // backing store which this function will be deleting. 315 // backing store which this function will be deleting.
329 GURL saved_origin_url(origin_url); 316 Origin saved_origin(origin);
330 DCHECK(context_); 317 DCHECK(context_);
331 base::FilePath path_base = context_->data_path(); 318 base::FilePath path_base = context_->data_path();
332 IndexedDBBackingStore::RecordCorruptionInfo( 319 IndexedDBBackingStore::RecordCorruptionInfo(
333 path_base, saved_origin_url, base::UTF16ToUTF8(error.message())); 320 path_base, saved_origin, base::UTF16ToUTF8(error.message()));
334 HandleBackingStoreFailure(saved_origin_url); 321 HandleBackingStoreFailure(saved_origin);
335 // Note: DestroyBackingStore only deletes LevelDB files, leaving all others, 322 // Note: DestroyBackingStore only deletes LevelDB files, leaving all others,
336 // so our corruption info file will remain. 323 // so our corruption info file will remain.
337 leveldb::Status s = 324 leveldb::Status s =
338 IndexedDBBackingStore::DestroyBackingStore(path_base, saved_origin_url); 325 IndexedDBBackingStore::DestroyBackingStore(path_base, saved_origin);
339 if (!s.ok()) 326 if (!s.ok())
340 DLOG(ERROR) << "Unable to delete backing store: " << s.ToString(); 327 DLOG(ERROR) << "Unable to delete backing store: " << s.ToString();
341 } 328 }
342 329
343 bool IndexedDBFactoryImpl::IsDatabaseOpen(const GURL& origin_url, 330 bool IndexedDBFactoryImpl::IsDatabaseOpen(const Origin& origin,
344 const base::string16& name) const { 331 const base::string16& name) const {
345 return !!database_map_.count(IndexedDBDatabase::Identifier(origin_url, name)); 332 return !!database_map_.count(IndexedDBDatabase::Identifier(origin, name));
346 } 333 }
347 334
348 bool IndexedDBFactoryImpl::IsBackingStoreOpen(const GURL& origin_url) const { 335 bool IndexedDBFactoryImpl::IsBackingStoreOpen(const Origin& origin) const {
349 return backing_store_map_.find(origin_url) != backing_store_map_.end(); 336 return backing_store_map_.find(origin) != backing_store_map_.end();
350 } 337 }
351 338
352 bool IndexedDBFactoryImpl::IsBackingStorePendingClose( 339 bool IndexedDBFactoryImpl::IsBackingStorePendingClose(
353 const GURL& origin_url) const { 340 const Origin& origin) const {
354 IndexedDBBackingStoreMap::const_iterator it = 341 IndexedDBBackingStoreMap::const_iterator it = backing_store_map_.find(origin);
355 backing_store_map_.find(origin_url);
356 if (it == backing_store_map_.end()) 342 if (it == backing_store_map_.end())
357 return false; 343 return false;
358 return it->second->close_timer()->IsRunning(); 344 return it->second->close_timer()->IsRunning();
359 } 345 }
360 346
361 scoped_refptr<IndexedDBBackingStore> 347 scoped_refptr<IndexedDBBackingStore>
362 IndexedDBFactoryImpl::OpenBackingStoreHelper( 348 IndexedDBFactoryImpl::OpenBackingStoreHelper(
363 const GURL& origin_url, 349 const Origin& origin,
364 const base::FilePath& data_directory, 350 const base::FilePath& data_directory,
365 net::URLRequestContext* request_context, 351 net::URLRequestContext* request_context,
366 blink::WebIDBDataLoss* data_loss, 352 blink::WebIDBDataLoss* data_loss,
367 std::string* data_loss_message, 353 std::string* data_loss_message,
368 bool* disk_full, 354 bool* disk_full,
369 bool first_time, 355 bool first_time,
370 leveldb::Status* status) { 356 leveldb::Status* status) {
371 return IndexedDBBackingStore::Open(this, 357 return IndexedDBBackingStore::Open(
372 origin_url, 358 this, origin, data_directory, request_context, data_loss,
373 data_directory, 359 data_loss_message, disk_full, context_->TaskRunner(), first_time, status);
374 request_context,
375 data_loss,
376 data_loss_message,
377 disk_full,
378 context_->TaskRunner(),
379 first_time,
380 status);
381 } 360 }
382 361
383 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore( 362 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
384 const GURL& origin_url, 363 const Origin& origin,
385 const base::FilePath& data_directory, 364 const base::FilePath& data_directory,
386 net::URLRequestContext* request_context, 365 net::URLRequestContext* request_context,
387 blink::WebIDBDataLoss* data_loss, 366 blink::WebIDBDataLoss* data_loss,
388 std::string* data_loss_message, 367 std::string* data_loss_message,
389 bool* disk_full, 368 bool* disk_full,
390 leveldb::Status* status) { 369 leveldb::Status* status) {
391 const bool open_in_memory = data_directory.empty(); 370 const bool open_in_memory = data_directory.empty();
392 371
393 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); 372 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin);
394 if (it2 != backing_store_map_.end()) { 373 if (it2 != backing_store_map_.end()) {
395 it2->second->close_timer()->Stop(); 374 it2->second->close_timer()->Stop();
396 return it2->second; 375 return it2->second;
397 } 376 }
398 377
399 scoped_refptr<IndexedDBBackingStore> backing_store; 378 scoped_refptr<IndexedDBBackingStore> backing_store;
400 bool first_time = false; 379 bool first_time = false;
401 if (open_in_memory) { 380 if (open_in_memory) {
402 backing_store = IndexedDBBackingStore::OpenInMemory( 381 backing_store = IndexedDBBackingStore::OpenInMemory(
403 origin_url, context_->TaskRunner(), status); 382 origin, context_->TaskRunner(), status);
404 } else { 383 } else {
405 first_time = !backends_opened_since_boot_.count(origin_url); 384 first_time = !backends_opened_since_boot_.count(origin);
406 385
407 backing_store = OpenBackingStoreHelper(origin_url, 386 backing_store = OpenBackingStoreHelper(
408 data_directory, 387 origin, data_directory, request_context, data_loss, data_loss_message,
409 request_context, 388 disk_full, first_time, status);
410 data_loss,
411 data_loss_message,
412 disk_full,
413 first_time,
414 status);
415 } 389 }
416 390
417 if (backing_store.get()) { 391 if (backing_store.get()) {
418 if (first_time) 392 if (first_time)
419 backends_opened_since_boot_.insert(origin_url); 393 backends_opened_since_boot_.insert(origin);
420 backing_store_map_[origin_url] = backing_store; 394 backing_store_map_[origin] = backing_store;
421 // If an in-memory database, bind lifetime to this factory instance. 395 // If an in-memory database, bind lifetime to this factory instance.
422 if (open_in_memory) 396 if (open_in_memory)
423 session_only_backing_stores_.insert(backing_store); 397 session_only_backing_stores_.insert(backing_store);
424 398
425 // All backing stores associated with this factory should be of the same 399 // All backing stores associated with this factory should be of the same
426 // type. 400 // type.
427 DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory); 401 DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory);
428 402
429 return backing_store; 403 return backing_store;
430 } 404 }
431 405
432 return 0; 406 return 0;
433 } 407 }
434 408
435 void IndexedDBFactoryImpl::Open(const base::string16& name, 409 void IndexedDBFactoryImpl::Open(const base::string16& name,
436 const IndexedDBPendingConnection& connection, 410 const IndexedDBPendingConnection& connection,
437 net::URLRequestContext* request_context, 411 net::URLRequestContext* request_context,
438 const url::Origin& origin, 412 const Origin& origin,
439 const base::FilePath& data_directory) { 413 const base::FilePath& data_directory) {
440 IDB_TRACE("IndexedDBFactoryImpl::Open"); 414 IDB_TRACE("IndexedDBFactoryImpl::Open");
441 scoped_refptr<IndexedDBDatabase> database; 415 scoped_refptr<IndexedDBDatabase> database;
442 GURL origin_url(origin.Serialize()); 416 IndexedDBDatabase::Identifier unique_identifier(origin, name);
443 IndexedDBDatabase::Identifier unique_identifier(origin_url, name);
444 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); 417 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier);
445 blink::WebIDBDataLoss data_loss = 418 blink::WebIDBDataLoss data_loss =
446 blink::WebIDBDataLossNone; 419 blink::WebIDBDataLossNone;
447 std::string data_loss_message; 420 std::string data_loss_message;
448 bool disk_full = false; 421 bool disk_full = false;
449 bool was_open = (it != database_map_.end()); 422 bool was_open = (it != database_map_.end());
450 if (!was_open) { 423 if (!was_open) {
451 leveldb::Status s; 424 leveldb::Status s;
452 scoped_refptr<IndexedDBBackingStore> backing_store = 425 scoped_refptr<IndexedDBBackingStore> backing_store =
453 OpenBackingStore(origin_url, 426 OpenBackingStore(origin, data_directory, request_context, &data_loss,
454 data_directory, 427 &data_loss_message, &disk_full, &s);
455 request_context,
456 &data_loss,
457 &data_loss_message,
458 &disk_full,
459 &s);
460 if (!backing_store.get()) { 428 if (!backing_store.get()) {
461 if (disk_full) { 429 if (disk_full) {
462 connection.callbacks->OnError( 430 connection.callbacks->OnError(
463 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, 431 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError,
464 ASCIIToUTF16( 432 ASCIIToUTF16(
465 "Encountered full disk while opening " 433 "Encountered full disk while opening "
466 "backing store for indexedDB.open."))); 434 "backing store for indexedDB.open.")));
467 return; 435 return;
468 } 436 }
469 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 437 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
470 ASCIIToUTF16( 438 ASCIIToUTF16(
471 "Internal error opening backing store" 439 "Internal error opening backing store"
472 " for indexedDB.open.")); 440 " for indexedDB.open."));
473 connection.callbacks->OnError(error); 441 connection.callbacks->OnError(error);
474 if (s.IsCorruption()) { 442 if (s.IsCorruption()) {
475 HandleBackingStoreCorruption(origin_url, error); 443 HandleBackingStoreCorruption(origin, error);
476 } 444 }
477 return; 445 return;
478 } 446 }
479 447
480 database = IndexedDBDatabase::Create( 448 database = IndexedDBDatabase::Create(
481 name, backing_store.get(), this, unique_identifier, &s); 449 name, backing_store.get(), this, unique_identifier, &s);
482 if (!database.get()) { 450 if (!database.get()) {
483 DLOG(ERROR) << "Unable to create the database"; 451 DLOG(ERROR) << "Unable to create the database";
484 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 452 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
485 ASCIIToUTF16( 453 ASCIIToUTF16(
486 "Internal error creating " 454 "Internal error creating "
487 "database backend for " 455 "database backend for "
488 "indexedDB.open.")); 456 "indexedDB.open."));
489 connection.callbacks->OnError(error); 457 connection.callbacks->OnError(error);
490 if (s.IsCorruption()) { 458 if (s.IsCorruption()) {
491 backing_store = NULL; // Closes the LevelDB so that it can be deleted 459 backing_store = NULL; // Closes the LevelDB so that it can be deleted
492 HandleBackingStoreCorruption(origin_url, error); 460 HandleBackingStoreCorruption(origin, error);
493 } 461 }
494 return; 462 return;
495 } 463 }
496 } else { 464 } else {
497 database = it->second; 465 database = it->second;
498 } 466 }
499 467
500 if (data_loss != blink::WebIDBDataLossNone) 468 if (data_loss != blink::WebIDBDataLossNone)
501 connection.callbacks->OnDataLoss(data_loss, data_loss_message); 469 connection.callbacks->OnDataLoss(data_loss, data_loss_message);
502 470
503 database->OpenConnection(connection); 471 database->OpenConnection(connection);
504 472
505 if (!was_open && database->ConnectionCount() > 0) { 473 if (!was_open && database->ConnectionCount() > 0) {
506 database_map_[unique_identifier] = database.get(); 474 database_map_[unique_identifier] = database.get();
507 origin_dbs_.insert(std::make_pair(origin_url, database.get())); 475 origin_dbs_.insert(std::make_pair(origin, database.get()));
508 } 476 }
509 } 477 }
510 478
511 std::pair<IndexedDBFactoryImpl::OriginDBMapIterator, 479 std::pair<IndexedDBFactoryImpl::OriginDBMapIterator,
512 IndexedDBFactoryImpl::OriginDBMapIterator> 480 IndexedDBFactoryImpl::OriginDBMapIterator>
513 IndexedDBFactoryImpl::GetOpenDatabasesForOrigin(const GURL& origin_url) const { 481 IndexedDBFactoryImpl::GetOpenDatabasesForOrigin(const Origin& origin) const {
514 return origin_dbs_.equal_range(origin_url); 482 return origin_dbs_.equal_range(origin);
515 } 483 }
516 484
517 size_t IndexedDBFactoryImpl::GetConnectionCount(const GURL& origin_url) const { 485 size_t IndexedDBFactoryImpl::GetConnectionCount(const Origin& origin) const {
518 size_t count(0); 486 size_t count(0);
519 487
520 OriginDBs range = GetOpenDatabasesForOrigin(origin_url); 488 OriginDBs range = GetOpenDatabasesForOrigin(origin);
521 for (OriginDBMapIterator it = range.first; it != range.second; ++it) 489 for (OriginDBMapIterator it = range.first; it != range.second; ++it)
522 count += it->second->ConnectionCount(); 490 count += it->second->ConnectionCount();
523 491
524 return count; 492 return count;
525 } 493 }
526 494
527 } // namespace content 495 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_factory_impl.h ('k') | content/browser/indexed_db/indexed_db_factory_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698