summaryrefslogtreecommitdiffstats
path: root/sync/api
diff options
context:
space:
mode:
Diffstat (limited to 'sync/api')
-rw-r--r--sync/api/mock_model_type_store.cc149
-rw-r--r--sync/api/mock_model_type_store.h118
-rw-r--r--sync/api/model_type_store.cc13
-rw-r--r--sync/api/model_type_store.h118
4 files changed, 392 insertions, 6 deletions
diff --git a/sync/api/mock_model_type_store.cc b/sync/api/mock_model_type_store.cc
new file mode 100644
index 0000000..6759be6
--- /dev/null
+++ b/sync/api/mock_model_type_store.cc
@@ -0,0 +1,149 @@
+// 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.
+
+#include "sync/api/mock_model_type_store.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+
+namespace syncer_v2 {
+
+MockModelTypeStore::MockModelTypeStore() {}
+
+MockModelTypeStore::~MockModelTypeStore() {}
+
+void MockModelTypeStore::ReadData(const IdList& id_list,
+ const ReadRecordsCallback& callback) {
+ if (!read_data_handler_.is_null()) {
+ read_data_handler_.Run(id_list, callback);
+ } else {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, Result::SUCCESS,
+ base::Passed(scoped_ptr<RecordList>())));
+ }
+}
+
+void MockModelTypeStore::ReadAllData(const ReadRecordsCallback& callback) {
+ if (!read_all_data_handler_.is_null()) {
+ read_all_data_handler_.Run(callback);
+ } else {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, Result::SUCCESS,
+ base::Passed(scoped_ptr<RecordList>())));
+ }
+}
+
+void MockModelTypeStore::ReadAllMetadata(const ReadMetadataCallback& callback) {
+ if (!read_all_metadata_handler_.is_null()) {
+ read_all_metadata_handler_.Run(callback);
+ } else {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, Result::SUCCESS,
+ base::Passed(scoped_ptr<RecordList>()), std::string()));
+ }
+}
+
+scoped_ptr<MockModelTypeStore::WriteBatch>
+MockModelTypeStore::CreateWriteBatch() {
+ return make_scoped_ptr(new MockModelTypeStore::WriteBatch());
+}
+
+void MockModelTypeStore::CommitWriteBatch(scoped_ptr<WriteBatch> write_batch,
+ const CallbackWithResult& callback) {
+ if (!commit_write_batch_handler_.is_null()) {
+ commit_write_batch_handler_.Run(write_batch.Pass(), callback);
+ } else {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, Result::SUCCESS));
+ }
+}
+
+void MockModelTypeStore::WriteData(WriteBatch* write_batch,
+ const std::string& id,
+ const std::string& value) {
+ if (!write_data_handler_.is_null()) {
+ write_data_handler_.Run(write_batch, id, value);
+ }
+}
+
+void MockModelTypeStore::WriteMetadata(WriteBatch* write_batch,
+ const std::string& id,
+ const std::string& value) {
+ if (!write_metadata_handler_.is_null()) {
+ write_metadata_handler_.Run(write_batch, id, value);
+ }
+}
+
+void MockModelTypeStore::WriteGlobalMetadata(WriteBatch* write_batch,
+ const std::string& value) {
+ if (!write_global_metadata_handler_.is_null()) {
+ write_global_metadata_handler_.Run(write_batch, value);
+ }
+}
+
+void MockModelTypeStore::DeleteData(WriteBatch* write_batch,
+ const std::string& id) {
+ if (!delete_data_handler_.is_null()) {
+ delete_data_handler_.Run(write_batch, id);
+ }
+}
+
+void MockModelTypeStore::DeleteMetadata(WriteBatch* write_batch,
+ const std::string& id) {
+ if (!delete_metadata_handler_.is_null()) {
+ delete_metadata_handler_.Run(write_batch, id);
+ }
+}
+
+void MockModelTypeStore::DeleteGlobalMetadata(WriteBatch* write_batch) {
+ if (!delete_global_metadata_handler_.is_null()) {
+ delete_global_metadata_handler_.Run(write_batch);
+ }
+}
+
+void MockModelTypeStore::RegisterReadDataHandler(
+ const ReadRecordsSignature& handler) {
+ read_data_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterReadAllDataHandler(
+ const ReadAllRecordsSignature& handler) {
+ read_all_data_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterReadAllMetadataHandler(
+ const ReadAllMetadataSignature& handler) {
+ read_all_metadata_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterCommitWriteBatchHandler(
+ const CommitWriteBatchSignature& handler) {
+ commit_write_batch_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterWriteDataHandler(
+ const WriteRecordSignature& handler) {
+ write_data_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterWriteMetadataHandler(
+ const WriteRecordSignature& handler) {
+ write_metadata_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterDeleteDataHandler(
+ const DeleteRecordSignature& handler) {
+ delete_data_handler_ = handler;
+}
+
+void MockModelTypeStore::RegisterDeleteMetadataHandler(
+ const DeleteRecordSignature& handler) {
+ delete_metadata_handler_ = handler;
+}
+
+} // namespace syncer_v2
diff --git a/sync/api/mock_model_type_store.h b/sync/api/mock_model_type_store.h
new file mode 100644
index 0000000..123d456
--- /dev/null
+++ b/sync/api/mock_model_type_store.h
@@ -0,0 +1,118 @@
+// 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_MOCK_MODEL_TYPE_STORE_H_
+#define SYNC_API_MOCK_MODEL_TYPE_STORE_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "sync/api/model_type_store.h"
+
+namespace syncer_v2 {
+
+// MockModelTypeStore is implementation of ModelTypeStore that does nothing.
+// Use it when testing components that depend on ModelTypeStore.
+//
+// By default all methods return SUCCESS and empty results. It is possible to
+// register custom handlers for certain functions to override behavior. It is
+// responsibility of handler to post callback with result.
+// Here is an example:
+// ===
+// void OnReadData(const ModelTypeStore::IdList& id_list,
+// const ModelTypeStore::ReadRecordsCallback& callback) {
+// // Verify id_list here.
+// // Prepare fake response.
+// scoped_ptr<ModelTypeStore::RecordList> record_list(
+// new ModelTypeStore::RecordList);
+// record_list->push_back(ModelTypeStore::Record("id1", "value1"));
+// base::ThreadTaskRunnerHandle::Get()->PostTask(
+// FROM_HERE, base::Bind(callback, Result::SUCCESS,
+// base::Passed(record_list)));
+// }
+//
+// MockModelTypeStore mock_model_type_store;
+// mock_model_type_store.RegisterReadDataHandler(base::Bind(&OnReadData));
+// ModelTypeStore::IdList id_list;
+// id_list.push_back("id1");
+// mock_model_type_store.ReadData(id_list, base::Bind(&ReadDone));
+// ===
+// TODO(pavel): When in-memory store is available this class should delegate all
+// calls to it instead of returning empty successful results.
+class MockModelTypeStore : public ModelTypeStore {
+ public:
+ // Signatures for all ModelTypeStore virtual functions.
+ typedef base::Callback<void(const ReadRecordsCallback&)>
+ ReadAllRecordsSignature;
+ typedef base::Callback<void(const IdList&, const ReadRecordsCallback&)>
+ ReadRecordsSignature;
+ typedef base::Callback<void(const ReadMetadataCallback& callback)>
+ ReadAllMetadataSignature;
+ typedef base::Callback<void(scoped_ptr<WriteBatch>, CallbackWithResult)>
+ CommitWriteBatchSignature;
+ typedef base::Callback<void(WriteBatch*,
+ const std::string&,
+ const std::string&)> WriteRecordSignature;
+ typedef base::Callback<void(WriteBatch*, const std::string&)>
+ WriteGlobalMetadataSignature;
+ typedef base::Callback<void(WriteBatch*, const std::string&)>
+ DeleteRecordSignature;
+ typedef base::Callback<void(WriteBatch*)> DeleteGlobalMetadataSignature;
+
+ MockModelTypeStore();
+ ~MockModelTypeStore() override;
+
+ // ModelTypeStore implementation.
+ void ReadData(const IdList& id_list,
+ const ReadRecordsCallback& callback) override;
+ void ReadAllData(const ReadRecordsCallback& callback) override;
+ void ReadAllMetadata(const ReadMetadataCallback& callback) override;
+
+ scoped_ptr<WriteBatch> CreateWriteBatch() override;
+ void CommitWriteBatch(scoped_ptr<WriteBatch> write_batch,
+ const CallbackWithResult& callback) override;
+
+ void WriteData(WriteBatch* write_batch,
+ const std::string& id,
+ const std::string& value) override;
+ void WriteMetadata(WriteBatch* write_batch,
+ const std::string& id,
+ const std::string& value) override;
+ void WriteGlobalMetadata(WriteBatch* write_batch,
+ const std::string& value) override;
+ void DeleteData(WriteBatch* write_batch, const std::string& id) override;
+ void DeleteMetadata(WriteBatch* write_batch, const std::string& id) override;
+ void DeleteGlobalMetadata(WriteBatch* write_batch) override;
+
+ // Register handler functions.
+ void RegisterReadDataHandler(const ReadRecordsSignature& handler);
+ void RegisterReadAllDataHandler(const ReadAllRecordsSignature& handler);
+ void RegisterReadAllMetadataHandler(const ReadAllMetadataSignature& handler);
+ void RegisterCommitWriteBatchHandler(
+ const CommitWriteBatchSignature& handler);
+ void RegisterWriteDataHandler(const WriteRecordSignature& handler);
+ void RegisterWriteMetadataHandler(const WriteRecordSignature& handler);
+ void RegisterWriteGlobalMetadataHandler(
+ const WriteGlobalMetadataSignature& handler);
+ void RegisterDeleteDataHandler(const DeleteRecordSignature& handler);
+ void RegisterDeleteMetadataHandler(const DeleteRecordSignature& handler);
+ void RegisterDeleteGlobalMetadataHandler(
+ const DeleteGlobalMetadataSignature& handler);
+
+ private:
+ ReadRecordsSignature read_data_handler_;
+ ReadAllRecordsSignature read_all_data_handler_;
+ ReadAllMetadataSignature read_all_metadata_handler_;
+ CommitWriteBatchSignature commit_write_batch_handler_;
+ WriteRecordSignature write_data_handler_;
+ WriteRecordSignature write_metadata_handler_;
+ WriteGlobalMetadataSignature write_global_metadata_handler_;
+ DeleteRecordSignature delete_data_handler_;
+ DeleteRecordSignature delete_metadata_handler_;
+ DeleteGlobalMetadataSignature delete_global_metadata_handler_;
+};
+
+} // namespace syncer_v2
+
+#endif // SYNC_API_MOCK_MODEL_TYPE_STORE_H_
diff --git a/sync/api/model_type_store.cc b/sync/api/model_type_store.cc
index 2555ddc..657932d 100644
--- a/sync/api/model_type_store.cc
+++ b/sync/api/model_type_store.cc
@@ -4,10 +4,19 @@
#include "sync/api/model_type_store.h"
+#include "base/logging.h"
+
namespace syncer_v2 {
-ModelTypeStore::ModelTypeStore() {}
+// static
+void ModelTypeStore::CreateInMemoryStoreForTest(const InitCallback& callback) {
+ NOTIMPLEMENTED();
+}
ModelTypeStore::~ModelTypeStore() {}
-} // namespace sync_v2
+ModelTypeStore::WriteBatch::WriteBatch() {}
+
+ModelTypeStore::WriteBatch::~WriteBatch() {}
+
+} // namespace syncer_v2
diff --git a/sync/api/model_type_store.h b/sync/api/model_type_store.h
index 817238e..2c0e4d3 100644
--- a/sync/api/model_type_store.h
+++ b/sync/api/model_type_store.h
@@ -5,14 +5,124 @@
#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 syncer_v2 {
-// Interface for store used by ModelTypeProcessor for persisting sync related
-// data (entity state and data type state).
-class ModelTypeStore {
+// 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:
- ModelTypeStore();
+ // 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, scoped_ptr<ModelTypeStore>)> InitCallback;
+ typedef base::Callback<void(Result)> CallbackWithResult;
+ typedef base::Callback<void(Result, scoped_ptr<RecordList>)>
+ ReadRecordsCallback;
+ typedef base::Callback<void(Result,
+ scoped_ptr<RecordList>,
+ const std::string&)> ReadMetadataCallback;
+
+ // 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.
+ virtual void ReadData(const IdList& id_list,
+ const ReadRecordsCallback& callback) = 0;
+ virtual void ReadAllData(const ReadRecordsCallback& 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