web_database_observer_impl.cc revision f2477e01787aa58f445919b809d89e252beef54f
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/web_database_observer_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/database_messages.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCString.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/sqlite/sqlite3.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kResultHistogramSize = 50;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCallsiteHistogramSize = 10;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DetermineHistogramResult(int websql_error, int sqlite_error) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we have a sqlite error, log it after trimming the extended bits.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are 26 possible values, but we leave room for some new ones.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sqlite_error)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::min(sqlite_error & 0xff, 30);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Otherwise, websql_error may be an SQLExceptionCode, SQLErrorCode
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or a DOMExceptionCode, or -1 for success.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (websql_error == -1)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;  // no error
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SQLExceptionCode starts at 1000
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (websql_error >= 1000)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    websql_error -= 1000;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::min(websql_error + 30, kResultHistogramSize - 1);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define HISTOGRAM_WEBSQL_RESULT(name, is_sync_database, \
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                callsite, websql_error, sqlite_error) \
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(callsite < kCallsiteHistogramSize); \
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result = DetermineHistogramResult(websql_error, sqlite_error); \
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (is_sync_database) { \
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("websql.Sync." name, \
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result, kResultHistogramSize); \
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (result) { \
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("websql.Sync." name ".ErrorSite", \
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  callsite, kCallsiteHistogramSize); \
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } \
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else { \
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("websql.Async." name, \
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result, kResultHistogramSize); \
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (result) { \
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("websql.Async." name ".ErrorSite", \
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  callsite, kCallsiteHistogramSize); \
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } \
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } \
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebDatabaseObserverImpl::WebDatabaseObserverImpl(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::SyncMessageFilter* sender)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sender_(sender),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      open_connections_(new webkit_database::DatabaseConnectionsWrapper) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sender);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebDatabaseObserverImpl::~WebDatabaseObserverImpl() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::databaseOpened(
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_display_name,
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned long estimated_size) {
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  open_connections_->AddOpenConnection(origin_identifier.utf8(),
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       database_name);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new DatabaseHostMsg_Opened(
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_identifier.utf8(), database_name,
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      database_display_name, estimated_size));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::databaseModified(
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new DatabaseHostMsg_Modified(
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_identifier.utf8(), database_name));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::databaseClosed(
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sender_->Send(new DatabaseHostMsg_Closed(
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_identifier.utf8(), database_name));
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  open_connections_->RemoveOpenConnection(origin_identifier.utf8(),
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          database_name);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::reportOpenDatabaseResult(
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_sync_database,
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int callsite, int websql_error, int sqlite_error) {
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HISTOGRAM_WEBSQL_RESULT("OpenResult", is_sync_database,
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          callsite, websql_error, sqlite_error);
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleSqliteError(origin_identifier, database_name, sqlite_error);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::reportChangeVersionResult(
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_sync_database,
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int callsite, int websql_error, int sqlite_error) {
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HISTOGRAM_WEBSQL_RESULT("ChangeVersionResult", is_sync_database,
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          callsite, websql_error, sqlite_error);
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleSqliteError(origin_identifier, database_name, sqlite_error);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::reportStartTransactionResult(
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_sync_database,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int callsite, int websql_error, int sqlite_error) {
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HISTOGRAM_WEBSQL_RESULT("BeginResult", is_sync_database,
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          callsite, websql_error, sqlite_error);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleSqliteError(origin_identifier, database_name, sqlite_error);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::reportCommitTransactionResult(
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_sync_database,
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int callsite, int websql_error, int sqlite_error) {
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HISTOGRAM_WEBSQL_RESULT("CommitResult", is_sync_database,
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          callsite, websql_error, sqlite_error);
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleSqliteError(origin_identifier, database_name, sqlite_error);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::reportExecuteStatementResult(
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_sync_database,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int callsite, int websql_error, int sqlite_error) {
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HISTOGRAM_WEBSQL_RESULT("StatementResult", is_sync_database,
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          callsite, websql_error, sqlite_error);
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleSqliteError(origin_identifier, database_name, sqlite_error);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::reportVacuumDatabaseResult(
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_sync_database,
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int sqlite_error) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = DetermineHistogramResult(-1, sqlite_error);
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (is_sync_database) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("websql.Sync.VacuumResult",
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              result, kResultHistogramSize);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("websql.Async.VacuumResult",
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              result, kResultHistogramSize);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleSqliteError(origin_identifier, database_name, sqlite_error);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::WaitForAllDatabasesToClose() {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  open_connections_->WaitForAllDatabasesToClose();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebDatabaseObserverImpl::HandleSqliteError(
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& origin_identifier,
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const WebString& database_name,
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int error) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We filter out errors which the backend doesn't act on to avoid
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a unnecessary ipc traffic, this method can get called at a fairly
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // high frequency (per-sqlstatement).
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sender_->Send(new DatabaseHostMsg_HandleSqliteError(
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        origin_identifier.utf8(),
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        database_name,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        error));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
189