Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / inspector / InspectorDatabaseAgent.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2015 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "InspectorDatabaseAgent.h"
32
33 #include "Database.h"
34 #include "ExceptionCode.h"
35 #include "ExceptionCodePlaceholder.h"
36 #include "InspectorDatabaseResource.h"
37 #include "InstrumentingAgents.h"
38 #include "SQLError.h"
39 #include "SQLResultSet.h"
40 #include "SQLResultSetRowList.h"
41 #include "SQLStatementCallback.h"
42 #include "SQLStatementErrorCallback.h"
43 #include "SQLTransaction.h"
44 #include "SQLTransactionCallback.h"
45 #include "SQLTransactionErrorCallback.h"
46 #include "SQLValue.h"
47 #include "VoidCallback.h"
48 #include <inspector/InspectorFrontendRouter.h>
49 #include <inspector/InspectorValues.h>
50 #include <wtf/Vector.h>
51
52 typedef Inspector::DatabaseBackendDispatcherHandler::ExecuteSQLCallback ExecuteSQLCallback;
53
54 using namespace Inspector;
55
56 namespace WebCore {
57
58 namespace {
59
60 void reportTransactionFailed(ExecuteSQLCallback& requestCallback, SQLError* error)
61 {
62     auto errorObject = Inspector::Protocol::Database::Error::create()
63         .setMessage(error->message())
64         .setCode(error->code())
65         .release();
66     requestCallback.sendSuccess(nullptr, nullptr, WTFMove(errorObject));
67 }
68
69 class StatementCallback : public SQLStatementCallback {
70 public:
71     static Ref<StatementCallback> create(Ref<ExecuteSQLCallback>&& requestCallback)
72     {
73         return adoptRef(*new StatementCallback(WTFMove(requestCallback)));
74     }
75
76     virtual ~StatementCallback() { }
77
78     virtual bool handleEvent(SQLTransaction*, SQLResultSet* resultSet) override
79     {
80         SQLResultSetRowList* rowList = resultSet->rows();
81
82         auto columnNames = Inspector::Protocol::Array<String>::create();
83         for (auto& column : rowList->columnNames())
84             columnNames->addItem(column);
85
86         auto values = Inspector::Protocol::Array<InspectorValue>::create();
87         for (auto& value : rowList->values()) {
88             RefPtr<InspectorValue> inspectorValue;
89             switch (value.type()) {
90             case SQLValue::StringValue: inspectorValue = InspectorString::create(value.string()); break;
91             case SQLValue::NumberValue: inspectorValue = InspectorBasicValue::create(value.number()); break;
92             case SQLValue::NullValue: inspectorValue = InspectorValue::null(); break;
93             }
94             
95             values->addItem(WTFMove(inspectorValue));
96         }
97         m_requestCallback->sendSuccess(WTFMove(columnNames), WTFMove(values), nullptr);
98         return true;
99     }
100
101 private:
102     StatementCallback(Ref<ExecuteSQLCallback>&& requestCallback)
103         : m_requestCallback(WTFMove(requestCallback)) { }
104     Ref<ExecuteSQLCallback> m_requestCallback;
105 };
106
107 class StatementErrorCallback : public SQLStatementErrorCallback {
108 public:
109     static Ref<StatementErrorCallback> create(Ref<ExecuteSQLCallback>&& requestCallback)
110     {
111         return adoptRef(*new StatementErrorCallback(WTFMove(requestCallback)));
112     }
113
114     virtual ~StatementErrorCallback() { }
115
116     virtual bool handleEvent(SQLTransaction*, SQLError* error) override
117     {
118         reportTransactionFailed(m_requestCallback.copyRef(), error);
119         return true;  
120     }
121
122 private:
123     StatementErrorCallback(Ref<ExecuteSQLCallback>&& requestCallback)
124         : m_requestCallback(WTFMove(requestCallback)) { }
125     Ref<ExecuteSQLCallback> m_requestCallback;
126 };
127
128 class TransactionCallback : public SQLTransactionCallback {
129 public:
130     static Ref<TransactionCallback> create(const String& sqlStatement, Ref<ExecuteSQLCallback>&& requestCallback)
131     {
132         return adoptRef(*new TransactionCallback(sqlStatement, WTFMove(requestCallback)));
133     }
134
135     virtual ~TransactionCallback() { }
136
137     virtual bool handleEvent(SQLTransaction* transaction) override
138     {
139         if (!m_requestCallback->isActive())
140             return true;
141
142         Vector<SQLValue> sqlValues;
143         Ref<SQLStatementCallback> callback(StatementCallback::create(m_requestCallback.copyRef()));
144         Ref<SQLStatementErrorCallback> errorCallback(StatementErrorCallback::create(m_requestCallback.copyRef()));
145         transaction->executeSQL(m_sqlStatement, sqlValues, WTFMove(callback), WTFMove(errorCallback), IGNORE_EXCEPTION);
146         return true;
147     }
148 private:
149     TransactionCallback(const String& sqlStatement, Ref<ExecuteSQLCallback>&& requestCallback)
150         : m_sqlStatement(sqlStatement)
151         , m_requestCallback(WTFMove(requestCallback)) { }
152     String m_sqlStatement;
153     Ref<ExecuteSQLCallback> m_requestCallback;
154 };
155
156 class TransactionErrorCallback : public SQLTransactionErrorCallback {
157 public:
158     static Ref<TransactionErrorCallback> create(Ref<ExecuteSQLCallback>&& requestCallback)
159     {
160         return adoptRef(*new TransactionErrorCallback(WTFMove(requestCallback)));
161     }
162
163     virtual ~TransactionErrorCallback() { }
164
165     virtual bool handleEvent(SQLError* error) override
166     {
167         reportTransactionFailed(m_requestCallback.get(), error);
168         return true;
169     }
170 private:
171     TransactionErrorCallback(Ref<ExecuteSQLCallback>&& requestCallback)
172         : m_requestCallback(WTFMove(requestCallback)) { }
173     Ref<ExecuteSQLCallback> m_requestCallback;
174 };
175
176 class TransactionSuccessCallback : public VoidCallback {
177 public:
178     static Ref<TransactionSuccessCallback> create()
179     {
180         return adoptRef(*new TransactionSuccessCallback());
181     }
182
183     virtual ~TransactionSuccessCallback() { }
184
185     virtual bool handleEvent() override { return false; }
186
187 private:
188     TransactionSuccessCallback() { }
189 };
190
191 } // namespace
192
193 void InspectorDatabaseAgent::didOpenDatabase(RefPtr<Database>&& database, const String& domain, const String& name, const String& version)
194 {
195     if (InspectorDatabaseResource* resource = findByFileName(database->fileName())) {
196         resource->setDatabase(WTFMove(database));
197         return;
198     }
199
200     RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(WTFMove(database), domain, name, version);
201     m_resources.set(resource->id(), resource);
202     // Resources are only bound while visible.
203     if (m_enabled)
204         resource->bind(m_frontendDispatcher.get());
205 }
206
207 void InspectorDatabaseAgent::clearResources()
208 {
209     m_resources.clear();
210 }
211
212 InspectorDatabaseAgent::InspectorDatabaseAgent(WebAgentContext& context)
213     : InspectorAgentBase(ASCIILiteral("Database"), context)
214     , m_frontendDispatcher(std::make_unique<Inspector::DatabaseFrontendDispatcher>(context.frontendRouter))
215     , m_backendDispatcher(Inspector::DatabaseBackendDispatcher::create(context.backendDispatcher, this))
216 {
217     m_instrumentingAgents.setInspectorDatabaseAgent(this);
218 }
219
220 InspectorDatabaseAgent::~InspectorDatabaseAgent()
221 {
222     m_instrumentingAgents.setInspectorDatabaseAgent(nullptr);
223 }
224
225 void InspectorDatabaseAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
226 {
227 }
228
229 void InspectorDatabaseAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
230 {
231     ErrorString unused;
232     disable(unused);
233 }
234
235 void InspectorDatabaseAgent::enable(ErrorString&)
236 {
237     if (m_enabled)
238         return;
239     m_enabled = true;
240
241     for (auto& resource : m_resources.values())
242         resource->bind(m_frontendDispatcher.get());
243 }
244
245 void InspectorDatabaseAgent::disable(ErrorString&)
246 {
247     if (!m_enabled)
248         return;
249     m_enabled = false;
250 }
251
252 void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString& error, const String& databaseId, RefPtr<Inspector::Protocol::Array<String>>& names)
253 {
254     if (!m_enabled) {
255         error = ASCIILiteral("Database agent is not enabled");
256         return;
257     }
258
259     names = Inspector::Protocol::Array<String>::create();
260
261     Database* database = databaseForId(databaseId);
262     if (database) {
263         for (auto& tableName : database->tableNames())
264             names->addItem(tableName);
265     }
266 }
267
268 void InspectorDatabaseAgent::executeSQL(ErrorString&, const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&& requestCallback)
269 {
270     if (!m_enabled) {
271         requestCallback->sendFailure("Database agent is not enabled");
272         return;
273     }
274
275     Database* database = databaseForId(databaseId);
276     if (!database) {
277         requestCallback->sendFailure("Database not found");
278         return;
279     }
280
281     Ref<SQLTransactionCallback> callback(TransactionCallback::create(query, requestCallback.get()));
282     Ref<SQLTransactionErrorCallback> errorCallback(TransactionErrorCallback::create(requestCallback.get()));
283     Ref<VoidCallback> successCallback(TransactionSuccessCallback::create());
284     database->transaction(WTFMove(callback), WTFMove(errorCallback), WTFMove(successCallback));
285 }
286
287 String InspectorDatabaseAgent::databaseId(Database* database)
288 {
289     for (auto& resource : m_resources) {
290         if (resource.value->database() == database)
291             return resource.key;
292     }
293     return String();
294 }
295
296 InspectorDatabaseResource* InspectorDatabaseAgent::findByFileName(const String& fileName)
297 {
298     for (auto& resource : m_resources.values()) {
299         if (resource->database()->fileName() == fileName)
300             return resource.get();
301     }
302     return nullptr;
303 }
304
305 Database* InspectorDatabaseAgent::databaseForId(const String& databaseId)
306 {
307     DatabaseResourcesMap::iterator it = m_resources.find(databaseId);
308     if (it == m_resources.end())
309         return nullptr;
310     return it->value->database();
311 }
312
313 } // namespace WebCore