diff options
Diffstat (limited to 'chrome/browser/history/download_database.cc')
-rw-r--r-- | chrome/browser/history/download_database.cc | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc new file mode 100644 index 0000000..aa3dbde --- /dev/null +++ b/chrome/browser/history/download_database.cc @@ -0,0 +1,218 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/history/download_database.h" + +#include <limits> +#include <vector> + +#include "app/sql/connection.h" +#include "app/sql/statement.h" +#include "base/file_path.h" +#include "base/utf_string_conversions.h" +#include "build/build_config.h" +#include "chrome/browser/download/download_item.h" +#include "chrome/browser/history/download_types.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 { + +namespace { + +#if defined(OS_POSIX) + +// Binds/reads the given file path to the given column of the given statement. +void BindFilePath(sql::Statement& statement, const FilePath& path, int col) { + statement.BindString(col, path.value()); +} +FilePath ColumnFilePath(sql::Statement& statement, int col) { + return FilePath(statement.ColumnString(col)); +} + +#else + +// See above. +void BindFilePath(sql::Statement& statement, const FilePath& path, int col) { + statement.BindString(col, UTF16ToUTF8(path.value())); +} +FilePath ColumnFilePath(sql::Statement& statement, int col) { + return FilePath(UTF8ToUTF16(statement.ColumnString(col))); +} + +#endif + +} // namespace + +DownloadDatabase::DownloadDatabase() { +} + +DownloadDatabase::~DownloadDatabase() { +} + +bool DownloadDatabase::InitDownloadTable() { + if (!GetDB().DoesTableExist("downloads")) { + if (!GetDB().Execute( + "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)")) + return false; + } + return true; +} + +bool DownloadDatabase::DropDownloadTable() { + return GetDB().Execute("DROP TABLE downloads"); +} + +void DownloadDatabase::QueryDownloads( + std::vector<DownloadCreateInfo>* results) { + results->clear(); + + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "SELECT id, full_path, url, start_time, received_bytes, " + "total_bytes, state " + "FROM downloads " + "ORDER BY start_time")); + if (!statement) + return; + + while (statement.Step()) { + DownloadCreateInfo info; + info.db_handle = statement.ColumnInt64(0); + + info.path = ColumnFilePath(statement, 1); + info.url = GURL(statement.ColumnString(2)); + info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3)); + info.received_bytes = statement.ColumnInt64(4); + info.total_bytes = statement.ColumnInt64(5); + info.state = statement.ColumnInt(6); + results->push_back(info); + } +} + +bool DownloadDatabase::UpdateDownload(int64 received_bytes, + int32 state, + DownloadID db_handle) { + DCHECK(db_handle > 0); + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "UPDATE downloads " + "SET received_bytes=?, state=? WHERE id=?")); + if (!statement) + return false; + + statement.BindInt64(0, received_bytes); + statement.BindInt(1, state); + statement.BindInt64(2, db_handle); + return statement.Run(); +} + +bool DownloadDatabase::UpdateDownloadPath(const FilePath& path, + DownloadID db_handle) { + DCHECK(db_handle > 0); + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "UPDATE downloads SET full_path=? WHERE id=?")); + if (!statement) + return false; + + BindFilePath(statement, path, 0); + statement.BindInt64(1, db_handle); + return statement.Run(); +} + +bool DownloadDatabase::CleanUpInProgressEntries() { + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "UPDATE downloads SET state=? WHERE state=?")); + if (!statement) + return false; + statement.BindInt(0, DownloadItem::CANCELLED); + statement.BindInt(1, DownloadItem::IN_PROGRESS); + return statement.Run(); +} + +int64 DownloadDatabase::CreateDownload(const DownloadCreateInfo& info) { + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "INSERT INTO downloads " + "(full_path, url, start_time, received_bytes, total_bytes, state) " + "VALUES (?, ?, ?, ?, ?, ?)")); + if (!statement) + return 0; + + BindFilePath(statement, info.path, 0); + statement.BindString(1, info.url.spec()); + statement.BindInt64(2, info.start_time.ToTimeT()); + statement.BindInt64(3, info.received_bytes); + statement.BindInt64(4, info.total_bytes); + statement.BindInt(5, info.state); + + if (statement.Run()) + return GetDB().GetLastInsertRowId(); + return 0; +} + +void DownloadDatabase::RemoveDownload(DownloadID db_handle) { + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "DELETE FROM downloads WHERE id=?")); + if (!statement) + return; + + statement.BindInt64(0, db_handle); + statement.Run(); +} + +void DownloadDatabase::RemoveDownloadsBetween(base::Time delete_begin, + base::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. + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "DELETE FROM downloads WHERE start_time >= ? AND start_time < ? " + "AND (State = ? OR State = ?)")); + if (!statement) + return; + + time_t start_time = delete_begin.ToTimeT(); + time_t end_time = delete_end.ToTimeT(); + statement.BindInt64(0, start_time); + statement.BindInt64( + 1, + end_time ? end_time : std::numeric_limits<int64>::max()); + statement.BindInt(2, DownloadItem::COMPLETE); + statement.BindInt(3, DownloadItem::CANCELLED); + statement.Run(); +} + +void DownloadDatabase::SearchDownloads(std::vector<int64>* results, + const string16& search_text) { + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "SELECT id FROM downloads WHERE url LIKE ? " + "OR full_path LIKE ? ORDER BY id")); + if (!statement) + return; + + std::string text("%"); + text.append(UTF16ToUTF8(search_text)); + text.push_back('%'); + statement.BindString(0, text); + statement.BindString(1, text); + + while (statement.Step()) + results->push_back(statement.ColumnInt64(0)); +} + +} // namespace history |