Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |