Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(793)

Side by Side Diff: chrome/browser/history/download_database.cc

Issue 10665049: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/browser/history/download_database.h" 5 #include "chrome/browser/history/download_database.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 DownloadDatabase::DownloadDatabase() 69 DownloadDatabase::DownloadDatabase()
70 : owning_thread_set_(false), 70 : owning_thread_set_(false),
71 owning_thread_(0), 71 owning_thread_(0),
72 next_id_(0), 72 next_id_(0),
73 next_db_handle_(0) { 73 next_db_handle_(0) {
74 } 74 }
75 75
76 DownloadDatabase::~DownloadDatabase() { 76 DownloadDatabase::~DownloadDatabase() {
77 } 77 }
78 78
79 void DownloadDatabase::CheckThread() {
80 if (owning_thread_set_) {
81 DCHECK(owning_thread_ == base::PlatformThread::CurrentId());
82 } else {
83 owning_thread_ = base::PlatformThread::CurrentId();
84 owning_thread_set_ = true;
85 }
86 }
87
88 bool DownloadDatabase::EnsureColumnExists( 79 bool DownloadDatabase::EnsureColumnExists(
89 const std::string& name, const std::string& type) { 80 const std::string& name, const std::string& type) {
90 std::string add_col = "ALTER TABLE downloads ADD COLUMN " + name + " " + type; 81 std::string add_col = "ALTER TABLE downloads ADD COLUMN " + name + " " + type;
91 return GetDB().DoesColumnExist("downloads", name.c_str()) || 82 return GetDB().DoesColumnExist("downloads", name.c_str()) ||
92 GetDB().Execute(add_col.c_str()); 83 GetDB().Execute(add_col.c_str());
93 } 84 }
94 85
95 bool DownloadDatabase::InitDownloadTable() { 86 bool DownloadDatabase::InitDownloadTable() {
96 CheckThread();
97 GetMetaTable().GetValue(kNextDownloadId, &next_id_); 87 GetMetaTable().GetValue(kNextDownloadId, &next_id_);
98 if (GetDB().DoesTableExist("downloads")) { 88 if (GetDB().DoesTableExist("downloads")) {
99 return EnsureColumnExists("end_time", "INTEGER NOT NULL DEFAULT 0") && 89 return EnsureColumnExists("end_time", "INTEGER NOT NULL DEFAULT 0") &&
100 EnsureColumnExists("opened", "INTEGER NOT NULL DEFAULT 0"); 90 EnsureColumnExists("opened", "INTEGER NOT NULL DEFAULT 0");
101 } else { 91 } else {
102 return GetDB().Execute(kSchema); 92 return GetDB().Execute(kSchema);
103 } 93 }
104 } 94 }
105 95
106 bool DownloadDatabase::DropDownloadTable() { 96 bool DownloadDatabase::DropDownloadTable() {
107 CheckThread();
108 return GetDB().Execute("DROP TABLE downloads"); 97 return GetDB().Execute("DROP TABLE downloads");
109 } 98 }
110 99
111 void DownloadDatabase::QueryDownloads( 100 void DownloadDatabase::QueryDownloads(
112 std::vector<DownloadPersistentStoreInfo>* results) { 101 std::vector<DownloadPersistentStoreInfo>* results) {
113 CheckThread();
114 results->clear(); 102 results->clear();
115 if (next_db_handle_ < 1) 103 if (next_db_handle_ < 1)
116 next_db_handle_ = 1; 104 next_db_handle_ = 1;
117 std::set<DownloadID> db_handles; 105 std::set<DownloadID> db_handles;
118 106
119 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 107 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
120 "SELECT id, full_path, url, start_time, received_bytes, " 108 "SELECT id, full_path, url, start_time, received_bytes, "
121 "total_bytes, state, end_time, opened " 109 "total_bytes, state, end_time, opened "
122 "FROM downloads " 110 "FROM downloads "
123 "ORDER BY start_time")); 111 "ORDER BY start_time"));
(...skipping 14 matching lines...) Expand all
138 next_db_handle_ = info.db_handle + 1; 126 next_db_handle_ = info.db_handle + 1;
139 if (!db_handles.insert(info.db_handle).second) { 127 if (!db_handles.insert(info.db_handle).second) {
140 // info.db_handle was already in db_handles. The database is corrupt. 128 // info.db_handle was already in db_handles. The database is corrupt.
141 base::debug::Alias(&info.db_handle); 129 base::debug::Alias(&info.db_handle);
142 DCHECK(false); 130 DCHECK(false);
143 } 131 }
144 } 132 }
145 } 133 }
146 134
147 bool DownloadDatabase::UpdateDownload(const DownloadPersistentStoreInfo& data) { 135 bool DownloadDatabase::UpdateDownload(const DownloadPersistentStoreInfo& data) {
148 CheckThread();
149 DCHECK(data.db_handle > 0); 136 DCHECK(data.db_handle > 0);
150 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 137 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
151 "UPDATE downloads " 138 "UPDATE downloads "
152 "SET received_bytes=?, state=?, end_time=?, opened=? WHERE id=?")); 139 "SET received_bytes=?, state=?, end_time=?, opened=? WHERE id=?"));
153 statement.BindInt64(0, data.received_bytes); 140 statement.BindInt64(0, data.received_bytes);
154 statement.BindInt(1, data.state); 141 statement.BindInt(1, data.state);
155 statement.BindInt64(2, data.end_time.ToTimeT()); 142 statement.BindInt64(2, data.end_time.ToTimeT());
156 statement.BindInt(3, (data.opened ? 1 : 0)); 143 statement.BindInt(3, (data.opened ? 1 : 0));
157 statement.BindInt64(4, data.db_handle); 144 statement.BindInt64(4, data.db_handle);
158 145
159 return statement.Run(); 146 return statement.Run();
160 } 147 }
161 148
162 bool DownloadDatabase::UpdateDownloadPath(const FilePath& path, 149 bool DownloadDatabase::UpdateDownloadPath(const FilePath& path,
163 DownloadID db_handle) { 150 DownloadID db_handle) {
164 CheckThread();
165 DCHECK(db_handle > 0); 151 DCHECK(db_handle > 0);
166 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 152 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
167 "UPDATE downloads SET full_path=? WHERE id=?")); 153 "UPDATE downloads SET full_path=? WHERE id=?"));
168 BindFilePath(statement, path, 0); 154 BindFilePath(statement, path, 0);
169 statement.BindInt64(1, db_handle); 155 statement.BindInt64(1, db_handle);
170 156
171 return statement.Run(); 157 return statement.Run();
172 } 158 }
173 159
174 bool DownloadDatabase::CleanUpInProgressEntries() { 160 bool DownloadDatabase::CleanUpInProgressEntries() {
175 CheckThread();
176 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 161 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
177 "UPDATE downloads SET state=? WHERE state=?")); 162 "UPDATE downloads SET state=? WHERE state=?"));
178 statement.BindInt(0, DownloadItem::CANCELLED); 163 statement.BindInt(0, DownloadItem::CANCELLED);
179 statement.BindInt(1, DownloadItem::IN_PROGRESS); 164 statement.BindInt(1, DownloadItem::IN_PROGRESS);
180 165
181 return statement.Run(); 166 return statement.Run();
182 } 167 }
183 168
184 int64 DownloadDatabase::CreateDownload( 169 int64 DownloadDatabase::CreateDownload(
185 const DownloadPersistentStoreInfo& info) { 170 const DownloadPersistentStoreInfo& info) {
186 CheckThread();
187 171
188 if (next_db_handle_ == 0) { 172 if (next_db_handle_ == 0) {
189 // This is unlikely. All current known tests and users already call 173 // This is unlikely. All current known tests and users already call
190 // QueryDownloads() before CreateDownload(). 174 // QueryDownloads() before CreateDownload().
191 std::vector<DownloadPersistentStoreInfo> results; 175 std::vector<DownloadPersistentStoreInfo> results;
192 QueryDownloads(&results); 176 QueryDownloads(&results);
193 CHECK_NE(0, next_db_handle_); 177 CHECK_NE(0, next_db_handle_);
194 } 178 }
195 179
196 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 180 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
(...skipping 16 matching lines...) Expand all
213 197
214 if (statement.Run()) { 198 if (statement.Run()) {
215 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} 199 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;}
216 GetMetaTable().SetValue(kNextDownloadId, ++next_id_); 200 GetMetaTable().SetValue(kNextDownloadId, ++next_id_);
217 201
218 return db_handle; 202 return db_handle;
219 } 203 }
220 return 0; 204 return 0;
221 } 205 }
222 206
223 void DownloadDatabase::RemoveDownload(DownloadID db_handle) { 207 void DownloadDatabase::RemoveDownloads(const std::set<DownloadID>& handles) {
224 CheckThread(); 208 base::TimeTicks started_removing = base::TimeTicks::Now();
225 209 for (std::set<DownloadID>::const_iterator it = handles.begin();
226 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 210 it != handles.end(); ++it) {
227 "DELETE FROM downloads WHERE id=?")); 211 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
228 statement.BindInt64(0, db_handle); 212 "DELETE FROM downloads WHERE id=?"));
229 213 statement.BindInt64(0, *it);
230 statement.Run(); 214 statement.Run();
231 }
232
233 bool DownloadDatabase::RemoveDownloadsBetween(base::Time delete_begin,
234 base::Time delete_end) {
235 CheckThread();
236 time_t start_time = delete_begin.ToTimeT();
237 time_t end_time = delete_end.ToTimeT();
238
239 int num_downloads_deleted = -1;
240 {
241 sql::Statement count(GetDB().GetCachedStatement(SQL_FROM_HERE,
242 "SELECT count(*) FROM downloads WHERE start_time >= ? "
243 "AND start_time < ? AND (State = ? OR State = ? OR State = ?)"));
244 count.BindInt64(0, start_time);
245 count.BindInt64(
246 1,
247 end_time ? end_time : std::numeric_limits<int64>::max());
248 count.BindInt(2, DownloadItem::COMPLETE);
249 count.BindInt(3, DownloadItem::CANCELLED);
250 count.BindInt(4, DownloadItem::INTERRUPTED);
251 if (count.Step())
252 num_downloads_deleted = count.ColumnInt(0);
253 } 215 }
254 216 int num_downloads_deleted = handles.size(); // TODO(benjhayden) measure
255
256 bool success = false;
257 base::TimeTicks started_removing = base::TimeTicks::Now();
258 {
259 // This does not use an index. We currently aren't likely to have enough
260 // downloads where an index by time will give us a lot of benefit.
261 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
262 "DELETE FROM downloads WHERE start_time >= ? AND start_time < ? "
263 "AND (State = ? OR State = ? OR State = ?)"));
264 statement.BindInt64(0, start_time);
265 statement.BindInt64(
266 1,
267 end_time ? end_time : std::numeric_limits<int64>::max());
268 statement.BindInt(2, DownloadItem::COMPLETE);
269 statement.BindInt(3, DownloadItem::CANCELLED);
270 statement.BindInt(4, DownloadItem::INTERRUPTED);
271
272 success = statement.Run();
273 }
274
275 base::TimeTicks finished_removing = base::TimeTicks::Now();
276
277 if (num_downloads_deleted >= 0) { 217 if (num_downloads_deleted >= 0) {
218 base::TimeTicks finished_removing = base::TimeTicks::Now();
278 UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCount", 219 UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCount",
279 num_downloads_deleted); 220 num_downloads_deleted);
280 base::TimeDelta micros = (1000 * (finished_removing - started_removing)); 221 base::TimeDelta micros = (1000 * (finished_removing - started_removing));
281 UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTime", micros); 222 UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTime", micros);
282 if (num_downloads_deleted > 0) { 223 if (num_downloads_deleted > 0) {
283 UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord", 224 UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord",
284 (1000 * micros) / num_downloads_deleted); 225 (1000 * micros) / num_downloads_deleted);
285 } 226 }
286 } 227 }
287
288 return success;
289 } 228 }
290 229
291 } // namespace history 230 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698