2010-12-29 Pavel Feldman <pfeldman@chromium.org>
[WebKit-https.git] / WebCore / inspector / InspectorStorageAgent.cpp
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 #include "InspectorStorageAgent.h"
32
33 #if ENABLE(INSPECTOR) && ENABLE(DATABASE)
34
35 #include "Database.h"
36 #include "ExceptionCode.h"
37 #include "InspectorFrontend.h"
38 #include "InspectorValues.h"
39 #include "SQLError.h"
40 #include "SQLStatementCallback.h"
41 #include "SQLStatementErrorCallback.h"
42 #include "SQLResultSetRowList.h"
43 #include "SQLTransaction.h"
44 #include "SQLTransactionCallback.h"
45 #include "SQLTransactionErrorCallback.h"
46 #include "SQLValue.h"
47 #include "VoidCallback.h"
48
49 #include <wtf/Vector.h>
50
51 namespace WebCore {
52
53 namespace {
54
55 long lastTransactionId = 0;
56
57 void reportTransactionFailed(InspectorStorageAgent* agent, long transactionId, SQLError* error)
58 {
59     if (!agent->frontend())
60         return;
61     RefPtr<InspectorObject> errorObject = InspectorObject::create();
62     errorObject->setString("message", error->message());
63     errorObject->setNumber("code", error->code());
64     agent->frontend()->sqlTransactionFailed(transactionId, errorObject);
65 }
66
67 class StatementCallback : public SQLStatementCallback {
68 public:
69     static PassRefPtr<StatementCallback> create(long transactionId, PassRefPtr<InspectorStorageAgent> agent)
70     {
71         return adoptRef(new StatementCallback(transactionId, agent));
72     }
73
74     virtual ~StatementCallback() { }
75
76     virtual bool handleEvent(SQLTransaction*, SQLResultSet* resultSet)
77     {
78         if (!m_agent->frontend())
79             return true;
80
81         SQLResultSetRowList* rowList = resultSet->rows();
82
83         RefPtr<InspectorArray> columnNames = InspectorArray::create();
84         const Vector<String>& columns = rowList->columnNames();
85         for (size_t i = 0; i < columns.size(); ++i)
86             columnNames->pushString(columns[i]);
87
88         RefPtr<InspectorArray> values = InspectorArray::create();
89         const Vector<SQLValue>& data = rowList->values();
90         for (size_t i = 0; i < data.size(); ++i) {
91             const SQLValue& value = rowList->values()[i];
92             switch (value.type()) {
93                 case SQLValue::StringValue: values->pushString(value.string()); break;
94                 case SQLValue::NumberValue: values->pushNumber(value.number()); break;
95                 case SQLValue::NullValue: values->pushValue(InspectorValue::null()); break;
96             }
97         }
98         m_agent->frontend()->sqlTransactionSucceeded(m_transactionId, columnNames, values);
99         return true;
100     }
101
102 private:
103     StatementCallback(long transactionId, PassRefPtr<InspectorStorageAgent> agent)
104         : m_transactionId(transactionId)
105         , m_agent(agent) { }
106     long m_transactionId;
107     RefPtr<InspectorStorageAgent> m_agent;
108 };
109
110 class StatementErrorCallback : public SQLStatementErrorCallback {
111 public:
112     static PassRefPtr<StatementErrorCallback> create(long transactionId, PassRefPtr<InspectorStorageAgent> agent)
113     {
114         return adoptRef(new StatementErrorCallback(transactionId, agent));
115     }
116
117     virtual ~StatementErrorCallback() { }
118
119     virtual bool handleEvent(SQLTransaction*, SQLError* error)
120     {
121         reportTransactionFailed(m_agent.get(), m_transactionId, error);
122         return true;  
123     }
124
125 private:
126     StatementErrorCallback(long transactionId, RefPtr<InspectorStorageAgent> agent)
127         : m_transactionId(transactionId)
128         , m_agent(agent) { }
129     long m_transactionId;
130     RefPtr<InspectorStorageAgent> m_agent;
131 };
132
133 class TransactionCallback : public SQLTransactionCallback {
134 public:
135     static PassRefPtr<TransactionCallback> create(const String& sqlStatement, long transactionId, PassRefPtr<InspectorStorageAgent> agent)
136     {
137         return adoptRef(new TransactionCallback(sqlStatement, transactionId, agent));
138     }
139
140     virtual ~TransactionCallback() { }
141
142     virtual bool handleEvent(SQLTransaction* transaction)
143     {
144         if (!m_agent->frontend())
145             return true;
146
147         Vector<SQLValue> sqlValues;
148         RefPtr<SQLStatementCallback> callback(StatementCallback::create(m_transactionId, m_agent));
149         RefPtr<SQLStatementErrorCallback> errorCallback(StatementErrorCallback::create(m_transactionId, m_agent));
150         ExceptionCode ec = 0;
151         transaction->executeSQL(m_sqlStatement, sqlValues, callback.release(), errorCallback.release(), ec);
152         return true;
153     }
154 private:
155     TransactionCallback(const String& sqlStatement, long transactionId, PassRefPtr<InspectorStorageAgent> agent)
156         : m_sqlStatement(sqlStatement)
157         , m_transactionId(transactionId)
158         , m_agent(agent) { }
159     String m_sqlStatement;
160     long m_transactionId;
161     RefPtr<InspectorStorageAgent> m_agent;
162 };
163
164 class TransactionErrorCallback : public SQLTransactionErrorCallback {
165 public:
166     static PassRefPtr<TransactionErrorCallback> create(long transactionId, PassRefPtr<InspectorStorageAgent> agent)
167     {
168         return adoptRef(new TransactionErrorCallback(transactionId, agent));
169     }
170
171     virtual ~TransactionErrorCallback() { }
172
173     virtual bool handleEvent(SQLError* error)
174     {
175         reportTransactionFailed(m_agent.get(), m_transactionId, error);
176         return true;
177     }
178 private:
179     TransactionErrorCallback(long transactionId, PassRefPtr<InspectorStorageAgent> agent)
180         : m_transactionId(transactionId)
181         , m_agent(agent) { }
182     long m_transactionId;
183     RefPtr<InspectorStorageAgent> m_agent;
184 };
185
186 class TransactionSuccessCallback : public VoidCallback {
187 public:
188     static PassRefPtr<TransactionSuccessCallback> create()
189     {
190         return adoptRef(new TransactionSuccessCallback());
191     }
192
193     virtual ~TransactionSuccessCallback() { }
194
195     virtual void handleEvent() { }
196
197 private:
198     TransactionSuccessCallback() { }
199 };
200
201 } // namespace
202
203 InspectorStorageAgent::InspectorStorageAgent(InspectorFrontend* frontend)
204     : m_frontend(frontend)
205 {
206 }
207
208 InspectorStorageAgent::~InspectorStorageAgent()
209 {
210 }
211
212 long InspectorStorageAgent::executeSQL(Database* database, const String& query)
213 {
214     long transactionId = ++lastTransactionId;
215     RefPtr<SQLTransactionCallback> callback(TransactionCallback::create(query, transactionId, this));
216     RefPtr<SQLTransactionErrorCallback> errorCallback(TransactionErrorCallback::create(transactionId, this));
217     RefPtr<VoidCallback> successCallback(TransactionSuccessCallback::create());
218     database->transaction(callback.release(), errorCallback.release(), successCallback.release());
219     return transactionId;
220 }
221
222 void InspectorStorageAgent::clearFrontend()
223 {
224     m_frontend = 0;
225 }
226
227 } // namespace WebCore
228
229 #endif // ENABLE(INSPECTOR) && ENABLE(DATABASE)