1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/web_database_observer_impl.h"
7 #include "base/metrics/histogram.h"
8 #include "base/strings/string16.h"
9 #include "content/common/database_messages.h"
10 #include "third_party/WebKit/public/platform/WebCString.h"
11 #include "third_party/WebKit/public/platform/WebString.h"
12 #include "third_party/sqlite/sqlite3.h"
14 using blink::WebString
;
20 const int kResultHistogramSize
= 50;
21 const int kCallsiteHistogramSize
= 10;
23 int DetermineHistogramResult(int websql_error
, int sqlite_error
) {
24 // If we have a sqlite error, log it after trimming the extended bits.
25 // There are 26 possible values, but we leave room for some new ones.
27 return std::min(sqlite_error
& 0xff, 30);
29 // Otherwise, websql_error may be an SQLExceptionCode, SQLErrorCode
30 // or a DOMExceptionCode, or -1 for success.
31 if (websql_error
== -1)
34 // SQLExceptionCode starts at 1000
35 if (websql_error
>= 1000)
38 return std::min(websql_error
+ 30, kResultHistogramSize
- 1);
41 #define HISTOGRAM_WEBSQL_RESULT(name, is_sync_database, \
42 callsite, websql_error, sqlite_error) \
44 DCHECK(callsite < kCallsiteHistogramSize); \
45 int result = DetermineHistogramResult(websql_error, sqlite_error); \
46 if (is_sync_database) { \
47 UMA_HISTOGRAM_ENUMERATION("websql.Sync." name, \
48 result, kResultHistogramSize); \
50 UMA_HISTOGRAM_ENUMERATION("websql.Sync." name ".ErrorSite", \
51 callsite, kCallsiteHistogramSize); \
54 UMA_HISTOGRAM_ENUMERATION("websql.Async." name, \
55 result, kResultHistogramSize); \
57 UMA_HISTOGRAM_ENUMERATION("websql.Async." name ".ErrorSite", \
58 callsite, kCallsiteHistogramSize); \
65 WebDatabaseObserverImpl::WebDatabaseObserverImpl(
66 IPC::SyncMessageFilter
* sender
)
68 open_connections_(new webkit_database::DatabaseConnectionsWrapper
) {
72 WebDatabaseObserverImpl::~WebDatabaseObserverImpl() {
75 void WebDatabaseObserverImpl::databaseOpened(
76 const WebString
& origin_identifier
,
77 const WebString
& database_name
,
78 const WebString
& database_display_name
,
79 unsigned long estimated_size
) {
80 open_connections_
->AddOpenConnection(origin_identifier
.utf8(),
82 sender_
->Send(new DatabaseHostMsg_Opened(
83 origin_identifier
.utf8(), database_name
,
84 database_display_name
, estimated_size
));
87 void WebDatabaseObserverImpl::databaseModified(
88 const WebString
& origin_identifier
,
89 const WebString
& database_name
) {
90 sender_
->Send(new DatabaseHostMsg_Modified(
91 origin_identifier
.utf8(), database_name
));
94 void WebDatabaseObserverImpl::databaseClosed(
95 const WebString
& origin_identifier
,
96 const WebString
& database_name
) {
97 sender_
->Send(new DatabaseHostMsg_Closed(
98 origin_identifier
.utf8(), database_name
));
99 open_connections_
->RemoveOpenConnection(origin_identifier
.utf8(),
103 void WebDatabaseObserverImpl::reportOpenDatabaseResult(
104 const WebString
& origin_identifier
,
105 const WebString
& database_name
,
106 bool is_sync_database
,
107 int callsite
, int websql_error
, int sqlite_error
) {
108 HISTOGRAM_WEBSQL_RESULT("OpenResult", is_sync_database
,
109 callsite
, websql_error
, sqlite_error
);
110 HandleSqliteError(origin_identifier
, database_name
, sqlite_error
);
113 void WebDatabaseObserverImpl::reportChangeVersionResult(
114 const WebString
& origin_identifier
,
115 const WebString
& database_name
,
116 bool is_sync_database
,
117 int callsite
, int websql_error
, int sqlite_error
) {
118 HISTOGRAM_WEBSQL_RESULT("ChangeVersionResult", is_sync_database
,
119 callsite
, websql_error
, sqlite_error
);
120 HandleSqliteError(origin_identifier
, database_name
, sqlite_error
);
123 void WebDatabaseObserverImpl::reportStartTransactionResult(
124 const WebString
& origin_identifier
,
125 const WebString
& database_name
,
126 bool is_sync_database
,
127 int callsite
, int websql_error
, int sqlite_error
) {
128 HISTOGRAM_WEBSQL_RESULT("BeginResult", is_sync_database
,
129 callsite
, websql_error
, sqlite_error
);
130 HandleSqliteError(origin_identifier
, database_name
, sqlite_error
);
133 void WebDatabaseObserverImpl::reportCommitTransactionResult(
134 const WebString
& origin_identifier
,
135 const WebString
& database_name
,
136 bool is_sync_database
,
137 int callsite
, int websql_error
, int sqlite_error
) {
138 HISTOGRAM_WEBSQL_RESULT("CommitResult", is_sync_database
,
139 callsite
, websql_error
, sqlite_error
);
140 HandleSqliteError(origin_identifier
, database_name
, sqlite_error
);
143 void WebDatabaseObserverImpl::reportExecuteStatementResult(
144 const WebString
& origin_identifier
,
145 const WebString
& database_name
,
146 bool is_sync_database
,
147 int callsite
, int websql_error
, int sqlite_error
) {
148 HISTOGRAM_WEBSQL_RESULT("StatementResult", is_sync_database
,
149 callsite
, websql_error
, sqlite_error
);
150 HandleSqliteError(origin_identifier
, database_name
, sqlite_error
);
153 void WebDatabaseObserverImpl::reportVacuumDatabaseResult(
154 const WebString
& origin_identifier
,
155 const WebString
& database_name
,
156 bool is_sync_database
,
158 int result
= DetermineHistogramResult(-1, sqlite_error
);
159 if (is_sync_database
) {
160 UMA_HISTOGRAM_ENUMERATION("websql.Sync.VacuumResult",
161 result
, kResultHistogramSize
);
163 UMA_HISTOGRAM_ENUMERATION("websql.Async.VacuumResult",
164 result
, kResultHistogramSize
);
166 HandleSqliteError(origin_identifier
, database_name
, sqlite_error
);
169 void WebDatabaseObserverImpl::WaitForAllDatabasesToClose() {
170 open_connections_
->WaitForAllDatabasesToClose();
173 void WebDatabaseObserverImpl::HandleSqliteError(
174 const WebString
& origin_identifier
,
175 const WebString
& database_name
,
177 // We filter out errors which the backend doesn't act on to avoid
178 // a unnecessary ipc traffic, this method can get called at a fairly
179 // high frequency (per-sqlstatement).
180 if (error
== SQLITE_CORRUPT
|| error
== SQLITE_NOTADB
) {
181 sender_
->Send(new DatabaseHostMsg_HandleSqliteError(
182 origin_identifier
.utf8(),
188 } // namespace content