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/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 634 } | 634 } |
| 635 | 635 |
| 636 bool Connection::Execute(const char* sql) { | 636 bool Connection::Execute(const char* sql) { |
| 637 if (!db_) { | 637 if (!db_) { |
| 638 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; | 638 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; |
| 639 return false; | 639 return false; |
| 640 } | 640 } |
| 641 | 641 |
| 642 int error = ExecuteAndReturnErrorCode(sql); | 642 int error = ExecuteAndReturnErrorCode(sql); |
| 643 if (error != SQLITE_OK) | 643 if (error != SQLITE_OK) |
| 644 error = OnSqliteError(error, NULL); | 644 error = OnSqliteError(error, NULL, sql); |
| 645 | 645 |
| 646 // This needs to be a FATAL log because the error case of arriving here is | 646 // This needs to be a FATAL log because the error case of arriving here is |
| 647 // that there's a malformed SQL statement. This can arise in development if | 647 // that there's a malformed SQL statement. This can arise in development if |
| 648 // a change alters the schema but not all queries adjust. This can happen | 648 // a change alters the schema but not all queries adjust. This can happen |
| 649 // in production if the schema is corrupted. | 649 // in production if the schema is corrupted. |
| 650 if (error == SQLITE_ERROR) | 650 if (error == SQLITE_ERROR) |
| 651 DLOG(FATAL) << "SQL Error in " << sql << ", " << GetErrorMessage(); | 651 DLOG(FATAL) << "SQL Error in " << sql << ", " << GetErrorMessage(); |
| 652 return error == SQLITE_OK; | 652 return error == SQLITE_OK; |
| 653 } | 653 } |
| 654 | 654 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 695 if (!db_) | 695 if (!db_) |
| 696 return new StatementRef(NULL, NULL, poisoned_); | 696 return new StatementRef(NULL, NULL, poisoned_); |
| 697 | 697 |
| 698 sqlite3_stmt* stmt = NULL; | 698 sqlite3_stmt* stmt = NULL; |
| 699 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); | 699 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); |
| 700 if (rc != SQLITE_OK) { | 700 if (rc != SQLITE_OK) { |
| 701 // This is evidence of a syntax error in the incoming SQL. | 701 // This is evidence of a syntax error in the incoming SQL. |
| 702 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 702 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
| 703 | 703 |
| 704 // It could also be database corruption. | 704 // It could also be database corruption. |
| 705 OnSqliteError(rc, NULL); | 705 OnSqliteError(rc, NULL, sql); |
| 706 return new StatementRef(NULL, NULL, false); | 706 return new StatementRef(NULL, NULL, false); |
| 707 } | 707 } |
| 708 return new StatementRef(this, stmt, true); | 708 return new StatementRef(this, stmt, true); |
| 709 } | 709 } |
| 710 | 710 |
| 711 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( | 711 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( |
| 712 const char* sql) const { | 712 const char* sql) const { |
| 713 // Return inactive statement. | 713 // Return inactive statement. |
| 714 if (!db_) | 714 if (!db_) |
| 715 return new StatementRef(NULL, NULL, poisoned_); | 715 return new StatementRef(NULL, NULL, poisoned_); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 int err = sqlite3_open(file_name.c_str(), &db_); | 857 int err = sqlite3_open(file_name.c_str(), &db_); |
| 858 if (err != SQLITE_OK) { | 858 if (err != SQLITE_OK) { |
| 859 // Extended error codes cannot be enabled until a handle is | 859 // Extended error codes cannot be enabled until a handle is |
| 860 // available, fetch manually. | 860 // available, fetch manually. |
| 861 err = sqlite3_extended_errcode(db_); | 861 err = sqlite3_extended_errcode(db_); |
| 862 | 862 |
| 863 // Histogram failures specific to initial open for debugging | 863 // Histogram failures specific to initial open for debugging |
| 864 // purposes. | 864 // purposes. |
| 865 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.OpenFailure", err); | 865 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.OpenFailure", err); |
| 866 | 866 |
| 867 OnSqliteError(err, NULL); | 867 OnSqliteError(err, NULL, "-- sqlite3_open()"); |
| 868 bool was_poisoned = poisoned_; | 868 bool was_poisoned = poisoned_; |
| 869 Close(); | 869 Close(); |
| 870 | 870 |
| 871 if (was_poisoned && retry_flag == RETRY_ON_POISON) | 871 if (was_poisoned && retry_flag == RETRY_ON_POISON) |
| 872 return OpenInternal(file_name, NO_RETRY); | 872 return OpenInternal(file_name, NO_RETRY); |
| 873 return false; | 873 return false; |
| 874 } | 874 } |
| 875 | 875 |
| 876 // TODO(shess): OS_WIN support? | 876 // TODO(shess): OS_WIN support? |
| 877 #if defined(OS_POSIX) | 877 #if defined(OS_POSIX) |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 // issue, the object could be cached alongside histogram_prefix_. | 1015 // issue, the object could be cached alongside histogram_prefix_. |
| 1016 std::string full_histogram_name = name + "." + histogram_tag_; | 1016 std::string full_histogram_name = name + "." + histogram_tag_; |
| 1017 base::HistogramBase* histogram = | 1017 base::HistogramBase* histogram = |
| 1018 base::SparseHistogram::FactoryGet( | 1018 base::SparseHistogram::FactoryGet( |
| 1019 full_histogram_name, | 1019 full_histogram_name, |
| 1020 base::HistogramBase::kUmaTargetedHistogramFlag); | 1020 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 1021 if (histogram) | 1021 if (histogram) |
| 1022 histogram->Add(sample); | 1022 histogram->Add(sample); |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 int Connection::OnSqliteError(int err, sql::Statement *stmt) { | 1025 int Connection::OnSqliteError(int err, sql::Statement *stmt, const char* sql) { |
| 1026 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.Error", err); | 1026 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.Error", err); |
| 1027 AddTaggedHistogram("Sqlite.Error", err); | 1027 AddTaggedHistogram("Sqlite.Error", err); |
| 1028 | 1028 |
| 1029 // Always log the error. | 1029 // Always log the error. |
| 1030 LOG(ERROR) << "sqlite error " << err | 1030 LOG(ERROR) << histogram_tag_ << " sqlite error " << err |
| 1031 << ", errno " << GetLastErrno() | 1031 << ", errno " << GetLastErrno() |
| 1032 << ": " << GetErrorMessage(); | 1032 << ": " << GetErrorMessage(); |
| 1033 | 1033 |
| 1034 // Also log the relevant sql statement, if possible. | |
| 1035 if (!sql && stmt) | |
| 1036 sql = stmt->GetSQLStatement(); | |
| 1037 if (sql) | |
| 1038 LOG(ERROR) << "sql: " << sql; | |
|
Greg Spencer (Chromium)
2013/09/25 20:01:18
nits: You might want to also output "sqlite error"
Scott Hess - ex-Googler
2013/09/25 20:22:36
I'm moving it up to the same line, just to be safe
| |
| 1039 | |
| 1034 if (!error_callback_.is_null()) { | 1040 if (!error_callback_.is_null()) { |
| 1035 // Fire from a copy of the callback in case of reentry into | 1041 // Fire from a copy of the callback in case of reentry into |
| 1036 // re/set_error_callback(). | 1042 // re/set_error_callback(). |
| 1037 // TODO(shess): <http://crbug.com/254584> | 1043 // TODO(shess): <http://crbug.com/254584> |
| 1038 ErrorCallback(error_callback_).Run(err, stmt); | 1044 ErrorCallback(error_callback_).Run(err, stmt); |
| 1039 return err; | 1045 return err; |
| 1040 } | 1046 } |
| 1041 | 1047 |
| 1042 // The default handling is to assert on debug and to ignore on release. | 1048 // The default handling is to assert on debug and to ignore on release. |
| 1043 if (!ShouldIgnore(err)) | 1049 if (!ShouldIgnore(err)) |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1074 } | 1080 } |
| 1075 | 1081 |
| 1076 // Best effort to put things back as they were before. | 1082 // Best effort to put things back as they were before. |
| 1077 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; | 1083 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; |
| 1078 ignore_result(Execute(kNoWritableSchema)); | 1084 ignore_result(Execute(kNoWritableSchema)); |
| 1079 | 1085 |
| 1080 return ret; | 1086 return ret; |
| 1081 } | 1087 } |
| 1082 | 1088 |
| 1083 } // namespace sql | 1089 } // namespace sql |
| OLD | NEW |