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 |