| OLD | NEW |
| 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 void DownloadDatabase::QueryDownloads( | 119 void DownloadDatabase::QueryDownloads( |
| 120 std::vector<DownloadPersistentStoreInfo>* results) { | 120 std::vector<DownloadPersistentStoreInfo>* results) { |
| 121 CheckThread(); | 121 CheckThread(); |
| 122 results->clear(); | 122 results->clear(); |
| 123 | 123 |
| 124 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 124 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 125 "SELECT id, full_path, url, start_time, received_bytes, " | 125 "SELECT id, full_path, url, start_time, received_bytes, " |
| 126 "total_bytes, state, end_time, opened " | 126 "total_bytes, state, end_time, opened " |
| 127 "FROM downloads " | 127 "FROM downloads " |
| 128 "ORDER BY start_time")); | 128 "ORDER BY start_time")); |
| 129 if (!statement) | |
| 130 return; | |
| 131 | 129 |
| 132 while (statement.Step()) { | 130 while (statement.Step()) { |
| 133 DownloadPersistentStoreInfo info; | 131 DownloadPersistentStoreInfo info; |
| 134 info.db_handle = statement.ColumnInt64(0); | 132 info.db_handle = statement.ColumnInt64(0); |
| 135 | 133 |
| 136 info.path = ColumnFilePath(statement, 1); | 134 info.path = ColumnFilePath(statement, 1); |
| 137 info.url = GURL(statement.ColumnString(2)); | 135 info.url = GURL(statement.ColumnString(2)); |
| 138 info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3)); | 136 info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3)); |
| 139 info.received_bytes = statement.ColumnInt64(4); | 137 info.received_bytes = statement.ColumnInt64(4); |
| 140 info.total_bytes = statement.ColumnInt64(5); | 138 info.total_bytes = statement.ColumnInt64(5); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 152 returned_ids_.insert(info.db_handle); | 150 returned_ids_.insert(info.db_handle); |
| 153 } | 151 } |
| 154 } | 152 } |
| 155 | 153 |
| 156 bool DownloadDatabase::UpdateDownload(const DownloadPersistentStoreInfo& data) { | 154 bool DownloadDatabase::UpdateDownload(const DownloadPersistentStoreInfo& data) { |
| 157 CheckThread(); | 155 CheckThread(); |
| 158 DCHECK(data.db_handle > 0); | 156 DCHECK(data.db_handle > 0); |
| 159 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 157 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 160 "UPDATE downloads " | 158 "UPDATE downloads " |
| 161 "SET received_bytes=?, state=?, end_time=?, opened=? WHERE id=?")); | 159 "SET received_bytes=?, state=?, end_time=?, opened=? WHERE id=?")); |
| 162 if (!statement) | |
| 163 return false; | |
| 164 | |
| 165 statement.BindInt64(0, data.received_bytes); | 160 statement.BindInt64(0, data.received_bytes); |
| 166 statement.BindInt(1, data.state); | 161 statement.BindInt(1, data.state); |
| 167 statement.BindInt64(2, data.end_time.ToTimeT()); | 162 statement.BindInt64(2, data.end_time.ToTimeT()); |
| 168 statement.BindInt(3, (data.opened ? 1 : 0)); | 163 statement.BindInt(3, (data.opened ? 1 : 0)); |
| 169 statement.BindInt64(4, data.db_handle); | 164 statement.BindInt64(4, data.db_handle); |
| 165 |
| 170 return statement.Run(); | 166 return statement.Run(); |
| 171 } | 167 } |
| 172 | 168 |
| 173 bool DownloadDatabase::UpdateDownloadPath(const FilePath& path, | 169 bool DownloadDatabase::UpdateDownloadPath(const FilePath& path, |
| 174 DownloadID db_handle) { | 170 DownloadID db_handle) { |
| 175 CheckThread(); | 171 CheckThread(); |
| 176 DCHECK(db_handle > 0); | 172 DCHECK(db_handle > 0); |
| 177 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 173 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 178 "UPDATE downloads SET full_path=? WHERE id=?")); | 174 "UPDATE downloads SET full_path=? WHERE id=?")); |
| 179 if (!statement) | |
| 180 return false; | |
| 181 | |
| 182 BindFilePath(statement, path, 0); | 175 BindFilePath(statement, path, 0); |
| 183 statement.BindInt64(1, db_handle); | 176 statement.BindInt64(1, db_handle); |
| 177 |
| 184 return statement.Run(); | 178 return statement.Run(); |
| 185 } | 179 } |
| 186 | 180 |
| 187 bool DownloadDatabase::CleanUpInProgressEntries() { | 181 bool DownloadDatabase::CleanUpInProgressEntries() { |
| 188 CheckThread(); | 182 CheckThread(); |
| 189 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 183 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 190 "UPDATE downloads SET state=? WHERE state=?")); | 184 "UPDATE downloads SET state=? WHERE state=?")); |
| 191 if (!statement) | |
| 192 return false; | |
| 193 statement.BindInt(0, DownloadItem::CANCELLED); | 185 statement.BindInt(0, DownloadItem::CANCELLED); |
| 194 statement.BindInt(1, DownloadItem::IN_PROGRESS); | 186 statement.BindInt(1, DownloadItem::IN_PROGRESS); |
| 187 |
| 195 return statement.Run(); | 188 return statement.Run(); |
| 196 } | 189 } |
| 197 | 190 |
| 198 int64 DownloadDatabase::CreateDownload( | 191 int64 DownloadDatabase::CreateDownload( |
| 199 const DownloadPersistentStoreInfo& info) { | 192 const DownloadPersistentStoreInfo& info) { |
| 200 CheckThread(); | 193 CheckThread(); |
| 201 | 194 |
| 202 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 195 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 203 "INSERT INTO downloads " | 196 "INSERT INTO downloads " |
| 204 "(full_path, url, start_time, received_bytes, total_bytes, state, " | 197 "(full_path, url, start_time, received_bytes, total_bytes, state, " |
| 205 "end_time, opened) " | 198 "end_time, opened) " |
| 206 "VALUES (?, ?, ?, ?, ?, ?, ?, ?)")); | 199 "VALUES (?, ?, ?, ?, ?, ?, ?, ?)")); |
| 207 if (!statement) | |
| 208 return 0; | |
| 209 | |
| 210 BindFilePath(statement, info.path, 0); | 200 BindFilePath(statement, info.path, 0); |
| 211 statement.BindString(1, info.url.spec()); | 201 statement.BindString(1, info.url.spec()); |
| 212 statement.BindInt64(2, info.start_time.ToTimeT()); | 202 statement.BindInt64(2, info.start_time.ToTimeT()); |
| 213 statement.BindInt64(3, info.received_bytes); | 203 statement.BindInt64(3, info.received_bytes); |
| 214 statement.BindInt64(4, info.total_bytes); | 204 statement.BindInt64(4, info.total_bytes); |
| 215 statement.BindInt(5, info.state); | 205 statement.BindInt(5, info.state); |
| 216 statement.BindInt64(6, info.end_time.ToTimeT()); | 206 statement.BindInt64(6, info.end_time.ToTimeT()); |
| 217 statement.BindInt(7, info.opened ? 1 : 0); | 207 statement.BindInt(7, info.opened ? 1 : 0); |
| 218 | 208 |
| 219 if (statement.Run()) { | 209 if (statement.Run()) { |
| 220 int64 id = GetDB().GetLastInsertRowId(); | 210 int64 id = GetDB().GetLastInsertRowId(); |
| 221 | 211 |
| 222 if (returned_ids_.count(id) != 0) { | 212 if (returned_ids_.count(id) != 0) { |
| 223 // We have an invariant violation and we're going to crash. Take a | 213 // We have an invariant violation and we're going to crash. Take a |
| 224 // moment more before crashing to figure out if it's a returned_ids_/DB | 214 // moment more before crashing to figure out if it's a returned_ids_/DB |
| 225 // inconsistency, or an inconsistency inside the DB. | 215 // inconsistency, or an inconsistency inside the DB. |
| 226 sql::Statement dbg_statement(GetDB().GetCachedStatement( | 216 sql::Statement dbg_statement(GetDB().GetCachedStatement( |
| 227 SQL_FROM_HERE, | 217 SQL_FROM_HERE, |
| 228 "SELECT id FROM downloads;")); | 218 "SELECT id FROM downloads;")); |
| 229 CHECK_96627(dbg_statement); | 219 CHECK_96627(dbg_statement.is_valid()); |
| 230 | 220 |
| 231 std::set<int64> database_ids; | 221 std::set<int64> database_ids; |
| 232 while (dbg_statement.Step()) { | 222 while (dbg_statement.Step()) { |
| 233 bool success = database_ids.insert(dbg_statement.ColumnInt64(0)).second; | 223 bool success = database_ids.insert(dbg_statement.ColumnInt64(0)).second; |
| 234 CHECK_96627(success); | 224 CHECK_96627(success); |
| 235 } | 225 } |
| 236 CHECK_96627(false); | 226 CHECK_96627(false); |
| 237 } | 227 } |
| 238 | 228 |
| 239 returned_ids_.insert(id); | 229 returned_ids_.insert(id); |
| 240 | 230 |
| 241 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} | 231 // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;} |
| 242 meta_table_.SetValue(kNextDownloadId, ++next_id_); | 232 meta_table_.SetValue(kNextDownloadId, ++next_id_); |
| 243 | 233 |
| 244 return id; | 234 return id; |
| 245 } | 235 } |
| 246 return 0; | 236 return 0; |
| 247 } | 237 } |
| 248 | 238 |
| 249 void DownloadDatabase::RemoveDownload(DownloadID db_handle) { | 239 void DownloadDatabase::RemoveDownload(DownloadID db_handle) { |
| 250 CheckThread(); | 240 CheckThread(); |
| 251 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 241 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 252 "DELETE FROM downloads WHERE id=?")); | 242 "DELETE FROM downloads WHERE id=?")); |
| 253 if (!statement) | 243 statement.BindInt64(0, db_handle); |
| 244 |
| 245 if (!statement.Run()) |
| 254 return; | 246 return; |
| 255 | 247 |
| 256 statement.BindInt64(0, db_handle); | 248 // TODO(rdsmith): Remove when http://crbug.com/96627 is resolved. |
| 257 if (statement.Run()) | 249 returned_ids_.erase(db_handle); |
| 258 // TODO(rdsmith): Remove when http://crbug.com/96627 is resolved. | |
| 259 returned_ids_.erase(db_handle); | |
| 260 } | 250 } |
| 261 | 251 |
| 262 void DownloadDatabase::RemoveDownloadsBetween(base::Time delete_begin, | 252 bool DownloadDatabase::RemoveDownloadsBetween(base::Time delete_begin, |
| 263 base::Time delete_end) { | 253 base::Time delete_end) { |
| 264 CheckThread(); | 254 CheckThread(); |
| 265 time_t start_time = delete_begin.ToTimeT(); | 255 time_t start_time = delete_begin.ToTimeT(); |
| 266 time_t end_time = delete_end.ToTimeT(); | 256 time_t end_time = delete_end.ToTimeT(); |
| 267 | 257 |
| 268 // TODO(rdsmith): Remove when http://crbug.com/96627 is resolved. | 258 // TODO(rdsmith): Remove when http://crbug.com/96627 is resolved. |
| 269 { | 259 { |
| 270 sql::Statement dbg_statement(GetDB().GetCachedStatement( | 260 sql::Statement dbg_statement(GetDB().GetCachedStatement( |
| 271 SQL_FROM_HERE, | 261 SQL_FROM_HERE, |
| 272 "SELECT id FROM downloads WHERE start_time >= ? AND start_time < ? " | 262 "SELECT id FROM downloads WHERE start_time >= ? AND start_time < ? " |
| 273 "AND (State = ? OR State = ? OR State = ?)")); | 263 "AND (State = ? OR State = ? OR State = ?)")); |
| 274 if (!dbg_statement) | |
| 275 return; | |
| 276 dbg_statement.BindInt64(0, start_time); | 264 dbg_statement.BindInt64(0, start_time); |
| 277 dbg_statement.BindInt64( | 265 dbg_statement.BindInt64( |
| 278 1, | 266 1, |
| 279 end_time ? end_time : std::numeric_limits<int64>::max()); | 267 end_time ? end_time : std::numeric_limits<int64>::max()); |
| 280 dbg_statement.BindInt(2, DownloadItem::COMPLETE); | 268 dbg_statement.BindInt(2, DownloadItem::COMPLETE); |
| 281 dbg_statement.BindInt(3, DownloadItem::CANCELLED); | 269 dbg_statement.BindInt(3, DownloadItem::CANCELLED); |
| 282 dbg_statement.BindInt(4, DownloadItem::INTERRUPTED); | 270 dbg_statement.BindInt(4, DownloadItem::INTERRUPTED); |
| 271 |
| 272 if (!dbg_statement.is_valid()) |
| 273 return false; |
| 274 |
| 283 while (dbg_statement.Step()) { | 275 while (dbg_statement.Step()) { |
| 284 int64 id_to_delete = dbg_statement.ColumnInt64(0); | 276 int64 id_to_delete = dbg_statement.ColumnInt64(0); |
| 285 returned_ids_.erase(id_to_delete); | 277 returned_ids_.erase(id_to_delete); |
| 286 } | 278 } |
| 287 int last_error_code = GetDB().GetErrorCode(); | 279 int last_error_code = GetDB().GetErrorCode(); |
| 288 base::debug::Alias(&last_error_code); | 280 base::debug::Alias(&last_error_code); |
| 289 CHECK_96627(dbg_statement.Succeeded()); | 281 CHECK_96627(dbg_statement.Succeeded()); |
| 290 } | 282 } |
| 291 | 283 |
| 292 // This does not use an index. We currently aren't likely to have enough | 284 // This does not use an index. We currently aren't likely to have enough |
| 293 // downloads where an index by time will give us a lot of benefit. | 285 // downloads where an index by time will give us a lot of benefit. |
| 294 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 286 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
| 295 "DELETE FROM downloads WHERE start_time >= ? AND start_time < ? " | 287 "DELETE FROM downloads WHERE start_time >= ? AND start_time < ? " |
| 296 "AND (State = ? OR State = ? OR State = ?)")); | 288 "AND (State = ? OR State = ? OR State = ?)")); |
| 297 if (!statement) | |
| 298 return; | |
| 299 | |
| 300 statement.BindInt64(0, start_time); | 289 statement.BindInt64(0, start_time); |
| 301 statement.BindInt64( | 290 statement.BindInt64( |
| 302 1, | 291 1, |
| 303 end_time ? end_time : std::numeric_limits<int64>::max()); | 292 end_time ? end_time : std::numeric_limits<int64>::max()); |
| 304 statement.BindInt(2, DownloadItem::COMPLETE); | 293 statement.BindInt(2, DownloadItem::COMPLETE); |
| 305 statement.BindInt(3, DownloadItem::CANCELLED); | 294 statement.BindInt(3, DownloadItem::CANCELLED); |
| 306 statement.BindInt(4, DownloadItem::INTERRUPTED); | 295 statement.BindInt(4, DownloadItem::INTERRUPTED); |
| 307 statement.Run(); | 296 |
| 297 return statement.Run(); |
| 308 } | 298 } |
| 309 | 299 |
| 310 } // namespace history | 300 } // namespace history |
| OLD | NEW |