Index: chrome/browser/history/download_database.cc |
diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc |
index 0f8dca6af414c710ad7aa1e9b14a97950140bec7..6ce94890bed26dfa73271770781eadcfc6d204fd 100644 |
--- a/chrome/browser/history/download_database.cc |
+++ b/chrome/browser/history/download_database.cc |
@@ -16,7 +16,7 @@ |
// Download schema: |
// |
-// id SQLite-generated primary key. |
+// pid DownloadPrefs-generated unique persistent identifier. |
// full_path Location of the download on disk. |
// url URL of the downloaded file. |
// start_time When the download was started. |
@@ -61,77 +61,136 @@ DownloadDatabase::~DownloadDatabase() { |
} |
bool DownloadDatabase::InitDownloadTable() { |
- if (!GetDB().DoesTableExist("downloads")) { |
- if (!GetDB().Execute( |
+ return GetDB().DoesTableExist("downloads") || |
+ GetDB().Execute( |
"CREATE TABLE downloads (" |
- "id INTEGER PRIMARY KEY," |
+ "pid INTEGER PRIMARY KEY," |
"full_path LONGVARCHAR NOT NULL," |
"url LONGVARCHAR NOT NULL," |
"start_time INTEGER NOT NULL," |
"received_bytes INTEGER NOT NULL," |
"total_bytes INTEGER NOT NULL," |
- "state INTEGER NOT NULL)")) |
- return false; |
- } |
- return true; |
+ "state INTEGER NOT NULL)"); |
} |
bool DownloadDatabase::DropDownloadTable() { |
return GetDB().Execute("DROP TABLE downloads"); |
} |
-void DownloadDatabase::QueryDownloads( |
- std::vector<DownloadHistoryInfo>* results) { |
- results->clear(); |
+bool DownloadDatabase::MaybeUpgradeTable( |
+ DownloadQueryParameters::GetNextIdThunk get_next_id) { |
+ static const char kNoPidColumnError[] = "no such column: pid"; |
+ sql::Statement have_pid(GetDB().GetUniqueStatement( |
+ "SELECT pid FROM downloads")); |
+ if (!have_pid && |
+ (std::string(GetDB().GetErrorMessage()) == std::string(kNoPidColumnError))) { |
+ CHECK(!get_next_id.is_null()); |
+ std::vector<DownloadHistoryInfo> infos; |
+ sql::Statement get_infos(GetDB().GetUniqueStatement( |
+ "SELECT full_path, url, start_time, received_bytes, " |
+ "total_bytes, state FROM downloads")); |
+ if (!get_infos) { |
+ return false; |
+ } |
+ while (get_infos.Step()) { |
+ infos.push_back(DownloadHistoryInfo( |
+ ColumnFilePath(get_infos, 1)/*path*/, |
+ GURL(get_infos.ColumnString(2))/*url*/, |
+ GURL("")/*referrer*/, |
+ base::Time::FromTimeT(get_infos.ColumnInt64(3))/*start*/, |
+ get_infos.ColumnInt64(4)/*received*/, |
+ get_infos.ColumnInt64(5)/*total*/, |
+ get_infos.ColumnInt(6)/*state*/, |
+ get_next_id.Run()/*id*/)); |
+ } |
+ if (!DropDownloadTable()) { |
+ return false; |
+ } |
+ if (!InitDownloadTable()) { |
+ return false; |
+ } |
+ for (std::vector<DownloadHistoryInfo>::const_iterator iter = infos.begin(); |
+ iter != infos.end(); ++iter) { |
+ sql::Statement reinsert(GetDB().GetCachedStatement(SQL_FROM_HERE, |
+ "INSERT INTO downloads (pid, full_path, url, start_time, " |
+ "received_bytes, total_bytes, state) VALUES (?, ?, ?, ?, ?, ?, ?)")); |
+ if (!reinsert) { |
+ return false; |
+ } |
+ reinsert.BindInt(0, iter->id); |
+ BindFilePath(reinsert, iter->path, 1); |
+ reinsert.BindString(2, iter->url.spec()); |
+ reinsert.BindInt64(3, iter->start_time.ToTimeT()); |
+ reinsert.BindInt64(4, iter->received_bytes); |
+ reinsert.BindInt64(5, iter->total_bytes); |
+ reinsert.BindInt(6, iter->state); |
+ if (!reinsert.Run()) { |
+ return false; |
+ } |
+ } |
+ sql::Statement have_pid2(GetDB().GetUniqueStatement( |
+ "SELECT pid FROM downloads")); |
+ if (!have_pid2) { |
+ return false; |
+ } |
+ } |
+ return true; |
+} |
+ |
+void DownloadDatabase::QueryDownloads(DownloadQueryParameters* params) { |
+ params->results.clear(); |
+ if (!MaybeUpgradeTable(params->get_next_id)) { |
+ return; |
+ } |
sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
- "SELECT id, full_path, url, start_time, received_bytes, " |
+ "SELECT pid, full_path, url, start_time, received_bytes, " |
"total_bytes, state " |
"FROM downloads " |
"ORDER BY start_time")); |
- if (!statement) |
+ if (!statement) { |
return; |
+ } |
while (statement.Step()) { |
- DownloadHistoryInfo info; |
- info.db_handle = statement.ColumnInt64(0); |
- |
- info.path = ColumnFilePath(statement, 1); |
- info.url = GURL(statement.ColumnString(2)); |
- info.start_time = base::Time::FromTimeT(statement.ColumnInt64(3)); |
- info.received_bytes = statement.ColumnInt64(4); |
- info.total_bytes = statement.ColumnInt64(5); |
- info.state = statement.ColumnInt(6); |
- results->push_back(info); |
+ params->results.push_back(DownloadHistoryInfo( |
+ ColumnFilePath(statement, 1)/*path*/, |
+ GURL(statement.ColumnString(2))/*url*/, |
+ GURL("")/*referrer*/, |
+ base::Time::FromTimeT(statement.ColumnInt64(3))/*start*/, |
+ statement.ColumnInt64(4)/*received*/, |
+ statement.ColumnInt64(5)/*total*/, |
+ statement.ColumnInt(6)/*state*/, |
+ statement.ColumnInt64(0)/*id*/)); |
} |
} |
bool DownloadDatabase::UpdateDownload(int64 received_bytes, |
int32 state, |
- DownloadID db_handle) { |
- DCHECK(db_handle > 0); |
+ DownloadID id) { |
+ DCHECK(id >= 0) << id; |
sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
"UPDATE downloads " |
- "SET received_bytes=?, state=? WHERE id=?")); |
+ "SET received_bytes=?, state=? WHERE pid=?")); |
if (!statement) |
return false; |
statement.BindInt64(0, received_bytes); |
statement.BindInt(1, state); |
- statement.BindInt64(2, db_handle); |
+ statement.BindInt64(2, id); |
return statement.Run(); |
} |
bool DownloadDatabase::UpdateDownloadPath(const FilePath& path, |
- DownloadID db_handle) { |
- DCHECK(db_handle > 0); |
+ DownloadID id) { |
+ DCHECK(id >= 0); |
sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
- "UPDATE downloads SET full_path=? WHERE id=?")); |
+ "UPDATE downloads SET full_path=? WHERE pid=?")); |
if (!statement) |
return false; |
BindFilePath(statement, path, 0); |
- statement.BindInt64(1, db_handle); |
+ statement.BindInt64(1, id); |
return statement.Run(); |
} |
@@ -145,33 +204,32 @@ bool DownloadDatabase::CleanUpInProgressEntries() { |
return statement.Run(); |
} |
-int64 DownloadDatabase::CreateDownload(const DownloadHistoryInfo& info) { |
+bool DownloadDatabase::CreateDownload(const DownloadHistoryInfo& info) { |
sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
"INSERT INTO downloads " |
- "(full_path, url, start_time, received_bytes, total_bytes, state) " |
- "VALUES (?, ?, ?, ?, ?, ?)")); |
+ "(pid, full_path, url, start_time, received_bytes, total_bytes, state) " |
+ "VALUES (?, ?, ?, ?, ?, ?, ?)")); |
if (!statement) |
- return 0; |
+ return false; |
- BindFilePath(statement, info.path, 0); |
- statement.BindString(1, info.url.spec()); |
- statement.BindInt64(2, info.start_time.ToTimeT()); |
- statement.BindInt64(3, info.received_bytes); |
- statement.BindInt64(4, info.total_bytes); |
- statement.BindInt(5, info.state); |
+ statement.BindInt(0, info.id); |
+ BindFilePath(statement, info.path, 1); |
+ statement.BindString(2, info.url.spec()); |
+ statement.BindInt64(3, info.start_time.ToTimeT()); |
+ statement.BindInt64(4, info.received_bytes); |
+ statement.BindInt64(5, info.total_bytes); |
+ statement.BindInt(6, info.state); |
- if (statement.Run()) |
- return GetDB().GetLastInsertRowId(); |
- return 0; |
+ return statement.Run(); |
} |
-void DownloadDatabase::RemoveDownload(DownloadID db_handle) { |
+void DownloadDatabase::RemoveDownload(DownloadID id) { |
sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
- "DELETE FROM downloads WHERE id=?")); |
+ "DELETE FROM downloads WHERE pid=?")); |
if (!statement) |
return; |
- statement.BindInt64(0, db_handle); |
+ statement.BindInt64(0, id); |
statement.Run(); |
} |