1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_factory.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/time/time.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_backing_store.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_context_impl.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_tracing.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "webkit/common/database/database_identifier.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const int64 kBackingStoreGracePeriodMs = 2000; 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)IndexedDBFactory::IndexedDBFactory(IndexedDBContextImpl* context) 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : context_(context) {} 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexedDBFactory::~IndexedDBFactory() {} 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void IndexedDBFactory::ReleaseDatabase( 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const IndexedDBDatabase::Identifier& identifier, 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL& origin_url, 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool forcedClose) { 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IndexedDBDatabaseMap::iterator it = database_map_.find(identifier); 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(it != database_map_.end()); 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!it->second->backing_store()); 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) database_map_.erase(it); 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // No grace period on a forced-close, as the initiator is 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // assuming the backing store will be released once all 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // connections are closed. 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReleaseBackingStore(origin_url, forcedClose); 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBFactory::ReleaseBackingStore(const GURL& origin_url, 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool immediate) { 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Only close if this is the last reference. 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!HasLastBackingStoreReference(origin_url)) 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If this factory does hold the last reference to the backing store, it can 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // be closed - but unless requested to close it immediately, keep it around 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // for a short period so that a re-open is fast. 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (immediate) { 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CloseBackingStore(origin_url); 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Start a timer to close the backing store, unless something else opens it 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // in the mean time. 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!backing_store_map_[origin_url]->close_timer()->IsRunning()); 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_map_[origin_url]->close_timer()->Start( 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kBackingStoreGracePeriodMs), 611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&IndexedDBFactory::MaybeCloseBackingStore, this, origin_url)); 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBFactory::MaybeCloseBackingStore(const GURL& origin_url) { 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Another reference may have opened since the maybe-close was posted, so it 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // is necessary to check again. 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (HasLastBackingStoreReference(origin_url)) 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CloseBackingStore(origin_url); 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBFactory::CloseBackingStore(const GURL& origin_url) { 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(it != backing_store_map_.end()); 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Stop the timer (if it's running) - this may happen if the timer was started 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // and then a forced close occurs. 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it->second->close_timer()->Stop(); 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_map_.erase(it); 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool IndexedDBFactory::HasLastBackingStoreReference(const GURL& origin_url) 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const { 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) IndexedDBBackingStore* ptr; 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Scope so that the implicit scoped_refptr<> is freed. 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) IndexedDBBackingStoreMap::const_iterator it = 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_map_.find(origin_url); 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(it != backing_store_map_.end()); 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ptr = it->second.get(); 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return ptr->HasOneRef(); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void IndexedDBFactory::ForceClose(const GURL& origin_url) { 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (backing_store_map_.find(origin_url) != backing_store_map_.end()) 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ReleaseBackingStore(origin_url, true /* immediate */); 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBFactory::ContextDestroyed() { 991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Timers on backing stores hold a reference to this factory. When the 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // context (which nominally owns this factory) is destroyed during thread 1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // termination the timers must be stopped so that this factory and the 1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // stores can be disposed of. 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (IndexedDBBackingStoreMap::iterator it = backing_store_map_.begin(); 1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != backing_store_map_.end(); 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ++it) 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it->second->close_timer()->Stop(); 1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_map_.clear(); 1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) context_ = NULL; 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBFactory::GetDatabaseNames( 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL& origin_url, 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& data_directory) { 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBFactory::GetDatabaseNames"); 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(dgrogan): Plumb data_loss back to script eventually? 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDataLoss data_loss; 1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::string data_loss_message; 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool disk_full; 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store = 1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) OpenBackingStore(origin_url, 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_directory, 1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &data_loss, 1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &data_loss_message, 1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &disk_full); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!backing_store) { 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError( 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error opening backing store for " 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "indexedDB.webkitGetDatabaseNames.")); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnSuccess(backing_store->GetDatabaseNames()); 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ReleaseBackingStore(origin_url, false /* immediate */); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBFactory::DeleteDatabase( 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL& origin_url, 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& data_directory) { 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBFactory::DeleteDatabase"); 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IndexedDBDatabase::Identifier unique_identifier(origin_url, name); 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (it != database_map_.end()) { 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If there are any connections to the database, directly delete the 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // database. 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->second->DeleteDatabase(callbacks); 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(dgrogan): Plumb data_loss back to script eventually? 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDataLoss data_loss; 1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::string data_loss_message; 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool disk_full = false; 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store = 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) OpenBackingStore(origin_url, 1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_directory, 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &data_loss, 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &data_loss_message, 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &disk_full); 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!backing_store) { 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) callbacks->OnError( 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASCIIToUTF16( 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "Internal error opening backing store " 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "for indexedDB.deleteDatabase."))); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database = 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBDatabase::Create(name, backing_store, this, unique_identifier); 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!database) { 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError(IndexedDBDatabaseError( 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASCIIToUTF16( 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "Internal error creating database backend for " 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "indexedDB.deleteDatabase."))); 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) database_map_[unique_identifier] = database; 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) database->DeleteDatabase(callbacks); 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) database_map_.erase(unique_identifier); 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ReleaseBackingStore(origin_url, false /* immediate */); 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IndexedDBFactory::HandleBackingStoreFailure(const GURL& origin_url) { 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // NULL after ContextDestroyed() called, and in some unit tests. 1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!context_) 1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) context_->ForceClose(origin_url); 1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 196d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool IndexedDBFactory::IsDatabaseOpen(const GURL& origin_url, 197d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const base::string16& name) const { 198d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 199d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return !!database_map_.count(IndexedDBDatabase::Identifier(origin_url, name)); 200d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} 201d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 202d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool IndexedDBFactory::IsBackingStoreOpen(const GURL& origin_url) const { 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return backing_store_map_.find(origin_url) != backing_store_map_.end(); 2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 206d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool IndexedDBFactory::IsBackingStorePendingClose(const GURL& origin_url) 207d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const { 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IndexedDBBackingStoreMap::const_iterator it = 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) backing_store_map_.find(origin_url); 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (it == backing_store_map_.end()) 211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return it->second->close_timer()->IsRunning(); 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL& origin_url, 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FilePath& data_directory, 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDataLoss* data_loss, 2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::string* data_loss_message, 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool* disk_full) { 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const bool open_in_memory = data_directory.empty(); 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (it2 != backing_store_map_.end()) { 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) it2->second->close_timer()->Stop(); 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return it2->second; 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store; 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (open_in_memory) { 2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store = IndexedDBBackingStore::OpenInMemory(origin_url); 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) backing_store = IndexedDBBackingStore::Open(origin_url, 2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_directory, 2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_loss, 2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_loss_message, 2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) disk_full); 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (backing_store.get()) { 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) backing_store_map_[origin_url] = backing_store; 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // If an in-memory database, bind lifetime to this factory instance. 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (open_in_memory) 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) session_only_backing_stores_.insert(backing_store); 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // All backing stores associated with this factory should be of the same 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // type. 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(session_only_backing_stores_.empty() || open_in_memory); 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return backing_store; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBFactory::Open( 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& name, 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 version, 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 transaction_id, 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBCallbacks> callbacks, 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL& origin_url, 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& data_directory) { 264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDB_TRACE("IndexedDBFactory::Open"); 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database; 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IndexedDBDatabase::Identifier unique_identifier(origin_url, name); 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDataLoss data_loss = 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDataLossNone; 2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::string data_loss_message; 27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool disk_full = false; 272d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) bool was_open = (it != database_map_.end()); 273d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!was_open) { 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<IndexedDBBackingStore> backing_store = 2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) OpenBackingStore(origin_url, 2760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_directory, 2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &data_loss, 2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &data_loss_message, 2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &disk_full); 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!backing_store) { 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (disk_full) { 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callbacks->OnError( 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ASCIIToUTF16( 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Encountered full disk while opening " 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "backing store for indexedDB.open."))); 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError(IndexedDBDatabaseError( 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16( 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error opening backing store for indexedDB.open."))); 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) database = 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBDatabase::Create(name, backing_store, this, unique_identifier); 298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!database) { 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks->OnError(IndexedDBDatabaseError( 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebIDBDatabaseExceptionUnknownError, 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASCIIToUTF16( 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Internal error creating database backend for indexedDB.open."))); 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) database = it->second; 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) database->OpenConnection(callbacks, 3100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) database_callbacks, 3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) transaction_id, 3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) version, 3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_loss, 3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) data_loss_message); 315d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 316d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!was_open && database->ConnectionCount() > 0) 317d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) database_map_[unique_identifier] = database; 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstd::vector<IndexedDBDatabase*> IndexedDBFactory::GetOpenDatabasesForOrigin( 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GURL& origin_url) const { 322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<IndexedDBDatabase*> result; 323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (IndexedDBDatabaseMap::const_iterator it = database_map_.begin(); 324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) it != database_map_.end(); 325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ++it) { 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it->first.first == origin_url) 327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch result.push_back(it->second.get()); 328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return result; 330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 333