| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| 11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
| 12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
| 13 * | 13 * |
| 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "modules/indexeddb/IDBDatabase.h" | 27 #include "modules/indexeddb/IDBDatabase.h" |
| 28 | 28 |
| 29 #include "bindings/v8/ExceptionState.h" |
| 30 #include "bindings/v8/ExceptionStatePlaceholder.h" |
| 29 #include "core/dom/DOMStringList.h" | 31 #include "core/dom/DOMStringList.h" |
| 30 #include "core/dom/EventQueue.h" | 32 #include "core/dom/EventQueue.h" |
| 31 #include "core/dom/ExceptionCode.h" | |
| 32 #include "core/dom/ExceptionCodePlaceholder.h" | |
| 33 #include "core/dom/ScriptExecutionContext.h" | 33 #include "core/dom/ScriptExecutionContext.h" |
| 34 #include "core/inspector/ScriptCallStack.h" | 34 #include "core/inspector/ScriptCallStack.h" |
| 35 #include "core/platform/HistogramSupport.h" | 35 #include "core/platform/HistogramSupport.h" |
| 36 #include "modules/indexeddb/IDBAny.h" | 36 #include "modules/indexeddb/IDBAny.h" |
| 37 #include "modules/indexeddb/IDBDatabaseCallbacks.h" | 37 #include "modules/indexeddb/IDBDatabaseCallbacks.h" |
| 38 #include "modules/indexeddb/IDBEventDispatcher.h" | 38 #include "modules/indexeddb/IDBEventDispatcher.h" |
| 39 #include "modules/indexeddb/IDBHistograms.h" | 39 #include "modules/indexeddb/IDBHistograms.h" |
| 40 #include "modules/indexeddb/IDBIndex.h" | 40 #include "modules/indexeddb/IDBIndex.h" |
| 41 #include "modules/indexeddb/IDBKeyPath.h" | 41 #include "modules/indexeddb/IDBKeyPath.h" |
| 42 #include "modules/indexeddb/IDBObjectStore.h" | 42 #include "modules/indexeddb/IDBObjectStore.h" |
| 43 #include "modules/indexeddb/IDBTracing.h" | 43 #include "modules/indexeddb/IDBTracing.h" |
| 44 #include "modules/indexeddb/IDBTransaction.h" | 44 #include "modules/indexeddb/IDBTransaction.h" |
| 45 #include "modules/indexeddb/IDBVersionChangeEvent.h" | 45 #include "modules/indexeddb/IDBVersionChangeEvent.h" |
| 46 #include <limits> | 46 #include <limits> |
| 47 #include "wtf/Atomics.h" | 47 #include "wtf/Atomics.h" |
| 48 | 48 |
| 49 namespace WebCore { | 49 namespace WebCore { |
| 50 | 50 |
| 51 const char IDBDatabase::notFoundErrorMessage[] = "An operation failed because th
e requested database object could not be found."; |
| 52 |
| 51 PassRefPtr<IDBDatabase> IDBDatabase::create(ScriptExecutionContext* context, Pas
sRefPtr<IDBDatabaseBackendInterface> database, PassRefPtr<IDBDatabaseCallbacks>
callbacks) | 53 PassRefPtr<IDBDatabase> IDBDatabase::create(ScriptExecutionContext* context, Pas
sRefPtr<IDBDatabaseBackendInterface> database, PassRefPtr<IDBDatabaseCallbacks>
callbacks) |
| 52 { | 54 { |
| 53 RefPtr<IDBDatabase> idbDatabase(adoptRef(new IDBDatabase(context, database,
callbacks))); | 55 RefPtr<IDBDatabase> idbDatabase(adoptRef(new IDBDatabase(context, database,
callbacks))); |
| 54 idbDatabase->suspendIfNeeded(); | 56 idbDatabase->suspendIfNeeded(); |
| 55 return idbDatabase.release(); | 57 return idbDatabase.release(); |
| 56 } | 58 } |
| 57 | 59 |
| 58 IDBDatabase::IDBDatabase(ScriptExecutionContext* context, PassRefPtr<IDBDatabase
BackendInterface> backend, PassRefPtr<IDBDatabaseCallbacks> callbacks) | 60 IDBDatabase::IDBDatabase(ScriptExecutionContext* context, PassRefPtr<IDBDatabase
BackendInterface> backend, PassRefPtr<IDBDatabaseCallbacks> callbacks) |
| 59 : ActiveDOMObject(context) | 61 : ActiveDOMObject(context) |
| 60 , m_backend(backend) | 62 , m_backend(backend) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 } | 146 } |
| 145 | 147 |
| 146 PassRefPtr<IDBAny> IDBDatabase::version() const | 148 PassRefPtr<IDBAny> IDBDatabase::version() const |
| 147 { | 149 { |
| 148 int64_t intVersion = m_metadata.intVersion; | 150 int64_t intVersion = m_metadata.intVersion; |
| 149 if (intVersion == IDBDatabaseMetadata::NoIntVersion) | 151 if (intVersion == IDBDatabaseMetadata::NoIntVersion) |
| 150 return IDBAny::createString(m_metadata.version); | 152 return IDBAny::createString(m_metadata.version); |
| 151 return IDBAny::create(intVersion); | 153 return IDBAny::create(intVersion); |
| 152 } | 154 } |
| 153 | 155 |
| 154 PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co
nst Dictionary& options, ExceptionCode& ec) | 156 PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co
nst Dictionary& options, ExceptionState& es) |
| 155 { | 157 { |
| 156 IDBKeyPath keyPath; | 158 IDBKeyPath keyPath; |
| 157 bool autoIncrement = false; | 159 bool autoIncrement = false; |
| 158 if (!options.isUndefinedOrNull()) { | 160 if (!options.isUndefinedOrNull()) { |
| 159 String keyPathString; | 161 String keyPathString; |
| 160 Vector<String> keyPathArray; | 162 Vector<String> keyPathArray; |
| 161 if (options.get("keyPath", keyPathArray)) | 163 if (options.get("keyPath", keyPathArray)) |
| 162 keyPath = IDBKeyPath(keyPathArray); | 164 keyPath = IDBKeyPath(keyPathArray); |
| 163 else if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString)) | 165 else if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString)) |
| 164 keyPath = IDBKeyPath(keyPathString); | 166 keyPath = IDBKeyPath(keyPathString); |
| 165 | 167 |
| 166 options.get("autoIncrement", autoIncrement); | 168 options.get("autoIncrement", autoIncrement); |
| 167 } | 169 } |
| 168 | 170 |
| 169 return createObjectStore(name, keyPath, autoIncrement, ec); | 171 return createObjectStore(name, keyPath, autoIncrement, es); |
| 170 } | 172 } |
| 171 | 173 |
| 172 PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co
nst IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec) | 174 PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co
nst IDBKeyPath& keyPath, bool autoIncrement, ExceptionState& es) |
| 173 { | 175 { |
| 174 IDB_TRACE("IDBDatabase::createObjectStore"); | 176 IDB_TRACE("IDBDatabase::createObjectStore"); |
| 175 HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls",
IDBCreateObjectStoreCall, IDBMethodsMax); | 177 HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls",
IDBCreateObjectStoreCall, IDBMethodsMax); |
| 176 if (!m_versionChangeTransaction) { | 178 if (!m_versionChangeTransaction) { |
| 177 ec = InvalidStateError; | 179 es.throwDOMException(InvalidStateError); |
| 178 return 0; | 180 return 0; |
| 179 } | 181 } |
| 180 if (!m_versionChangeTransaction->isActive()) { | 182 if (!m_versionChangeTransaction->isActive()) { |
| 181 ec = TransactionInactiveError; | 183 es.throwDOMException(TransactionInactiveError); |
| 182 return 0; | 184 return 0; |
| 183 } | 185 } |
| 184 | 186 |
| 185 if (containsObjectStore(name)) { | 187 if (containsObjectStore(name)) { |
| 186 ec = ConstraintError; | 188 es.throwDOMException(ConstraintError); |
| 187 return 0; | 189 return 0; |
| 188 } | 190 } |
| 189 | 191 |
| 190 if (!keyPath.isNull() && !keyPath.isValid()) { | 192 if (!keyPath.isNull() && !keyPath.isValid()) { |
| 191 ec = SyntaxError; | 193 es.throwDOMException(SyntaxError); |
| 192 return 0; | 194 return 0; |
| 193 } | 195 } |
| 194 | 196 |
| 195 if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.s
tring().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { | 197 if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.s
tring().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { |
| 196 ec = InvalidAccessError; | 198 es.throwDOMException(InvalidAccessError); |
| 197 return 0; | 199 return 0; |
| 198 } | 200 } |
| 199 | 201 |
| 200 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; | 202 int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; |
| 201 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId
, name, keyPath, autoIncrement); | 203 m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId
, name, keyPath, autoIncrement); |
| 202 | 204 |
| 203 IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement,
IDBDatabaseBackendInterface::MinimumIndexId); | 205 IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement,
IDBDatabaseBackendInterface::MinimumIndexId); |
| 204 RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, m_vers
ionChangeTransaction.get()); | 206 RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, m_vers
ionChangeTransaction.get()); |
| 205 m_metadata.objectStores.set(metadata.id, metadata); | 207 m_metadata.objectStores.set(metadata.id, metadata); |
| 206 ++m_metadata.maxObjectStoreId; | 208 ++m_metadata.maxObjectStoreId; |
| 207 | 209 |
| 208 m_versionChangeTransaction->objectStoreCreated(name, objectStore); | 210 m_versionChangeTransaction->objectStoreCreated(name, objectStore); |
| 209 return objectStore.release(); | 211 return objectStore.release(); |
| 210 } | 212 } |
| 211 | 213 |
| 212 void IDBDatabase::deleteObjectStore(const String& name, ExceptionCode& ec) | 214 void IDBDatabase::deleteObjectStore(const String& name, ExceptionState& es) |
| 213 { | 215 { |
| 214 IDB_TRACE("IDBDatabase::deleteObjectStore"); | 216 IDB_TRACE("IDBDatabase::deleteObjectStore"); |
| 215 HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls",
IDBDeleteObjectStoreCall, IDBMethodsMax); | 217 HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls",
IDBDeleteObjectStoreCall, IDBMethodsMax); |
| 216 if (!m_versionChangeTransaction) { | 218 if (!m_versionChangeTransaction) { |
| 217 ec = InvalidStateError; | 219 es.throwDOMException(InvalidStateError); |
| 218 return; | 220 return; |
| 219 } | 221 } |
| 220 if (!m_versionChangeTransaction->isActive()) { | 222 if (!m_versionChangeTransaction->isActive()) { |
| 221 ec = TransactionInactiveError; | 223 es.throwDOMException(TransactionInactiveError); |
| 222 return; | 224 return; |
| 223 } | 225 } |
| 224 | 226 |
| 225 int64_t objectStoreId = findObjectStoreId(name); | 227 int64_t objectStoreId = findObjectStoreId(name); |
| 226 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { | 228 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { |
| 227 // FIXME: Should use (NotFoundError, "..."). | 229 es.throwDOMException(NotFoundError, IDBDatabase::notFoundErrorMessage); |
| 228 ec = IDBNotFoundError; | |
| 229 return; | 230 return; |
| 230 } | 231 } |
| 231 | 232 |
| 232 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId
); | 233 m_backend->deleteObjectStore(m_versionChangeTransaction->id(), objectStoreId
); |
| 233 m_versionChangeTransaction->objectStoreDeleted(name); | 234 m_versionChangeTransaction->objectStoreDeleted(name); |
| 234 m_metadata.objectStores.remove(objectStoreId); | 235 m_metadata.objectStores.remove(objectStoreId); |
| 235 } | 236 } |
| 236 | 237 |
| 237 PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* cont
ext, const Vector<String>& scope, const String& modeString, ExceptionCode& ec) | 238 PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* cont
ext, const Vector<String>& scope, const String& modeString, ExceptionState& es) |
| 238 { | 239 { |
| 239 IDB_TRACE("IDBDatabase::transaction"); | 240 IDB_TRACE("IDBDatabase::transaction"); |
| 240 HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls",
IDBTransactionCall, IDBMethodsMax); | 241 HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls",
IDBTransactionCall, IDBMethodsMax); |
| 241 if (!scope.size()) { | 242 if (!scope.size()) { |
| 242 ec = InvalidAccessError; | 243 es.throwDOMException(InvalidAccessError); |
| 243 return 0; | 244 return 0; |
| 244 } | 245 } |
| 245 | 246 |
| 246 IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, e
c); | 247 IndexedDB::TransactionMode mode = IDBTransaction::stringToMode(modeString, e
s); |
| 247 if (ec) | 248 if (es.hadException()) |
| 248 return 0; | 249 return 0; |
| 249 | 250 |
| 250 if (m_versionChangeTransaction || m_closePending) { | 251 if (m_versionChangeTransaction || m_closePending) { |
| 251 ec = InvalidStateError; | 252 es.throwDOMException(InvalidStateError); |
| 252 return 0; | 253 return 0; |
| 253 } | 254 } |
| 254 | 255 |
| 255 Vector<int64_t> objectStoreIds; | 256 Vector<int64_t> objectStoreIds; |
| 256 for (size_t i = 0; i < scope.size(); ++i) { | 257 for (size_t i = 0; i < scope.size(); ++i) { |
| 257 int64_t objectStoreId = findObjectStoreId(scope[i]); | 258 int64_t objectStoreId = findObjectStoreId(scope[i]); |
| 258 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { | 259 if (objectStoreId == IDBObjectStoreMetadata::InvalidId) { |
| 259 // FIXME: Should use (NotFoundError, "..."). | 260 es.throwDOMException(NotFoundError, IDBDatabase::notFoundErrorMessag
e); |
| 260 ec = IDBNotFoundError; | |
| 261 return 0; | 261 return 0; |
| 262 } | 262 } |
| 263 objectStoreIds.append(objectStoreId); | 263 objectStoreIds.append(objectStoreId); |
| 264 } | 264 } |
| 265 | 265 |
| 266 int64_t transactionId = nextTransactionId(); | 266 int64_t transactionId = nextTransactionId(); |
| 267 m_backend->createTransaction(transactionId, m_databaseCallbacks, objectStore
Ids, mode); | 267 m_backend->createTransaction(transactionId, m_databaseCallbacks, objectStore
Ids, mode); |
| 268 | 268 |
| 269 RefPtr<IDBTransaction> transaction = IDBTransaction::create(context, transac
tionId, scope, mode, this); | 269 RefPtr<IDBTransaction> transaction = IDBTransaction::create(context, transac
tionId, scope, mode, this); |
| 270 return transaction.release(); | 270 return transaction.release(); |
| 271 } | 271 } |
| 272 | 272 |
| 273 PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* cont
ext, const String& storeName, const String& mode, ExceptionCode& ec) | 273 PassRefPtr<IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext* cont
ext, const String& storeName, const String& mode, ExceptionState& es) |
| 274 { | 274 { |
| 275 RefPtr<DOMStringList> storeNames = DOMStringList::create(); | 275 RefPtr<DOMStringList> storeNames = DOMStringList::create(); |
| 276 storeNames->append(storeName); | 276 storeNames->append(storeName); |
| 277 return transaction(context, storeNames, mode, ec); | 277 return transaction(context, storeNames, mode, es); |
| 278 } | 278 } |
| 279 | 279 |
| 280 void IDBDatabase::forceClose() | 280 void IDBDatabase::forceClose() |
| 281 { | 281 { |
| 282 for (TransactionMap::const_iterator::Values it = m_transactions.begin().valu
es(), end = m_transactions.end().values(); it != end; ++it) | 282 for (TransactionMap::const_iterator::Values it = m_transactions.begin().valu
es(), end = m_transactions.end().values(); it != end; ++it) |
| 283 (*it)->abort(IGNORE_EXCEPTION); | 283 (*it)->abort(IGNORE_EXCEPTION_STATE); |
| 284 this->close(); | 284 this->close(); |
| 285 } | 285 } |
| 286 | 286 |
| 287 void IDBDatabase::close() | 287 void IDBDatabase::close() |
| 288 { | 288 { |
| 289 IDB_TRACE("IDBDatabase::close"); | 289 IDB_TRACE("IDBDatabase::close"); |
| 290 if (m_closePending) | 290 if (m_closePending) |
| 291 return; | 291 return; |
| 292 | 292 |
| 293 m_closePending = true; | 293 m_closePending = true; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 { | 391 { |
| 392 return &m_eventTargetData; | 392 return &m_eventTargetData; |
| 393 } | 393 } |
| 394 | 394 |
| 395 EventTargetData* IDBDatabase::ensureEventTargetData() | 395 EventTargetData* IDBDatabase::ensureEventTargetData() |
| 396 { | 396 { |
| 397 return &m_eventTargetData; | 397 return &m_eventTargetData; |
| 398 } | 398 } |
| 399 | 399 |
| 400 } // namespace WebCore | 400 } // namespace WebCore |
| OLD | NEW |