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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 } | 54 } |
55 | 55 |
56 ErrorDelegate::~ErrorDelegate() { | 56 ErrorDelegate::~ErrorDelegate() { |
57 } | 57 } |
58 | 58 |
59 Connection::StatementRef::StatementRef() | 59 Connection::StatementRef::StatementRef() |
60 : connection_(NULL), | 60 : connection_(NULL), |
61 stmt_(NULL) { | 61 stmt_(NULL) { |
62 } | 62 } |
63 | 63 |
| 64 Connection::StatementRef::StatementRef(sqlite3_stmt* stmt) |
| 65 : connection_(NULL), |
| 66 stmt_(stmt) { |
| 67 } |
| 68 |
64 Connection::StatementRef::StatementRef(Connection* connection, | 69 Connection::StatementRef::StatementRef(Connection* connection, |
65 sqlite3_stmt* stmt) | 70 sqlite3_stmt* stmt) |
66 : connection_(connection), | 71 : connection_(connection), |
67 stmt_(stmt) { | 72 stmt_(stmt) { |
68 connection_->StatementRefCreated(this); | 73 connection_->StatementRefCreated(this); |
69 } | 74 } |
70 | 75 |
71 Connection::StatementRef::~StatementRef() { | 76 Connection::StatementRef::~StatementRef() { |
72 if (connection_) | 77 if (connection_) |
73 connection_->StatementRefDeleted(this); | 78 connection_->StatementRefDeleted(this); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 341 |
337 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); | 342 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); |
338 if (statement->is_valid()) | 343 if (statement->is_valid()) |
339 statement_cache_[id] = statement; // Only cache valid statements. | 344 statement_cache_[id] = statement; // Only cache valid statements. |
340 return statement; | 345 return statement; |
341 } | 346 } |
342 | 347 |
343 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( | 348 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( |
344 const char* sql) { | 349 const char* sql) { |
345 if (!db_) | 350 if (!db_) |
346 return new StatementRef(this, NULL); // Return inactive statement. | 351 return new StatementRef(); // Return inactive statement. |
347 | 352 |
348 sqlite3_stmt* stmt = NULL; | 353 sqlite3_stmt* stmt = NULL; |
349 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { | 354 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { |
350 // This is evidence of a syntax error in the incoming SQL. | 355 // This is evidence of a syntax error in the incoming SQL. |
351 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 356 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
352 return new StatementRef(this, NULL); | 357 return new StatementRef(); |
353 } | 358 } |
354 return new StatementRef(this, stmt); | 359 return new StatementRef(this, stmt); |
355 } | 360 } |
356 | 361 |
| 362 scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement( |
| 363 const char* sql) const { |
| 364 if (!db_) |
| 365 return new StatementRef(); // Return inactive statement. |
| 366 |
| 367 sqlite3_stmt* stmt = NULL; |
| 368 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL); |
| 369 if (rc != SQLITE_OK) { |
| 370 // This is evidence of a syntax error in the incoming SQL. |
| 371 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
| 372 return new StatementRef(); |
| 373 } |
| 374 return new StatementRef(stmt); |
| 375 } |
| 376 |
357 bool Connection::IsSQLValid(const char* sql) { | 377 bool Connection::IsSQLValid(const char* sql) { |
358 sqlite3_stmt* stmt = NULL; | 378 sqlite3_stmt* stmt = NULL; |
359 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) | 379 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) |
360 return false; | 380 return false; |
361 | 381 |
362 sqlite3_finalize(stmt); | 382 sqlite3_finalize(stmt); |
363 return true; | 383 return true; |
364 } | 384 } |
365 | 385 |
366 bool Connection::DoesTableExist(const char* table_name) const { | 386 bool Connection::DoesTableExist(const char* table_name) const { |
367 return DoesTableOrIndexExist(table_name, "table"); | 387 return DoesTableOrIndexExist(table_name, "table"); |
368 } | 388 } |
369 | 389 |
370 bool Connection::DoesIndexExist(const char* index_name) const { | 390 bool Connection::DoesIndexExist(const char* index_name) const { |
371 return DoesTableOrIndexExist(index_name, "index"); | 391 return DoesTableOrIndexExist(index_name, "index"); |
372 } | 392 } |
373 | 393 |
374 bool Connection::DoesTableOrIndexExist( | 394 bool Connection::DoesTableOrIndexExist( |
375 const char* name, const char* type) const { | 395 const char* name, const char* type) const { |
376 // GetUniqueStatement can't be const since statements may modify the | 396 const char* kSql = "SELECT name FROM sqlite_master WHERE type=? AND name=?"; |
377 // database, but we know ours doesn't modify it, so the cast is safe. | 397 Statement statement(GetUntrackedStatement(kSql)); |
378 Statement statement(const_cast<Connection*>(this)->GetUniqueStatement( | |
379 "SELECT name FROM sqlite_master " | |
380 "WHERE type=? AND name=?")); | |
381 statement.BindString(0, type); | 398 statement.BindString(0, type); |
382 statement.BindString(1, name); | 399 statement.BindString(1, name); |
383 | 400 |
384 return statement.Step(); // Table exists if any row was returned. | 401 return statement.Step(); // Table exists if any row was returned. |
385 } | 402 } |
386 | 403 |
387 bool Connection::DoesColumnExist(const char* table_name, | 404 bool Connection::DoesColumnExist(const char* table_name, |
388 const char* column_name) const { | 405 const char* column_name) const { |
389 std::string sql("PRAGMA TABLE_INFO("); | 406 std::string sql("PRAGMA TABLE_INFO("); |
390 sql.append(table_name); | 407 sql.append(table_name); |
391 sql.append(")"); | 408 sql.append(")"); |
392 | 409 |
393 // Our SQL is non-mutating, so this cast is OK. | 410 Statement statement(GetUntrackedStatement(sql.c_str())); |
394 Statement statement(const_cast<Connection*>(this)->GetUniqueStatement( | |
395 sql.c_str())); | |
396 | |
397 while (statement.Step()) { | 411 while (statement.Step()) { |
398 if (!statement.ColumnString(1).compare(column_name)) | 412 if (!statement.ColumnString(1).compare(column_name)) |
399 return true; | 413 return true; |
400 } | 414 } |
401 return false; | 415 return false; |
402 } | 416 } |
403 | 417 |
404 int64 Connection::GetLastInsertRowId() const { | 418 int64 Connection::GetLastInsertRowId() const { |
405 if (!db_) { | 419 if (!db_) { |
406 DLOG(FATAL) << "Illegal use of connection without a db"; | 420 DLOG(FATAL) << "Illegal use of connection without a db"; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 | 563 |
550 int Connection::OnSqliteError(int err, sql::Statement *stmt) { | 564 int Connection::OnSqliteError(int err, sql::Statement *stmt) { |
551 if (error_delegate_.get()) | 565 if (error_delegate_.get()) |
552 return error_delegate_->OnError(err, this, stmt); | 566 return error_delegate_->OnError(err, this, stmt); |
553 // The default handling is to assert on debug and to ignore on release. | 567 // The default handling is to assert on debug and to ignore on release. |
554 DLOG(FATAL) << GetErrorMessage(); | 568 DLOG(FATAL) << GetErrorMessage(); |
555 return err; | 569 return err; |
556 } | 570 } |
557 | 571 |
558 } // namespace sql | 572 } // namespace sql |
OLD | NEW |