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/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 if (stmt_) { | 78 if (stmt_) { |
| 79 // Call to AssertIOAllowed() cannot go at the beginning of the function |
| 80 // because Close() is called unconditionally from destructor to clean |
| 81 // connection_. And if this is inactive statement this won't cause any |
| 82 // disk access and destructor most probably will be called on thread |
| 83 // not allowing disk access. |
| 84 // TODO(paivanof@gmail.com): This should move to the beginning |
| 85 // of the function. http://crbug.com/136655. |
| 86 AssertIOAllowed(); |
79 sqlite3_finalize(stmt_); | 87 sqlite3_finalize(stmt_); |
80 stmt_ = NULL; | 88 stmt_ = NULL; |
81 } | 89 } |
82 connection_ = NULL; // The connection may be getting deleted. | 90 connection_ = NULL; // The connection may be getting deleted. |
83 } | 91 } |
84 | 92 |
85 Connection::Connection() | 93 Connection::Connection() |
86 : db_(NULL), | 94 : db_(NULL), |
87 page_size_(0), | 95 page_size_(0), |
88 cache_size_(0), | 96 cache_size_(0), |
89 exclusive_locking_(false), | 97 exclusive_locking_(false), |
90 transaction_nesting_(0), | 98 transaction_nesting_(0), |
91 needs_rollback_(false) { | 99 needs_rollback_(false), |
| 100 in_memory_(false) { |
92 } | 101 } |
93 | 102 |
94 Connection::~Connection() { | 103 Connection::~Connection() { |
95 Close(); | 104 Close(); |
96 } | 105 } |
97 | 106 |
98 bool Connection::Open(const FilePath& path) { | 107 bool Connection::Open(const FilePath& path) { |
99 #if defined(OS_WIN) | 108 #if defined(OS_WIN) |
100 return OpenInternal(WideToUTF8(path.value())); | 109 return OpenInternal(WideToUTF8(path.value())); |
101 #elif defined(OS_POSIX) | 110 #elif defined(OS_POSIX) |
102 return OpenInternal(path.value()); | 111 return OpenInternal(path.value()); |
103 #endif | 112 #endif |
104 } | 113 } |
105 | 114 |
106 bool Connection::OpenInMemory() { | 115 bool Connection::OpenInMemory() { |
| 116 in_memory_ = true; |
107 return OpenInternal(":memory:"); | 117 return OpenInternal(":memory:"); |
108 } | 118 } |
109 | 119 |
110 void Connection::Close() { | 120 void Connection::Close() { |
111 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point | 121 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point |
112 // will delete the -journal file. For ChromiumOS or other more | 122 // will delete the -journal file. For ChromiumOS or other more |
113 // embedded systems, this is probably not appropriate, whereas on | 123 // embedded systems, this is probably not appropriate, whereas on |
114 // desktop it might make some sense. | 124 // desktop it might make some sense. |
115 | 125 |
116 // sqlite3_close() needs all prepared statements to be finalized. | 126 // sqlite3_close() needs all prepared statements to be finalized. |
117 // Release all cached statements, then assert that the client has | 127 // Release all cached statements, then assert that the client has |
118 // released all statements. | 128 // released all statements. |
119 statement_cache_.clear(); | 129 statement_cache_.clear(); |
120 DCHECK(open_statements_.empty()); | 130 DCHECK(open_statements_.empty()); |
121 | 131 |
122 // Additionally clear the prepared statements, because they contain | 132 // Additionally clear the prepared statements, because they contain |
123 // weak references to this connection. This case has come up when | 133 // weak references to this connection. This case has come up when |
124 // error-handling code is hit in production. | 134 // error-handling code is hit in production. |
125 ClearCache(); | 135 ClearCache(); |
126 | 136 |
127 if (db_) { | 137 if (db_) { |
| 138 // Call to AssertIOAllowed() cannot go at the beginning of the function |
| 139 // because Close() must be called from destructor to clean |
| 140 // statement_cache_, it won't cause any disk access and it most probably |
| 141 // will happen on thread not allowing disk access. |
| 142 // TODO(paivanof@gmail.com): This should move to the beginning |
| 143 // of the function. http://crbug.com/136655. |
| 144 AssertIOAllowed(); |
128 // TODO(shess): Histogram for failure. | 145 // TODO(shess): Histogram for failure. |
129 sqlite3_close(db_); | 146 sqlite3_close(db_); |
130 db_ = NULL; | 147 db_ = NULL; |
131 } | 148 } |
132 } | 149 } |
133 | 150 |
134 void Connection::Preload() { | 151 void Connection::Preload() { |
| 152 AssertIOAllowed(); |
| 153 |
135 if (!db_) { | 154 if (!db_) { |
136 DLOG(FATAL) << "Cannot preload null db"; | 155 DLOG(FATAL) << "Cannot preload null db"; |
137 return; | 156 return; |
138 } | 157 } |
139 | 158 |
140 // A statement must be open for the preload command to work. If the meta | 159 // 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 | 160 // 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). | 161 // is nothing to preload (so it's OK we do nothing). |
143 if (!DoesTableExist("meta")) | 162 if (!DoesTableExist("meta")) |
144 return; | 163 return; |
145 Statement dummy(GetUniqueStatement("SELECT * FROM meta")); | 164 Statement dummy(GetUniqueStatement("SELECT * FROM meta")); |
146 if (!dummy.Step()) | 165 if (!dummy.Step()) |
147 return; | 166 return; |
148 | 167 |
149 #if !defined(USE_SYSTEM_SQLITE) | 168 #if !defined(USE_SYSTEM_SQLITE) |
150 // This function is only defined in Chromium's version of sqlite. | 169 // This function is only defined in Chromium's version of sqlite. |
151 // Do not call it when using system sqlite. | 170 // Do not call it when using system sqlite. |
152 sqlite3_preload(db_); | 171 sqlite3_preload(db_); |
153 #endif | 172 #endif |
154 } | 173 } |
155 | 174 |
156 // Create an in-memory database with the existing database's page | 175 // Create an in-memory database with the existing database's page |
157 // size, then backup that database over the existing database. | 176 // size, then backup that database over the existing database. |
158 bool Connection::Raze() { | 177 bool Connection::Raze() { |
| 178 AssertIOAllowed(); |
| 179 |
159 if (!db_) { | 180 if (!db_) { |
160 DLOG(FATAL) << "Cannot raze null db"; | 181 DLOG(FATAL) << "Cannot raze null db"; |
161 return false; | 182 return false; |
162 } | 183 } |
163 | 184 |
164 if (transaction_nesting_ > 0) { | 185 if (transaction_nesting_ > 0) { |
165 DLOG(FATAL) << "Cannot raze within a transaction"; | 186 DLOG(FATAL) << "Cannot raze within a transaction"; |
166 return false; | 187 return false; |
167 } | 188 } |
168 | 189 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 if (needs_rollback_) { | 306 if (needs_rollback_) { |
286 DoRollback(); | 307 DoRollback(); |
287 return false; | 308 return false; |
288 } | 309 } |
289 | 310 |
290 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT")); | 311 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT")); |
291 return commit.Run(); | 312 return commit.Run(); |
292 } | 313 } |
293 | 314 |
294 int Connection::ExecuteAndReturnErrorCode(const char* sql) { | 315 int Connection::ExecuteAndReturnErrorCode(const char* sql) { |
| 316 AssertIOAllowed(); |
295 if (!db_) | 317 if (!db_) |
296 return false; | 318 return false; |
297 return sqlite3_exec(db_, sql, NULL, NULL, NULL); | 319 return sqlite3_exec(db_, sql, NULL, NULL, NULL); |
298 } | 320 } |
299 | 321 |
300 bool Connection::Execute(const char* sql) { | 322 bool Connection::Execute(const char* sql) { |
301 int error = ExecuteAndReturnErrorCode(sql); | 323 int error = ExecuteAndReturnErrorCode(sql); |
302 // This needs to be a FATAL log because the error case of arriving here is | 324 // 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 | 325 // that there's a malformed SQL statement. This can arise in development if |
304 // a change alters the schema but not all queries adjust. | 326 // a change alters the schema but not all queries adjust. |
(...skipping 30 matching lines...) Expand all Loading... |
335 } | 357 } |
336 | 358 |
337 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); | 359 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); |
338 if (statement->is_valid()) | 360 if (statement->is_valid()) |
339 statement_cache_[id] = statement; // Only cache valid statements. | 361 statement_cache_[id] = statement; // Only cache valid statements. |
340 return statement; | 362 return statement; |
341 } | 363 } |
342 | 364 |
343 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( | 365 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( |
344 const char* sql) { | 366 const char* sql) { |
| 367 AssertIOAllowed(); |
| 368 |
345 if (!db_) | 369 if (!db_) |
346 return new StatementRef(this, NULL); // Return inactive statement. | 370 return new StatementRef(this, NULL); // Return inactive statement. |
347 | 371 |
348 sqlite3_stmt* stmt = NULL; | 372 sqlite3_stmt* stmt = NULL; |
349 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { | 373 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { |
350 // This is evidence of a syntax error in the incoming SQL. | 374 // This is evidence of a syntax error in the incoming SQL. |
351 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 375 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
352 return new StatementRef(this, NULL); | 376 return new StatementRef(this, NULL); |
353 } | 377 } |
354 return new StatementRef(this, stmt); | 378 return new StatementRef(this, stmt); |
355 } | 379 } |
356 | 380 |
357 bool Connection::IsSQLValid(const char* sql) { | 381 bool Connection::IsSQLValid(const char* sql) { |
| 382 AssertIOAllowed(); |
358 sqlite3_stmt* stmt = NULL; | 383 sqlite3_stmt* stmt = NULL; |
359 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) | 384 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) |
360 return false; | 385 return false; |
361 | 386 |
362 sqlite3_finalize(stmt); | 387 sqlite3_finalize(stmt); |
363 return true; | 388 return true; |
364 } | 389 } |
365 | 390 |
366 bool Connection::DoesTableExist(const char* table_name) const { | 391 bool Connection::DoesTableExist(const char* table_name) const { |
367 return DoesTableOrIndexExist(table_name, "table"); | 392 return DoesTableOrIndexExist(table_name, "table"); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 return err; | 459 return err; |
435 } | 460 } |
436 | 461 |
437 const char* Connection::GetErrorMessage() const { | 462 const char* Connection::GetErrorMessage() const { |
438 if (!db_) | 463 if (!db_) |
439 return "sql::Connection has no connection."; | 464 return "sql::Connection has no connection."; |
440 return sqlite3_errmsg(db_); | 465 return sqlite3_errmsg(db_); |
441 } | 466 } |
442 | 467 |
443 bool Connection::OpenInternal(const std::string& file_name) { | 468 bool Connection::OpenInternal(const std::string& file_name) { |
| 469 AssertIOAllowed(); |
| 470 |
444 if (db_) { | 471 if (db_) { |
445 DLOG(FATAL) << "sql::Connection is already open."; | 472 DLOG(FATAL) << "sql::Connection is already open."; |
446 return false; | 473 return false; |
447 } | 474 } |
448 | 475 |
449 int err = sqlite3_open(file_name.c_str(), &db_); | 476 int err = sqlite3_open(file_name.c_str(), &db_); |
450 if (err != SQLITE_OK) { | 477 if (err != SQLITE_OK) { |
451 OnSqliteError(err, NULL); | 478 OnSqliteError(err, NULL); |
452 Close(); | 479 Close(); |
453 db_ = NULL; | 480 db_ = NULL; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 | 576 |
550 int Connection::OnSqliteError(int err, sql::Statement *stmt) { | 577 int Connection::OnSqliteError(int err, sql::Statement *stmt) { |
551 if (error_delegate_.get()) | 578 if (error_delegate_.get()) |
552 return error_delegate_->OnError(err, this, stmt); | 579 return error_delegate_->OnError(err, this, stmt); |
553 // The default handling is to assert on debug and to ignore on release. | 580 // The default handling is to assert on debug and to ignore on release. |
554 DLOG(FATAL) << GetErrorMessage(); | 581 DLOG(FATAL) << GetErrorMessage(); |
555 return err; | 582 return err; |
556 } | 583 } |
557 | 584 |
558 } // namespace sql | 585 } // namespace sql |
OLD | NEW |