summaryrefslogtreecommitdiffstats
path: root/chrome/browser/history/download_database.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/history/download_database.cc')
-rw-r--r--chrome/browser/history/download_database.cc218
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