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/read_node.h"
6
7#include "base/logging.h"
8#include "sync/internal_api/public/base_transaction.h"
9#include "sync/syncable/entry.h"
10#include "sync/syncable/syncable_base_transaction.h"
11#include "sync/syncable/syncable_util.h"
12
13namespace syncer {
14
15//////////////////////////////////////////////////////////////////////////
16// ReadNode member definitions
17ReadNode::ReadNode(const BaseTransaction* transaction)
18    : entry_(NULL), transaction_(transaction) {
19  DCHECK(transaction);
20}
21
22ReadNode::ReadNode() {
23  entry_ = NULL;
24  transaction_ = NULL;
25}
26
27ReadNode::~ReadNode() {
28  delete entry_;
29}
30
31void ReadNode::InitByRootLookup() {
32  DCHECK(!entry_) << "Init called twice";
33  syncable::BaseTransaction* trans = transaction_->GetWrappedTrans();
34  entry_ = new syncable::Entry(trans, syncable::GET_BY_ID, trans->root_id());
35  if (!entry_->good())
36    DCHECK(false) << "Could not lookup root node for reading.";
37}
38
39BaseNode::InitByLookupResult ReadNode::InitByIdLookup(int64 id) {
40  DCHECK(!entry_) << "Init called twice";
41  DCHECK_NE(id, kInvalidId);
42  syncable::BaseTransaction* trans = transaction_->GetWrappedTrans();
43  entry_ = new syncable::Entry(trans, syncable::GET_BY_HANDLE, id);
44  if (!entry_->good())
45    return INIT_FAILED_ENTRY_NOT_GOOD;
46  if (entry_->GetIsDel())
47    return INIT_FAILED_ENTRY_IS_DEL;
48  ModelType model_type = GetModelType();
49  LOG_IF(WARNING, model_type == UNSPECIFIED || model_type == TOP_LEVEL_FOLDER)
50      << "SyncAPI InitByIdLookup referencing unusual object.";
51  return DecryptIfNecessary() ? INIT_OK : INIT_FAILED_DECRYPT_IF_NECESSARY;
52}
53
54BaseNode::InitByLookupResult ReadNode::InitByClientTagLookup(
55    ModelType model_type,
56    const std::string& tag) {
57  DCHECK(!entry_) << "Init called twice";
58  if (tag.empty())
59    return INIT_FAILED_PRECONDITION;
60
61  const std::string hash = syncable::GenerateSyncableHash(model_type, tag);
62
63  entry_ = new syncable::Entry(transaction_->GetWrappedTrans(),
64                               syncable::GET_BY_CLIENT_TAG, hash);
65  if (!entry_->good())
66    return INIT_FAILED_ENTRY_NOT_GOOD;
67  if (entry_->GetIsDel())
68    return INIT_FAILED_ENTRY_IS_DEL;
69  return DecryptIfNecessary() ? INIT_OK : INIT_FAILED_DECRYPT_IF_NECESSARY;
70}
71
72const syncable::Entry* ReadNode::GetEntry() const {
73  return entry_;
74}
75
76const BaseTransaction* ReadNode::GetTransaction() const {
77  return transaction_;
78}
79
80BaseNode::InitByLookupResult ReadNode::InitByTagLookup(
81    const std::string& tag) {
82  DCHECK(!entry_) << "Init called twice";
83  if (tag.empty())
84    return INIT_FAILED_PRECONDITION;
85  syncable::BaseTransaction* trans = transaction_->GetWrappedTrans();
86  entry_ = new syncable::Entry(trans, syncable::GET_BY_SERVER_TAG, tag);
87  if (!entry_->good())
88    return INIT_FAILED_ENTRY_NOT_GOOD;
89  if (entry_->GetIsDel())
90    return INIT_FAILED_ENTRY_IS_DEL;
91  ModelType model_type = GetModelType();
92  LOG_IF(WARNING, model_type == UNSPECIFIED || model_type == TOP_LEVEL_FOLDER)
93      << "SyncAPI InitByTagLookup referencing unusually typed object.";
94  return DecryptIfNecessary() ? INIT_OK : INIT_FAILED_DECRYPT_IF_NECESSARY;
95}
96
97}  // namespace syncer
98