summaryrefslogtreecommitdiffstats
path: root/sync/api/model_type_store.h
blob: 51ddca6ac35d69aa3776085fcf1bb9317702e55e (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
157
158
// Copyright 2015 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.

#ifndef SYNC_API_MODEL_TYPE_STORE_H_
#define SYNC_API_MODEL_TYPE_STORE_H_

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "sync/base/sync_export.h"

namespace base {
class SequencedTaskRunner;
}  // namespace base

namespace syncer_v2 {

// ModelTypeStore is leveldb backed store for model type's data, metadata and
// global metadata.
//
// Store keeps records for entries identified by ids. For each entry store keeps
// data and metadata. Also store keeps one record for global metadata.
//
// To create store call one of Create*Store static factory functions. Model type
// controls store's lifetime with returned scoped_ptr. Call to Create*Store
// function triggers asynchronous store backend initialization, callback will be
// called with results when initialization is done.
//
// Read operations are asynchronous, initiated with one of Read* functions,
// provided callback will be called with result code and output of read
// operation.
//
// Write operations are done in context of write batch. To get one call
// CreateWriteBatch(). After that pass write batch object to Write/Delete
// functions. WriteBatch only accumulates pending changes, doesn't actually do
// data modification. Calling CommitWriteBatch writes all accumulated changes to
// disk atomically. Callback passed to CommitWriteBatch will be called with
// result of write operation. If write batch object is destroyed without
// comitting accumulated write operations will not be persisted.
//
// Destroying store object doesn't necessarily cancel asynchronous operations
// issued previously. You should be prepared to handle callbacks from those
// operations.
class SYNC_EXPORT ModelTypeStore {
 public:
  // Result of store operations.
  enum class Result {
    SUCCESS,
    UNSPECIFIED_ERROR,
  };

  // Output of read operations is passed back as list of Record structures.
  struct Record {
    Record(const std::string& id, const std::string& value)
        : id(id), value(value) {}

    std::string id;
    std::string value;
  };

  // WriteBatch object is used in all modification operations.
  class SYNC_EXPORT WriteBatch {
   public:
    virtual ~WriteBatch();

   protected:
    friend class MockModelTypeStore;
    WriteBatch();
  };

  typedef std::vector<Record> RecordList;
  typedef std::vector<std::string> IdList;

  typedef base::Callback<void(Result result, scoped_ptr<ModelTypeStore> store)>
      InitCallback;
  typedef base::Callback<void(Result result)> CallbackWithResult;
  typedef base::Callback<void(Result result,
                              scoped_ptr<RecordList> data_records,
                              scoped_ptr<IdList> missing_id_list)>
      ReadDataCallback;
  typedef base::Callback<void(Result result,
                              scoped_ptr<RecordList> data_records)>
      ReadAllDataCallback;
  typedef base::Callback<void(Result result,
                              scoped_ptr<RecordList> metadata_records,
                              const std::string& global_metadata)>
      ReadMetadataCallback;

  // CreateStore takes |path| and |blocking_task_runner|. Here is how to get
  // task runner in production code:
  //
  // base::SequencedWorkerPool* worker_pool =
  //     content::BrowserThread::GetBlockingPool();
  // scoped_refptr<base::SequencedTaskRunner> blocking_task_runner(
  //     worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
  //         worker_pool->GetSequenceToken(),
  //         base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
  //
  // In test get task runner from MessageLoop::task_runner().
  static void CreateStore(
      const std::string& path,
      scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
      const InitCallback& callback);
  // Creates store object backed by in-memory leveldb database. It is used in
  // tests.
  static void CreateInMemoryStoreForTest(const InitCallback& callback);

  virtual ~ModelTypeStore();

  // Read operations return records either for all entries or only for ones
  // identified in |id_list|. Result is SUCCESS if all records were read
  // successfully. If reading any of records fails result is UNSPECIFIED_ERROR
  // and RecordList contains some records that were read successfully. There is
  // no guarantee that RecordList will contain all successfully read records in
  // this case.
  // Callback for ReadData (ReadDataCallback) in addition receives list of ids
  // that were not found in store (missing_id_list).
  virtual void ReadData(const IdList& id_list,
                        const ReadDataCallback& callback) = 0;
  virtual void ReadAllData(const ReadAllDataCallback& callback) = 0;
  // ReadMetadataCallback will be invoked with three parameters: result of
  // operation, list of metadata records and global metadata.
  virtual void ReadAllMetadata(const ReadMetadataCallback& callback) = 0;

  // Creates write batch for write operations.
  virtual scoped_ptr<WriteBatch> CreateWriteBatch() = 0;

  // Commits write operations accumulated in write batch. If write operation
  // fails result is UNSPECIFIED_ERROR and write operations will not be
  // reflected in the store.
  virtual void CommitWriteBatch(scoped_ptr<WriteBatch> write_batch,
                                const CallbackWithResult& callback) = 0;

  // Write operations.
  virtual void WriteData(WriteBatch* write_batch,
                         const std::string& id,
                         const std::string& value) = 0;
  virtual void WriteMetadata(WriteBatch* write_batch,
                             const std::string& id,
                             const std::string& value) = 0;
  virtual void WriteGlobalMetadata(WriteBatch* write_batch,
                                   const std::string& value) = 0;
  virtual void DeleteData(WriteBatch* write_batch, const std::string& id) = 0;
  virtual void DeleteMetadata(WriteBatch* write_batch,
                              const std::string& id) = 0;
  virtual void DeleteGlobalMetadata(WriteBatch* write_batch) = 0;
  // TODO(pavely): Consider implementing DeleteAllMetadata with following
  // signature:
  // virtual void DeleteAllMetadata(const CallbackWithResult& callback) = 0.
  // It will delete all metadata records and global metadata record.
};

}  // namespace syncer_v2

#endif  // SYNC_API_MODEL_TYPE_STORE_H_