diff options
3 files changed, 92 insertions, 1 deletions
diff --git a/chrome/browser/sync/syncable/directory_backing_store.cc b/chrome/browser/sync/syncable/directory_backing_store.cc index 2a29789..26bb31f 100644 --- a/chrome/browser/sync/syncable/directory_backing_store.cc +++ b/chrome/browser/sync/syncable/directory_backing_store.cc @@ -581,6 +581,35 @@ bool DirectoryBackingStore::DeleteExtendedAttributeFromDB( return true; } +bool DirectoryBackingStore::DeleteEntries(const MetahandleSet& handles) { + if (handles.empty()) + return true; + + sqlite3* db_handle = NULL; + if (!OpenAndConfigureHandleHelper(&db_handle)) + return false; + + sqlite_utils::scoped_sqlite_db_ptr scoped_handle(db_handle); + string query = "DELETE FROM metas WHERE metahandle IN ("; + for (MetahandleSet::const_iterator it = handles.begin(); it != handles.end(); + ++it) { + if (it != handles.begin()) + query.append(","); + query.append(Int64ToString(*it)); + } + query.append(")"); + SQLStatement statement; + int result = statement.prepare(scoped_handle.get(), query.data(), + query.size()); + if (SQLITE_OK == result) { + result = statement.step(); + if (SQLITE_DONE == result) + statement.finalize(); + } + + return SQLITE_DONE == result; +} + bool DirectoryBackingStore::DropDeletedEntries() { static const char delete_extended_attributes[] = "DELETE FROM extended_attributes WHERE metahandle IN " diff --git a/chrome/browser/sync/syncable/directory_backing_store.h b/chrome/browser/sync/syncable/directory_backing_store.h index 4e4ab19..b240ed7 100644 --- a/chrome/browser/sync/syncable/directory_backing_store.h +++ b/chrome/browser/sync/syncable/directory_backing_store.h @@ -75,6 +75,10 @@ class DirectoryBackingStore { // calls SaveChanges *must* be the thread that owns/destroys |this|. virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot); + // Removes each entry whose metahandle is in |handles| from the database. + // Does synchronous I/O. Returns false on error. + bool DeleteEntries(const MetahandleSet& handles); + private: FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion67To68); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion68To69); @@ -82,7 +86,9 @@ class DirectoryBackingStore { FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion70To71); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, ModelTypeIds); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, Corruption); + FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, DeleteEntries); FRIEND_TEST_ALL_PREFIXES(MigrationTest, ToCurrentVersion); + friend class MigrationTest; // General Directory initialization and load helpers. DirOpenResult InitializeTables(); @@ -149,7 +155,7 @@ class DirectoryBackingStore { int GetVersion(); bool MigrateToSpecifics(const char* old_columns, const char* specifics_column, - void (*handler_function) ( + void(*handler_function) ( SQLStatement* old_value_query, int old_value_column, sync_pb::EntitySpecifics* mutable_new_value)); diff --git a/chrome/browser/sync/syncable/directory_backing_store_unittest.cc b/chrome/browser/sync/syncable/directory_backing_store_unittest.cc index 777a163..971f170 100644 --- a/chrome/browser/sync/syncable/directory_backing_store_unittest.cc +++ b/chrome/browser/sync/syncable/directory_backing_store_unittest.cc @@ -47,6 +47,18 @@ class MigrationTest : public testing::TestWithParam<int> { void SetUpVersion69Database(); void SetUpVersion70Database(); + void SetUpCurrentDatabaseAndCheckVersion() { + SetUpVersion70Database(); // Prepopulates data. + scoped_ptr<DirectoryBackingStore> dbs( + new DirectoryBackingStore(GetUsername(), GetDatabasePath())); + + dbs->BeginLoad(); + ASSERT_EQ(OPENED, dbs->InitializeTables()); + ASSERT_FALSE(dbs->needs_column_refresh_); + ASSERT_EQ(kCurrentDBVersion, dbs->GetVersion()); + dbs->EndLoad(); + } + private: ScopedTempDir temp_dir_; }; @@ -894,4 +906,48 @@ TEST_F(DirectoryBackingStoreTest, Corruption) { } } +TEST_F(DirectoryBackingStoreTest, DeleteEntries) { + SetUpCurrentDatabaseAndCheckVersion(); + scoped_ptr<DirectoryBackingStore> dbs( + new DirectoryBackingStore(GetUsername(), GetDatabasePath())); + dbs->BeginLoad(); + + MetahandlesIndex index; + dbs->LoadEntries(&index); + size_t initial_size = index.size(); + ASSERT_LT(0U, initial_size) << "Test requires entries to delete."; + int64 first_to_die = (*index.begin())->ref(META_HANDLE); + MetahandleSet to_delete; + to_delete.insert(first_to_die); + EXPECT_TRUE(dbs->DeleteEntries(to_delete)); + + index.clear(); + dbs->LoadEntries(&index); + + EXPECT_EQ(initial_size - 1, index.size()); + bool delete_failed = false; + for (MetahandlesIndex::iterator it = index.begin(); it != index.end(); + ++it) { + if ((*it)->ref(META_HANDLE) == first_to_die) { + delete_failed = true; + break; + } + } + EXPECT_FALSE(delete_failed); + + to_delete.clear(); + for (MetahandlesIndex::iterator it = index.begin(); it != index.end(); + ++it) { + to_delete.insert((*it)->ref(META_HANDLE)); + } + + EXPECT_TRUE(dbs->DeleteEntries(to_delete)); + + index.clear(); + dbs->LoadEntries(&index); + EXPECT_EQ(0U, index.size()); + + dbs->EndLoad(); +} + } // namespace syncable |