Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sql/connection.h" | 5 #include "sql/connection.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/metrics/sparse_histogram.h" | |
| 12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 13 #include "base/stringprintf.h" | 14 #include "base/stringprintf.h" |
| 14 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 15 #include "sql/statement.h" | 16 #include "sql/statement.h" |
| 16 #include "third_party/sqlite/sqlite3.h" | 17 #include "third_party/sqlite/sqlite3.h" |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 // Spin for up to a second waiting for the lock to clear when setting | 21 // Spin for up to a second waiting for the lock to clear when setting |
| 21 // up the database. | 22 // up the database. |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 } | 702 } |
| 702 | 703 |
| 703 void Connection::StatementRefDeleted(StatementRef* ref) { | 704 void Connection::StatementRefDeleted(StatementRef* ref) { |
| 704 StatementRefSet::iterator i = open_statements_.find(ref); | 705 StatementRefSet::iterator i = open_statements_.find(ref); |
| 705 if (i == open_statements_.end()) | 706 if (i == open_statements_.end()) |
| 706 DLOG(FATAL) << "Could not find statement"; | 707 DLOG(FATAL) << "Could not find statement"; |
| 707 else | 708 else |
| 708 open_statements_.erase(i); | 709 open_statements_.erase(i); |
| 709 } | 710 } |
| 710 | 711 |
| 712 void Connection::AddSparseHistogram(const std::string& suffix, | |
| 713 size_t sample) const { | |
| 714 if (histogram_prefix_.empty()) | |
| 715 return; | |
| 716 | |
| 717 // TODO(shess): The histogram macros create a bit of static | |
| 718 // storage for caching the histogram object. Since SQLite is | |
| 719 // being used for I/O, generally without error, this code | |
| 720 // shouldn't execute often enough for such caching to be crucial. | |
| 721 // If it becomes an issue, the object could be cached alongside | |
| 722 // histogram_prefix_. | |
| 723 std::string full_histogram_name = histogram_prefix_ + suffix; | |
| 724 base::HistogramBase* histogram = | |
| 725 base::SparseHistogram::FactoryGet( | |
| 726 full_histogram_name, | |
| 727 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 728 if (histogram) | |
| 729 histogram->Add(sample); | |
| 730 } | |
| 731 | |
| 711 int Connection::OnSqliteError(int err, sql::Statement *stmt) { | 732 int Connection::OnSqliteError(int err, sql::Statement *stmt) { |
| 733 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.ExtendedError", err); | |
| 734 AddSparseHistogram(".ExtendedError", err); | |
| 735 | |
| 736 // TODO(shess): Use of linear histograms predates existence of | |
| 737 // sparse histograms. Remove the .Error histograms once the | |
|
jar (doing other things)
2013/05/13 22:05:59
I think you can nicely get away with using the exi
Scott Hess - ex-Googler
2013/05/13 22:43:08
Done.
| |
| 738 // .ExtendedError histograms have reached stable. | |
| 739 | |
| 712 // Strip extended error codes. | 740 // Strip extended error codes. |
| 713 int base_err = err&0xff; | 741 int base_err = err&0xff; |
| 714 | 742 |
| 715 static size_t kSqliteErrorMax = 50; | 743 static size_t kSqliteErrorMax = 50; |
| 716 UMA_HISTOGRAM_ENUMERATION("Sqlite.Error", base_err, kSqliteErrorMax); | 744 UMA_HISTOGRAM_ENUMERATION("Sqlite.Error", base_err, kSqliteErrorMax); |
| 717 if (base_err == SQLITE_IOERR) { | |
| 718 // TODO(shess): Consider folding the IOERR range into the main | |
| 719 // histogram directly. Perhaps 30..49? The downside risk would | |
| 720 // be that SQLite core adds a bunch of codes and this becomes a | |
| 721 // complicated mapping. | |
| 722 static size_t kSqliteIOErrorMax = 20; | |
| 723 UMA_HISTOGRAM_ENUMERATION("Sqlite.Error.IOERR", err>>8, kSqliteIOErrorMax); | |
| 724 } | |
| 725 | 745 |
| 726 if (!error_histogram_name_.empty()) { | 746 if (!histogram_prefix_.empty()) { |
| 727 // TODO(shess): The histogram macros create a bit of static | 747 // TODO(shess): The histogram macros create a bit of static |
| 728 // storage for caching the histogram object. Since SQLite is | 748 // storage for caching the histogram object. Since SQLite is |
| 729 // being used for I/O, generally without error, this code | 749 // being used for I/O, generally without error, this code |
| 730 // shouldn't execute often enough for such caching to be crucial. | 750 // shouldn't execute often enough for such caching to be crucial. |
| 731 // If it becomes an issue, the object could be cached alongside | 751 // If it becomes an issue, the object could be cached alongside |
| 732 // error_histogram_name_. | 752 // error_histogram_name_. |
| 753 std::string error_histogram_name = histogram_prefix_ + ".Error"; | |
| 733 base::HistogramBase* histogram = | 754 base::HistogramBase* histogram = |
| 734 base::LinearHistogram::FactoryGet( | 755 base::LinearHistogram::FactoryGet( |
| 735 error_histogram_name_, 1, kSqliteErrorMax, kSqliteErrorMax + 1, | 756 error_histogram_name, 1, kSqliteErrorMax, kSqliteErrorMax + 1, |
| 736 base::HistogramBase::kUmaTargetedHistogramFlag); | 757 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 737 if (histogram) | 758 if (histogram) |
| 738 histogram->Add(base_err); | 759 histogram->Add(base_err); |
| 739 } | 760 } |
| 740 | 761 |
| 741 // Always log the error. | 762 // Always log the error. |
| 742 LOG(ERROR) << "sqlite error " << err | 763 LOG(ERROR) << "sqlite error " << err |
| 743 << ", errno " << GetLastErrno() | 764 << ", errno " << GetLastErrno() |
| 744 << ": " << GetErrorMessage(); | 765 << ": " << GetErrorMessage(); |
| 745 | 766 |
| 746 if (error_delegate_.get()) | 767 if (error_delegate_.get()) |
| 747 return error_delegate_->OnError(err, this, stmt); | 768 return error_delegate_->OnError(err, this, stmt); |
| 748 | 769 |
| 749 // The default handling is to assert on debug and to ignore on release. | 770 // The default handling is to assert on debug and to ignore on release. |
| 750 DLOG(FATAL) << GetErrorMessage(); | 771 DLOG(FATAL) << GetErrorMessage(); |
| 751 return err; | 772 return err; |
| 752 } | 773 } |
| 753 | 774 |
| 754 } // namespace sql | 775 } // namespace sql |
| OLD | NEW |