1 // Copyright 2012 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.
5 #ifndef SYNC_SYNCABLE_ENTRY_KERNEL_H_
6 #define SYNC_SYNCABLE_ENTRY_KERNEL_H_
10 #include "base/time/time.h"
11 #include "base/values.h"
12 #include "sync/base/sync_export.h"
13 #include "sync/internal_api/public/base/model_type.h"
14 #include "sync/internal_api/public/base/unique_position.h"
15 #include "sync/internal_api/public/util/immutable.h"
16 #include "sync/protocol/attachments.pb.h"
17 #include "sync/protocol/sync.pb.h"
18 #include "sync/syncable/metahandle_set.h"
19 #include "sync/syncable/syncable_id.h"
20 #include "sync/util/time.h"
28 // Things you need to update if you change any of the fields below:
29 // - EntryKernel struct in this file
30 // - syncable_columns.h
31 // - syncable_enum_conversions{.h,.cc,_unittest.cc}
32 // - EntryKernel::EntryKernel(), EntryKernel::ToValue() in entry_kernel.cc
33 // - operator<< in Entry.cc
34 // - BindFields() and UnpackEntry() in directory_backing_store.cc
35 // - kCurrentDBVersion, DirectoryBackingStore::InitializeTables in
36 // directory_backing_store.cc
37 // - TestSimpleFieldsPreservedDuringSaveChanges in syncable_unittest.cc
39 static const int64 kInvalidMetaHandle
= 0;
43 INT64_FIELDS_BEGIN
= BEGIN_FIELDS
46 enum MetahandleField
{
47 // Primary key into the table. Keep this as a handle to the meta entry
48 // across transactions.
49 META_HANDLE
= INT64_FIELDS_BEGIN
53 // After initial upload, the version is controlled by the server, and is
54 // increased whenever the data or metadata changes on the server.
55 BASE_VERSION
= META_HANDLE
+ 1,
59 SERVER_VERSION
= BASE_VERSION
+ 1,
60 LOCAL_EXTERNAL_ID
, // ID of an item in the external local storage that this
61 // entry is associated with. (such as bookmarks.js)
67 INT64_FIELDS_COUNT
= INT64_FIELDS_END
- INT64_FIELDS_BEGIN
,
68 TIME_FIELDS_BEGIN
= INT64_FIELDS_END
,
72 MTIME
= TIME_FIELDS_BEGIN
,
80 TIME_FIELDS_COUNT
= TIME_FIELDS_END
- TIME_FIELDS_BEGIN
,
81 ID_FIELDS_BEGIN
= TIME_FIELDS_END
,
85 // Code in InitializeTables relies on ID being the first IdField value.
93 ID_FIELDS_COUNT
= ID_FIELDS_END
- ID_FIELDS_BEGIN
,
94 BIT_FIELDS_BEGIN
= ID_FIELDS_END
97 enum IndexedBitField
{
98 IS_UNSYNCED
= BIT_FIELDS_BEGIN
,
100 INDEXED_BIT_FIELDS_END
,
104 IS_DEL
= INDEXED_BIT_FIELDS_END
,
115 BIT_FIELDS_COUNT
= BIT_FIELDS_END
- BIT_FIELDS_BEGIN
,
116 STRING_FIELDS_BEGIN
= BIT_FIELDS_END
120 // Name, will be truncated by server. Can be duplicated in a folder.
121 NON_UNIQUE_NAME
= STRING_FIELDS_BEGIN
,
122 // The server version of |NON_UNIQUE_NAME|.
123 SERVER_NON_UNIQUE_NAME
,
125 // A tag string which identifies this node as a particular top-level
126 // permanent object. The tag can be thought of as a unique key that
127 // identifies a singleton instance.
128 UNIQUE_SERVER_TAG
, // Tagged by the server
129 UNIQUE_CLIENT_TAG
, // Tagged by the client
130 UNIQUE_BOOKMARK_TAG
, // Client tags for bookmark items
135 STRING_FIELDS_COUNT
= STRING_FIELDS_END
- STRING_FIELDS_BEGIN
,
136 PROTO_FIELDS_BEGIN
= STRING_FIELDS_END
139 // From looking at the sqlite3 docs, it's not directly stated, but it
140 // seems the overhead for storing a NULL blob is very small.
142 SPECIFICS
= PROTO_FIELDS_BEGIN
,
144 BASE_SERVER_SPECIFICS
,
149 PROTO_FIELDS_COUNT
= PROTO_FIELDS_END
- PROTO_FIELDS_BEGIN
,
150 UNIQUE_POSITION_FIELDS_BEGIN
= PROTO_FIELDS_END
153 enum UniquePositionField
{
154 SERVER_UNIQUE_POSITION
= UNIQUE_POSITION_FIELDS_BEGIN
,
156 UNIQUE_POSITION_FIELDS_END
160 UNIQUE_POSITION_FIELDS_COUNT
=
161 UNIQUE_POSITION_FIELDS_END
- UNIQUE_POSITION_FIELDS_BEGIN
,
162 ATTACHMENT_METADATA_FIELDS_BEGIN
= UNIQUE_POSITION_FIELDS_END
165 enum AttachmentMetadataField
{
166 ATTACHMENT_METADATA
= ATTACHMENT_METADATA_FIELDS_BEGIN
,
167 SERVER_ATTACHMENT_METADATA
,
168 ATTACHMENT_METADATA_FIELDS_END
172 ATTACHMENT_METADATA_FIELDS_COUNT
=
173 ATTACHMENT_METADATA_FIELDS_END
- ATTACHMENT_METADATA_FIELDS_BEGIN
,
174 FIELD_COUNT
= ATTACHMENT_METADATA_FIELDS_END
- BEGIN_FIELDS
,
175 // Past this point we have temporaries, stored in memory only.
176 BEGIN_TEMPS
= ATTACHMENT_METADATA_FIELDS_END
,
177 BIT_TEMPS_BEGIN
= BEGIN_TEMPS
,
181 // Not to be confused with IS_UNSYNCED, this bit is used to detect local
182 // changes to items that happen during the server Commit operation.
183 SYNCING
= BIT_TEMPS_BEGIN
,
188 BIT_TEMPS_COUNT
= BIT_TEMPS_END
- BIT_TEMPS_BEGIN
193 struct SYNC_EXPORT_PRIVATE EntryKernel
{
195 std::string string_fields
[STRING_FIELDS_COUNT
];
196 sync_pb::EntitySpecifics specifics_fields
[PROTO_FIELDS_COUNT
];
197 int64 int64_fields
[INT64_FIELDS_COUNT
];
198 base::Time time_fields
[TIME_FIELDS_COUNT
];
199 Id id_fields
[ID_FIELDS_COUNT
];
200 UniquePosition unique_position_fields
[UNIQUE_POSITION_FIELDS_COUNT
];
201 sync_pb::AttachmentMetadata
202 attachment_metadata_fields
[ATTACHMENT_METADATA_FIELDS_COUNT
];
203 std::bitset
<BIT_FIELDS_COUNT
> bit_fields
;
204 std::bitset
<BIT_TEMPS_COUNT
> bit_temps
;
210 // Set the dirty bit, and optionally add this entry's metahandle to
211 // a provided index on dirty bits in |dirty_index|. Parameter may be null,
212 // and will result only in setting the dirty bit of this entry.
213 inline void mark_dirty(syncable::MetahandleSet
* dirty_index
) {
214 if (!dirty_
&& dirty_index
) {
215 DCHECK_NE(0, ref(META_HANDLE
));
216 dirty_index
->insert(ref(META_HANDLE
));
221 // Clear the dirty bit, and optionally remove this entry's metahandle from
222 // a provided index on dirty bits in |dirty_index|. Parameter may be null,
223 // and will result only in clearing dirty bit of this entry.
224 inline void clear_dirty(syncable::MetahandleSet
* dirty_index
) {
225 if (dirty_
&& dirty_index
) {
226 DCHECK_NE(0, ref(META_HANDLE
));
227 dirty_index
->erase(ref(META_HANDLE
));
232 inline bool is_dirty() const {
237 inline void put(MetahandleField field
, int64 value
) {
238 int64_fields
[field
- INT64_FIELDS_BEGIN
] = value
;
240 inline void put(Int64Field field
, int64 value
) {
241 int64_fields
[field
- INT64_FIELDS_BEGIN
] = value
;
243 inline void put(TimeField field
, const base::Time
& value
) {
244 // Round-trip to proto time format and back so that we have
245 // consistent time resolutions (ms).
246 time_fields
[field
- TIME_FIELDS_BEGIN
] =
247 ProtoTimeToTime(TimeToProtoTime(value
));
249 inline void put(IdField field
, const Id
& value
) {
250 id_fields
[field
- ID_FIELDS_BEGIN
] = value
;
252 inline void put(BaseVersion field
, int64 value
) {
253 int64_fields
[field
- INT64_FIELDS_BEGIN
] = value
;
255 inline void put(IndexedBitField field
, bool value
) {
256 bit_fields
[field
- BIT_FIELDS_BEGIN
] = value
;
258 inline void put(IsDelField field
, bool value
) {
259 bit_fields
[field
- BIT_FIELDS_BEGIN
] = value
;
261 inline void put(BitField field
, bool value
) {
262 bit_fields
[field
- BIT_FIELDS_BEGIN
] = value
;
264 inline void put(StringField field
, const std::string
& value
) {
265 string_fields
[field
- STRING_FIELDS_BEGIN
] = value
;
267 inline void put(ProtoField field
, const sync_pb::EntitySpecifics
& value
) {
268 specifics_fields
[field
- PROTO_FIELDS_BEGIN
].CopyFrom(value
);
270 inline void put(UniquePositionField field
, const UniquePosition
& value
) {
271 unique_position_fields
[field
- UNIQUE_POSITION_FIELDS_BEGIN
] = value
;
273 inline void put(AttachmentMetadataField field
,
274 const sync_pb::AttachmentMetadata
& value
) {
275 attachment_metadata_fields
[field
- ATTACHMENT_METADATA_FIELDS_BEGIN
] =
278 inline void put(BitTemp field
, bool value
) {
279 bit_temps
[field
- BIT_TEMPS_BEGIN
] = value
;
282 // Const ref getters.
283 inline int64
ref(MetahandleField field
) const {
284 return int64_fields
[field
- INT64_FIELDS_BEGIN
];
286 inline int64
ref(Int64Field field
) const {
287 return int64_fields
[field
- INT64_FIELDS_BEGIN
];
289 inline const base::Time
& ref(TimeField field
) const {
290 return time_fields
[field
- TIME_FIELDS_BEGIN
];
292 inline const Id
& ref(IdField field
) const {
293 return id_fields
[field
- ID_FIELDS_BEGIN
];
295 inline int64
ref(BaseVersion field
) const {
296 return int64_fields
[field
- INT64_FIELDS_BEGIN
];
298 inline bool ref(IndexedBitField field
) const {
299 return bit_fields
[field
- BIT_FIELDS_BEGIN
];
301 inline bool ref(IsDelField field
) const {
302 return bit_fields
[field
- BIT_FIELDS_BEGIN
];
304 inline bool ref(BitField field
) const {
305 return bit_fields
[field
- BIT_FIELDS_BEGIN
];
307 inline const std::string
& ref(StringField field
) const {
308 return string_fields
[field
- STRING_FIELDS_BEGIN
];
310 inline const sync_pb::EntitySpecifics
& ref(ProtoField field
) const {
311 return specifics_fields
[field
- PROTO_FIELDS_BEGIN
];
313 inline const UniquePosition
& ref(UniquePositionField field
) const {
314 return unique_position_fields
[field
- UNIQUE_POSITION_FIELDS_BEGIN
];
316 inline const sync_pb::AttachmentMetadata
& ref(
317 AttachmentMetadataField field
) const {
318 return attachment_metadata_fields
[field
- ATTACHMENT_METADATA_FIELDS_BEGIN
];
320 inline bool ref(BitTemp field
) const {
321 return bit_temps
[field
- BIT_TEMPS_BEGIN
];
324 // Non-const, mutable ref getters for object types only.
325 inline std::string
& mutable_ref(StringField field
) {
326 return string_fields
[field
- STRING_FIELDS_BEGIN
];
328 inline sync_pb::EntitySpecifics
& mutable_ref(ProtoField field
) {
329 return specifics_fields
[field
- PROTO_FIELDS_BEGIN
];
331 inline Id
& mutable_ref(IdField field
) {
332 return id_fields
[field
- ID_FIELDS_BEGIN
];
334 inline UniquePosition
& mutable_ref(UniquePositionField field
) {
335 return unique_position_fields
[field
- UNIQUE_POSITION_FIELDS_BEGIN
];
337 inline sync_pb::AttachmentMetadata
& mutable_ref(
338 AttachmentMetadataField field
) {
339 return attachment_metadata_fields
[field
- ATTACHMENT_METADATA_FIELDS_BEGIN
];
342 ModelType
GetModelType() const;
343 ModelType
GetServerModelType() const;
344 bool ShouldMaintainPosition() const;
345 bool ShouldMaintainHierarchy() const;
347 // Dumps all kernel info into a DictionaryValue and returns it.
348 // Transfers ownership of the DictionaryValue to the caller.
349 // Note: |cryptographer| is an optional parameter for use in decrypting
350 // encrypted specifics. If it is NULL or the specifics are not decryptsble,
351 // they will be serialized as empty proto's.
352 base::DictionaryValue
* ToValue(Cryptographer
* cryptographer
) const;
355 // Tracks whether this entry needs to be saved to the database.
359 class EntryKernelLessByMetaHandle
{
361 inline bool operator()(const EntryKernel
* a
,
362 const EntryKernel
* b
) const {
363 return a
->ref(META_HANDLE
) < b
->ref(META_HANDLE
);
367 typedef std::set
<const EntryKernel
*, EntryKernelLessByMetaHandle
>
370 struct EntryKernelMutation
{
371 EntryKernel original
, mutated
;
374 typedef std::map
<int64
, EntryKernelMutation
> EntryKernelMutationMap
;
376 typedef Immutable
<EntryKernelMutationMap
> ImmutableEntryKernelMutationMap
;
378 // Caller owns the return value.
379 base::DictionaryValue
* EntryKernelMutationToValue(
380 const EntryKernelMutation
& mutation
);
382 // Caller owns the return value.
383 base::ListValue
* EntryKernelMutationMapToValue(
384 const EntryKernelMutationMap
& mutations
);
386 } // namespace syncable
387 } // namespace syncer
389 #endif // SYNC_SYNCABLE_ENTRY_KERNEL_H_