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