summaryrefslogtreecommitdiffstats
path: root/sync
diff options
context:
space:
mode:
authormaniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-02 03:40:29 +0000
committermaniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-02 03:40:29 +0000
commit96c08a8850dfd2039696b553a974b1faddbf2636 (patch)
tree5f4dd3fd1eebe6a2a59f73a3b393aadfd06b2037 /sync
parent26d8482f9f2554a9926c7e5da18fa623ae3ad62f (diff)
downloadchromium_src-96c08a8850dfd2039696b553a974b1faddbf2636.zip
chromium_src-96c08a8850dfd2039696b553a974b1faddbf2636.tar.gz
chromium_src-96c08a8850dfd2039696b553a974b1faddbf2636.tar.bz2
Add AttachmentMetadata to Sync's EntryKernel.
In future CLs, AttachmentMetadata will be extended to include metadata about the sync entries attachments such as attachment ids and whether they have been upload to the server. BUG=348625 Review URL: https://codereview.chromium.org/211523002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261046 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync')
-rw-r--r--sync/engine/get_commit_ids.cc21
-rw-r--r--sync/protocol/attachments.proto5
-rw-r--r--sync/syncable/directory_backing_store.cc20
-rw-r--r--sync/syncable/directory_backing_store.h1
-rw-r--r--sync/syncable/directory_backing_store_unittest.cc155
-rw-r--r--sync/syncable/entry.cc7
-rw-r--r--sync/syncable/entry.h5
-rw-r--r--sync/syncable/entry_kernel.cc13
-rw-r--r--sync/syncable/entry_kernel.h29
-rw-r--r--sync/syncable/syncable_columns.h7
-rw-r--r--sync/syncable/syncable_enum_conversions.cc14
-rw-r--r--sync/syncable/syncable_enum_conversions.h3
-rw-r--r--sync/syncable/syncable_enum_conversions_unittest.cc6
-rw-r--r--sync/test/test_directory_backing_store.h1
14 files changed, 280 insertions, 7 deletions
diff --git a/sync/engine/get_commit_ids.cc b/sync/engine/get_commit_ids.cc
index 42faf21..80222ee 100644
--- a/sync/engine/get_commit_ids.cc
+++ b/sync/engine/get_commit_ids.cc
@@ -105,6 +105,15 @@ bool IsEntryInConflict(const syncable::Entry& entry) {
return false;
}
+// Return true if this entry has any attachments that haven't yet been uploaded
+// to the server.
+bool HasAttachmentNotOnServer(const syncable::Entry& entry) {
+ // TODO(maniscalco): Once AttachmentMetadata is fleshed out, implement this
+ // function to return true if any of the attachments haven't been uploaded to
+ // the server. Add test case (bug 356266).
+ return false;
+}
+
// An entry is not considered ready for commit if any are true:
// 1. It's in conflict.
// 2. It requires encryption (either the type is encrypted but a passphrase
@@ -161,6 +170,13 @@ bool IsEntryReadyForCommit(ModelTypeSet requested_types,
return false;
}
+ if (HasAttachmentNotOnServer(entry)) {
+ // This entry is not ready to be sent to the server because it has one or
+ // more attachments that have not yet been uploaded to the server. The idea
+ // here is avoid propagating an entry with dangling attachment references.
+ return false;
+ }
+
DVLOG(2) << "Entry is ready for commit: " << entry;
return true;
}
@@ -177,6 +193,11 @@ void FilterUnreadyEntries(
for (syncable::Directory::Metahandles::const_iterator iter =
unsynced_handles.begin(); iter != unsynced_handles.end(); ++iter) {
syncable::Entry entry(trans, syncable::GET_BY_HANDLE, *iter);
+ // TODO(maniscalco): While we check if entry is ready to be committed, we
+ // also need to check that all of its ancestors (parents, transitive) are
+ // ready to be committed. Once attachments can prevent an entry from being
+ // committable, this method must ensure all ancestors are ready for commit
+ // (bug 356273).
if (IsEntryReadyForCommit(requested_types,
encrypted_types,
passphrase_missing,
diff --git a/sync/protocol/attachments.proto b/sync/protocol/attachments.proto
index 8ba8710..50815d3 100644
--- a/sync/protocol/attachments.proto
+++ b/sync/protocol/attachments.proto
@@ -20,3 +20,8 @@ message AttachmentIdProto {
// are considered equivalent.
optional string unique_id = 1;
}
+
+// A collection of attachment metadata. This proto is part of EntryKernel's "on
+// disk" representation. Private to sync.
+message AttachmentMetadata {
+}
diff --git a/sync/syncable/directory_backing_store.cc b/sync/syncable/directory_backing_store.cc
index 417a4d1..5371f43 100644
--- a/sync/syncable/directory_backing_store.cc
+++ b/sync/syncable/directory_backing_store.cc
@@ -35,7 +35,7 @@ namespace syncable {
static const string::size_type kUpdateStatementBufferSize = 2048;
// Increment this version whenever updating DB tables.
-const int32 kCurrentDBVersion = 86;
+const int32 kCurrentDBVersion = 87;
// Iterate over the fields of |entry| and bind each to |statement| for
// updating. Returns the number of args bound.
@@ -406,6 +406,12 @@ bool DirectoryBackingStore::InitializeTables() {
version_on_disk = 86;
}
+ // Version 87 migration adds a collection of attachment ids per sync entry.
+ if (version_on_disk == 86) {
+ if (MigrateVersion86To87())
+ version_on_disk = 87;
+ }
+
// If one of the migrations requested it, drop columns that aren't current.
// It's only safe to do this after migrating all the way to the current
// version.
@@ -1266,6 +1272,18 @@ bool DirectoryBackingStore::MigrateVersion85To86() {
return true;
}
+bool DirectoryBackingStore::MigrateVersion86To87() {
+ // Version 87 adds AttachmentMetadata proto.
+ if (!db_->Execute(
+ "ALTER TABLE metas ADD COLUMN "
+ "attachment_metadata BLOB")) {
+ return false;
+ }
+ SetVersion(87);
+ needs_column_refresh_ = true;
+ return true;
+}
+
bool DirectoryBackingStore::CreateTables() {
DVLOG(1) << "First run, creating tables";
// Create two little tables share_version and share_info
diff --git a/sync/syncable/directory_backing_store.h b/sync/syncable/directory_backing_store.h
index 995a014..5b96848e 100644
--- a/sync/syncable/directory_backing_store.h
+++ b/sync/syncable/directory_backing_store.h
@@ -170,6 +170,7 @@ class SYNC_EXPORT_PRIVATE DirectoryBackingStore : public base::NonThreadSafe {
bool MigrateVersion83To84();
bool MigrateVersion84To85();
bool MigrateVersion85To86();
+ bool MigrateVersion86To87();
scoped_ptr<sql::Connection> db_;
sql::Statement save_meta_statment_;
diff --git a/sync/syncable/directory_backing_store_unittest.cc b/sync/syncable/directory_backing_store_unittest.cc
index c913265..c87f360 100644
--- a/sync/syncable/directory_backing_store_unittest.cc
+++ b/sync/syncable/directory_backing_store_unittest.cc
@@ -74,9 +74,10 @@ class MigrationTest : public testing::TestWithParam<int> {
void SetUpVersion84Database(sql::Connection* connection);
void SetUpVersion85Database(sql::Connection* connection);
void SetUpVersion86Database(sql::Connection* connection);
+ void SetUpVersion87Database(sql::Connection* connection);
void SetUpCurrentDatabaseAndCheckVersion(sql::Connection* connection) {
- SetUpVersion86Database(connection); // Prepopulates data.
+ SetUpVersion87Database(connection); // Prepopulates data.
scoped_ptr<TestDirectoryBackingStore> dbs(
new TestDirectoryBackingStore(GetUsername(), connection));
ASSERT_EQ(kCurrentDBVersion, dbs->GetVersion());
@@ -2534,6 +2535,121 @@ void MigrationTest::SetUpVersion86Database(sql::Connection* connection) {
ASSERT_TRUE(connection->CommitTransaction());
}
+void MigrationTest::SetUpVersion87Database(sql::Connection* connection) {
+ ASSERT_TRUE(connection->is_open());
+ ASSERT_TRUE(connection->BeginTransaction());
+ ASSERT_TRUE(connection->Execute(
+ "CREATE TABLE share_version (id VARCHAR(128) primary key, data INT);"
+ "INSERT INTO 'share_version' VALUES('nick@chromium.org',87);"
+ "CREATE TABLE models (model_id BLOB primary key, progress_marker BLOB, tr"
+ "ansaction_version BIGINT default 0);"
+ "INSERT INTO 'models' VALUES(X'C2881000',X'0888810218B605',1);"
+ "CREATE TABLE 'metas'(metahandle bigint primary key ON CONFLICT FAIL,base"
+ "_version bigint default -1,server_version bigint default 0,local_exte"
+ "rnal_id bigint default 0,transaction_version bigint default 0,mtime b"
+ "igint default 0,server_mtime bigint default 0,ctime bigint default 0,"
+ "server_ctime bigint default 0,id varchar(255) default 'r',parent_id v"
+ "archar(255) default 'r',server_parent_id varchar(255) default 'r',is_"
+ "unsynced bit default 0,is_unapplied_update bit default 0,is_del bit d"
+ "efault 0,is_dir bit default 0,server_is_dir bit default 0,server_is_d"
+ "el bit default 0,non_unique_name varchar,server_non_unique_name varch"
+ "ar(255),unique_server_tag varchar,unique_client_tag varchar,unique_bo"
+ "okmark_tag varchar,specifics blob,server_specifics blob,base_server_s"
+ "pecifics blob,server_unique_position blob,unique_position blob,attach"
+ "ment_metadata blob);"
+ "INSERT INTO 'metas' VALUES(1,-1,0,0,0,"
+ META_PROTO_TIMES_VALS(1)
+ ",'r','r','r',0,0,0,1,0,0,NULL,NULL,NULL,NULL,X''"
+ ",X'',X'',NULL,X'2200',X'2200',NULL);"
+ "INSERT INTO 'metas' VALUES(6,694,694,6,0,"
+ META_PROTO_TIMES_VALS(6)
+ ",'s_ID_6','s_ID_9','s_ID_9',0,0,0,1,1,0,'The "
+ "Internet','The Internet',NULL,NULL,X'6754307476346749735A5734654D6532"
+ "73625336557753582F77673D',X'C2881000',X'C2881000',NULL,X'22247FFFFFFF"
+ "FFC000006754307476346749735A5734654D653273625336557753582F77673D',X'2"
+ "2247FFFFFFFFFC000006754307476346749735A5734654D653273625336557753582F"
+ "77673D',NULL);"
+ "INSERT INTO 'metas' VALUES(7,663,663,0,0,"
+ META_PROTO_TIMES_VALS(7)
+ ",'s_ID_7','r','r',0,0,0,1,1,0,'Google Chrome'"
+ ",'Google Chrome','google_chrome',NULL,X'',NULL,NULL,NULL,X'2200',X'22"
+ "00',NULL);"
+ "INSERT INTO 'metas' VALUES(8,664,664,0,0,"
+ META_PROTO_TIMES_VALS(8)
+ ",'s_ID_8','s_ID_7','s_ID_7',0,0,0,1,1,0,'Book"
+ "marks','Bookmarks','google_chrome_bookmarks',NULL,X'',X'C2881000',X'C"
+ "2881000',NULL,X'2200',X'2200',NULL);"
+ "INSERT INTO 'metas' VALUES(9,665,665,1,0,"
+ META_PROTO_TIMES_VALS(9)
+ ",'s_ID_9','s_ID_8','s_ID_8',0,0,0,1,1,0,'Book"
+ "mark Bar','Bookmark Bar','bookmark_bar',NULL,X'',X'C2881000',X'C28810"
+ "00',NULL,X'2200',X'2200',NULL);"
+ "INSERT INTO 'metas' VALUES(10,666,666,2,0,"
+ META_PROTO_TIMES_VALS(10)
+ ",'s_ID_10','s_ID_8','s_ID_8',0,0,0,1,1,0,'Ot"
+ "her Bookmarks','Other Bookmarks','other_bookmarks',NULL,X'',X'C288100"
+ "0',X'C2881000',NULL,X'2200',X'2200',NULL);"
+ "INSERT INTO 'metas' VALUES(11,683,683,8,0,"
+ META_PROTO_TIMES_VALS(11)
+ ",'s_ID_11','s_ID_6','s_ID_6',0,0,0,0,0,0,'Ho"
+ "me (The Chromium Projects)','Home (The Chromium Projects)',NULL,NULL,"
+ "X'50514C784A456D623579366267644237646A7A2B62314130346E493D',X'C288102"
+ "20A18687474703A2F2F6465762E6368726F6D69756D2E6F72672F1206414741545741"
+ "',X'C28810290A1D687474703A2F2F6465762E6368726F6D69756D2E6F72672F6F746"
+ "8657212084146414756415346',NULL,X'22247FFFFFFFFFF0000050514C784A456D6"
+ "23579366267644237646A7A2B62314130346E493D',X'22247FFFFFFFFFF000005051"
+ "4C784A456D623579366267644237646A7A2B62314130346E493D',NULL);"
+ "INSERT INTO 'metas' VALUES(12,685,685,9,0,"
+ META_PROTO_TIMES_VALS(12)
+ ",'s_ID_12','s_ID_6','s_ID_6',0,0,0,1,1,0,'Ex"
+ "tra Bookmarks','Extra Bookmarks',NULL,NULL,X'7867626A704A646134635A6F"
+ "616C376A49513338734B46324837773D',X'C2881000',X'C2881000',NULL,X'2224"
+ "80000000000000007867626A704A646134635A6F616C376A49513338734B463248377"
+ "73D',X'222480000000000000007867626A704A646134635A6F616C376A4951333873"
+ "4B46324837773D',NULL);"
+ "INSERT INTO 'metas' VALUES(13,687,687,10,0,"
+ META_PROTO_TIMES_VALS(13)
+ ",'s_ID_13','s_ID_6','s_ID_6',0,0,0,0,0,0,'I"
+ "CANN | Internet Corporation for Assigned Names and Numbers','ICANN | "
+ "Internet Corporation for Assigned Names and Numbers',NULL,NULL,X'3142"
+ "756B572F7741766956504179672B304A614A514B3452384A413D',X'C28810240A156"
+ "87474703A2F2F7777772E6963616E6E2E636F6D2F120B504E474158463041414646',"
+ "X'C28810200A15687474703A2F2F7777772E6963616E6E2E636F6D2F1207444141464"
+ "15346',NULL,X'22247FFFFFFFFFF200003142756B572F7741766956504179672B304"
+ "A614A514B3452384A413D',X'22247FFFFFFFFFF200003142756B572F774176695650"
+ "4179672B304A614A514B3452384A413D',NULL);"
+ "INSERT INTO 'metas' VALUES(14,692,692,11,0,"
+ META_PROTO_TIMES_VALS(14)
+ ",'s_ID_14','s_ID_6','s_ID_6',0,0,0,0,0,0,'T"
+ "he WebKit Open Source Project','The WebKit Open Source Project',NULL,"
+ "NULL,X'5A5678314E7976364579524D3177494F7236563159552F6E644C553D',X'C2"
+ "88101A0A12687474703A2F2F7765626B69742E6F72672F1204504E4758',X'C288101"
+ "C0A13687474703A2F2F7765626B69742E6F72672F781205504E473259',NULL,X'222"
+ "480000000001000005A5678314E7976364579524D3177494F7236563159552F6E644C"
+ "553D',X'222480000000001000005A5678314E7976364579524D3177494F723656315"
+ "9552F6E644C553D',NULL);"
+ "CREATE TABLE deleted_metas (metahandle bigint primary key ON CONFLICT FA"
+ "IL,base_version bigint default -1,server_version bigint default 0,loc"
+ "al_external_id bigint default 0,transaction_version bigint default 0,"
+ "mtime bigint default 0,server_mtime bigint default 0,ctime bigint def"
+ "ault 0,server_ctime bigint default 0,id varchar(255) default 'r',pare"
+ "nt_id varchar(255) default 'r',server_parent_id varchar(255) default "
+ "'r',is_unsynced bit default 0,is_unapplied_update bit default 0,is_de"
+ "l bit default 0,is_dir bit default 0,server_is_dir bit default 0,serv"
+ "er_is_del bit default 0,non_unique_name varchar,server_non_unique_nam"
+ "e varchar(255),unique_server_tag varchar,unique_client_tag varchar,un"
+ "ique_bookmark_tag varchar,specifics blob,server_specifics blob,base_s"
+ "erver_specifics blob,server_unique_position blob,unique_position blob"
+ ",attachment_metadata blob);"
+ "CREATE TABLE 'share_info' (id TEXT primary key, name TEXT, store_birthda"
+ "y TEXT, db_create_version TEXT, db_create_time INT, next_id INT defau"
+ "lt -2, cache_guid TEXT, notification_state BLOB, bag_of_chips BLOB);"
+ "INSERT INTO 'share_info' VALUES('nick@chromium.org','nick@chromium.org',"
+ "'c27e9f59-08ca-46f8-b0cc-f16a2ed778bb','Unknown',1263522064,-131078,'"
+ "9010788312004066376x-6609234393368420856x',NULL,NULL);"));
+ ASSERT_TRUE(connection->CommitTransaction());
+}
+
TEST_F(DirectoryBackingStoreTest, MigrateVersion67To68) {
sql::Connection connection;
ASSERT_TRUE(connection.OpenInMemory());
@@ -2998,6 +3114,20 @@ TEST_F(DirectoryBackingStoreTest, MigrateVersion85To86) {
ASSERT_TRUE(dbs->needs_column_refresh_);
}
+TEST_F(DirectoryBackingStoreTest, MigrateVersion86To87) {
+ sql::Connection connection;
+ EXPECT_TRUE(connection.OpenInMemory());
+ SetUpVersion86Database(&connection);
+ EXPECT_FALSE(connection.DoesColumnExist("metas", "attachment_metadata"));
+
+ scoped_ptr<TestDirectoryBackingStore> dbs(
+ new TestDirectoryBackingStore(GetUsername(), &connection));
+ EXPECT_TRUE(dbs->MigrateVersion86To87());
+ EXPECT_EQ(87, dbs->GetVersion());
+ EXPECT_TRUE(connection.DoesColumnExist("metas", "attachment_metadata"));
+ EXPECT_TRUE(dbs->needs_column_refresh_);
+}
+
// The purpose of this test case is to make it easier to get a dump of the
// database so you can implement a SetUpVersionYDatabase method. Here's what
// you should do:
@@ -3019,13 +3149,13 @@ TEST_F(DirectoryBackingStoreTest, MigrateToLatestAndDump) {
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
- SetUpVersion85Database(&connection); // Update this.
+ SetUpVersion86Database(&connection); // Update this.
scoped_ptr<TestDirectoryBackingStore> dbs(
new TestDirectoryBackingStore(GetUsername(), &connection));
- ASSERT_TRUE(dbs->MigrateVersion85To86()); // Update this.
+ ASSERT_TRUE(dbs->MigrateVersion86To87()); // Update this.
ASSERT_TRUE(LoadAndIgnoreReturnedData(dbs.get()));
- EXPECT_EQ(86, dbs->GetVersion()); // Update this.
+ EXPECT_EQ(87, dbs->GetVersion()); // Update this.
ASSERT_FALSE(dbs->needs_column_refresh_);
}
// Set breakpoint here.
@@ -3121,6 +3251,9 @@ TEST_P(MigrationTest, ToCurrentVersion) {
case 86:
SetUpVersion86Database(&connection);
break;
+ case 87:
+ SetUpVersion87Database(&connection);
+ break;
default:
// If you see this error, it may mean that you've increased the
// database version number but you haven't finished adding unit tests
@@ -3207,6 +3340,9 @@ TEST_P(MigrationTest, ToCurrentVersion) {
ASSERT_FALSE(connection.DoesColumnExist("metas", "prev_id"));
ASSERT_FALSE(connection.DoesColumnExist("metas", "server_ordinal_in_parent"));
+ // Column added in version 87.
+ ASSERT_TRUE(connection.DoesColumnExist("metas", "attachment_metadata"));
+
// Check download_progress state (v75 migration)
ASSERT_EQ(694,
dir_info.kernel_info.download_progress[BOOKMARKS]
@@ -3242,6 +3378,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid());
EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
// Items 2, 4, and 5 were deleted.
it = handles_map.find(2);
@@ -3263,6 +3400,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_EQ(UniquePosition::kSuffixLength,
it->second->ref(UNIQUE_BOOKMARK_TAG).length());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(7);
ASSERT_EQ(7, it->second->ref(META_HANDLE));
@@ -3273,6 +3411,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid());
EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(8);
ASSERT_EQ(8, it->second->ref(META_HANDLE));
@@ -3284,6 +3423,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid());
EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(9);
ASSERT_EQ(9, it->second->ref(META_HANDLE));
@@ -3294,6 +3434,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid());
EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(10);
ASSERT_EQ(10, it->second->ref(META_HANDLE));
@@ -3308,10 +3449,12 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_EQ("Other Bookmarks", it->second->ref(NON_UNIQUE_NAME));
EXPECT_EQ("Other Bookmarks", it->second->ref(SERVER_NON_UNIQUE_NAME));
ASSERT_EQ(it->second->ref(ID).value(), "s_ID_10");
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
// Make sure we didn't assign positions to server-created folders, either.
EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid());
EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(11);
ASSERT_EQ(11, it->second->ref(META_HANDLE));
@@ -3333,6 +3476,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_EQ(UniquePosition::kSuffixLength,
it->second->ref(UNIQUE_BOOKMARK_TAG).length());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(12);
ASSERT_EQ(12, it->second->ref(META_HANDLE));
@@ -3350,6 +3494,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_EQ(UniquePosition::kSuffixLength,
it->second->ref(UNIQUE_BOOKMARK_TAG).length());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(13);
ASSERT_EQ(13, it->second->ref(META_HANDLE));
@@ -3357,6 +3502,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_EQ(UniquePosition::kSuffixLength,
it->second->ref(UNIQUE_BOOKMARK_TAG).length());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
it = handles_map.find(14);
ASSERT_EQ(14, it->second->ref(META_HANDLE));
@@ -3364,6 +3510,7 @@ TEST_P(MigrationTest, ToCurrentVersion) {
EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid());
EXPECT_EQ(UniquePosition::kSuffixLength,
it->second->ref(UNIQUE_BOOKMARK_TAG).length());
+ EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized());
ASSERT_EQ(static_cast<size_t>(10), handles_map.size());
diff --git a/sync/syncable/entry.cc b/sync/syncable/entry.cc
index 852c33e..2be2aad 100644
--- a/sync/syncable/entry.cc
+++ b/sync/syncable/entry.cc
@@ -157,6 +157,13 @@ std::ostream& operator<<(std::ostream& os, const Entry& entry) {
<< kernel->ref(static_cast<UniquePositionField>(i)).ToDebugString()
<< ", ";
}
+ for ( ; i < ATTACHMENT_METADATA_FIELDS_END; ++i) {
+ std::string escaped_str = base::EscapeBytesAsInvalidJSONString(
+ kernel->ref(static_cast<AttachmentMetadataField>(i))
+ .SerializeAsString(),
+ false);
+ os << g_metas_columns[i].name << ": " << escaped_str << ", ";
+ }
os << "TempFlags: ";
for ( ; i < BIT_TEMPS_END; ++i) {
if (kernel->ref(static_cast<BitTemp>(i)))
diff --git a/sync/syncable/entry.h b/sync/syncable/entry.h
index 09ff9c7..47b9c59 100644
--- a/sync/syncable/entry.h
+++ b/sync/syncable/entry.h
@@ -196,6 +196,11 @@ class SYNC_EXPORT Entry {
return kernel_->ref(UNIQUE_POSITION);
}
+ const sync_pb::AttachmentMetadata& GetAttachmentMetadata() const {
+ DCHECK(kernel_);
+ return kernel_->ref(ATTACHMENT_METADATA);
+ }
+
bool GetSyncing() const {
DCHECK(kernel_);
return kernel_->ref(SYNCING);
diff --git a/sync/syncable/entry_kernel.cc b/sync/syncable/entry_kernel.cc
index 9734483..0821999 100644
--- a/sync/syncable/entry_kernel.cc
+++ b/sync/syncable/entry_kernel.cc
@@ -129,6 +129,11 @@ base::StringValue* UniquePositionToValue(const UniquePosition& pos) {
return new base::StringValue(pos.ToDebugString());
}
+base::StringValue* AttachmentMetadataToValue(
+ const sync_pb::AttachmentMetadata& a) {
+ return new base::StringValue(a.SerializeAsString());
+}
+
} // namespace
base::DictionaryValue* EntryKernel::ToValue(
@@ -186,6 +191,14 @@ base::DictionaryValue* EntryKernel::ToValue(
&GetUniquePositionFieldString, &UniquePositionToValue,
UNIQUE_POSITION_FIELDS_BEGIN, UNIQUE_POSITION_FIELDS_END - 1);
+ // AttachmentMetadata fields
+ SetFieldValues(*this,
+ kernel_info,
+ &GetAttachmentMetadataFieldString,
+ &AttachmentMetadataToValue,
+ ATTACHMENT_METADATA_FIELDS_BEGIN,
+ ATTACHMENT_METADATA_FIELDS_END - 1);
+
// Bit temps.
SetFieldValues(*this, kernel_info,
&GetBitTempString, &BooleanToValue,
diff --git a/sync/syncable/entry_kernel.h b/sync/syncable/entry_kernel.h
index 562ebdb..b6bc2ab 100644
--- a/sync/syncable/entry_kernel.h
+++ b/sync/syncable/entry_kernel.h
@@ -13,6 +13,7 @@
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/base/unique_position.h"
#include "sync/internal_api/public/util/immutable.h"
+#include "sync/protocol/attachments.pb.h"
#include "sync/protocol/sync.pb.h"
#include "sync/syncable/metahandle_set.h"
#include "sync/syncable/syncable_id.h"
@@ -31,6 +32,8 @@ namespace syncable {
// - EntryKernel::EntryKernel(), EntryKernel::ToValue() in entry_kernel.cc
// - operator<< in Entry.cc
// - BindFields() and UnpackEntry() in directory_backing_store.cc
+// - kCurrentDBVersion, DirectoryBackingStore::InitializeTables in
+// directory_backing_store.cc
// - TestSimpleFieldsPreservedDuringSaveChanges in syncable_unittest.cc
static const int64 kInvalidMetaHandle = 0;
@@ -156,9 +159,20 @@ enum UniquePositionField {
enum {
UNIQUE_POSITION_FIELDS_COUNT =
UNIQUE_POSITION_FIELDS_END - UNIQUE_POSITION_FIELDS_BEGIN,
- FIELD_COUNT = UNIQUE_POSITION_FIELDS_END - BEGIN_FIELDS,
+ ATTACHMENT_METADATA_FIELDS_BEGIN = UNIQUE_POSITION_FIELDS_END
+};
+
+enum AttachmentMetadataField {
+ ATTACHMENT_METADATA = ATTACHMENT_METADATA_FIELDS_BEGIN,
+ ATTACHMENT_METADATA_FIELDS_END
+};
+
+enum {
+ ATTACHMENT_METADATA_FIELDS_COUNT =
+ ATTACHMENT_METADATA_FIELDS_END - ATTACHMENT_METADATA_FIELDS_BEGIN,
+ FIELD_COUNT = ATTACHMENT_METADATA_FIELDS_END - BEGIN_FIELDS,
// Past this point we have temporaries, stored in memory only.
- BEGIN_TEMPS = UNIQUE_POSITION_FIELDS_END,
+ BEGIN_TEMPS = ATTACHMENT_METADATA_FIELDS_END,
BIT_TEMPS_BEGIN = BEGIN_TEMPS,
};
@@ -183,6 +197,8 @@ struct SYNC_EXPORT_PRIVATE EntryKernel {
base::Time time_fields[TIME_FIELDS_COUNT];
Id id_fields[ID_FIELDS_COUNT];
UniquePosition unique_position_fields[UNIQUE_POSITION_FIELDS_COUNT];
+ sync_pb::AttachmentMetadata
+ attachment_metadata_fields[ATTACHMENT_METADATA_FIELDS_COUNT];
std::bitset<BIT_FIELDS_COUNT> bit_fields;
std::bitset<BIT_TEMPS_COUNT> bit_temps;
@@ -253,6 +269,11 @@ struct SYNC_EXPORT_PRIVATE EntryKernel {
inline void put(UniquePositionField field, const UniquePosition& value) {
unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN] = value;
}
+ inline void put(AttachmentMetadataField field,
+ const sync_pb::AttachmentMetadata& value) {
+ attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN] =
+ value;
+ }
inline void put(BitTemp field, bool value) {
bit_temps[field - BIT_TEMPS_BEGIN] = value;
}
@@ -291,6 +312,10 @@ struct SYNC_EXPORT_PRIVATE EntryKernel {
inline const UniquePosition& ref(UniquePositionField field) const {
return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
}
+ inline const sync_pb::AttachmentMetadata& ref(
+ AttachmentMetadataField field) const {
+ return attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN];
+ }
inline bool ref(BitTemp field) const {
return bit_temps[field - BIT_TEMPS_BEGIN];
}
diff --git a/sync/syncable/syncable_columns.h b/sync/syncable/syncable_columns.h
index 9d45c74..f923bc4 100644
--- a/sync/syncable/syncable_columns.h
+++ b/sync/syncable/syncable_columns.h
@@ -61,6 +61,13 @@ static const ColumnSpec g_metas_columns[] = {
// Blobs (positions).
{"server_unique_position", "blob"},
{"unique_position", "blob"},
+ //////////////////////////////////////
+ // AttachmentMetadata is a proto that contains all the metadata associated
+ // with an entry's attachments. Each entry has only one AttachmentMetadata
+ // proto. We store a single proto per entry (as opposed to one for each
+ // attachment) because it simplifies the database schema and implementation of
+ // DirectoryBackingStore.
+ {"attachment_metadata", "blob"}
};
// At least enforce that there are equal number of column names and fields.
diff --git a/sync/syncable/syncable_enum_conversions.cc b/sync/syncable/syncable_enum_conversions.cc
index 8f27912..0fc2147 100644
--- a/sync/syncable/syncable_enum_conversions.cc
+++ b/sync/syncable/syncable_enum_conversions.cc
@@ -160,6 +160,20 @@ const char* GetUniquePositionFieldString(UniquePositionField position_field) {
return "";
}
+const char* GetAttachmentMetadataFieldString(
+ AttachmentMetadataField attachment_metadata_field) {
+ ASSERT_ENUM_BOUNDS(ATTACHMENT_METADATA,
+ ATTACHMENT_METADATA,
+ ATTACHMENT_METADATA_FIELDS_BEGIN,
+ ATTACHMENT_METADATA_FIELDS_END - 1);
+ switch(attachment_metadata_field) {
+ ENUM_CASE(ATTACHMENT_METADATA);
+ case ATTACHMENT_METADATA_FIELDS_END: break;
+ }
+ NOTREACHED();
+ return "";
+}
+
const char* GetBitTempString(BitTemp bit_temp) {
ASSERT_ENUM_BOUNDS(SYNCING, SYNCING,
BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1);
diff --git a/sync/syncable/syncable_enum_conversions.h b/sync/syncable/syncable_enum_conversions.h
index 12f6428..0ae53ad 100644
--- a/sync/syncable/syncable_enum_conversions.h
+++ b/sync/syncable/syncable_enum_conversions.h
@@ -44,6 +44,9 @@ SYNC_EXPORT_PRIVATE const char* GetProtoFieldString(ProtoField proto_field);
SYNC_EXPORT_PRIVATE const char* GetUniquePositionFieldString(
UniquePositionField position_field);
+SYNC_EXPORT_PRIVATE const char* GetAttachmentMetadataFieldString(
+ AttachmentMetadataField attachment_metadata_field);
+
SYNC_EXPORT_PRIVATE const char* GetBitTempString(BitTemp bit_temp);
} // namespace syncable
diff --git a/sync/syncable/syncable_enum_conversions_unittest.cc b/sync/syncable/syncable_enum_conversions_unittest.cc
index f74d130..d11d017 100644
--- a/sync/syncable/syncable_enum_conversions_unittest.cc
+++ b/sync/syncable/syncable_enum_conversions_unittest.cc
@@ -83,6 +83,12 @@ TEST_F(SyncableEnumConversionsTest, GetUniquePositionFieldString) {
UNIQUE_POSITION_FIELDS_BEGIN, UNIQUE_POSITION_FIELDS_END - 1);
}
+TEST_F(SyncableEnumConversionsTest, GetAttachmentMetadataFieldString) {
+ TestEnumStringFunction(
+ GetAttachmentMetadataFieldString,
+ ATTACHMENT_METADATA_FIELDS_BEGIN, ATTACHMENT_METADATA_FIELDS_END - 1);
+}
+
TEST_F(SyncableEnumConversionsTest, GetBitTempString) {
TestEnumStringFunction(
GetBitTempString, BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1);
diff --git a/sync/test/test_directory_backing_store.h b/sync/test/test_directory_backing_store.h
index 7cb26b6..6c74291 100644
--- a/sync/test/test_directory_backing_store.h
+++ b/sync/test/test_directory_backing_store.h
@@ -49,6 +49,7 @@ class TestDirectoryBackingStore : public DirectoryBackingStore {
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion83To84);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion84To85);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion85To86);
+ FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion86To87);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, DetectInvalidPosition);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, ModelTypeIds);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, Corruption);