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