// RELOAD visits, which will be stripped.
static const int kMaxVisitsToFetch = 1000;
-const char kTypedUrlTag[] = "google_chrome_typed_urls";
-
static bool CheckVisitOrdering(const history::VisitVector& visits) {
int64 previous_visit_time = 0;
for (history::VisitVector::const_iterator visit = visits.begin();
TypedUrlModelAssociator::TypedUrlModelAssociator(
ProfileSyncService* sync_service,
history::HistoryBackend* history_backend,
- DataTypeErrorHandler* error_handler)
+ sync_driver::DataTypeErrorHandler* error_handler)
: sync_service_(sync_service),
history_backend_(history_backend),
expected_loop_(base::MessageLoop::current()),
// This is a workaround for http://crbug.com/84258.
if (visits->empty()) {
DVLOG(1) << "Found empty visits for URL: " << url->url();
+
+ if (url->last_visit().is_null()) {
+ // If modified URL is bookmarked, history backend treats it as modified
+ // even if all its visits are deleted. Return false to stop further
+ // processing because sync expects valid visit time for modified entry.
+ return false;
+ }
+
history::VisitRow visit(
url->id(), url->last_visit(), 0, content::PAGE_TRANSITION_TYPED, 0);
visits->push_back(visit);
history_backend_ && history_backend_->GetAllTypedURLs(&typed_urls);
history::URLRows new_urls;
+ history::URLRows updated_urls;
TypedUrlVisitVector new_visits;
- TypedUrlUpdateVector updated_urls;
{
base::AutoLock au(abort_lock_);
if (abort_requested_) {
syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
syncer::ReadNode typed_url_root(&trans);
- if (typed_url_root.InitByTagLookup(kTypedUrlTag) !=
- syncer::BaseNode::INIT_OK) {
+ if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
+ syncer::BaseNode::INIT_OK) {
return error_handler_->CreateAndUploadError(
FROM_HERE,
"Server did not create the top-level typed_url node. We "
WriteToSyncNode(new_url, visits, &write_node);
}
if (difference & DIFF_LOCAL_ROW_CHANGED) {
- updated_urls.push_back(
- std::pair<history::URLID, history::URLRow>(ix->id(), new_url));
+ DCHECK_EQ(ix->id(), new_url.id());
+ updated_urls.push_back(new_url);
}
if (difference & DIFF_LOCAL_VISITS_ADDED) {
new_visits.push_back(
model_type());
}
- node.SetTitle(base::UTF8ToWide(tag));
+ node.SetTitle(tag);
WriteToSyncNode(*ix, visits, &node);
}
const sync_pb::TypedUrlSpecifics& typed_url,
TypedUrlVisitVector* visits_to_add,
history::VisitVector* visits_to_remove,
- TypedUrlUpdateVector* updated_urls,
+ history::URLRows* updated_urls,
history::URLRows* new_urls) {
history::URLRow new_url(GURL(typed_url.url()));
history::VisitVector existing_visits;
visits_to_remove);
if (existing_url) {
- updated_urls->push_back(
- std::pair<history::URLID, history::URLRow>(new_url.id(), new_url));
+ updated_urls->push_back(new_url);
} else {
new_urls->push_back(new_url);
}
// Just walk through all our child nodes and delete them.
syncer::ReadNode typed_url_root(trans);
- if (typed_url_root.InitByTagLookup(kTypedUrlTag) !=
+ if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
syncer::BaseNode::INIT_OK) {
LOG(ERROR) << "Could not lookup root node";
return false;
*has_nodes = false;
syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
syncer::ReadNode sync_node(&trans);
- if (sync_node.InitByTagLookup(kTypedUrlTag) != syncer::BaseNode::INIT_OK) {
+ if (sync_node.InitTypeRoot(syncer::TYPED_URLS) != syncer::BaseNode::INIT_OK) {
LOG(ERROR) << "Server did not create the top-level typed_url node. We "
<< "might be running against an out-of-date server.";
return false;
void TypedUrlModelAssociator::WriteToHistoryBackend(
const history::URLRows* new_urls,
- const TypedUrlUpdateVector* updated_urls,
+ const history::URLRows* updated_urls,
const TypedUrlVisitVector* new_visits,
const history::VisitVector* deleted_visits) {
if (new_urls) {
history_backend_->AddPagesWithDetails(*new_urls, history::SOURCE_SYNCED);
}
if (updated_urls) {
- for (TypedUrlUpdateVector::const_iterator url = updated_urls->begin();
- url != updated_urls->end(); ++url) {
- // This is an existing entry in the URL database. We don't verify the
- // visit_count or typed_count values here, because either one (or both)
- // could be zero in the case of bookmarks, or in the case of a URL
- // transitioning from non-typed to typed as a result of this sync.
- ++num_db_accesses_;
- if (!history_backend_->UpdateURL(url->first, url->second)) {
- // In the field we sometimes run into errors on specific URLs. It's OK
- // to just continue on (we can try writing again on the next model
- // association).
- ++num_db_errors_;
- DLOG(ERROR) << "Could not update page: " << url->second.url().spec();
- }
- }
+ ++num_db_accesses_;
+ // These are existing entries in the URL database. We don't verify the
+ // visit_count or typed_count values here, because either one (or both)
+ // could be zero in the case of bookmarks, or in the case of a URL
+ // transitioning from non-typed to typed as a result of this sync.
+ // In the field we sometimes run into errors on specific URLs. It's OK to
+ // just continue, as we can try writing again on the next model association.
+ size_t num_successful_updates = history_backend_->UpdateURLs(*updated_urls);
+ num_db_errors_ += updated_urls->size() - num_successful_updates;
}
if (new_visits) {
for (TypedUrlVisitVector::const_iterator visits = new_visits->begin();