blob: aa3dbdef9dc5ec42352d28826e530961ca210e60 [file] [log] [blame]
[email protected]e53668962010-06-23 15:35:251// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]42eb6b02008-11-25 23:14:465#include "chrome/browser/history/download_database.h"
6
initial.commit09911bf2008-07-26 23:55:297#include <limits>
8#include <vector>
9
[email protected]765b44502009-10-02 05:01:4210#include "app/sql/connection.h"
11#include "app/sql/statement.h"
[email protected]e53668962010-06-23 15:35:2512#include "base/file_path.h"
[email protected]9da5f162009-12-11 16:30:1613#include "base/utf_string_conversions.h"
[email protected]765b44502009-10-02 05:01:4214#include "build/build_config.h"
[email protected]6c69796d2010-07-16 21:41:1615#include "chrome/browser/download/download_item.h"
initial.commit09911bf2008-07-26 23:55:2916#include "chrome/browser/history/download_types.h"
[email protected]e1acf6f2008-10-27 20:43:3317
initial.commit09911bf2008-07-26 23:55:2918// Download schema:
19//
20// id SQLite-generated primary key.
21// full_path Location of the download on disk.
22// url URL of the downloaded file.
23// start_time When the download was started.
24// received_bytes Total size downloaded.
25// total_bytes Total size of the download.
26// state Identifies if this download is completed or not. Not used
27// directly by the history system. See DownloadItem's
28// DownloadState for where this is used.
29
30namespace history {
31
[email protected]765b44502009-10-02 05:01:4232namespace {
33
34#if defined(OS_POSIX)
35
36// Binds/reads the given file path to the given column of the given statement.
37void BindFilePath(sql::Statement& statement, const FilePath& path, int col) {
38 statement.BindString(col, path.value());
39}
40FilePath ColumnFilePath(sql::Statement& statement, int col) {
41 return FilePath(statement.ColumnString(col));
42}
43
44#else
45
46// See above.
47void BindFilePath(sql::Statement& statement, const FilePath& path, int col) {
48 statement.BindString(col, UTF16ToUTF8(path.value()));
49}
50FilePath ColumnFilePath(sql::Statement& statement, int col) {
51 return FilePath(UTF8ToUTF16(statement.ColumnString(col)));
52}
53
54#endif
55
56} // namespace
57
initial.commit09911bf2008-07-26 23:55:2958DownloadDatabase::DownloadDatabase() {
59}
60
61DownloadDatabase::~DownloadDatabase() {
62}
63
64bool DownloadDatabase::InitDownloadTable() {
[email protected]765b44502009-10-02 05:01:4265 if (!GetDB().DoesTableExist("downloads")) {
66 if (!GetDB().Execute(
67 "CREATE TABLE downloads ("
68 "id INTEGER PRIMARY KEY,"
69 "full_path LONGVARCHAR NOT NULL,"
70 "url LONGVARCHAR NOT NULL,"
71 "start_time INTEGER NOT NULL,"
72 "received_bytes INTEGER NOT NULL,"
73 "total_bytes INTEGER NOT NULL,"
74 "state INTEGER NOT NULL)"))
initial.commit09911bf2008-07-26 23:55:2975 return false;
76 }
77 return true;
78}
79
80bool DownloadDatabase::DropDownloadTable() {
[email protected]765b44502009-10-02 05:01:4281 return GetDB().Execute("DROP TABLE downloads");
initial.commit09911bf2008-07-26 23:55:2982}
83
[email protected]d3216442009-03-05 21:07:2784void DownloadDatabase::QueryDownloads(
85 std::vector<DownloadCreateInfo>* results) {
initial.commit09911bf2008-07-26 23:55:2986 results->clear();
87
[email protected]765b44502009-10-02 05:01:4288 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
initial.commit09911bf2008-07-26 23:55:2989 "SELECT id, full_path, url, start_time, received_bytes, "
90 "total_bytes, state "
91 "FROM downloads "
[email protected]765b44502009-10-02 05:01:4292 "ORDER BY start_time"));
93 if (!statement)
initial.commit09911bf2008-07-26 23:55:2994 return;
95
[email protected]765b44502009-10-02 05:01:4296 while (statement.Step()) {
initial.commit09911bf2008-07-26 23:55:2997 DownloadCreateInfo info;
[email protected]765b44502009-10-02 05:01:4298 info.db_handle = statement.ColumnInt64(0);
99
100 info.path = ColumnFilePath(statement, 1);
101 info.url = GURL(statement.ColumnString(2));
102 info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3));
103 info.received_bytes = statement.ColumnInt64(4);
104 info.total_bytes = statement.ColumnInt64(5);
105 info.state = statement.ColumnInt(6);
initial.commit09911bf2008-07-26 23:55:29106 results->push_back(info);
107 }
108}
109
110bool DownloadDatabase::UpdateDownload(int64 received_bytes,
111 int32 state,
112 DownloadID db_handle) {
113 DCHECK(db_handle > 0);
[email protected]765b44502009-10-02 05:01:42114 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
initial.commit09911bf2008-07-26 23:55:29115 "UPDATE downloads "
[email protected]765b44502009-10-02 05:01:42116 "SET received_bytes=?, state=? WHERE id=?"));
117 if (!statement)
initial.commit09911bf2008-07-26 23:55:29118 return false;
119
[email protected]765b44502009-10-02 05:01:42120 statement.BindInt64(0, received_bytes);
121 statement.BindInt(1, state);
122 statement.BindInt64(2, db_handle);
123 return statement.Run();
initial.commit09911bf2008-07-26 23:55:29124}
125
[email protected]e53668962010-06-23 15:35:25126bool DownloadDatabase::UpdateDownloadPath(const FilePath& path,
[email protected]9ccbb372008-10-10 18:50:32127 DownloadID db_handle) {
128 DCHECK(db_handle > 0);
[email protected]765b44502009-10-02 05:01:42129 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
130 "UPDATE downloads SET full_path=? WHERE id=?"));
131 if (!statement)
[email protected]9ccbb372008-10-10 18:50:32132 return false;
133
[email protected]e53668962010-06-23 15:35:25134 BindFilePath(statement, path, 0);
[email protected]765b44502009-10-02 05:01:42135 statement.BindInt64(1, db_handle);
136 return statement.Run();
[email protected]9ccbb372008-10-10 18:50:32137}
138
[email protected]024f2f02010-04-30 22:51:46139bool DownloadDatabase::CleanUpInProgressEntries() {
140 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
141 "UPDATE downloads SET state=? WHERE state=?"));
142 if (!statement)
143 return false;
144 statement.BindInt(0, DownloadItem::CANCELLED);
145 statement.BindInt(1, DownloadItem::IN_PROGRESS);
146 return statement.Run();
147}
148
initial.commit09911bf2008-07-26 23:55:29149int64 DownloadDatabase::CreateDownload(const DownloadCreateInfo& info) {
[email protected]765b44502009-10-02 05:01:42150 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
initial.commit09911bf2008-07-26 23:55:29151 "INSERT INTO downloads "
152 "(full_path, url, start_time, received_bytes, total_bytes, state) "
[email protected]765b44502009-10-02 05:01:42153 "VALUES (?, ?, ?, ?, ?, ?)"));
154 if (!statement)
initial.commit09911bf2008-07-26 23:55:29155 return 0;
156
[email protected]765b44502009-10-02 05:01:42157 BindFilePath(statement, info.path, 0);
158 statement.BindString(1, info.url.spec());
159 statement.BindInt64(2, info.start_time.ToTimeT());
160 statement.BindInt64(3, info.received_bytes);
161 statement.BindInt64(4, info.total_bytes);
162 statement.BindInt(5, info.state);
initial.commit09911bf2008-07-26 23:55:29163
[email protected]765b44502009-10-02 05:01:42164 if (statement.Run())
165 return GetDB().GetLastInsertRowId();
initial.commit09911bf2008-07-26 23:55:29166 return 0;
167}
168
169void DownloadDatabase::RemoveDownload(DownloadID db_handle) {
[email protected]765b44502009-10-02 05:01:42170 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
171 "DELETE FROM downloads WHERE id=?"));
172 if (!statement)
initial.commit09911bf2008-07-26 23:55:29173 return;
174
[email protected]765b44502009-10-02 05:01:42175 statement.BindInt64(0, db_handle);
176 statement.Run();
initial.commit09911bf2008-07-26 23:55:29177}
178
[email protected]765b44502009-10-02 05:01:42179void DownloadDatabase::RemoveDownloadsBetween(base::Time delete_begin,
180 base::Time delete_end) {
initial.commit09911bf2008-07-26 23:55:29181 // This does not use an index. We currently aren't likely to have enough
182 // downloads where an index by time will give us a lot of benefit.
[email protected]765b44502009-10-02 05:01:42183 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
initial.commit09911bf2008-07-26 23:55:29184 "DELETE FROM downloads WHERE start_time >= ? AND start_time < ? "
[email protected]765b44502009-10-02 05:01:42185 "AND (State = ? OR State = ?)"));
186 if (!statement)
initial.commit09911bf2008-07-26 23:55:29187 return;
188
189 time_t start_time = delete_begin.ToTimeT();
190 time_t end_time = delete_end.ToTimeT();
[email protected]765b44502009-10-02 05:01:42191 statement.BindInt64(0, start_time);
192 statement.BindInt64(
[email protected]d3216442009-03-05 21:07:27193 1,
194 end_time ? end_time : std::numeric_limits<int64>::max());
[email protected]765b44502009-10-02 05:01:42195 statement.BindInt(2, DownloadItem::COMPLETE);
196 statement.BindInt(3, DownloadItem::CANCELLED);
197 statement.Run();
initial.commit09911bf2008-07-26 23:55:29198}
199
200void DownloadDatabase::SearchDownloads(std::vector<int64>* results,
[email protected]e53668962010-06-23 15:35:25201 const string16& search_text) {
[email protected]765b44502009-10-02 05:01:42202 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
initial.commit09911bf2008-07-26 23:55:29203 "SELECT id FROM downloads WHERE url LIKE ? "
[email protected]765b44502009-10-02 05:01:42204 "OR full_path LIKE ? ORDER BY id"));
205 if (!statement)
initial.commit09911bf2008-07-26 23:55:29206 return;
207
[email protected]765b44502009-10-02 05:01:42208 std::string text("%");
[email protected]e53668962010-06-23 15:35:25209 text.append(UTF16ToUTF8(search_text));
[email protected]765b44502009-10-02 05:01:42210 text.push_back('%');
211 statement.BindString(0, text);
212 statement.BindString(1, text);
initial.commit09911bf2008-07-26 23:55:29213
[email protected]765b44502009-10-02 05:01:42214 while (statement.Step())
215 results->push_back(statement.ColumnInt64(0));
initial.commit09911bf2008-07-26 23:55:29216}
217
218} // namespace history