Index: sync/syncable/directory_backing_store.cc |
diff --git a/sync/syncable/directory_backing_store.cc b/sync/syncable/directory_backing_store.cc |
index f18badaed3beabcbf2e4366ccadde66c9af69c00..442c9e7d5518bae1cc787590089ff35e67ab9f4f 100644 |
--- a/sync/syncable/directory_backing_store.cc |
+++ b/sync/syncable/directory_backing_store.cc |
@@ -171,12 +171,24 @@ DirectoryBackingStore::DirectoryBackingStore(const string& dir_name, |
DirectoryBackingStore::~DirectoryBackingStore() { |
} |
-bool DirectoryBackingStore::DeleteEntries(const MetahandleSet& handles) { |
+bool DirectoryBackingStore::DeleteEntries(EntryTable from, |
+ const MetahandleSet& handles) { |
if (handles.empty()) |
return true; |
- sql::Statement statement(db_->GetCachedStatement( |
+ sql::Statement statement; |
+ // Call GetCachedStatement() separately to get different statements for |
+ // different tables. |
+ switch (from) { |
+ case METAS_TABLE: |
+ statement.Assign(db_->GetCachedStatement( |
SQL_FROM_HERE, "DELETE FROM metas WHERE metahandle = ?")); |
+ break; |
+ case DELETE_JOURNAL_TABLE: |
+ statement.Assign(db_->GetCachedStatement( |
+ SQL_FROM_HERE, "DELETE FROM deleted_metas WHERE metahandle = ?")); |
+ break; |
+ } |
for (MetahandleSet::const_iterator i = handles.begin(); i != handles.end(); |
++i) { |
@@ -196,9 +208,9 @@ bool DirectoryBackingStore::SaveChanges( |
// Back out early if there is nothing to write. |
bool save_info = |
(Directory::KERNEL_SHARE_INFO_DIRTY == snapshot.kernel_info_status); |
- if (snapshot.dirty_metas.empty() |
- && snapshot.metahandles_to_purge.empty() |
- && !save_info) { |
+ if (snapshot.dirty_metas.empty() && snapshot.metahandles_to_purge.empty() && |
+ snapshot.delete_journals.empty() && |
+ snapshot.delete_journals_to_purge.empty() && !save_info) { |
return true; |
} |
@@ -206,14 +218,26 @@ bool DirectoryBackingStore::SaveChanges( |
if (!transaction.Begin()) |
return false; |
+ PrepareSaveEntryStatement(METAS_TABLE, &save_meta_statment_); |
for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); |
i != snapshot.dirty_metas.end(); ++i) { |
- DCHECK(i->is_dirty()); |
- if (!SaveEntryToDB(*i)) |
+ DCHECK((*i)->is_dirty()); |
+ if (!SaveEntryToDB(&save_meta_statment_, **i)) |
+ return false; |
+ } |
+ |
+ if (!DeleteEntries(METAS_TABLE, snapshot.metahandles_to_purge)) |
+ return false; |
+ |
+ PrepareSaveEntryStatement(DELETE_JOURNAL_TABLE, |
+ &save_delete_journal_statment_); |
+ for (EntryKernelSet::const_iterator i = snapshot.delete_journals.begin(); |
+ i != snapshot.delete_journals.end(); ++i) { |
+ if (!SaveEntryToDB(&save_delete_journal_statment_, **i)) |
return false; |
} |
- if (!DeleteEntries(snapshot.metahandles_to_purge)) |
+ if (!DeleteEntries(DELETE_JOURNAL_TABLE, snapshot.delete_journals_to_purge)) |
return false; |
if (save_info) { |
@@ -465,22 +489,12 @@ bool DirectoryBackingStore::RefreshColumns() { |
} |
bool DirectoryBackingStore::LoadEntries(MetahandlesIndex* entry_bucket) { |
- string select; |
- select.reserve(kUpdateStatementBufferSize); |
- select.append("SELECT "); |
- AppendColumnList(&select); |
- select.append(" FROM metas "); |
- |
- sql::Statement s(db_->GetUniqueStatement(select.c_str())); |
+ return LoadEntriesInternal("metas", entry_bucket); |
+} |
- while (s.Step()) { |
- scoped_ptr<EntryKernel> kernel = UnpackEntry(&s); |
- // A null kernel is evidence of external data corruption. |
- if (!kernel.get()) |
- return false; |
- entry_bucket->insert(kernel.release()); |
- } |
- return s.Succeeded(); |
+bool DirectoryBackingStore::LoadDeleteJournals( |
+ JournalIndex* delete_journals) { |
+ return LoadEntriesInternal("deleted_metas", delete_journals); |
} |
bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) { |
@@ -538,38 +552,12 @@ bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) { |
return true; |
} |
-bool DirectoryBackingStore::SaveEntryToDB(const EntryKernel& entry) { |
- // This statement is constructed at runtime, so we can't use |
- // GetCachedStatement() to let the Connection cache it. We will construct |
- // and cache it ourselves the first time this function is called. |
- if (!save_entry_statement_.is_valid()) { |
- string query; |
- query.reserve(kUpdateStatementBufferSize); |
- query.append("INSERT OR REPLACE INTO metas "); |
- string values; |
- values.reserve(kUpdateStatementBufferSize); |
- values.append("VALUES "); |
- const char* separator = "( "; |
- int i = 0; |
- for (i = BEGIN_FIELDS; i < FIELD_COUNT; ++i) { |
- query.append(separator); |
- values.append(separator); |
- separator = ", "; |
- query.append(ColumnName(i)); |
- values.append("?"); |
- } |
- query.append(" ) "); |
- values.append(" )"); |
- query.append(values); |
- |
- save_entry_statement_.Assign( |
- db_->GetUniqueStatement(query.c_str())); |
- } else { |
- save_entry_statement_.Reset(true); |
- } |
- |
- BindFields(entry, &save_entry_statement_); |
- return save_entry_statement_.Run(); |
+/* static */ |
+bool DirectoryBackingStore::SaveEntryToDB(sql::Statement* save_statement, |
+ const EntryKernel& entry) { |
+ save_statement->Reset(true); |
+ BindFields(entry, save_statement); |
+ return save_statement->Run(); |
} |
bool DirectoryBackingStore::DropDeletedEntries() { |
@@ -1093,7 +1081,6 @@ bool DirectoryBackingStore::MigrateVersion83To84() { |
query.append(ComposeCreateTableColumnSpecs()); |
if (!db_->Execute(query.c_str())) |
return false; |
- |
SetVersion(84); |
return true; |
} |
@@ -1314,5 +1301,61 @@ bool DirectoryBackingStore::VerifyReferenceIntegrity( |
return is_ok; |
} |
+template<class T> |
+bool DirectoryBackingStore::LoadEntriesInternal(const std::string& table, |
+ T* bucket) { |
+ string select; |
+ select.reserve(kUpdateStatementBufferSize); |
+ select.append("SELECT "); |
+ AppendColumnList(&select); |
+ select.append(" FROM " + table); |
+ |
+ sql::Statement s(db_->GetUniqueStatement(select.c_str())); |
+ |
+ while (s.Step()) { |
+ scoped_ptr<EntryKernel> kernel = UnpackEntry(&s); |
+ // A null kernel is evidence of external data corruption. |
+ if (!kernel.get()) |
+ return false; |
+ bucket->insert(kernel.release()); |
+ } |
+ return s.Succeeded(); |
+} |
+ |
+void DirectoryBackingStore::PrepareSaveEntryStatement( |
+ EntryTable table, sql::Statement* save_statement) { |
+ if (save_statement->is_valid()) |
+ return; |
+ |
+ string query; |
+ query.reserve(kUpdateStatementBufferSize); |
+ switch (table) { |
+ case METAS_TABLE: |
+ query.append("INSERT OR REPLACE INTO metas "); |
+ break; |
+ case DELETE_JOURNAL_TABLE: |
+ query.append("INSERT OR REPLACE INTO deleted_metas "); |
+ break; |
+ } |
+ |
+ string values; |
+ values.reserve(kUpdateStatementBufferSize); |
+ values.append(" VALUES "); |
+ const char* separator = "( "; |
+ int i = 0; |
+ for (i = BEGIN_FIELDS; i < FIELD_COUNT; ++i) { |
+ query.append(separator); |
+ values.append(separator); |
+ separator = ", "; |
+ query.append(ColumnName(i)); |
+ values.append("?"); |
+ } |
+ query.append(" ) "); |
+ values.append(" )"); |
+ query.append(values); |
+ save_statement->Assign(db_->GetUniqueStatement( |
+ base::StringPrintf(query.c_str(), "metas").c_str())); |
+} |
+ |
} // namespace syncable |
} // namespace syncer |