#include "sync/internal_api/public/test/test_entry_factory.h"
#include "sync/syncable/directory.h"
#include "sync/syncable/entry.h"
#include "sync/syncable/mutable_entry.h"
#include "sync/syncable/read_transaction.h"
#include "sync/syncable/syncable_id.h"
#include "sync/syncable/write_transaction.h"
#include "sync/test/engine/test_id_factory.h"
using std::string;
namespace syncer {
using syncable::Id;
using syncable::MutableEntry;
using syncable::UNITTEST;
using syncable::WriteTransaction;
TestEntryFactory::TestEntryFactory(syncable::Directory *dir)
: directory_(dir), next_revision_(1) {
}
TestEntryFactory::~TestEntryFactory() { }
void TestEntryFactory::CreateUnappliedNewItemWithParent(
const string& item_id,
const sync_pb::EntitySpecifics& specifics,
const string& parent_id) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM,
Id::CreateFromServerId(item_id));
DCHECK(entry.good());
entry.Put(syncable::SERVER_VERSION, GetNextRevision());
entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
entry.Put(syncable::SERVER_NON_UNIQUE_NAME, item_id);
entry.Put(syncable::SERVER_PARENT_ID, Id::CreateFromServerId(parent_id));
entry.Put(syncable::SERVER_IS_DIR, true);
entry.Put(syncable::SERVER_SPECIFICS, specifics);
}
int64 TestEntryFactory::CreateUnappliedNewItem(
const string& item_id,
const sync_pb::EntitySpecifics& specifics,
bool is_unique) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM,
Id::CreateFromServerId(item_id));
DCHECK(entry.good());
entry.Put(syncable::SERVER_VERSION, GetNextRevision());
entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
entry.Put(syncable::SERVER_NON_UNIQUE_NAME, item_id);
entry.Put(syncable::SERVER_PARENT_ID, syncable::GetNullId());
entry.Put(syncable::SERVER_IS_DIR, false);
entry.Put(syncable::SERVER_SPECIFICS, specifics);
if (is_unique)
entry.Put(syncable::UNIQUE_SERVER_TAG, item_id);
return entry.Get(syncable::META_HANDLE);
}
void TestEntryFactory::CreateUnsyncedItem(
const Id& item_id,
const Id& parent_id,
const string& name,
bool is_folder,
ModelType model_type,
int64* metahandle_out) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
Id predecessor_id;
DCHECK(
directory_->GetLastChildIdForTest(&trans, parent_id, &predecessor_id));
MutableEntry entry(&trans, syncable::CREATE, parent_id, name);
DCHECK(entry.good());
entry.Put(syncable::ID, item_id);
entry.Put(syncable::BASE_VERSION,
item_id.ServerKnows() ? GetNextRevision() : 0);
entry.Put(syncable::IS_UNSYNCED, true);
entry.Put(syncable::IS_DIR, is_folder);
entry.Put(syncable::IS_DEL, false);
entry.Put(syncable::PARENT_ID, parent_id);
CHECK(entry.PutPredecessor(predecessor_id));
sync_pb::EntitySpecifics default_specifics;
AddDefaultFieldValue(model_type, &default_specifics);
entry.Put(syncable::SPECIFICS, default_specifics);
if (item_id.ServerKnows()) {
entry.Put(syncable::SERVER_SPECIFICS, default_specifics);
entry.Put(syncable::SERVER_IS_DIR, is_folder);
entry.Put(syncable::SERVER_PARENT_ID, parent_id);
entry.Put(syncable::SERVER_IS_DEL, false);
}
if (metahandle_out)
*metahandle_out = entry.Get(syncable::META_HANDLE);
}
int64 TestEntryFactory::CreateUnappliedAndUnsyncedItem(
const string& name,
ModelType model_type) {
int64 metahandle = 0;
CreateUnsyncedItem(
TestIdFactory::MakeServer(name), TestIdFactory::root(),
name, false, model_type, &metahandle);
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
MutableEntry entry(&trans, syncable::GET_BY_HANDLE, metahandle);
if (!entry.good()) {
NOTREACHED();
return syncable::kInvalidMetaHandle;
}
entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
entry.Put(syncable::SERVER_VERSION, GetNextRevision());
return metahandle;
}
int64 TestEntryFactory::CreateSyncedItem(
const std::string& name, ModelType
model_type, bool is_folder) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
syncable::Id parent_id(TestIdFactory::root());
syncable::Id item_id(TestIdFactory::MakeServer(name));
int64 version = GetNextRevision();
sync_pb::EntitySpecifics default_specifics;
AddDefaultFieldValue(model_type, &default_specifics);
MutableEntry entry(&trans, syncable::CREATE, parent_id, name);
if (!entry.good()) {
NOTREACHED();
return syncable::kInvalidMetaHandle;
}
entry.Put(syncable::ID, item_id);
entry.Put(syncable::BASE_VERSION, version);
entry.Put(syncable::IS_UNSYNCED, false);
entry.Put(syncable::NON_UNIQUE_NAME, name);
entry.Put(syncable::IS_DIR, is_folder);
entry.Put(syncable::IS_DEL, false);
entry.Put(syncable::PARENT_ID, parent_id);
if (!entry.PutPredecessor(TestIdFactory::root())) {
NOTREACHED();
return syncable::kInvalidMetaHandle;
}
entry.Put(syncable::SPECIFICS, default_specifics);
entry.Put(syncable::SERVER_VERSION, GetNextRevision());
entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
entry.Put(syncable::SERVER_NON_UNIQUE_NAME, "X");
entry.Put(syncable::SERVER_PARENT_ID, TestIdFactory::MakeServer("Y"));
entry.Put(syncable::SERVER_IS_DIR, is_folder);
entry.Put(syncable::SERVER_IS_DEL, false);
entry.Put(syncable::SERVER_SPECIFICS, default_specifics);
entry.Put(syncable::SERVER_PARENT_ID, parent_id);
return entry.Get(syncable::META_HANDLE);
}
bool TestEntryFactory::SetServerSpecificsForItem(
int64 meta_handle,
const sync_pb::EntitySpecifics specifics) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
MutableEntry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
if (!entry.good()) {
return false;
}
entry.Put(syncable::SERVER_SPECIFICS, specifics);
entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
return true;
}
bool TestEntryFactory::SetLocalSpecificsForItem(
int64 meta_handle,
const sync_pb::EntitySpecifics specifics) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
MutableEntry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
if (!entry.good()) {
return false;
}
entry.Put(syncable::SPECIFICS, specifics);
entry.Put(syncable::IS_UNSYNCED, true);
return true;
}
const sync_pb::EntitySpecifics& TestEntryFactory::GetServerSpecificsForItem(
int64 meta_handle) const {
syncable::ReadTransaction trans(FROM_HERE, directory_);
syncable::Entry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
DCHECK(entry.good());
return entry.Get(syncable::SERVER_SPECIFICS);
}
const sync_pb::EntitySpecifics& TestEntryFactory::GetLocalSpecificsForItem(
int64 meta_handle) const {
syncable::ReadTransaction trans(FROM_HERE, directory_);
syncable::Entry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
DCHECK(entry.good());
return entry.Get(syncable::SPECIFICS);
}
bool TestEntryFactory::GetIsUnsyncedForItem(int64 meta_handle) const {
syncable::ReadTransaction trans(FROM_HERE, directory_);
syncable::Entry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
if (!entry.good()) {
NOTREACHED();
return false;
}
return entry.Get(syncable::IS_UNSYNCED);
}
bool TestEntryFactory::GetIsUnappliedForItem(int64 meta_handle) const {
syncable::ReadTransaction trans(FROM_HERE, directory_);
syncable::Entry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
if (!entry.good()) {
NOTREACHED();
return false;
}
return entry.Get(syncable::IS_UNAPPLIED_UPDATE);
}
int64 TestEntryFactory::GetNextRevision() {
return next_revision_++;
}
}