summaryrefslogtreecommitdiff
path: root/chromium/components/history/core/browser/typed_url_sync_metadata_database.cc
blob: 81e9da0a8e930690b7a6bbfda50714e61fc99998 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/history/core/browser/typed_url_sync_metadata_database.h"

#include "base/big_endian.h"
#include "base/logging.h"
#include "components/history/core/browser/url_row.h"
#include "sql/statement.h"

namespace history {

namespace {

// Key in sql::MetaTable, the value will be Serialization of sync
// ModelTypeState, which is for tracking sync state of typed url datatype.
const char kTypedURLModelTypeStateKey[] = "typed_url_model_type_state";

}  // namespace

// Description of database table:
//
// typed_url_sync_metadata
//   storage_key      the rowid of an entry in urls table, used by service to
//                    look up native data with sync metadata records.
//   value            Serialize sync EntityMetadata, which is for tracking sync
//                    state of each typed url.

TypedURLSyncMetadataDatabase::TypedURLSyncMetadataDatabase() {}

TypedURLSyncMetadataDatabase::~TypedURLSyncMetadataDatabase() {}

bool TypedURLSyncMetadataDatabase::GetAllSyncMetadata(
    syncer::MetadataBatch* metadata_batch) {
  DCHECK(metadata_batch);
  if (!GetAllSyncEntityMetadata(metadata_batch)) {
    return false;
  }

  sync_pb::ModelTypeState model_type_state;
  if (GetModelTypeState(&model_type_state)) {
    metadata_batch->SetModelTypeState(model_type_state);
  } else {
    return false;
  }

  return true;
}

bool TypedURLSyncMetadataDatabase::UpdateSyncMetadata(
    syncer::ModelType model_type,
    const std::string& storage_key,
    const sync_pb::EntityMetadata& metadata) {
  DCHECK_EQ(model_type, syncer::TYPED_URLS)
      << "Only the TYPED_URLS model type is supported";

  int64_t storage_key_int = 0;
  DCHECK_EQ(storage_key.size(), sizeof(storage_key_int));
  base::ReadBigEndian(storage_key.data(), &storage_key_int);
  // Make sure storage_key_int is set.
  DCHECK_NE(storage_key_int, 0);

  sql::Statement s(GetDB().GetUniqueStatement(
      "INSERT OR REPLACE INTO typed_url_sync_metadata "
      "(storage_key, value) VALUES(?, ?)"));
  s.BindInt64(0, storage_key_int);
  s.BindString(1, metadata.SerializeAsString());

  return s.Run();
}

bool TypedURLSyncMetadataDatabase::ClearSyncMetadata(
    syncer::ModelType model_type,
    const std::string& storage_key) {
  DCHECK_EQ(model_type, syncer::TYPED_URLS)
      << "Only the TYPED_URLS model type is supported";

  int64_t storage_key_int = 0;
  DCHECK_EQ(storage_key.size(), sizeof(storage_key_int));
  base::ReadBigEndian(storage_key.data(), &storage_key_int);
  // Make sure storage_key_int is set.
  DCHECK_NE(storage_key_int, 0);

  sql::Statement s(GetDB().GetUniqueStatement(
      "DELETE FROM typed_url_sync_metadata WHERE storage_key=?"));
  s.BindInt64(0, storage_key_int);

  return s.Run();
}

bool TypedURLSyncMetadataDatabase::UpdateModelTypeState(
    syncer::ModelType model_type,
    const sync_pb::ModelTypeState& model_type_state) {
  DCHECK_EQ(model_type, syncer::TYPED_URLS)
      << "Only the TYPED_URLS model type is supported";
  DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);

  std::string serialized_state = model_type_state.SerializeAsString();
  return GetMetaTable().SetValue(kTypedURLModelTypeStateKey, serialized_state);
}

bool TypedURLSyncMetadataDatabase::ClearModelTypeState(
    syncer::ModelType model_type) {
  DCHECK_EQ(model_type, syncer::TYPED_URLS)
      << "Only the TYPED_URLS model type is supported";
  DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
  return GetMetaTable().DeleteKey(kTypedURLModelTypeStateKey);
}

bool TypedURLSyncMetadataDatabase::InitSyncTable() {
  if (!GetDB().DoesTableExist("typed_url_sync_metadata")) {
    if (!GetDB().Execute("CREATE TABLE typed_url_sync_metadata ("
                         "storage_key INTEGER PRIMARY KEY NOT NULL,"
                         "value BLOB)")) {
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool TypedURLSyncMetadataDatabase::GetAllSyncEntityMetadata(
    syncer::MetadataBatch* metadata_batch) {
  DCHECK(metadata_batch);
  sql::Statement s(GetDB().GetUniqueStatement(
      "SELECT storage_key, value FROM typed_url_sync_metadata"));

  while (s.Step()) {
    std::string storage_key(sizeof(URLID), 0);
    base::WriteBigEndian<URLID>(&storage_key[0], s.ColumnInt64(0));
    std::string serialized_metadata = s.ColumnString(1);
    sync_pb::EntityMetadata entity_metadata;
    if (entity_metadata.ParseFromString(serialized_metadata)) {
      metadata_batch->AddMetadata(storage_key, entity_metadata);
    } else {
      DLOG(WARNING) << "Failed to deserialize TYPED_URLS model type "
                       "sync_pb::EntityMetadata.";
      return false;
    }
  }
  return true;
}

bool TypedURLSyncMetadataDatabase::GetModelTypeState(
    sync_pb::ModelTypeState* state) {
  DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
  std::string serialized_state;
  if (!GetMetaTable().GetValue(kTypedURLModelTypeStateKey, &serialized_state)) {
    return true;
  }

  return state->ParseFromString(serialized_state);
}

}  // namespace history