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/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 const char* sql) { | 717 const char* sql) { |
718 AssertIOAllowed(); | 718 AssertIOAllowed(); |
719 | 719 |
720 // Return inactive statement. | 720 // Return inactive statement. |
721 if (!db_) | 721 if (!db_) |
722 return new StatementRef(NULL, NULL, poisoned_); | 722 return new StatementRef(NULL, NULL, poisoned_); |
723 | 723 |
724 sqlite3_stmt* stmt = NULL; | 724 sqlite3_stmt* stmt = NULL; |
725 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); | 725 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); |
726 if (rc != SQLITE_OK) { | 726 if (rc != SQLITE_OK) { |
727 // This is evidence of a syntax error in the incoming SQL. | 727 // This is evidence of a syntax error in the incoming SQL. |
maniscalco
2015/04/08 22:40:27
I'm thinking about this comment and the one in Get
Scott Hess - ex-Googler
2015/04/08 22:49:20
Maybe, it depends. Corruption can cause almost an
maniscalco
2015/04/09 15:11:08
That makes sense to me.
| |
728 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 728 DLOG_IF(FATAL, !ShouldIgnoreSqliteError(rc)) |
maniscalco
2015/04/09 20:40:52
I just realized that ShouldIgnoreSqliteError is no
Scott Hess - ex-Googler
2015/04/09 20:46:30
At this site, OnSqliteError() should call ShouldIg
| |
729 << "SQL compile error " << GetErrorMessage(); | |
729 | 730 |
730 // It could also be database corruption. | 731 // It could also be database corruption. |
731 OnSqliteError(rc, NULL, sql); | 732 OnSqliteError(rc, NULL, sql); |
732 return new StatementRef(NULL, NULL, false); | 733 return new StatementRef(NULL, NULL, false); |
733 } | 734 } |
734 return new StatementRef(this, stmt, true); | 735 return new StatementRef(this, stmt, true); |
735 } | 736 } |
736 | 737 |
737 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( | 738 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( |
738 const char* sql) const { | 739 const char* sql) const { |
739 // Return inactive statement. | 740 // Return inactive statement. |
740 if (!db_) | 741 if (!db_) |
741 return new StatementRef(NULL, NULL, poisoned_); | 742 return new StatementRef(NULL, NULL, poisoned_); |
742 | 743 |
743 sqlite3_stmt* stmt = NULL; | 744 sqlite3_stmt* stmt = NULL; |
744 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); | 745 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); |
745 if (rc != SQLITE_OK) { | 746 if (rc != SQLITE_OK) { |
746 // This is evidence of a syntax error in the incoming SQL. | 747 // This is evidence of a syntax error in the incoming SQL. |
747 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 748 DLOG_IF(FATAL, !ShouldIgnoreSqliteError(rc)) |
749 << "SQL compile error " << GetErrorMessage(); | |
748 return new StatementRef(NULL, NULL, false); | 750 return new StatementRef(NULL, NULL, false); |
749 } | 751 } |
750 return new StatementRef(NULL, stmt, true); | 752 return new StatementRef(NULL, stmt, true); |
751 } | 753 } |
752 | 754 |
753 std::string Connection::GetSchema() const { | 755 std::string Connection::GetSchema() const { |
754 // The ORDER BY should not be necessary, but relying on organic | 756 // The ORDER BY should not be necessary, but relying on organic |
755 // order for something like this is questionable. | 757 // order for something like this is questionable. |
756 const char* kSql = | 758 const char* kSql = |
757 "SELECT type, name, tbl_name, sql " | 759 "SELECT type, name, tbl_name, sql " |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
791 bool Connection::DoesTableExist(const char* table_name) const { | 793 bool Connection::DoesTableExist(const char* table_name) const { |
792 return DoesTableOrIndexExist(table_name, "table"); | 794 return DoesTableOrIndexExist(table_name, "table"); |
793 } | 795 } |
794 | 796 |
795 bool Connection::DoesIndexExist(const char* index_name) const { | 797 bool Connection::DoesIndexExist(const char* index_name) const { |
796 return DoesTableOrIndexExist(index_name, "index"); | 798 return DoesTableOrIndexExist(index_name, "index"); |
797 } | 799 } |
798 | 800 |
799 bool Connection::DoesTableOrIndexExist( | 801 bool Connection::DoesTableOrIndexExist( |
800 const char* name, const char* type) const { | 802 const char* name, const char* type) const { |
801 const char* kSql = "SELECT name FROM sqlite_master WHERE type=? AND name=?"; | 803 const char* kSql = |
804 "SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE"; | |
802 Statement statement(GetUntrackedStatement(kSql)); | 805 Statement statement(GetUntrackedStatement(kSql)); |
806 | |
807 // This can happen if the database is corrupt and the error is being ignored | |
808 // for testing purposes. | |
809 if (!statement.is_valid()) | |
810 return false; | |
811 | |
803 statement.BindString(0, type); | 812 statement.BindString(0, type); |
804 statement.BindString(1, name); | 813 statement.BindString(1, name); |
805 | 814 |
806 return statement.Step(); // Table exists if any row was returned. | 815 return statement.Step(); // Table exists if any row was returned. |
807 } | 816 } |
808 | 817 |
809 bool Connection::DoesColumnExist(const char* table_name, | 818 bool Connection::DoesColumnExist(const char* table_name, |
810 const char* column_name) const { | 819 const char* column_name) const { |
811 std::string sql("PRAGMA TABLE_INFO("); | 820 std::string sql("PRAGMA TABLE_INFO("); |
812 sql.append(table_name); | 821 sql.append(table_name); |
813 sql.append(")"); | 822 sql.append(")"); |
814 | 823 |
815 Statement statement(GetUntrackedStatement(sql.c_str())); | 824 Statement statement(GetUntrackedStatement(sql.c_str())); |
825 | |
826 // This can happen if the database is corrupt and the error is being ignored | |
827 // for testing purposes. | |
828 if (!statement.is_valid()) | |
829 return false; | |
830 | |
816 while (statement.Step()) { | 831 while (statement.Step()) { |
817 if (!statement.ColumnString(1).compare(column_name)) | 832 if (!base::strcasecmp(statement.ColumnString(1).c_str(), column_name)) |
818 return true; | 833 return true; |
819 } | 834 } |
820 return false; | 835 return false; |
821 } | 836 } |
822 | 837 |
823 int64 Connection::GetLastInsertRowId() const { | 838 int64 Connection::GetLastInsertRowId() const { |
824 if (!db_) { | 839 if (!db_) { |
825 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; | 840 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; |
826 return 0; | 841 return 0; |
827 } | 842 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1116 } | 1131 } |
1117 | 1132 |
1118 // Best effort to put things back as they were before. | 1133 // Best effort to put things back as they were before. |
1119 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; | 1134 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; |
1120 ignore_result(Execute(kNoWritableSchema)); | 1135 ignore_result(Execute(kNoWritableSchema)); |
1121 | 1136 |
1122 return ret; | 1137 return ret; |
1123 } | 1138 } |
1124 | 1139 |
1125 } // namespace sql | 1140 } // namespace sql |
OLD | NEW |