Unreviewed test gardening.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / legacy / LegacyOpenDBRequest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
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
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
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "LegacyOpenDBRequest.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBDatabaseCallbacksImpl.h"
32 #include "IDBPendingTransactionMonitor.h"
33 #include "IDBVersionChangeEvent.h"
34 #include "LegacyDatabase.h"
35 #include "LegacyVersionChangeEvent.h"
36 #include "Logging.h"
37 #include "ScriptExecutionContext.h"
38
39 namespace WebCore {
40
41 Ref<LegacyOpenDBRequest> LegacyOpenDBRequest::create(ScriptExecutionContext* context, PassRefPtr<IDBDatabaseCallbacks> callbacks, int64_t transactionId, uint64_t version, IndexedDB::VersionNullness versionNullness)
42 {
43     Ref<LegacyOpenDBRequest> request(adoptRef(*new LegacyOpenDBRequest(context, callbacks, transactionId, version, versionNullness)));
44     request->suspendIfNeeded();
45     return request;
46 }
47
48 LegacyOpenDBRequest::LegacyOpenDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBDatabaseCallbacks> callbacks, int64_t transactionId, uint64_t version, IndexedDB::VersionNullness versionNullness)
49     : LegacyRequest(context, LegacyAny::createNull(), IDBDatabaseBackend::NormalTask, 0)
50     , m_databaseCallbacks(callbacks)
51     , m_transactionId(transactionId)
52     , m_version(version)
53     , m_versionNullness(versionNullness)
54 {
55     ASSERT(!m_result);
56 }
57
58 LegacyOpenDBRequest::~LegacyOpenDBRequest()
59 {
60 }
61
62 EventTargetInterface LegacyOpenDBRequest::eventTargetInterface() const
63 {
64     return IDBOpenDBRequestEventTargetInterfaceType;
65 }
66
67 void LegacyOpenDBRequest::onBlocked(uint64_t oldVersion)
68 {
69     LOG(StorageAPI, "LegacyOpenDBRequest::onBlocked()");
70     if (!shouldEnqueueEvent())
71         return;
72     
73     enqueueEvent(LegacyVersionChangeEvent::create(oldVersion, m_version, eventNames().blockedEvent));
74 }
75
76 void LegacyOpenDBRequest::onUpgradeNeeded(uint64_t oldVersion, PassRefPtr<IDBDatabaseBackend> prpDatabaseBackend, const IDBDatabaseMetadata& metadata)
77 {
78     LOG(StorageAPI, "LegacyOpenDBRequest::onUpgradeNeeded()");
79     if (m_contextStopped || !scriptExecutionContext()) {
80         RefPtr<IDBDatabaseBackend> db = prpDatabaseBackend;
81         db->abort(m_transactionId);
82         db->close(m_databaseCallbacks);
83         return;
84     }
85     if (!shouldEnqueueEvent())
86         return;
87
88     ASSERT(m_databaseCallbacks);
89
90     RefPtr<IDBDatabaseBackend> databaseBackend = prpDatabaseBackend;
91
92     RefPtr<LegacyDatabase> idbDatabase = LegacyDatabase::create(scriptExecutionContext(), databaseBackend, m_databaseCallbacks);
93     idbDatabase->setMetadata(metadata);
94     m_databaseCallbacks->connect(idbDatabase.get());
95     m_databaseCallbacks = nullptr;
96
97     IDBDatabaseMetadata oldMetadata(metadata);
98     oldMetadata.version = oldVersion;
99
100     m_transaction = LegacyTransaction::create(scriptExecutionContext(), m_transactionId, idbDatabase.get(), this, oldMetadata);
101     m_result = LegacyAny::create(idbDatabase.release());
102
103     if (m_versionNullness == IndexedDB::VersionNullness::Null)
104         m_version = 1;
105     enqueueEvent(LegacyVersionChangeEvent::create(oldVersion, m_version, eventNames().upgradeneededEvent));
106 }
107
108 void LegacyOpenDBRequest::onSuccess(PassRefPtr<IDBDatabaseBackend> prpBackend, const IDBDatabaseMetadata& metadata)
109 {
110     LOG(StorageAPI, "LegacyOpenDBRequest::onSuccess()");
111     if (!shouldEnqueueEvent())
112         return;
113
114     RefPtr<IDBDatabaseBackend> backend = prpBackend;
115     RefPtr<LegacyDatabase> idbDatabase;
116     if (m_result) {
117         idbDatabase = m_result->legacyDatabase();
118         ASSERT(idbDatabase);
119         ASSERT(!m_databaseCallbacks);
120     } else {
121         ASSERT(m_databaseCallbacks);
122         idbDatabase = LegacyDatabase::create(scriptExecutionContext(), backend.release(), m_databaseCallbacks);
123         m_databaseCallbacks->connect(idbDatabase.get());
124         m_databaseCallbacks = nullptr;
125         m_result = LegacyAny::create(idbDatabase.get());
126     }
127     idbDatabase->setMetadata(metadata);
128     enqueueEvent(Event::create(eventNames().successEvent, false, false));
129 }
130
131 bool LegacyOpenDBRequest::shouldEnqueueEvent() const
132 {
133     if (m_contextStopped || !scriptExecutionContext())
134         return false;
135     ASSERT(m_readyState == IDBRequestReadyState::Pending || m_readyState == IDBRequestReadyState::Done);
136     if (m_requestAborted)
137         return false;
138     return true;
139 }
140
141 bool LegacyOpenDBRequest::dispatchEvent(Event& event)
142 {
143     // If the connection closed between onUpgradeNeeded and the delivery of the "success" event,
144     // an "error" event should be fired instead.
145     if (event.type() == eventNames().successEvent && m_result->type() == IDBAny::Type::IDBDatabase && m_result->legacyDatabase()->isClosePending()) {
146         m_result = nullptr;
147         onError(IDBDatabaseError::create(IDBDatabaseException::AbortError, "The connection was closed."));
148         return false;
149     }
150
151     return LegacyRequest::dispatchEvent(event);
152 }
153
154 } // namespace WebCore
155
156 #endif