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.
4
5#include "sync/internal_api/public/write_transaction.h"
6
7#include "sync/syncable/directory.h"
8#include "sync/syncable/mutable_entry.h"
9#include "sync/syncable/syncable_write_transaction.h"
10
11namespace syncer {
12
13//////////////////////////////////////////////////////////////////////////
14// WriteTransaction member definitions
15WriteTransaction::WriteTransaction(const tracked_objects::Location& from_here,
16                                   UserShare* share)
17    : BaseTransaction(share),
18      transaction_(NULL) {
19  transaction_ = new syncable::WriteTransaction(from_here, syncable::SYNCAPI,
20                                                share->directory.get());
21}
22
23WriteTransaction::WriteTransaction(const tracked_objects::Location& from_here,
24                                   UserShare* share,
25                                   int64* new_model_version)
26    : BaseTransaction(share),
27      transaction_(NULL) {
28  transaction_ = new syncable::WriteTransaction(from_here,
29                                                share->directory.get(),
30                                                new_model_version);
31}
32
33WriteTransaction::~WriteTransaction() {
34  delete transaction_;
35}
36
37syncable::BaseTransaction* WriteTransaction::GetWrappedTrans() const {
38  return transaction_;
39}
40
41void WriteTransaction::SetDataTypeContext(
42    ModelType type,
43    syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status,
44    const std::string& context) {
45  DCHECK(ProtocolTypes().Has(type));
46  int field_number = GetSpecificsFieldNumberFromModelType(type);
47  sync_pb::DataTypeContext local_context;
48  GetDirectory()->GetDataTypeContext(transaction_,
49                                     type,
50                                     &local_context);
51  if (local_context.context() == context)
52    return;
53
54  if (!local_context.has_data_type_id())
55    local_context.set_data_type_id(field_number);
56
57  DCHECK_EQ(field_number, local_context.data_type_id());
58  DCHECK_GE(local_context.version(), 0);
59  local_context.set_version(local_context.version() + 1);
60  local_context.set_context(context);
61  GetDirectory()->SetDataTypeContext(transaction_,
62                                     type,
63                                     local_context);
64  if (refresh_status == syncer::SyncChangeProcessor::REFRESH_NEEDED) {
65    DVLOG(1) << "Forcing refresh of type " << ModelTypeToString(type);
66    // Clear the progress token from the progress markers. Preserve all other
67    // state, in case a GC directive was present.
68    sync_pb::DataTypeProgressMarker progress_marker;
69    GetDirectory()->GetDownloadProgress(type, &progress_marker);
70    progress_marker.clear_token();
71    GetDirectory()->SetDownloadProgress(type, progress_marker);
72
73    // Go through and reset the versions for all the synced entities of this
74    // data type.
75    GetDirectory()->ResetVersionsForType(transaction_, type);
76  }
77
78  // Note that it's possible for a GetUpdatesResponse that arrives immediately
79  // after the context update to override the cleared progress markers.
80  // TODO(zea): add a flag in the directory to prevent this from happening.
81  // See crbug.com/360280
82}
83
84void WriteTransaction::UpdateEntriesMarkAttachmentAsOnServer(
85    const AttachmentId& attachment_id) {
86  syncable::Directory::Metahandles handles;
87  GetDirectory()->GetMetahandlesByAttachmentId(
88      transaction_, attachment_id.GetProto(), &handles);
89  for (syncable::Directory::Metahandles::iterator iter = handles.begin();
90       iter != handles.end();
91       ++iter) {
92    syncable::MutableEntry entry(transaction_, syncable::GET_BY_HANDLE, *iter);
93    entry.MarkAttachmentAsOnServer(attachment_id.GetProto());
94  }
95}
96
97}  // namespace syncer
98