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)#include "sync/syncable/entry.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iomanip> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/string_escape.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/blob.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/directory.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/syncable/syncable_base_transaction.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/syncable_columns.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncable { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Entry::Entry(BaseTransaction* trans, GetById, const Id& id) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : basetrans_(trans) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kernel_ = trans->directory()->GetEntryById(id); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Entry::Entry(BaseTransaction* trans, GetByClientTag, const string& tag) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : basetrans_(trans) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kernel_ = trans->directory()->GetEntryByClientTag(tag); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Entry::Entry(BaseTransaction* trans, GetByServerTag, const string& tag) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : basetrans_(trans) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kernel_ = trans->directory()->GetEntryByServerTag(tag); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Entry::Entry(BaseTransaction* trans, GetByHandle, int64 metahandle) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : basetrans_(trans) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kernel_ = trans->directory()->GetEntryByHandle(metahandle); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Directory* Entry::dir() const { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return basetrans_->directory(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::DictionaryValue* Entry::ToValue(Cryptographer* cryptographer) const { 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* entry_info = new base::DictionaryValue(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_info->SetBoolean("good", good()); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (good()) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry_info->Set("kernel", kernel_->ToValue(cryptographer)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_info->Set("modelType", 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelTypeToValue(GetModelType())); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_info->SetBoolean("existsOnClientBecauseNameIsNonEmpty", 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExistsOnClientBecauseNameIsNonEmpty()); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_info->SetBoolean("isRoot", IsRoot()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry_info; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const string& Entry::Get(StringField field) const { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(kernel_); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kernel_->ref(field); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelType Entry::GetServerModelType() const { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType specifics_type = kernel_->GetServerModelType(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (specifics_type != UNSPECIFIED) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return specifics_type; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, we don't have a server type yet. That should only happen 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the item is an uncommitted locally created item. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible we'll need to relax these checks in the future; they're 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just here for now as a safety measure. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Get(IS_UNSYNCED)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(Get(SERVER_VERSION), 0); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Get(SERVER_IS_DEL)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: can't enforce !Get(ID).ServerKnows() here because that could 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually happen if we hit AttemptReuniteLostCommitResponses. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UNSPECIFIED; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModelType Entry::GetModelType() const { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelType specifics_type = GetModelTypeFromSpecifics(Get(SPECIFICS)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (specifics_type != UNSPECIFIED) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return specifics_type; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRoot()) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TOP_LEVEL_FOLDER; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loose check for server-created top-level folders that aren't 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bound to a particular model type. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Get(UNIQUE_SERVER_TAG).empty() && Get(IS_DIR)) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TOP_LEVEL_FOLDER; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UNSPECIFIED; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Id Entry::GetPredecessorId() const { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return dir()->GetPredecessorId(kernel_); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Id Entry::GetSuccessorId() const { 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return dir()->GetSuccessorId(kernel_); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Id Entry::GetFirstChildId() const { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return dir()->GetFirstChildId(basetrans_, kernel_); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Entry::GetChildHandles(std::vector<int64>* result) const { 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dir()->GetChildHandlesById(basetrans_, Get(ID), result); 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int Entry::GetTotalNodeCount() const { 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return dir()->GetTotalNodeCount(basetrans_, kernel_); 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int Entry::GetPositionIndex() const { 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return dir()->GetPositionIndex(basetrans_, kernel_); 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool Entry::ShouldMaintainPosition() const { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kernel_->ShouldMaintainPosition(); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& s, const Blob& blob) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Blob::const_iterator i = blob.begin(); i != blob.end(); ++i) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s << std::hex << std::setw(2) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::setfill('0') << static_cast<unsigned int>(*i); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s << std::dec; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& os, const Entry& entry) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryKernel* const kernel = entry.kernel_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ": " 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << kernel->ref(static_cast<Int64Field>(i)) << ", "; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; i < TIME_FIELDS_END; ++i) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ": " 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << GetTimeDebugString(kernel->ref(static_cast<TimeField>(i))) << ", "; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; i < ID_FIELDS_END; ++i) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ": " 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << kernel->ref(static_cast<IdField>(i)) << ", "; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "Flags: "; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; i < BIT_FIELDS_END; ++i) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kernel->ref(static_cast<BitField>(i))) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ", "; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; i < STRING_FIELDS_END; ++i) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& field = kernel->ref(static_cast<StringField>(i)); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ": " << field << ", "; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; i < PROTO_FIELDS_END; ++i) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string escaped_str; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::JsonDoubleQuote( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kernel->ref(static_cast<ProtoField>(i)).SerializeAsString(), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &escaped_str); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ": " << escaped_str << ", "; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for ( ; i < UNIQUE_POSITION_FIELDS_END; ++i) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << g_metas_columns[i].name << ": " 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << kernel->ref(static_cast<UniquePositionField>(i)).ToDebugString() 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", "; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "TempFlags: "; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( ; i < BIT_TEMPS_END; ++i) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kernel->ref(static_cast<BitTemp>(i))) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "#" << i - BIT_TEMPS_BEGIN << ", "; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return os; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncable 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncer 177