Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: sql/connection.cc

Issue 10540155: Annotate calls to SQLite functions - they have to be executed on a thread allowing IO access. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/file_path.h" 9 #include "base/file_path.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 connection_->StatementRefCreated(this); 68 connection_->StatementRefCreated(this);
69 } 69 }
70 70
71 Connection::StatementRef::~StatementRef() { 71 Connection::StatementRef::~StatementRef() {
72 if (connection_) 72 if (connection_)
73 connection_->StatementRefDeleted(this); 73 connection_->StatementRefDeleted(this);
74 Close(); 74 Close();
75 } 75 }
76 76
77 void Connection::StatementRef::Close() { 77 void Connection::StatementRef::Close() {
78 AssertIOAllowed();
78 if (stmt_) { 79 if (stmt_) {
79 sqlite3_finalize(stmt_); 80 sqlite3_finalize(stmt_);
80 stmt_ = NULL; 81 stmt_ = NULL;
81 } 82 }
82 connection_ = NULL; // The connection may be getting deleted. 83 connection_ = NULL; // The connection may be getting deleted.
83 } 84 }
84 85
85 Connection::Connection() 86 Connection::Connection()
86 : db_(NULL), 87 : db_(NULL),
87 page_size_(0), 88 page_size_(0),
88 cache_size_(0), 89 cache_size_(0),
89 exclusive_locking_(false), 90 exclusive_locking_(false),
90 transaction_nesting_(0), 91 transaction_nesting_(0),
91 needs_rollback_(false) { 92 needs_rollback_(false),
93 in_memory_(false) {
92 } 94 }
93 95
94 Connection::~Connection() { 96 Connection::~Connection() {
95 Close(); 97 Close();
96 } 98 }
97 99
98 bool Connection::Open(const FilePath& path) { 100 bool Connection::Open(const FilePath& path) {
99 #if defined(OS_WIN) 101 #if defined(OS_WIN)
100 return OpenInternal(WideToUTF8(path.value())); 102 return OpenInternal(WideToUTF8(path.value()));
101 #elif defined(OS_POSIX) 103 #elif defined(OS_POSIX)
102 return OpenInternal(path.value()); 104 return OpenInternal(path.value());
103 #endif 105 #endif
104 } 106 }
105 107
106 bool Connection::OpenInMemory() { 108 bool Connection::OpenInMemory() {
109 in_memory_ = true;
107 return OpenInternal(":memory:"); 110 return OpenInternal(":memory:");
108 } 111 }
109 112
110 void Connection::Close() { 113 void Connection::Close() {
114 AssertIOAllowed();
115
111 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point 116 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point
112 // will delete the -journal file. For ChromiumOS or other more 117 // will delete the -journal file. For ChromiumOS or other more
113 // embedded systems, this is probably not appropriate, whereas on 118 // embedded systems, this is probably not appropriate, whereas on
114 // desktop it might make some sense. 119 // desktop it might make some sense.
115 120
116 // sqlite3_close() needs all prepared statements to be finalized. 121 // sqlite3_close() needs all prepared statements to be finalized.
117 // Release all cached statements, then assert that the client has 122 // Release all cached statements, then assert that the client has
118 // released all statements. 123 // released all statements.
119 statement_cache_.clear(); 124 statement_cache_.clear();
120 DCHECK(open_statements_.empty()); 125 DCHECK(open_statements_.empty());
121 126
122 // Additionally clear the prepared statements, because they contain 127 // Additionally clear the prepared statements, because they contain
123 // weak references to this connection. This case has come up when 128 // weak references to this connection. This case has come up when
124 // error-handling code is hit in production. 129 // error-handling code is hit in production.
125 ClearCache(); 130 ClearCache();
126 131
127 if (db_) { 132 if (db_) {
128 // TODO(shess): Histogram for failure. 133 // TODO(shess): Histogram for failure.
129 sqlite3_close(db_); 134 sqlite3_close(db_);
130 db_ = NULL; 135 db_ = NULL;
131 } 136 }
132 } 137 }
133 138
134 void Connection::Preload() { 139 void Connection::Preload() {
140 AssertIOAllowed();
141
135 if (!db_) { 142 if (!db_) {
136 DLOG(FATAL) << "Cannot preload null db"; 143 DLOG(FATAL) << "Cannot preload null db";
137 return; 144 return;
138 } 145 }
139 146
140 // A statement must be open for the preload command to work. If the meta 147 // A statement must be open for the preload command to work. If the meta
141 // table doesn't exist, it probably means this is a new database and there 148 // table doesn't exist, it probably means this is a new database and there
142 // is nothing to preload (so it's OK we do nothing). 149 // is nothing to preload (so it's OK we do nothing).
143 if (!DoesTableExist("meta")) 150 if (!DoesTableExist("meta"))
144 return; 151 return;
145 Statement dummy(GetUniqueStatement("SELECT * FROM meta")); 152 Statement dummy(GetUniqueStatement("SELECT * FROM meta"));
146 if (!dummy.Step()) 153 if (!dummy.Step())
147 return; 154 return;
148 155
149 #if !defined(USE_SYSTEM_SQLITE) 156 #if !defined(USE_SYSTEM_SQLITE)
150 // This function is only defined in Chromium's version of sqlite. 157 // This function is only defined in Chromium's version of sqlite.
151 // Do not call it when using system sqlite. 158 // Do not call it when using system sqlite.
152 sqlite3_preload(db_); 159 sqlite3_preload(db_);
153 #endif 160 #endif
154 } 161 }
155 162
156 // Create an in-memory database with the existing database's page 163 // Create an in-memory database with the existing database's page
157 // size, then backup that database over the existing database. 164 // size, then backup that database over the existing database.
158 bool Connection::Raze() { 165 bool Connection::Raze() {
166 AssertIOAllowed();
167
159 if (!db_) { 168 if (!db_) {
160 DLOG(FATAL) << "Cannot raze null db"; 169 DLOG(FATAL) << "Cannot raze null db";
161 return false; 170 return false;
162 } 171 }
163 172
164 if (transaction_nesting_ > 0) { 173 if (transaction_nesting_ > 0) {
165 DLOG(FATAL) << "Cannot raze within a transaction"; 174 DLOG(FATAL) << "Cannot raze within a transaction";
166 return false; 175 return false;
167 } 176 }
168 177
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 if (needs_rollback_) { 294 if (needs_rollback_) {
286 DoRollback(); 295 DoRollback();
287 return false; 296 return false;
288 } 297 }
289 298
290 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT")); 299 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT"));
291 return commit.Run(); 300 return commit.Run();
292 } 301 }
293 302
294 int Connection::ExecuteAndReturnErrorCode(const char* sql) { 303 int Connection::ExecuteAndReturnErrorCode(const char* sql) {
304 AssertIOAllowed();
295 if (!db_) 305 if (!db_)
296 return false; 306 return false;
297 return sqlite3_exec(db_, sql, NULL, NULL, NULL); 307 return sqlite3_exec(db_, sql, NULL, NULL, NULL);
298 } 308 }
299 309
300 bool Connection::Execute(const char* sql) { 310 bool Connection::Execute(const char* sql) {
301 int error = ExecuteAndReturnErrorCode(sql); 311 int error = ExecuteAndReturnErrorCode(sql);
302 // This needs to be a FATAL log because the error case of arriving here is 312 // This needs to be a FATAL log because the error case of arriving here is
303 // that there's a malformed SQL statement. This can arise in development if 313 // that there's a malformed SQL statement. This can arise in development if
304 // a change alters the schema but not all queries adjust. 314 // a change alters the schema but not all queries adjust.
(...skipping 30 matching lines...) Expand all
335 } 345 }
336 346
337 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); 347 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql);
338 if (statement->is_valid()) 348 if (statement->is_valid())
339 statement_cache_[id] = statement; // Only cache valid statements. 349 statement_cache_[id] = statement; // Only cache valid statements.
340 return statement; 350 return statement;
341 } 351 }
342 352
343 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( 353 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement(
344 const char* sql) { 354 const char* sql) {
355 AssertIOAllowed();
356
345 if (!db_) 357 if (!db_)
346 return new StatementRef(this, NULL); // Return inactive statement. 358 return new StatementRef(this, NULL); // Return inactive statement.
347 359
348 sqlite3_stmt* stmt = NULL; 360 sqlite3_stmt* stmt = NULL;
349 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { 361 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) {
350 // This is evidence of a syntax error in the incoming SQL. 362 // This is evidence of a syntax error in the incoming SQL.
351 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); 363 DLOG(FATAL) << "SQL compile error " << GetErrorMessage();
352 return new StatementRef(this, NULL); 364 return new StatementRef(this, NULL);
353 } 365 }
354 return new StatementRef(this, stmt); 366 return new StatementRef(this, stmt);
355 } 367 }
356 368
357 bool Connection::IsSQLValid(const char* sql) { 369 bool Connection::IsSQLValid(const char* sql) {
370 AssertIOAllowed();
358 sqlite3_stmt* stmt = NULL; 371 sqlite3_stmt* stmt = NULL;
359 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) 372 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK)
360 return false; 373 return false;
361 374
362 sqlite3_finalize(stmt); 375 sqlite3_finalize(stmt);
363 return true; 376 return true;
364 } 377 }
365 378
366 bool Connection::DoesTableExist(const char* table_name) const { 379 bool Connection::DoesTableExist(const char* table_name) const {
367 return DoesTableOrIndexExist(table_name, "table"); 380 return DoesTableOrIndexExist(table_name, "table");
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 return err; 447 return err;
435 } 448 }
436 449
437 const char* Connection::GetErrorMessage() const { 450 const char* Connection::GetErrorMessage() const {
438 if (!db_) 451 if (!db_)
439 return "sql::Connection has no connection."; 452 return "sql::Connection has no connection.";
440 return sqlite3_errmsg(db_); 453 return sqlite3_errmsg(db_);
441 } 454 }
442 455
443 bool Connection::OpenInternal(const std::string& file_name) { 456 bool Connection::OpenInternal(const std::string& file_name) {
457 AssertIOAllowed();
458
444 if (db_) { 459 if (db_) {
445 DLOG(FATAL) << "sql::Connection is already open."; 460 DLOG(FATAL) << "sql::Connection is already open.";
446 return false; 461 return false;
447 } 462 }
448 463
449 int err = sqlite3_open(file_name.c_str(), &db_); 464 int err = sqlite3_open(file_name.c_str(), &db_);
450 if (err != SQLITE_OK) { 465 if (err != SQLITE_OK) {
451 OnSqliteError(err, NULL); 466 OnSqliteError(err, NULL);
452 Close(); 467 Close();
453 db_ = NULL; 468 db_ = NULL;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 564
550 int Connection::OnSqliteError(int err, sql::Statement *stmt) { 565 int Connection::OnSqliteError(int err, sql::Statement *stmt) {
551 if (error_delegate_.get()) 566 if (error_delegate_.get())
552 return error_delegate_->OnError(err, this, stmt); 567 return error_delegate_->OnError(err, this, stmt);
553 // The default handling is to assert on debug and to ignore on release. 568 // The default handling is to assert on debug and to ignore on release.
554 DLOG(FATAL) << GetErrorMessage(); 569 DLOG(FATAL) << GetErrorMessage();
555 return err; 570 return err;
556 } 571 }
557 572
558 } // namespace sql 573 } // namespace sql
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698