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