| 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 <limits.h> | 7 #include <limits.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 #elif defined(OS_POSIX) | 221 #elif defined(OS_POSIX) |
| 222 return path.value(); | 222 return path.value(); |
| 223 #endif | 223 #endif |
| 224 } | 224 } |
| 225 | 225 |
| 226 } // namespace | 226 } // namespace |
| 227 | 227 |
| 228 namespace sql { | 228 namespace sql { |
| 229 | 229 |
| 230 // static | 230 // static |
| 231 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL; | 231 Connection::ErrorExpecterCallback* Connection::current_expecter_cb_ = NULL; |
| 232 | 232 |
| 233 // static | 233 // static |
| 234 bool Connection::ShouldIgnoreSqliteError(int error) { | 234 bool Connection::IsExpectedSqliteError(int error) { |
| 235 if (!current_ignorer_cb_) | 235 if (!current_expecter_cb_) |
| 236 return false; | 236 return false; |
| 237 return current_ignorer_cb_->Run(error); | 237 return current_expecter_cb_->Run(error); |
| 238 } | 238 } |
| 239 | 239 |
| 240 // static | 240 // static |
| 241 bool Connection::ShouldIgnoreSqliteCompileError(int error) { | 241 bool Connection::IsExpectedSqliteCompileError(int error) { |
| 242 // Put this first in case tests need to see that the check happened. | 242 // Put this first in case tests need to see that the check happened. |
| 243 if (ShouldIgnoreSqliteError(error)) | 243 if (IsExpectedSqliteError(error)) |
| 244 return true; | 244 return true; |
| 245 | 245 |
| 246 // Trim extended error codes. | 246 // Trim extended error codes. |
| 247 int basic_error = error & 0xff; | 247 int basic_error = error & 0xff; |
| 248 | 248 |
| 249 // These errors relate more to the runtime context of the system than to | 249 // These errors relate more to the runtime context of the system than to |
| 250 // errors with a SQL statement or with the schema, so they aren't generally | 250 // errors with a SQL statement or with the schema, so they aren't generally |
| 251 // interesting to flag. This list is not comprehensive. | 251 // interesting to flag. This list is not comprehensive. |
| 252 return basic_error == SQLITE_BUSY || | 252 return basic_error == SQLITE_BUSY || |
| 253 basic_error == SQLITE_NOTADB || | 253 basic_error == SQLITE_NOTADB || |
| (...skipping 22 matching lines...) Expand all Loading... |
| 276 if (!debug_info.empty() && RegisterIntentToUpload()) { | 276 if (!debug_info.empty() && RegisterIntentToUpload()) { |
| 277 char debug_buf[2000]; | 277 char debug_buf[2000]; |
| 278 base::strlcpy(debug_buf, debug_info.c_str(), arraysize(debug_buf)); | 278 base::strlcpy(debug_buf, debug_info.c_str(), arraysize(debug_buf)); |
| 279 base::debug::Alias(&debug_buf); | 279 base::debug::Alias(&debug_buf); |
| 280 | 280 |
| 281 base::debug::DumpWithoutCrashing(); | 281 base::debug::DumpWithoutCrashing(); |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 // static | 285 // static |
| 286 void Connection::SetErrorIgnorer(Connection::ErrorIgnorerCallback* cb) { | 286 void Connection::SetErrorExpecter(Connection::ErrorExpecterCallback* cb) { |
| 287 CHECK(current_ignorer_cb_ == NULL); | 287 CHECK(current_expecter_cb_ == NULL); |
| 288 current_ignorer_cb_ = cb; | 288 current_expecter_cb_ = cb; |
| 289 } | 289 } |
| 290 | 290 |
| 291 // static | 291 // static |
| 292 void Connection::ResetErrorIgnorer() { | 292 void Connection::ResetErrorExpecter() { |
| 293 CHECK(current_ignorer_cb_); | 293 CHECK(current_expecter_cb_); |
| 294 current_ignorer_cb_ = NULL; | 294 current_expecter_cb_ = NULL; |
| 295 } | 295 } |
| 296 | 296 |
| 297 bool StatementID::operator<(const StatementID& other) const { | 297 bool StatementID::operator<(const StatementID& other) const { |
| 298 if (number_ != other.number_) | 298 if (number_ != other.number_) |
| 299 return number_ < other.number_; | 299 return number_ < other.number_; |
| 300 return strcmp(str_, other.str_) < 0; | 300 return strcmp(str_, other.str_) < 0; |
| 301 } | 301 } |
| 302 | 302 |
| 303 Connection::StatementRef::StatementRef(Connection* connection, | 303 Connection::StatementRef::StatementRef(Connection* connection, |
| 304 sqlite3_stmt* stmt, | 304 sqlite3_stmt* stmt, |
| (...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 AssertIOAllowed(); | 1463 AssertIOAllowed(); |
| 1464 | 1464 |
| 1465 // Return inactive statement. | 1465 // Return inactive statement. |
| 1466 if (!db_) | 1466 if (!db_) |
| 1467 return new StatementRef(NULL, NULL, poisoned_); | 1467 return new StatementRef(NULL, NULL, poisoned_); |
| 1468 | 1468 |
| 1469 sqlite3_stmt* stmt = NULL; | 1469 sqlite3_stmt* stmt = NULL; |
| 1470 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); | 1470 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); |
| 1471 if (rc != SQLITE_OK) { | 1471 if (rc != SQLITE_OK) { |
| 1472 // This is evidence of a syntax error in the incoming SQL. | 1472 // This is evidence of a syntax error in the incoming SQL. |
| 1473 if (!ShouldIgnoreSqliteCompileError(rc)) | 1473 if (!IsExpectedSqliteCompileError(rc)) |
| 1474 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 1474 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
| 1475 | 1475 |
| 1476 // It could also be database corruption. | 1476 // It could also be database corruption. |
| 1477 OnSqliteError(rc, NULL, sql); | 1477 OnSqliteError(rc, NULL, sql); |
| 1478 return new StatementRef(NULL, NULL, false); | 1478 return new StatementRef(NULL, NULL, false); |
| 1479 } | 1479 } |
| 1480 return new StatementRef(this, stmt, true); | 1480 return new StatementRef(this, stmt, true); |
| 1481 } | 1481 } |
| 1482 | 1482 |
| 1483 // TODO(shess): Unify this with GetUniqueStatement(). The only difference that | 1483 // TODO(shess): Unify this with GetUniqueStatement(). The only difference that |
| 1484 // seems legitimate is not passing |this| to StatementRef. | 1484 // seems legitimate is not passing |this| to StatementRef. |
| 1485 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( | 1485 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( |
| 1486 const char* sql) const { | 1486 const char* sql) const { |
| 1487 // Return inactive statement. | 1487 // Return inactive statement. |
| 1488 if (!db_) | 1488 if (!db_) |
| 1489 return new StatementRef(NULL, NULL, poisoned_); | 1489 return new StatementRef(NULL, NULL, poisoned_); |
| 1490 | 1490 |
| 1491 sqlite3_stmt* stmt = NULL; | 1491 sqlite3_stmt* stmt = NULL; |
| 1492 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); | 1492 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); |
| 1493 if (rc != SQLITE_OK) { | 1493 if (rc != SQLITE_OK) { |
| 1494 // This is evidence of a syntax error in the incoming SQL. | 1494 // This is evidence of a syntax error in the incoming SQL. |
| 1495 if (!ShouldIgnoreSqliteCompileError(rc)) | 1495 if (!IsExpectedSqliteCompileError(rc)) |
| 1496 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 1496 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
| 1497 return new StatementRef(NULL, NULL, false); | 1497 return new StatementRef(NULL, NULL, false); |
| 1498 } | 1498 } |
| 1499 return new StatementRef(NULL, stmt, true); | 1499 return new StatementRef(NULL, stmt, true); |
| 1500 } | 1500 } |
| 1501 | 1501 |
| 1502 std::string Connection::GetSchema() const { | 1502 std::string Connection::GetSchema() const { |
| 1503 // The ORDER BY should not be necessary, but relying on organic | 1503 // The ORDER BY should not be necessary, but relying on organic |
| 1504 // order for something like this is questionable. | 1504 // order for something like this is questionable. |
| 1505 const char* kSql = | 1505 const char* kSql = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 bool Connection::DoesIndexExist(const char* index_name) const { | 1544 bool Connection::DoesIndexExist(const char* index_name) const { |
| 1545 return DoesTableOrIndexExist(index_name, "index"); | 1545 return DoesTableOrIndexExist(index_name, "index"); |
| 1546 } | 1546 } |
| 1547 | 1547 |
| 1548 bool Connection::DoesTableOrIndexExist( | 1548 bool Connection::DoesTableOrIndexExist( |
| 1549 const char* name, const char* type) const { | 1549 const char* name, const char* type) const { |
| 1550 const char* kSql = | 1550 const char* kSql = |
| 1551 "SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE"; | 1551 "SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE"; |
| 1552 Statement statement(GetUntrackedStatement(kSql)); | 1552 Statement statement(GetUntrackedStatement(kSql)); |
| 1553 | 1553 |
| 1554 // This can happen if the database is corrupt and the error is being ignored | 1554 // This can happen if the database is corrupt and the error is a test |
| 1555 // for testing purposes. | 1555 // expectation. |
| 1556 if (!statement.is_valid()) | 1556 if (!statement.is_valid()) |
| 1557 return false; | 1557 return false; |
| 1558 | 1558 |
| 1559 statement.BindString(0, type); | 1559 statement.BindString(0, type); |
| 1560 statement.BindString(1, name); | 1560 statement.BindString(1, name); |
| 1561 | 1561 |
| 1562 return statement.Step(); // Table exists if any row was returned. | 1562 return statement.Step(); // Table exists if any row was returned. |
| 1563 } | 1563 } |
| 1564 | 1564 |
| 1565 bool Connection::DoesColumnExist(const char* table_name, | 1565 bool Connection::DoesColumnExist(const char* table_name, |
| 1566 const char* column_name) const { | 1566 const char* column_name) const { |
| 1567 std::string sql("PRAGMA TABLE_INFO("); | 1567 std::string sql("PRAGMA TABLE_INFO("); |
| 1568 sql.append(table_name); | 1568 sql.append(table_name); |
| 1569 sql.append(")"); | 1569 sql.append(")"); |
| 1570 | 1570 |
| 1571 Statement statement(GetUntrackedStatement(sql.c_str())); | 1571 Statement statement(GetUntrackedStatement(sql.c_str())); |
| 1572 | 1572 |
| 1573 // This can happen if the database is corrupt and the error is being ignored | 1573 // This can happen if the database is corrupt and the error is a test |
| 1574 // for testing purposes. | 1574 // expectation. |
| 1575 if (!statement.is_valid()) | 1575 if (!statement.is_valid()) |
| 1576 return false; | 1576 return false; |
| 1577 | 1577 |
| 1578 while (statement.Step()) { | 1578 while (statement.Step()) { |
| 1579 if (base::EqualsCaseInsensitiveASCII(statement.ColumnString(1), | 1579 if (base::EqualsCaseInsensitiveASCII(statement.ColumnString(1), |
| 1580 column_name)) | 1580 column_name)) |
| 1581 return true; | 1581 return true; |
| 1582 } | 1582 } |
| 1583 return false; | 1583 return false; |
| 1584 } | 1584 } |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1916 | 1916 |
| 1917 if (!error_callback_.is_null()) { | 1917 if (!error_callback_.is_null()) { |
| 1918 // Fire from a copy of the callback in case of reentry into | 1918 // Fire from a copy of the callback in case of reentry into |
| 1919 // re/set_error_callback(). | 1919 // re/set_error_callback(). |
| 1920 // TODO(shess): <http://crbug.com/254584> | 1920 // TODO(shess): <http://crbug.com/254584> |
| 1921 ErrorCallback(error_callback_).Run(err, stmt); | 1921 ErrorCallback(error_callback_).Run(err, stmt); |
| 1922 return err; | 1922 return err; |
| 1923 } | 1923 } |
| 1924 | 1924 |
| 1925 // The default handling is to assert on debug and to ignore on release. | 1925 // The default handling is to assert on debug and to ignore on release. |
| 1926 if (!ShouldIgnoreSqliteError(err)) | 1926 if (!IsExpectedSqliteError(err)) |
| 1927 DLOG(FATAL) << GetErrorMessage(); | 1927 DLOG(FATAL) << GetErrorMessage(); |
| 1928 return err; | 1928 return err; |
| 1929 } | 1929 } |
| 1930 | 1930 |
| 1931 bool Connection::FullIntegrityCheck(std::vector<std::string>* messages) { | 1931 bool Connection::FullIntegrityCheck(std::vector<std::string>* messages) { |
| 1932 return IntegrityCheckHelper("PRAGMA integrity_check", messages); | 1932 return IntegrityCheckHelper("PRAGMA integrity_check", messages); |
| 1933 } | 1933 } |
| 1934 | 1934 |
| 1935 bool Connection::QuickIntegrityCheck() { | 1935 bool Connection::QuickIntegrityCheck() { |
| 1936 std::vector<std::string> messages; | 1936 std::vector<std::string> messages; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1973 ignore_result(Execute(kNoWritableSchema)); | 1973 ignore_result(Execute(kNoWritableSchema)); |
| 1974 | 1974 |
| 1975 return ret; | 1975 return ret; |
| 1976 } | 1976 } |
| 1977 | 1977 |
| 1978 base::TimeTicks TimeSource::Now() { | 1978 base::TimeTicks TimeSource::Now() { |
| 1979 return base::TimeTicks::Now(); | 1979 return base::TimeTicks::Now(); |
| 1980 } | 1980 } |
| 1981 | 1981 |
| 1982 } // namespace sql | 1982 } // namespace sql |
| OLD | NEW |