12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SYNC_SYNCABLE_ENTRY_KERNEL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYNC_SYNCABLE_ENTRY_KERNEL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/base/sync_export.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "sync/internal_api/public/base/unique_position.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/util/immutable.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/metahandle_set.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/syncable_id.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/util/time.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Cryptographer;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncable {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Things you need to update if you change any of the fields below:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - EntryKernel struct in this file
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - syncable_columns.h
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - syncable_enum_conversions{.h,.cc,_unittest.cc}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - EntryKernel::EntryKernel(), EntryKernel::ToValue() in entry_kernel.cc
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - operator<< in Entry.cc
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - BindFields() and UnpackEntry() in directory_backing_store.cc
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - TestSimpleFieldsPreservedDuringSaveChanges in syncable_unittest.cc
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int64 kInvalidMetaHandle = 0;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BEGIN_FIELDS = 0,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INT64_FIELDS_BEGIN = BEGIN_FIELDS
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum MetahandleField {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Primary key into the table.  Keep this as a handle to the meta entry
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // across transactions.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  META_HANDLE = INT64_FIELDS_BEGIN
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BaseVersion {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After initial upload, the version is controlled by the server, and is
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increased whenever the data or metadata changes on the server.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BASE_VERSION = META_HANDLE + 1,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum Int64Field {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_VERSION = BASE_VERSION + 1,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOCAL_EXTERNAL_ID,  // ID of an item in the external local storage that this
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      // entry is associated with. (such as bookmarks.js)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRANSACTION_VERSION,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INT64_FIELDS_END
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INT64_FIELDS_COUNT = INT64_FIELDS_END - INT64_FIELDS_BEGIN,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TIME_FIELDS_BEGIN = INT64_FIELDS_END,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum TimeField {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MTIME = TIME_FIELDS_BEGIN,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_MTIME,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CTIME,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_CTIME,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TIME_FIELDS_END,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TIME_FIELDS_COUNT = TIME_FIELDS_END - TIME_FIELDS_BEGIN,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ID_FIELDS_BEGIN = TIME_FIELDS_END,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum IdField {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Code in InitializeTables relies on ID being the first IdField value.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ID = ID_FIELDS_BEGIN,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PARENT_ID,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_PARENT_ID,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ID_FIELDS_END
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ID_FIELDS_COUNT = ID_FIELDS_END - ID_FIELDS_BEGIN,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BIT_FIELDS_BEGIN = ID_FIELDS_END
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum IndexedBitField {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IS_UNSYNCED = BIT_FIELDS_BEGIN,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IS_UNAPPLIED_UPDATE,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INDEXED_BIT_FIELDS_END,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum IsDelField {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IS_DEL = INDEXED_BIT_FIELDS_END,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BitField {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IS_DIR = IS_DEL + 1,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_IS_DIR,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_IS_DEL,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BIT_FIELDS_END
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BIT_FIELDS_COUNT = BIT_FIELDS_END - BIT_FIELDS_BEGIN,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STRING_FIELDS_BEGIN = BIT_FIELDS_END
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum StringField {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Name, will be truncated by server. Can be duplicated in a folder.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NON_UNIQUE_NAME = STRING_FIELDS_BEGIN,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The server version of |NON_UNIQUE_NAME|.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_NON_UNIQUE_NAME,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A tag string which identifies this node as a particular top-level
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // permanent object.  The tag can be thought of as a unique key that
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identifies a singleton instance.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNIQUE_SERVER_TAG,  // Tagged by the server
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNIQUE_CLIENT_TAG,  // Tagged by the client
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UNIQUE_BOOKMARK_TAG,  // Client tags for bookmark items
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STRING_FIELDS_END,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STRING_FIELDS_COUNT = STRING_FIELDS_END - STRING_FIELDS_BEGIN,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROTO_FIELDS_BEGIN = STRING_FIELDS_END
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// From looking at the sqlite3 docs, it's not directly stated, but it
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// seems the overhead for storing a NULL blob is very small.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ProtoField {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPECIFICS = PROTO_FIELDS_BEGIN,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SERVER_SPECIFICS,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BASE_SERVER_SPECIFICS,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROTO_FIELDS_END,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROTO_FIELDS_COUNT = PROTO_FIELDS_END - PROTO_FIELDS_BEGIN,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UNIQUE_POSITION_FIELDS_BEGIN = PROTO_FIELDS_END
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum UniquePositionField {
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SERVER_UNIQUE_POSITION = UNIQUE_POSITION_FIELDS_BEGIN,
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UNIQUE_POSITION,
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UNIQUE_POSITION_FIELDS_END
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UNIQUE_POSITION_FIELDS_COUNT =
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UNIQUE_POSITION_FIELDS_END - UNIQUE_POSITION_FIELDS_BEGIN,
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FIELD_COUNT = UNIQUE_POSITION_FIELDS_END - BEGIN_FIELDS,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Past this point we have temporaries, stored in memory only.
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BEGIN_TEMPS = UNIQUE_POSITION_FIELDS_END,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BIT_TEMPS_BEGIN = BEGIN_TEMPS,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BitTemp {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not to be confused with IS_UNSYNCED, this bit is used to detect local
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changes to items that happen during the server Commit operation.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SYNCING = BIT_TEMPS_BEGIN,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BIT_TEMPS_END,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct SYNC_EXPORT_PRIVATE EntryKernel {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string string_fields[STRING_FIELDS_COUNT];
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EntitySpecifics specifics_fields[PROTO_FIELDS_COUNT];
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 int64_fields[INT64_FIELDS_COUNT];
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time time_fields[TIME_FIELDS_COUNT];
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Id id_fields[ID_FIELDS_COUNT];
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UniquePosition unique_position_fields[UNIQUE_POSITION_FIELDS_COUNT];
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::bitset<BIT_FIELDS_COUNT> bit_fields;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::bitset<BIT_TEMPS_COUNT> bit_temps;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EntryKernel();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~EntryKernel();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the dirty bit, and optionally add this entry's metahandle to
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a provided index on dirty bits in |dirty_index|. Parameter may be null,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and will result only in setting the dirty bit of this entry.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void mark_dirty(syncable::MetahandleSet* dirty_index) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dirty_ && dirty_index) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_NE(0, ref(META_HANDLE));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dirty_index->insert(ref(META_HANDLE));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dirty_ = true;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the dirty bit, and optionally remove this entry's metahandle from
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a provided index on dirty bits in |dirty_index|. Parameter may be null,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and will result only in clearing dirty bit of this entry.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void clear_dirty(syncable::MetahandleSet* dirty_index) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dirty_ && dirty_index) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_NE(0, ref(META_HANDLE));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dirty_index->erase(ref(META_HANDLE));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dirty_ = false;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool is_dirty() const {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return dirty_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setters.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(MetahandleField field, int64 value) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64_fields[field - INT64_FIELDS_BEGIN] = value;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(Int64Field field, int64 value) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64_fields[field - INT64_FIELDS_BEGIN] = value;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(TimeField field, const base::Time& value) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Round-trip to proto time format and back so that we have
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // consistent time resolutions (ms).
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_fields[field - TIME_FIELDS_BEGIN] =
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProtoTimeToTime(TimeToProtoTime(value));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(IdField field, const Id& value) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id_fields[field - ID_FIELDS_BEGIN] = value;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(BaseVersion field, int64 value) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64_fields[field - INT64_FIELDS_BEGIN] = value;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(IndexedBitField field, bool value) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bit_fields[field - BIT_FIELDS_BEGIN] = value;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(IsDelField field, bool value) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bit_fields[field - BIT_FIELDS_BEGIN] = value;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(BitField field, bool value) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bit_fields[field - BIT_FIELDS_BEGIN] = value;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(StringField field, const std::string& value) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string_fields[field - STRING_FIELDS_BEGIN] = value;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(ProtoField field, const sync_pb::EntitySpecifics& value) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    specifics_fields[field - PROTO_FIELDS_BEGIN].CopyFrom(value);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  inline void put(UniquePositionField field, const UniquePosition& value) {
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN] = value;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void put(BitTemp field, bool value) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bit_temps[field - BIT_TEMPS_BEGIN] = value;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Const ref getters.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline int64 ref(MetahandleField field) const {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return int64_fields[field - INT64_FIELDS_BEGIN];
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline int64 ref(Int64Field field) const {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return int64_fields[field - INT64_FIELDS_BEGIN];
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const base::Time& ref(TimeField field) const {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return time_fields[field - TIME_FIELDS_BEGIN];
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const Id& ref(IdField field) const {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return id_fields[field - ID_FIELDS_BEGIN];
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline int64 ref(BaseVersion field) const {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return int64_fields[field - INT64_FIELDS_BEGIN];
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool ref(IndexedBitField field) const {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bit_fields[field - BIT_FIELDS_BEGIN];
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool ref(IsDelField field) const {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bit_fields[field - BIT_FIELDS_BEGIN];
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool ref(BitField field) const {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bit_fields[field - BIT_FIELDS_BEGIN];
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const std::string& ref(StringField field) const {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return string_fields[field - STRING_FIELDS_BEGIN];
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const sync_pb::EntitySpecifics& ref(ProtoField field) const {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return specifics_fields[field - PROTO_FIELDS_BEGIN];
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  inline const UniquePosition& ref(UniquePositionField field) const {
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool ref(BitTemp field) const {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bit_temps[field - BIT_TEMPS_BEGIN];
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-const, mutable ref getters for object types only.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline std::string& mutable_ref(StringField field) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return string_fields[field - STRING_FIELDS_BEGIN];
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline sync_pb::EntitySpecifics& mutable_ref(ProtoField field) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return specifics_fields[field - PROTO_FIELDS_BEGIN];
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline Id& mutable_ref(IdField field) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return id_fields[field - ID_FIELDS_BEGIN];
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  inline UniquePosition& mutable_ref(UniquePositionField field) {
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ModelType GetModelType() const;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelType GetServerModelType() const;
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool ShouldMaintainPosition() const;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Dumps all kernel info into a DictionaryValue and returns it.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transfers ownership of the DictionaryValue to the caller.
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: |cryptographer| is an optional parameter for use in decrypting
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // encrypted specifics. If it is NULL or the specifics are not decryptsble,
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they will be serialized as empty proto's.
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* ToValue(Cryptographer* cryptographer) const;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tracks whether this entry needs to be saved to the database.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dirty_;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EntryKernelLessByMetaHandle {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool operator()(const EntryKernel* a,
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const EntryKernel* b) const {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return a->ref(META_HANDLE) < b->ref(META_HANDLE);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::set<const EntryKernel*, EntryKernelLessByMetaHandle>
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EntryKernelSet;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct EntryKernelMutation {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EntryKernel original, mutated;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<int64, EntryKernelMutation> EntryKernelMutationMap;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef Immutable<EntryKernelMutationMap> ImmutableEntryKernelMutationMap;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Caller owns the return value.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::DictionaryValue* EntryKernelMutationToValue(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const EntryKernelMutation& mutation);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Caller owns the return value.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ListValue* EntryKernelMutationMapToValue(
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const EntryKernelMutationMap& mutations);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncable
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SYNC_SYNCABLE_ENTRY_KERNEL_H_
359