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

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

Issue 8008021: Add new UMA stats to get a handle on Downloads UI Usage (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: uma Created 9 years, 3 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <vector> 8 #include <vector>
9 9
10 #include "base/file_path.h" 10 #include "base/file_path.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "content/browser/browser_thread.h" 13 #include "content/browser/browser_thread.h"
14 #include "content/browser/download/download_item.h" 14 #include "content/browser/download/download_item.h"
15 #include "content/browser/download/download_persistent_store_info.h" 15 #include "content/browser/download/download_persistent_store_info.h"
16 #include "sql/statement.h" 16 #include "sql/statement.h"
17 17
18 // Download schema: 18 // Download schema:
19 // 19 //
20 // id SQLite-generated primary key. 20 // id SQLite-generated primary key.
21 // full_path Location of the download on disk. 21 // full_path Location of the download on disk.
22 // url URL of the downloaded file. 22 // url URL of the downloaded file.
23 // start_time When the download was started. 23 // start_time When the download was started.
24 // received_bytes Total size downloaded. 24 // received_bytes Total size downloaded.
25 // total_bytes Total size of the download. 25 // total_bytes Total size of the download.
26 // state Identifies if this download is completed or not. Not used 26 // state Identifies if this download is completed or not. Not used
27 // directly by the history system. See DownloadItem's 27 // directly by the history system. See DownloadItem's
28 // DownloadState for where this is used. 28 // DownloadState for where this is used.
29 // end_time When the download completed.
30 // opened 1 if the download has ever been opened else 0
29 31
30 namespace history { 32 namespace history {
31 33
32 namespace { 34 namespace {
33 35
34 #if defined(OS_POSIX) 36 #if defined(OS_POSIX)
35 37
36 // Binds/reads the given file path to the given column of the given statement. 38 // Binds/reads the given file path to the given column of the given statement.
37 void BindFilePath(sql::Statement& statement, const FilePath& path, int col) { 39 void BindFilePath(sql::Statement& statement, const FilePath& path, int col) {
38 statement.BindString(col, path.value()); 40 statement.BindString(col, path.value());
(...skipping 11 matching lines...) Expand all
50 FilePath ColumnFilePath(sql::Statement& statement, int col) { 52 FilePath ColumnFilePath(sql::Statement& statement, int col) {
51 return FilePath(UTF8ToUTF16(statement.ColumnString(col))); 53 return FilePath(UTF8ToUTF16(statement.ColumnString(col)));
52 } 54 }
53 55
54 #endif 56 #endif
55 57
56 // Key in the meta_table containing the next id to use for a new download in 58 // Key in the meta_table containing the next id to use for a new download in
57 // this profile. 59 // this profile.
58 static const char kNextDownloadId[] = "next_download_id"; 60 static const char kNextDownloadId[] = "next_download_id";
59 61
62 // Key in the meta_table containing the active schema version of the downloads
63 // table.
64 static const char kDownloadsSchemaVersion[] = "downloads_schema_version";
65
60 } // namespace 66 } // namespace
61 67
62 DownloadDatabase::DownloadDatabase() 68 DownloadDatabase::DownloadDatabase()
63 : owning_thread_set_(false), 69 : owning_thread_set_(false),
64 next_id_(0) { 70 next_id_(0),
71 schema_version_(DOWNLOADS_SCHEMA_VERSION_UNINITIALIZED) {
65 } 72 }
66 73
67 DownloadDatabase::~DownloadDatabase() { 74 DownloadDatabase::~DownloadDatabase() {
68 } 75 }
69 76
70 bool DownloadDatabase::InitDownloadTable() { 77 bool DownloadDatabase::CreateDownloadsTable() {
71 if (!GetDB().DoesTableExist("downloads")) { 78 if (!GetDB().Execute(
72 if (!GetDB().Execute(
73 "CREATE TABLE downloads (" 79 "CREATE TABLE downloads ("
74 "id INTEGER PRIMARY KEY," 80 "id INTEGER PRIMARY KEY,"
75 "full_path LONGVARCHAR NOT NULL," 81 "full_path LONGVARCHAR NOT NULL,"
76 "url LONGVARCHAR NOT NULL," 82 "url LONGVARCHAR NOT NULL,"
77 "start_time INTEGER NOT NULL," 83 "start_time INTEGER NOT NULL,"
78 "received_bytes INTEGER NOT NULL," 84 "received_bytes INTEGER NOT NULL,"
79 "total_bytes INTEGER NOT NULL," 85 "total_bytes INTEGER NOT NULL,"
80 "state INTEGER NOT NULL)")) 86 "state INTEGER NOT NULL,"
81 return false; 87 "end_time INTEGER NOT NULL,"
82 } 88 "opened INTEGER NOT NULL)"))
83 meta_table_.Init(&GetDB(), 0, 0); 89 return false;
84 meta_table_.GetValue(kNextDownloadId, &next_id_); 90 schema_version_ = kCurrentDownloadsSchemaVersion;
85 return true; 91 return true;
86 } 92 }
87 93
94 bool DownloadDatabase::MaybeUpgradeDownloadsSchema() {
95 if (schema_version_ == kCurrentDownloadsSchemaVersion)
96 return true;
97 // Don't rely on the schema always being backwards-compatible.
98 if (schema_version_ > kCurrentDownloadsSchemaVersion)
99 return false;
100 if (schema_version_ == DOWNLOADS_SCHEMA_VERSION_BASE) {
101 if (!GetDB().Execute(
102 "ALTER TABLE downloads ADD COLUMN "
103 "end_time INTEGER NOT NULL DEFAULT 0") ||
104 !GetDB().Execute(
105 "ALTER TABLE downloads ADD COLUMN "
106 "opened INTEGER NOT NULL DEFAULT 0")) {
107 return false;
108 }
109 schema_version_ = DOWNLOADS_SCHEMA_VERSION_OPENED;
110 }
111 return true;
112 }
113
114 bool DownloadDatabase::InitDownloadTable() {
115 meta_table_.Init(&GetDB(), 0, 0);
116 meta_table_.GetValue(kNextDownloadId, &next_id_);
117 int version = schema_version_;
Randy Smith (Not in Mondays) 2011/09/26 18:27:26 Does initializing version do anything here? It lo
benjhayden 2011/09/28 17:35:23 Rewritten to use DoesColumnExist, which is easier
118 if (!meta_table_.GetValue(kDownloadsSchemaVersion, &version)) {
119 version = DOWNLOADS_SCHEMA_VERSION_BASE;
120 }
121 schema_version_ = static_cast<DownloadsSchemaVersion>(version);
122 if (GetDB().DoesTableExist("downloads")) {
123 if (!MaybeUpgradeDownloadsSchema())
124 return false;
125 } else {
126 if (!CreateDownloadsTable())
127 return false;
128 }
129 meta_table_.SetValue(kDownloadsSchemaVersion, schema_version_);
130 return true;
131 }
132
88 bool DownloadDatabase::DropDownloadTable() { 133 bool DownloadDatabase::DropDownloadTable() {
89 return GetDB().Execute("DROP TABLE downloads"); 134 return GetDB().Execute("DROP TABLE downloads");
90 } 135 }
91 136
92 void DownloadDatabase::QueryDownloads( 137 void DownloadDatabase::QueryDownloads(
93 std::vector<DownloadPersistentStoreInfo>* results) { 138 std::vector<DownloadPersistentStoreInfo>* results) {
94 results->clear(); 139 results->clear();
95 140
141 CHECK(schema_version_ >= DOWNLOADS_SCHEMA_VERSION_OPENED);
96 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 142 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
97 "SELECT id, full_path, url, start_time, received_bytes, " 143 "SELECT id, full_path, url, start_time, received_bytes, "
98 "total_bytes, state " 144 "total_bytes, state, end_time, opened "
99 "FROM downloads " 145 "FROM downloads "
100 "ORDER BY start_time")); 146 "ORDER BY start_time"));
101 if (!statement) 147 if (!statement)
102 return; 148 return;
103 149
104 while (statement.Step()) { 150 while (statement.Step()) {
105 DownloadPersistentStoreInfo info; 151 DownloadPersistentStoreInfo info;
106 info.db_handle = statement.ColumnInt64(0); 152 info.db_handle = statement.ColumnInt64(0);
107 153
108 info.path = ColumnFilePath(statement, 1); 154 info.path = ColumnFilePath(statement, 1);
109 info.url = GURL(statement.ColumnString(2)); 155 info.url = GURL(statement.ColumnString(2));
110 info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3)); 156 info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3));
111 info.received_bytes = statement.ColumnInt64(4); 157 info.received_bytes = statement.ColumnInt64(4);
112 info.total_bytes = statement.ColumnInt64(5); 158 info.total_bytes = statement.ColumnInt64(5);
113 info.state = statement.ColumnInt(6); 159 info.state = statement.ColumnInt(6);
160 info.end_time = base::Time::FromTimeT(statement.ColumnInt64(7));
161 info.opened = statement.ColumnInt(8) != 0;
114 results->push_back(info); 162 results->push_back(info);
115 } 163 }
116 } 164 }
117 165
118 bool DownloadDatabase::UpdateDownload(int64 received_bytes, 166 bool DownloadDatabase::UpdateDownload(int64 received_bytes,
119 int32 state, 167 int32 state,
168 const base::Time& end_time,
120 DownloadID db_handle) { 169 DownloadID db_handle) {
121 DCHECK(db_handle > 0); 170 DCHECK(db_handle > 0);
122 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 171 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
123 "UPDATE downloads " 172 "UPDATE downloads "
124 "SET received_bytes=?, state=? WHERE id=?")); 173 "SET received_bytes=?, state=?, end_time=? WHERE id=?"));
125 if (!statement) 174 if (!statement)
126 return false; 175 return false;
127 176
128 statement.BindInt64(0, received_bytes); 177 statement.BindInt64(0, received_bytes);
129 statement.BindInt(1, state); 178 statement.BindInt(1, state);
130 statement.BindInt64(2, db_handle); 179 statement.BindInt64(2, end_time.ToTimeT());
180 statement.BindInt64(3, db_handle);
131 return statement.Run(); 181 return statement.Run();
132 } 182 }
133 183
184 void DownloadDatabase::MarkDownloadOpened(DownloadID db_handle) {
185 CHECK(schema_version_ >= DOWNLOADS_SCHEMA_VERSION_OPENED);
186 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
187 "UPDATE downloads SET opened=? WHERE id=?"));
188 if (!statement)
189 return;
190 statement.BindInt(0, 1);
191 statement.BindInt64(1, db_handle);
192 statement.Run();
193 }
194
134 bool DownloadDatabase::UpdateDownloadPath(const FilePath& path, 195 bool DownloadDatabase::UpdateDownloadPath(const FilePath& path,
135 DownloadID db_handle) { 196 DownloadID db_handle) {
136 DCHECK(db_handle > 0); 197 DCHECK(db_handle > 0);
137 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 198 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
138 "UPDATE downloads SET full_path=? WHERE id=?")); 199 "UPDATE downloads SET full_path=? WHERE id=?"));
139 if (!statement) 200 if (!statement)
140 return false; 201 return false;
141 202
142 BindFilePath(statement, path, 0); 203 BindFilePath(statement, path, 0);
143 statement.BindInt64(1, db_handle); 204 statement.BindInt64(1, db_handle);
(...skipping 12 matching lines...) Expand all
156 217
157 int64 DownloadDatabase::CreateDownload( 218 int64 DownloadDatabase::CreateDownload(
158 const DownloadPersistentStoreInfo& info) { 219 const DownloadPersistentStoreInfo& info) {
159 if (owning_thread_set_) { 220 if (owning_thread_set_) {
160 CHECK_EQ(owning_thread_, base::PlatformThread::CurrentId()); 221 CHECK_EQ(owning_thread_, base::PlatformThread::CurrentId());
161 } else { 222 } else {
162 owning_thread_ = base::PlatformThread::CurrentId(); 223 owning_thread_ = base::PlatformThread::CurrentId();
163 owning_thread_set_ = true; 224 owning_thread_set_ = true;
164 } 225 }
165 226
227 CHECK(schema_version_ >= DOWNLOADS_SCHEMA_VERSION_OPENED);
166 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 228 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
167 "INSERT INTO downloads " 229 "INSERT INTO downloads "
168 "(full_path, url, start_time, received_bytes, total_bytes, state) " 230 "(full_path, url, start_time, received_bytes, total_bytes, state, "
169 "VALUES (?, ?, ?, ?, ?, ?)")); 231 "end_time, opened) "
232 "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"));
170 if (!statement) 233 if (!statement)
171 return 0; 234 return 0;
172 235
173 BindFilePath(statement, info.path, 0); 236 BindFilePath(statement, info.path, 0);
174 statement.BindString(1, info.url.spec()); 237 statement.BindString(1, info.url.spec());
175 statement.BindInt64(2, info.start_time.ToTimeT()); 238 statement.BindInt64(2, info.start_time.ToTimeT());
176 statement.BindInt64(3, info.received_bytes); 239 statement.BindInt64(3, info.received_bytes);
177 statement.BindInt64(4, info.total_bytes); 240 statement.BindInt64(4, info.total_bytes);
178 statement.BindInt(5, info.state); 241 statement.BindInt(5, info.state);
242 statement.BindInt64(6, info.end_time.ToTimeT());
243 statement.BindInt(7, info.opened ? 1 : 0);
179 244
180 if (statement.Run()) { 245 if (statement.Run()) {
181 int64 id = GetDB().GetLastInsertRowId(); 246 int64 id = GetDB().GetLastInsertRowId();
182 247
183 CHECK_EQ(0u, returned_ids_.count(id)); 248 CHECK_EQ(0u, returned_ids_.count(id));
184 returned_ids_.insert(id); 249 returned_ids_.insert(id);
185 250
186 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} 251 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;}
187 meta_table_.SetValue(kNextDownloadId, ++next_id_); 252 meta_table_.SetValue(kNextDownloadId, ++next_id_);
188 253
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 statement.BindInt64( 306 statement.BindInt64(
242 1, 307 1,
243 end_time ? end_time : std::numeric_limits<int64>::max()); 308 end_time ? end_time : std::numeric_limits<int64>::max());
244 statement.BindInt(2, DownloadItem::COMPLETE); 309 statement.BindInt(2, DownloadItem::COMPLETE);
245 statement.BindInt(3, DownloadItem::CANCELLED); 310 statement.BindInt(3, DownloadItem::CANCELLED);
246 statement.BindInt(4, DownloadItem::INTERRUPTED); 311 statement.BindInt(4, DownloadItem::INTERRUPTED);
247 statement.Run(); 312 statement.Run();
248 } 313 }
249 314
250 } // namespace history 315 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698