OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sync/internal_api/public/write_node.h" | 5 #include "sync/internal_api/public/write_node.h" |
6 | 6 |
7 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "sync/internal_api/public/base_transaction.h" | 9 #include "sync/internal_api/public/base_transaction.h" |
10 #include "sync/internal_api/public/write_transaction.h" | 10 #include "sync/internal_api/public/write_transaction.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 SetEntitySpecifics(entity_specifics); | 205 SetEntitySpecifics(entity_specifics); |
206 } | 206 } |
207 | 207 |
208 void WriteNode::SetEntitySpecifics( | 208 void WriteNode::SetEntitySpecifics( |
209 const sync_pb::EntitySpecifics& new_value) { | 209 const sync_pb::EntitySpecifics& new_value) { |
210 ModelType new_specifics_type = | 210 ModelType new_specifics_type = |
211 GetModelTypeFromSpecifics(new_value); | 211 GetModelTypeFromSpecifics(new_value); |
212 DCHECK_NE(new_specifics_type, UNSPECIFIED); | 212 DCHECK_NE(new_specifics_type, UNSPECIFIED); |
213 DVLOG(1) << "Writing entity specifics of type " | 213 DVLOG(1) << "Writing entity specifics of type " |
214 << ModelTypeToString(new_specifics_type); | 214 << ModelTypeToString(new_specifics_type); |
215 DCHECK_EQ(new_specifics_type, GetModelType()); | 215 // GetModelType() can be unspecified if this is the first time this |
| 216 // node is being initialized (see PutModelType()). Otherwise, it |
| 217 // should match |new_specifics_type|. |
| 218 if (GetModelType() != UNSPECIFIED) { |
| 219 DCHECK_EQ(new_specifics_type, GetModelType()); |
| 220 } |
216 | 221 |
217 // Preserve unknown fields. | 222 // Preserve unknown fields. |
218 const sync_pb::EntitySpecifics& old_specifics = entry_->Get(SPECIFICS); | 223 const sync_pb::EntitySpecifics& old_specifics = entry_->Get(SPECIFICS); |
219 sync_pb::EntitySpecifics new_specifics; | 224 sync_pb::EntitySpecifics new_specifics; |
220 new_specifics.CopyFrom(new_value); | 225 new_specifics.CopyFrom(new_value); |
221 new_specifics.mutable_unknown_fields()->MergeFrom( | 226 new_specifics.mutable_unknown_fields()->MergeFrom( |
222 old_specifics.unknown_fields()); | 227 old_specifics.unknown_fields()); |
223 | 228 |
224 // Will update the entry if encryption was necessary. | 229 // Will update the entry if encryption was necessary. |
225 if (!UpdateEntryWithEncryption(GetTransaction()->GetWrappedTrans(), | 230 if (!UpdateEntryWithEncryption(GetTransaction()->GetWrappedTrans(), |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 syncable::GET_BY_SERVER_TAG, tag); | 320 syncable::GET_BY_SERVER_TAG, tag); |
316 if (!entry_->good()) | 321 if (!entry_->good()) |
317 return INIT_FAILED_ENTRY_NOT_GOOD; | 322 return INIT_FAILED_ENTRY_NOT_GOOD; |
318 if (entry_->Get(syncable::IS_DEL)) | 323 if (entry_->Get(syncable::IS_DEL)) |
319 return INIT_FAILED_ENTRY_IS_DEL; | 324 return INIT_FAILED_ENTRY_IS_DEL; |
320 ModelType model_type = GetModelType(); | 325 ModelType model_type = GetModelType(); |
321 DCHECK_EQ(model_type, NIGORI); | 326 DCHECK_EQ(model_type, NIGORI); |
322 return INIT_OK; | 327 return INIT_OK; |
323 } | 328 } |
324 | 329 |
| 330 void WriteNode::PutModelType(ModelType model_type) { |
| 331 // Set an empty specifics of the appropriate datatype. The presence |
| 332 // of the specific field will identify the model type. |
| 333 DCHECK(GetModelType() == model_type || |
| 334 GetModelType() == UNSPECIFIED); // Immutable once set. |
| 335 |
| 336 sync_pb::EntitySpecifics specifics; |
| 337 AddDefaultFieldValue(model_type, &specifics); |
| 338 SetEntitySpecifics(specifics); |
| 339 } |
| 340 |
325 // Create a new node with default properties, and bind this WriteNode to it. | 341 // Create a new node with default properties, and bind this WriteNode to it. |
326 // Return true on success. | 342 // Return true on success. |
327 bool WriteNode::InitBookmarkByCreation(const BaseNode& parent, | 343 bool WriteNode::InitByCreation(ModelType model_type, |
328 const BaseNode* predecessor) { | 344 const BaseNode& parent, |
| 345 const BaseNode* predecessor) { |
329 DCHECK(!entry_) << "Init called twice"; | 346 DCHECK(!entry_) << "Init called twice"; |
330 // |predecessor| must be a child of |parent| or NULL. | 347 // |predecessor| must be a child of |parent| or NULL. |
331 if (predecessor && predecessor->GetParentId() != parent.GetId()) { | 348 if (predecessor && predecessor->GetParentId() != parent.GetId()) { |
332 DCHECK(false); | 349 DCHECK(false); |
333 return false; | 350 return false; |
334 } | 351 } |
335 | 352 |
336 syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID); | 353 syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID); |
337 | 354 |
338 // Start out with a dummy name. We expect | 355 // Start out with a dummy name. We expect |
339 // the caller to set a meaningful name after creation. | 356 // the caller to set a meaningful name after creation. |
340 string dummy(kDefaultNameForNewNodes); | 357 string dummy(kDefaultNameForNewNodes); |
341 | 358 |
342 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), | 359 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), |
343 syncable::CREATE, BOOKMARKS, | 360 syncable::CREATE, parent_id, dummy); |
344 parent_id, dummy); | |
345 | 361 |
346 if (!entry_->good()) | 362 if (!entry_->good()) |
347 return false; | 363 return false; |
348 | 364 |
349 // Entries are untitled folders by default. | 365 // Entries are untitled folders by default. |
350 entry_->Put(syncable::IS_DIR, true); | 366 entry_->Put(syncable::IS_DIR, true); |
351 | 367 |
| 368 PutModelType(model_type); |
| 369 |
352 // Now set the predecessor, which sets IS_UNSYNCED as necessary. | 370 // Now set the predecessor, which sets IS_UNSYNCED as necessary. |
353 return PutPredecessor(predecessor); | 371 return PutPredecessor(predecessor); |
354 } | 372 } |
355 | 373 |
356 // Create a new node with default properties and a client defined unique tag, | 374 // Create a new node with default properties and a client defined unique tag, |
357 // and bind this WriteNode to it. | 375 // and bind this WriteNode to it. |
358 // Return true on success. If the tag exists in the database, then | 376 // Return true on success. If the tag exists in the database, then |
359 // we will attempt to undelete the node. | 377 // we will attempt to undelete the node. |
360 // TODO(chron): Code datatype into hash tag. | 378 // TODO(chron): Code datatype into hash tag. |
361 // TODO(chron): Is model type ever lost? | 379 // TODO(chron): Is model type ever lost? |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 // tags and updates. | 427 // tags and updates. |
410 | 428 |
411 existing_entry->Put(syncable::NON_UNIQUE_NAME, dummy); | 429 existing_entry->Put(syncable::NON_UNIQUE_NAME, dummy); |
412 existing_entry->Put(syncable::PARENT_ID, parent_id); | 430 existing_entry->Put(syncable::PARENT_ID, parent_id); |
413 entry_ = existing_entry.release(); | 431 entry_ = existing_entry.release(); |
414 } else { | 432 } else { |
415 return INIT_FAILED_ENTRY_ALREADY_EXISTS; | 433 return INIT_FAILED_ENTRY_ALREADY_EXISTS; |
416 } | 434 } |
417 } else { | 435 } else { |
418 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), | 436 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), |
419 syncable::CREATE, | 437 syncable::CREATE, parent_id, dummy); |
420 model_type, parent_id, dummy); | |
421 if (!entry_->good()) | 438 if (!entry_->good()) |
422 return INIT_FAILED_COULD_NOT_CREATE_ENTRY; | 439 return INIT_FAILED_COULD_NOT_CREATE_ENTRY; |
423 | 440 |
424 // Only set IS_DIR for new entries. Don't bitflip undeleted ones. | 441 // Only set IS_DIR for new entries. Don't bitflip undeleted ones. |
425 entry_->Put(syncable::UNIQUE_CLIENT_TAG, hash); | 442 entry_->Put(syncable::UNIQUE_CLIENT_TAG, hash); |
426 } | 443 } |
427 | 444 |
428 // We don't support directory and tag combinations. | 445 // We don't support directory and tag combinations. |
429 entry_->Put(syncable::IS_DIR, false); | 446 entry_->Put(syncable::IS_DIR, false); |
430 | 447 |
| 448 // Will clear specifics data. |
| 449 PutModelType(model_type); |
| 450 |
431 // Now set the predecessor, which sets IS_UNSYNCED as necessary. | 451 // Now set the predecessor, which sets IS_UNSYNCED as necessary. |
432 bool success = PutPredecessor(NULL); | 452 bool success = PutPredecessor(NULL); |
433 if (!success) | 453 if (!success) |
434 return INIT_FAILED_SET_PREDECESSOR; | 454 return INIT_FAILED_SET_PREDECESSOR; |
435 | 455 |
436 return INIT_SUCCESS; | 456 return INIT_SUCCESS; |
437 } | 457 } |
438 | 458 |
439 bool WriteNode::SetPosition(const BaseNode& new_parent, | 459 bool WriteNode::SetPosition(const BaseNode& new_parent, |
440 const BaseNode* predecessor) { | 460 const BaseNode* predecessor) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 MarkForSyncing(); | 513 MarkForSyncing(); |
494 | 514 |
495 return true; | 515 return true; |
496 } | 516 } |
497 | 517 |
498 void WriteNode::MarkForSyncing() { | 518 void WriteNode::MarkForSyncing() { |
499 syncable::MarkForSyncing(entry_); | 519 syncable::MarkForSyncing(entry_); |
500 } | 520 } |
501 | 521 |
502 } // namespace syncer | 522 } // namespace syncer |
OLD | NEW |