~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/inspector/InspectorDatabaseAgent.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 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
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 
14
 *     its contributors may be used to endorse or promote products derived
 
15
 *     from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 
18
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
20
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
22
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
23
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
24
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
#include "config.h"
 
30
 
 
31
#if ENABLE(INSPECTOR) && ENABLE(SQL_DATABASE)
 
32
 
 
33
#include "InspectorDatabaseAgent.h"
 
34
 
 
35
#include "Database.h"
 
36
#include "ExceptionCode.h"
 
37
#include "InspectorDatabaseResource.h"
 
38
#include "InspectorFrontend.h"
 
39
#include "InspectorState.h"
 
40
#include "InspectorValues.h"
 
41
#include "InstrumentingAgents.h"
 
42
#include "SQLError.h"
 
43
#include "SQLStatementCallback.h"
 
44
#include "SQLStatementErrorCallback.h"
 
45
#include "SQLResultSetRowList.h"
 
46
#include "SQLTransaction.h"
 
47
#include "SQLTransactionCallback.h"
 
48
#include "SQLTransactionErrorCallback.h"
 
49
#include "SQLValue.h"
 
50
#include "VoidCallback.h"
 
51
 
 
52
#include <wtf/Vector.h>
 
53
 
 
54
typedef WebCore::InspectorBackendDispatcher::DatabaseCommandHandler::ExecuteSQLCallback ExecuteSQLCallback;
 
55
 
 
56
namespace WebCore {
 
57
 
 
58
namespace DatabaseAgentState {
 
59
static const char databaseAgentEnabled[] = "databaseAgentEnabled";
 
60
};
 
61
 
 
62
namespace {
 
63
 
 
64
void reportTransactionFailed(ExecuteSQLCallback* requestCallback, SQLError* error)
 
65
{
 
66
    RefPtr<TypeBuilder::Database::Error> errorObject = TypeBuilder::Database::Error::create()
 
67
        .setMessage(error->message())
 
68
        .setCode(error->code());
 
69
    requestCallback->sendSuccess(0, 0, errorObject.release());
 
70
}
 
71
 
 
72
class StatementCallback : public SQLStatementCallback {
 
73
public:
 
74
    static PassRefPtr<StatementCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback)
 
75
    {
 
76
        return adoptRef(new StatementCallback(requestCallback));
 
77
    }
 
78
 
 
79
    virtual ~StatementCallback() { }
 
80
 
 
81
    virtual bool handleEvent(SQLTransaction*, SQLResultSet* resultSet)
 
82
    {
 
83
        SQLResultSetRowList* rowList = resultSet->rows();
 
84
 
 
85
        RefPtr<TypeBuilder::Array<String> > columnNames = TypeBuilder::Array<String>::create();
 
86
        const Vector<String>& columns = rowList->columnNames();
 
87
        for (size_t i = 0; i < columns.size(); ++i)
 
88
            columnNames->addItem(columns[i]);
 
89
 
 
90
        RefPtr<TypeBuilder::Array<InspectorValue> > values = TypeBuilder::Array<InspectorValue>::create();
 
91
        const Vector<SQLValue>& data = rowList->values();
 
92
        for (size_t i = 0; i < data.size(); ++i) {
 
93
            const SQLValue& value = rowList->values()[i];
 
94
            switch (value.type()) {
 
95
            case SQLValue::StringValue: values->addItem(InspectorString::create(value.string())); break;
 
96
            case SQLValue::NumberValue: values->addItem(InspectorBasicValue::create(value.number())); break;
 
97
            case SQLValue::NullValue: values->addItem(InspectorValue::null()); break;
 
98
            }
 
99
        }
 
100
        m_requestCallback->sendSuccess(columnNames.release(), values.release(), 0);
 
101
        return true;
 
102
    }
 
103
 
 
104
private:
 
105
    StatementCallback(PassRefPtr<ExecuteSQLCallback> requestCallback)
 
106
        : m_requestCallback(requestCallback) { }
 
107
    RefPtr<ExecuteSQLCallback> m_requestCallback;
 
108
};
 
109
 
 
110
class StatementErrorCallback : public SQLStatementErrorCallback {
 
111
public:
 
112
    static PassRefPtr<StatementErrorCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback)
 
113
    {
 
114
        return adoptRef(new StatementErrorCallback(requestCallback));
 
115
    }
 
116
 
 
117
    virtual ~StatementErrorCallback() { }
 
118
 
 
119
    virtual bool handleEvent(SQLTransaction*, SQLError* error)
 
120
    {
 
121
        reportTransactionFailed(m_requestCallback.get(), error);
 
122
        return true;  
 
123
    }
 
124
 
 
125
private:
 
126
    StatementErrorCallback(PassRefPtr<ExecuteSQLCallback> requestCallback)
 
127
        : m_requestCallback(requestCallback) { }
 
128
    RefPtr<ExecuteSQLCallback> m_requestCallback;
 
129
};
 
130
 
 
131
class TransactionCallback : public SQLTransactionCallback {
 
132
public:
 
133
    static PassRefPtr<TransactionCallback> create(const String& sqlStatement, PassRefPtr<ExecuteSQLCallback> requestCallback)
 
134
    {
 
135
        return adoptRef(new TransactionCallback(sqlStatement, requestCallback));
 
136
    }
 
137
 
 
138
    virtual ~TransactionCallback() { }
 
139
 
 
140
    virtual bool handleEvent(SQLTransaction* transaction)
 
141
    {
 
142
        if (!m_requestCallback->isActive())
 
143
            return true;
 
144
 
 
145
        Vector<SQLValue> sqlValues;
 
146
        RefPtr<SQLStatementCallback> callback(StatementCallback::create(m_requestCallback.get()));
 
147
        RefPtr<SQLStatementErrorCallback> errorCallback(StatementErrorCallback::create(m_requestCallback.get()));
 
148
        ExceptionCode ec = 0;
 
149
        transaction->executeSQL(m_sqlStatement, sqlValues, callback.release(), errorCallback.release(), ec);
 
150
        return true;
 
151
    }
 
152
private:
 
153
    TransactionCallback(const String& sqlStatement, PassRefPtr<ExecuteSQLCallback> requestCallback)
 
154
        : m_sqlStatement(sqlStatement)
 
155
        , m_requestCallback(requestCallback) { }
 
156
    String m_sqlStatement;
 
157
    RefPtr<ExecuteSQLCallback> m_requestCallback;
 
158
};
 
159
 
 
160
class TransactionErrorCallback : public SQLTransactionErrorCallback {
 
161
public:
 
162
    static PassRefPtr<TransactionErrorCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback)
 
163
    {
 
164
        return adoptRef(new TransactionErrorCallback(requestCallback));
 
165
    }
 
166
 
 
167
    virtual ~TransactionErrorCallback() { }
 
168
 
 
169
    virtual bool handleEvent(SQLError* error)
 
170
    {
 
171
        reportTransactionFailed(m_requestCallback.get(), error);
 
172
        return true;
 
173
    }
 
174
private:
 
175
    TransactionErrorCallback(PassRefPtr<ExecuteSQLCallback> requestCallback)
 
176
        : m_requestCallback(requestCallback) { }
 
177
    RefPtr<ExecuteSQLCallback> m_requestCallback;
 
178
};
 
179
 
 
180
class TransactionSuccessCallback : public VoidCallback {
 
181
public:
 
182
    static PassRefPtr<TransactionSuccessCallback> create()
 
183
    {
 
184
        return adoptRef(new TransactionSuccessCallback());
 
185
    }
 
186
 
 
187
    virtual ~TransactionSuccessCallback() { }
 
188
 
 
189
    virtual bool handleEvent() { return false; }
 
190
 
 
191
private:
 
192
    TransactionSuccessCallback() { }
 
193
};
 
194
 
 
195
} // namespace
 
196
 
 
197
void InspectorDatabaseAgent::didOpenDatabase(PassRefPtr<Database> database, const String& domain, const String& name, const String& version)
 
198
{
 
199
    if (InspectorDatabaseResource* resource = findByFileName(database->fileName())) {
 
200
        resource->setDatabase(database);
 
201
        return;
 
202
    }
 
203
 
 
204
    RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(database, domain, name, version);
 
205
    m_resources.set(resource->id(), resource);
 
206
    // Resources are only bound while visible.
 
207
    if (m_frontend && m_enabled)
 
208
        resource->bind(m_frontend);
 
209
}
 
210
 
 
211
void InspectorDatabaseAgent::clearResources()
 
212
{
 
213
    m_resources.clear();
 
214
}
 
215
 
 
216
InspectorDatabaseAgent::InspectorDatabaseAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state)
 
217
    : InspectorBaseAgent<InspectorDatabaseAgent>("Database", instrumentingAgents, state)
 
218
    , m_enabled(false)
 
219
{
 
220
    m_instrumentingAgents->setInspectorDatabaseAgent(this);
 
221
}
 
222
 
 
223
InspectorDatabaseAgent::~InspectorDatabaseAgent()
 
224
{
 
225
    m_instrumentingAgents->setInspectorDatabaseAgent(0);
 
226
}
 
227
 
 
228
void InspectorDatabaseAgent::setFrontend(InspectorFrontend* frontend)
 
229
{
 
230
    m_frontend = frontend->database();
 
231
}
 
232
 
 
233
void InspectorDatabaseAgent::clearFrontend()
 
234
{
 
235
    m_frontend = 0;
 
236
    disable(0);
 
237
}
 
238
 
 
239
void InspectorDatabaseAgent::enable(ErrorString*)
 
240
{
 
241
    if (m_enabled)
 
242
        return;
 
243
    m_enabled = true;
 
244
    m_state->setBoolean(DatabaseAgentState::databaseAgentEnabled, m_enabled);
 
245
 
 
246
    DatabaseResourcesMap::iterator databasesEnd = m_resources.end();
 
247
    for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != databasesEnd; ++it)
 
248
        it->value->bind(m_frontend);
 
249
}
 
250
 
 
251
void InspectorDatabaseAgent::disable(ErrorString*)
 
252
{
 
253
    if (!m_enabled)
 
254
        return;
 
255
    m_enabled = false;
 
256
    m_state->setBoolean(DatabaseAgentState::databaseAgentEnabled, m_enabled);
 
257
}
 
258
 
 
259
void InspectorDatabaseAgent::restore()
 
260
{
 
261
    m_enabled = m_state->getBoolean(DatabaseAgentState::databaseAgentEnabled);
 
262
}
 
263
 
 
264
void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString* error, const String& databaseId, RefPtr<TypeBuilder::Array<String> >& names)
 
265
{
 
266
    if (!m_enabled) {
 
267
        *error = "Database agent is not enabled";
 
268
        return;
 
269
    }
 
270
 
 
271
    names = TypeBuilder::Array<String>::create();
 
272
 
 
273
    Database* database = databaseForId(databaseId);
 
274
    if (database) {
 
275
        Vector<String> tableNames = database->tableNames();
 
276
        unsigned length = tableNames.size();
 
277
        for (unsigned i = 0; i < length; ++i)
 
278
            names->addItem(tableNames[i]);
 
279
    }
 
280
}
 
281
 
 
282
void InspectorDatabaseAgent::executeSQL(ErrorString*, const String& databaseId, const String& query, PassRefPtr<ExecuteSQLCallback> prpRequestCallback)
 
283
{
 
284
    RefPtr<ExecuteSQLCallback> requestCallback = prpRequestCallback;
 
285
 
 
286
    if (!m_enabled) {
 
287
        requestCallback->sendFailure("Database agent is not enabled");
 
288
        return;
 
289
    }
 
290
 
 
291
    Database* database = databaseForId(databaseId);
 
292
    if (!database) {
 
293
        requestCallback->sendFailure("Database not found");
 
294
        return;
 
295
    }
 
296
 
 
297
    RefPtr<SQLTransactionCallback> callback(TransactionCallback::create(query, requestCallback.get()));
 
298
    RefPtr<SQLTransactionErrorCallback> errorCallback(TransactionErrorCallback::create(requestCallback.get()));
 
299
    RefPtr<VoidCallback> successCallback(TransactionSuccessCallback::create());
 
300
    database->transaction(callback.release(), errorCallback.release(), successCallback.release());
 
301
}
 
302
 
 
303
String InspectorDatabaseAgent::databaseId(Database* database)
 
304
{
 
305
    for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) {
 
306
        if (it->value->database() == database)
 
307
            return it->key;
 
308
    }
 
309
    return String();
 
310
}
 
311
 
 
312
InspectorDatabaseResource* InspectorDatabaseAgent::findByFileName(const String& fileName)
 
313
{
 
314
    for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) {
 
315
        if (it->value->database()->fileName() == fileName)
 
316
            return it->value.get();
 
317
    }
 
318
    return 0;
 
319
}
 
320
 
 
321
Database* InspectorDatabaseAgent::databaseForId(const String& databaseId)
 
322
{
 
323
    DatabaseResourcesMap::iterator it = m_resources.find(databaseId);
 
324
    if (it == m_resources.end())
 
325
        return 0;
 
326
    return it->value->database();
 
327
}
 
328
 
 
329
} // namespace WebCore
 
330
 
 
331
#endif // ENABLE(INSPECTOR) && ENABLE(SQL_DATABASE)