OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/sync/user_events/user_event_sync_bridge.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/big_endian.h" | |
10 #include "base/bind.h" | |
11 #include "base/location.h" | |
12 #include "base/logging.h" | |
13 #include "base/memory/ptr_util.h" | |
14 #include "base/strings/string_number_conversions.h" | |
15 #include "components/sync/model/entity_change.h" | |
16 #include "components/sync/model/metadata_batch.h" | |
17 #include "components/sync/model/mutable_data_batch.h" | |
18 #include "components/sync/protocol/sync.pb.h" | |
19 | |
20 namespace syncer { | |
21 | |
22 using sync_pb::UserEventSpecifics; | |
23 using sync_pb::ModelTypeState; | |
24 using IdList = ModelTypeStore::IdList; | |
25 using Record = ModelTypeStore::Record; | |
26 using RecordList = ModelTypeStore::RecordList; | |
27 using Result = ModelTypeStore::Result; | |
28 using WriteBatch = ModelTypeStore::WriteBatch; | |
29 | |
30 namespace { | |
31 | |
32 std::string GetStorageKeyFromSpecifics(const UserEventSpecifics& specifics) { | |
33 // Force Big Endian, this means newly created keys are last in sort order, | |
34 // which allows leveldb to append new writes, which it is best at. | |
35 // TODO(skym): Until we force |event_time_usec| to never conflict, this has | |
36 // the potential for errors. | |
37 std::string key(8, 0); | |
38 base::WriteBigEndian(&key[0], specifics.event_time_usec()); | |
Patrick Noland
2017/05/04 19:43:18
For my own curiosity, why does this (and other use
skym
2017/05/04 20:34:00
It would seem c_str() is too const.
../../compone
| |
39 return key; | |
40 } | |
41 | |
42 std::unique_ptr<EntityData> MoveToEntityData( | |
43 std::unique_ptr<UserEventSpecifics> specifics) { | |
44 auto entity_data = base::MakeUnique<EntityData>(); | |
45 entity_data->non_unique_name = | |
46 base::Int64ToString(specifics->event_time_usec()); | |
47 entity_data->specifics.set_allocated_user_event(specifics.release()); | |
48 return entity_data; | |
49 } | |
50 | |
51 std::unique_ptr<EntityData> CopyToEntityData( | |
52 const UserEventSpecifics specifics) { | |
53 auto entity_data = base::MakeUnique<EntityData>(); | |
54 entity_data->non_unique_name = | |
55 base::Int64ToString(specifics.event_time_usec()); | |
56 *entity_data->specifics.mutable_user_event() = specifics; | |
57 return entity_data; | |
58 } | |
59 | |
60 } // namespace | |
61 | |
62 UserEventSyncBridge::UserEventSyncBridge( | |
63 const ModelTypeStoreFactory& store_factory, | |
64 const ChangeProcessorFactory& change_processor_factory) | |
65 : ModelTypeSyncBridge(change_processor_factory, USER_EVENTS) { | |
66 store_factory.Run( | |
67 base::Bind(&UserEventSyncBridge::OnStoreCreated, base::AsWeakPtr(this))); | |
68 } | |
69 | |
70 UserEventSyncBridge::~UserEventSyncBridge() {} | |
71 | |
72 std::unique_ptr<MetadataChangeList> | |
73 UserEventSyncBridge::CreateMetadataChangeList() { | |
74 return WriteBatch::CreateMetadataChangeList(); | |
75 } | |
76 | |
77 base::Optional<ModelError> UserEventSyncBridge::MergeSyncData( | |
78 std::unique_ptr<MetadataChangeList> metadata_change_list, | |
79 EntityDataMap entity_data_map) { | |
80 NOTREACHED(); | |
81 return {}; | |
82 } | |
83 | |
84 base::Optional<ModelError> UserEventSyncBridge::ApplySyncChanges( | |
85 std::unique_ptr<MetadataChangeList> metadata_change_list, | |
86 EntityChangeList entity_changes) { | |
87 NOTREACHED(); | |
88 return {}; | |
89 } | |
90 | |
91 void UserEventSyncBridge::GetData(StorageKeyList storage_keys, | |
92 DataCallback callback) { | |
93 store_->ReadData(storage_keys, base::Bind(&UserEventSyncBridge::OnReadData, | |
94 base::AsWeakPtr(this), callback)); | |
95 } | |
96 | |
97 void UserEventSyncBridge::GetAllData(DataCallback callback) { | |
98 store_->ReadAllData(base::Bind(&UserEventSyncBridge::OnReadAllData, | |
99 base::AsWeakPtr(this), callback)); | |
100 } | |
101 | |
102 std::string UserEventSyncBridge::GetClientTag(const EntityData& entity_data) { | |
103 return GetStorageKey(entity_data); | |
104 } | |
105 | |
106 std::string UserEventSyncBridge::GetStorageKey(const EntityData& entity_data) { | |
107 return GetStorageKeyFromSpecifics(entity_data.specifics.user_event()); | |
108 } | |
109 | |
110 void UserEventSyncBridge::DisableSync() { | |
111 // No data should be retained through sign out. | |
112 store_->ReadAllData(base::Bind(&UserEventSyncBridge::OnReadAllDataToDelete, | |
113 base::AsWeakPtr(this))); | |
114 } | |
115 | |
116 void UserEventSyncBridge::RecordUserEvent( | |
117 std::unique_ptr<UserEventSpecifics> specifics) { | |
118 std::string storage_key = GetStorageKeyFromSpecifics(*specifics); | |
119 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); | |
120 batch->WriteData(storage_key, specifics->SerializeAsString()); | |
121 change_processor()->Put(storage_key, MoveToEntityData(std::move(specifics)), | |
122 batch->GetMetadataChangeList()); | |
123 store_->CommitWriteBatch( | |
124 std::move(batch), | |
125 base::Bind(&UserEventSyncBridge::OnCommit, base::AsWeakPtr(this))); | |
126 } | |
127 | |
128 void UserEventSyncBridge::OnStoreCreated( | |
129 Result result, | |
130 std::unique_ptr<ModelTypeStore> store) { | |
131 if (result == Result::SUCCESS) { | |
132 std::swap(store_, store); | |
133 store_->ReadAllMetadata(base::Bind(&UserEventSyncBridge::OnReadAllMetadata, | |
134 base::AsWeakPtr(this))); | |
135 } else { | |
136 change_processor()->ReportError(FROM_HERE, | |
137 "ModelTypeStore creation failed."); | |
138 } | |
139 } | |
140 | |
141 void UserEventSyncBridge::OnReadAllMetadata( | |
142 base::Optional<ModelError> error, | |
143 std::unique_ptr<MetadataBatch> metadata_batch) { | |
144 if (error) { | |
145 change_processor()->ReportError(error.value()); | |
146 } else { | |
147 if (!metadata_batch->GetModelTypeState().initial_sync_done()) { | |
148 // We have never initialized before, force it to true. We are not going to | |
149 // ever have a GetUpdates because our type is commit only. | |
150 // TODO(skym): Do we need to worry about saving this back ourselves? Or | |
151 // does that get taken care for us? | |
152 ModelTypeState state = metadata_batch->GetModelTypeState(); | |
153 state.set_initial_sync_done(true); | |
154 metadata_batch->SetModelTypeState(state); | |
155 } | |
156 change_processor()->ModelReadyToSync(std::move(metadata_batch)); | |
157 } | |
158 } | |
159 | |
160 void UserEventSyncBridge::OnCommit(Result result) { | |
161 if (result != Result::SUCCESS) { | |
162 change_processor()->ReportError(FROM_HERE, "Failed writing user events."); | |
163 } | |
164 } | |
165 | |
166 void UserEventSyncBridge::OnReadData(DataCallback callback, | |
167 Result result, | |
168 std::unique_ptr<RecordList> data_records, | |
169 std::unique_ptr<IdList> missing_id_list) { | |
170 OnReadAllData(callback, result, std::move(data_records)); | |
171 } | |
172 | |
173 void UserEventSyncBridge::OnReadAllData( | |
174 DataCallback callback, | |
175 Result result, | |
176 std::unique_ptr<RecordList> data_records) { | |
177 if (result != Result::SUCCESS) { | |
178 change_processor()->ReportError(FROM_HERE, "Failed reading user events."); | |
179 return; | |
180 } | |
181 | |
182 auto batch = base::MakeUnique<MutableDataBatch>(); | |
183 UserEventSpecifics specifics; | |
Patrick Noland
2017/05/04 19:43:18
Again for my own curiosity, any reason this is dec
skym
2017/05/04 20:34:00
I'm mostly copying this pattern from other places
| |
184 for (const Record& r : *data_records) { | |
185 if (specifics.ParseFromString(r.value)) { | |
186 DCHECK_EQ(r.id, GetStorageKeyFromSpecifics(specifics)); | |
187 batch->Put(r.id, CopyToEntityData(specifics)); | |
188 } else { | |
189 change_processor()->ReportError(FROM_HERE, | |
Patrick Noland
2017/05/04 19:43:18
Do we want to keep the loop going if serialization
skym
2017/05/04 20:34:00
Probably not! Added an early return.
| |
190 "Failed deserializing user events."); | |
191 } | |
192 } | |
193 callback.Run(std::move(batch)); | |
194 } | |
195 | |
196 void UserEventSyncBridge::OnReadAllDataToDelete( | |
197 Result result, | |
198 std::unique_ptr<RecordList> data_records) { | |
199 if (result != Result::SUCCESS) { | |
200 change_processor()->ReportError(FROM_HERE, "Failed reading user events."); | |
201 return; | |
202 } | |
203 | |
204 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); | |
205 for (const Record& r : *data_records) { | |
206 batch->DeleteData(r.id); | |
207 } | |
208 store_->CommitWriteBatch( | |
209 std::move(batch), | |
210 base::Bind(&UserEventSyncBridge::OnCommit, base::AsWeakPtr(this))); | |
211 } | |
212 | |
213 } // namespace syncer | |
OLD | NEW |