// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include "chrome/browser/history/download_database.h" #include "chrome/browser/download_manager.h" #include "chrome/browser/history/download_types.h" #include "chrome/common/sqlite_utils.h" #include "chrome/common/sqlite_compiled_statement.h" // Download schema: // // id SQLite-generated primary key. // full_path Location of the download on disk. // url URL of the downloaded file. // start_time When the download was started. // received_bytes Total size downloaded. // total_bytes Total size of the download. // state Identifies if this download is completed or not. Not used // directly by the history system. See DownloadItem's // DownloadState for where this is used. namespace history { DownloadDatabase::DownloadDatabase() { } DownloadDatabase::~DownloadDatabase() { } bool DownloadDatabase::InitDownloadTable() { if (!DoesSqliteTableExist(GetDB(), "downloads")) { if (sqlite3_exec(GetDB(), "CREATE TABLE downloads (" "id INTEGER PRIMARY KEY," "full_path LONGVARCHAR NOT NULL," "url LONGVARCHAR NOT NULL," "start_time INTEGER NOT NULL," "received_bytes INTEGER NOT NULL," "total_bytes INTEGER NOT NULL," "state INTEGER NOT NULL)", NULL, NULL, NULL) != SQLITE_OK) return false; } return true; } bool DownloadDatabase::DropDownloadTable() { return sqlite3_exec(GetDB(), "DROP TABLE downloads", NULL, NULL, NULL) == SQLITE_OK; } void DownloadDatabase::QueryDownloads(std::vector* results) { results->clear(); SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(), "SELECT id, full_path, url, start_time, received_bytes, " "total_bytes, state " "FROM downloads " "ORDER BY start_time"); if (!statement.is_valid()) return; while (statement->step() == SQLITE_ROW) { DownloadCreateInfo info; info.db_handle = statement->column_int64(0); statement->column_string16(1, &info.path); statement->column_string16(2, &info.url); info.start_time = Time::FromTimeT(statement->column_int64(3)); info.received_bytes = statement->column_int64(4); info.total_bytes = statement->column_int64(5); info.state = statement->column_int(6); results->push_back(info); } } bool DownloadDatabase::UpdateDownload(int64 received_bytes, int32 state, DownloadID db_handle) { DCHECK(db_handle > 0); SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(), "UPDATE downloads " "SET received_bytes=?, state=? WHERE id=?"); if (!statement.is_valid()) return false; statement->bind_int64(0, received_bytes); statement->bind_int(1, state); statement->bind_int64(2, db_handle); return statement->step() == SQLITE_DONE; } int64 DownloadDatabase::CreateDownload(const DownloadCreateInfo& info) { SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(), "INSERT INTO downloads " "(full_path, url, start_time, received_bytes, total_bytes, state) " "VALUES (?, ?, ?, ?, ?, ?)"); if (!statement.is_valid()) return 0; statement->bind_wstring(0, info.path); statement->bind_wstring(1, info.url); statement->bind_int64(2, info.start_time.ToTimeT()); statement->bind_int64(3, info.received_bytes); statement->bind_int64(4, info.total_bytes); statement->bind_int(5, info.state); if (statement->step() == SQLITE_DONE) return sqlite3_last_insert_rowid(GetDB()); return 0; } void DownloadDatabase::RemoveDownload(DownloadID db_handle) { SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(), "DELETE FROM downloads WHERE id=?"); if (!statement.is_valid()) return; statement->bind_int64(0, db_handle); statement->step(); } void DownloadDatabase::RemoveDownloadsBetween(Time delete_begin, Time delete_end) { // This does not use an index. We currently aren't likely to have enough // downloads where an index by time will give us a lot of benefit. SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(), "DELETE FROM downloads WHERE start_time >= ? AND start_time < ? " "AND (State = ? OR State = ?)"); if (!statement.is_valid()) return; time_t start_time = delete_begin.ToTimeT(); time_t end_time = delete_end.ToTimeT(); statement->bind_int64(0, start_time); statement->bind_int64(1, end_time ? end_time : std::numeric_limits::max()); statement->bind_int(2, DownloadItem::COMPLETE); statement->bind_int(3, DownloadItem::CANCELLED); statement->step(); } void DownloadDatabase::SearchDownloads(std::vector* results, const std::wstring& search_text) { SQLITE_UNIQUE_STATEMENT(statement, GetStatementCache(), "SELECT id FROM downloads WHERE url LIKE ? " "OR full_path LIKE ? ORDER BY id"); if (!statement.is_valid()) return; std::wstring text(L"%"); text.append(search_text); text.append(L"%"); statement->bind_wstring(0, text); statement->bind_wstring(1, text); while (statement->step() == SQLITE_ROW) results->push_back(statement->column_int64(0)); } } // namespace history