Skip to content

Commit

Permalink
Use constants for blip replication strings, internal doc properties (#…
Browse files Browse the repository at this point in the history
…3799)

* Refactor rev message for feedback

* Use constants for blip replication strings, internal doc properties

Switch to using constants for blip message names and message properties, as well as the internal doc properties _id, _rev and _deleted.

Includes some refactoring of blip_sync_messages to better support read/write of message properties, and a new test for the SetCheckpoint message.
  • Loading branch information
adamcfraser committed Oct 15, 2018
1 parent 5e49546 commit 35f7ac6
Show file tree
Hide file tree
Showing 29 changed files with 434 additions and 260 deletions.
6 changes: 3 additions & 3 deletions db/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ func (db *Database) WriteMultipartDocument(body Body, writer *multipart.Writer,
info.contentType, _ = meta["content_type"].(string)
info.data, err = decodeAttachment(meta["data"])
if info.data == nil {
base.Warnf(base.KeyAll, "Couldn't decode attachment %q of doc %q: %v", base.UD(name), base.UD(body["_id"]), err)
base.Warnf(base.KeyAll, "Couldn't decode attachment %q of doc %q: %v", base.UD(name), base.UD(body[BodyId]), err)
meta["stub"] = true
delete(meta, "data")
} else if len(info.data) > kMaxInlineAttachmentSize {
Expand Down Expand Up @@ -317,8 +317,8 @@ func (db *Database) WriteMultipartDocument(body Body, writer *multipart.Writer,
// The revision will be written as a nested multipart body if it has attachments.
func (db *Database) WriteRevisionAsPart(revBody Body, isError bool, compressPart bool, writer *multipart.Writer) error {
partHeaders := textproto.MIMEHeader{}
docID, _ := revBody["_id"].(string)
revID, _ := revBody["_rev"].(string)
docID, _ := revBody[BodyId].(string)
revID, _ := revBody[BodyRev].(string)
if len(docID) > 0 {
partHeaders.Set("X-Doc-ID", docID)
partHeaders.Set("X-Rev-ID", revID)
Expand Down
4 changes: 2 additions & 2 deletions db/attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestAttachments(t *testing.T) {
rev2str := `{"_attachments": {"hello.txt": {"stub":true, "revpos":1}, "bye.txt": {"data": "YnllLXlh"}}}`
var body2 Body
json.Unmarshal([]byte(rev2str), &body2)
body2["_rev"] = revid
body2[BodyRev] = revid
revid, err = db.Put("doc1", body2)
assertNoError(t, err, "Couldn't update document")
assert.Equals(t, revid, "2-08b42c51334c0469bd060e6d9e6d797b")
Expand All @@ -87,7 +87,7 @@ func TestAttachments(t *testing.T) {
rev3str := `{"_attachments": {"bye.txt": {"stub":true,"revpos":2}}}`
var body3 Body
json.Unmarshal([]byte(rev3str), &body3)
body3["_rev"] = revid
body3[BodyRev] = revid
revid, err = db.Put("doc1", body3)
assertNoError(t, err, "Couldn't update document")
assert.Equals(t, revid, "3-252b9fa1f306930bffc07e7d75b77faf")
Expand Down
4 changes: 2 additions & 2 deletions db/changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -849,14 +849,14 @@ func (db *Database) DocIDChangesFeed(userChannels base.Set, explicitDocIds []str
}

changes := make([]ChangeRev, 1)
changes[0] = ChangeRev{"rev": body["_rev"].(string)}
changes[0] = ChangeRev{"rev": body[BodyRev].(string)}
row.Changes = changes
row.Seq = SequenceID{Seq: populatedDoc.Sequence}
row.SetBranched((populatedDoc.Flags & channels.Branched) != 0)

var removedChannels []string

if deleted, _ := body["_deleted"].(bool); deleted {
if deleted, _ := body[BodyDeleted].(bool); deleted {
row.Deleted = true
}

Expand Down
52 changes: 26 additions & 26 deletions db/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func (context *DatabaseContext) revCacheLoaderForDocument(doc *document, revid s
}
}
if doc.History[revid].Deleted {
body["_deleted"] = true
body[BodyDeleted] = true
}

validatedHistory, getHistoryErr := doc.History.getHistory(revid)
Expand Down Expand Up @@ -272,10 +272,10 @@ func (db *Database) GetRevWithHistory(docid, revid string, maxHistory int, histo
// On access failure, return (only) the doc history and deletion/removal
// status instead of returning an error. For justification see the comment in
// the getRevFromDoc method, below
deleted, _ := body["_deleted"].(bool)
redactedBody := Body{"_id": docid, "_rev": revid}
deleted, _ := body[BodyDeleted].(bool)
redactedBody := Body{BodyId: docid, BodyRev: revid}
if deleted {
redactedBody["_deleted"] = true
redactedBody[BodyDeleted] = true
} else {
redactedBody["_removed"] = true
}
Expand All @@ -287,7 +287,7 @@ func (db *Database) GetRevWithHistory(docid, revid string, maxHistory int, histo
}

if !revIDGiven {
if deleted, _ := body["_deleted"].(bool); deleted {
if deleted, _ := body[BodyDeleted].(bool); deleted {
return nil, base.HTTPErrorf(404, "deleted")
}
}
Expand Down Expand Up @@ -415,8 +415,8 @@ func (db *DatabaseContext) getRevision(doc *document, revid string) (Body, error
}
}
body.FixJSONNumbers() // Make sure big ints won't get output in scientific notation
body["_id"] = doc.ID
body["_rev"] = revid
body[BodyId] = doc.ID
body[BodyRev] = revid

if doc.Attachments != nil {
body["_attachments"] = doc.Attachments
Expand Down Expand Up @@ -465,7 +465,7 @@ func (db *Database) getRevFromDoc(doc *document, revid string, listRevisions boo
if revid == "" || doc.History[revid] == nil /*|| !doc.History[revid].Deleted*/ {
return nil, err
}
body = Body{"_id": doc.ID, "_rev": revid}
body = Body{BodyId: doc.ID, BodyRev: revid}
if !doc.History[revid].Deleted {
body["_removed"] = true
}
Expand All @@ -482,7 +482,7 @@ func (db *Database) getRevFromDoc(doc *document, revid string, listRevisions boo
}
}
if doc.History[revid].Deleted {
body["_deleted"] = true
body[BodyDeleted] = true
}
if listRevisions {
validatedHistory, getHistoryErr := doc.History.getHistory(revid)
Expand Down Expand Up @@ -541,7 +541,7 @@ func (db *Database) backupAncestorRevs(doc *document, revid string) {
func (db *Database) initializeSyncData(doc *document) (err error) {
body := doc.Body()
doc.CurrentRev = createRevID(1, "", body)
body["_rev"] = doc.CurrentRev
body[BodyRev] = doc.CurrentRev
doc.setFlag(channels.Deleted, false)
doc.History = make(RevTree)
if err = doc.History.addRevision(doc.ID, RevInfo{ID: doc.CurrentRev, Parent: "", Deleted: false}); err != nil {
Expand All @@ -560,7 +560,7 @@ func (db *Database) OnDemandImportForWrite(docid string, doc *document, body Bod
if doc.Body() == nil {
isDelete = true
} else {
deletedInBody, ok := body["_deleted"].(bool)
deletedInBody, ok := body[BodyDeleted].(bool)
if ok {
isDelete = deletedInBody
}
Expand All @@ -582,16 +582,16 @@ func (db *Database) OnDemandImportForWrite(docid string, doc *document, body Bod
}

// Updates or creates a document.
// The new body's "_rev" property must match the current revision's, if any.
// The new body's BodyRev property must match the current revision's, if any.
func (db *Database) Put(docid string, body Body) (newRevID string, err error) {
// Get the revision ID to match, and the new generation number:
matchRev, _ := body["_rev"].(string)
matchRev, _ := body[BodyRev].(string)
generation, _ := ParseRevID(matchRev)
if generation < 0 {
return "", base.HTTPErrorf(http.StatusBadRequest, "Invalid revision ID")
}
generation++
deleted, _ := body["_deleted"].(bool)
deleted, _ := body[BodyDeleted].(bool)

expiry, err := body.extractExpiry()
if err != nil {
Expand Down Expand Up @@ -636,7 +636,7 @@ func (db *Database) Put(docid string, body Body) (newRevID string, err error) {

// Make up a new _rev, and add it to the history:
newRev := createRevID(generation, matchRev, body)
body["_rev"] = newRev
body[BodyRev] = newRev
if err := doc.History.addRevision(docid, RevInfo{ID: newRev, Parent: matchRev, Deleted: deleted}); err != nil {
base.Infof(base.KeyCRUD, "Failed to add revision ID: %s, error: %v", newRev, err)
return nil, nil, nil, base.ErrRevTreeAddRevFailure
Expand Down Expand Up @@ -668,7 +668,7 @@ func (db *Database) PutExistingRev(docid string, body Body, docHistory []string,
if generation < 0 {
return base.HTTPErrorf(http.StatusBadRequest, "Invalid revision ID")
}
deleted, _ := body["_deleted"].(bool)
deleted, _ := body[BodyDeleted].(bool)

expiry, err := body.extractExpiry()
if err != nil {
Expand Down Expand Up @@ -699,7 +699,7 @@ func (db *Database) PutExistingRev(docid string, body Body, docHistory []string,
}
if currentRevIndex == 0 {
base.Debugf(base.KeyCRUD, "PutExistingRev(%q): No new revisions to add", base.UD(docid))
body["_rev"] = newRev // The _rev field is expected by some callers. If missing, may cause problems for callers.
body[BodyRev] = newRev // The _rev field is expected by some callers. If missing, may cause problems for callers.
return nil, nil, nil, base.ErrUpdateCancel // No new revisions to add
}

Expand Down Expand Up @@ -728,7 +728,7 @@ func (db *Database) PutExistingRev(docid string, body Body, docHistory []string,
if err != nil {
return nil, nil, nil, err
}
body["_rev"] = newRev
body[BodyRev] = newRev
return body, newAttachments, nil, nil
})
return err
Expand Down Expand Up @@ -843,7 +843,7 @@ func (db *Database) updateAndReturnDoc(
}

// Determine which is the current "winning" revision (it's not necessarily the new one):
newRevID = body["_rev"].(string)
newRevID = body[BodyRev].(string)
prevCurrentRev := doc.CurrentRev
var branched, inConflict bool
doc.CurrentRev, branched, inConflict = doc.History.winningRevision()
Expand Down Expand Up @@ -882,7 +882,7 @@ func (db *Database) updateAndReturnDoc(
}

// Run the sync function, to validate the update and compute its channels/access:
body["_id"] = doc.ID
body[BodyId] = doc.ID
channelSet, access, roles, syncExpiry, oldBody, err := db.getChannelsAndAccess(doc, body, newRevID)
if err != nil {
return
Expand Down Expand Up @@ -1148,7 +1148,7 @@ func (db *Database) updateAndReturnDoc(
}

if doc.History[newRevID].Deleted {
body["_deleted"] = true
body[BodyDeleted] = true
}
revChannels := doc.History[newRevID].Channels
db.revisionCache.Put(doc.ID, newRevID, storedBody, encodeRevisions(history), revChannels)
Expand Down Expand Up @@ -1233,12 +1233,12 @@ func (db *Database) MarkPrincipalsChanged(docid string, newRevID string, changed

// Creates a new document, assigning it a random doc ID.
func (db *Database) Post(body Body) (string, string, error) {
if body["_rev"] != nil {
if body[BodyRev] != nil {
return "", "", base.HTTPErrorf(http.StatusNotFound, "No previous revision to replace")
}

// If there's an incoming _id property, use that as the doc ID.
docid, idFound := body["_id"].(string)
docid, idFound := body[BodyId].(string)
if !idFound {
docid = base.CreateUUID()
}
Expand All @@ -1250,9 +1250,9 @@ func (db *Database) Post(body Body) (string, string, error) {
return docid, rev, err
}

// Deletes a document, by adding a new revision whose "_deleted" property is true.
// Deletes a document, by adding a new revision whose _deleted property is true.
func (db *Database) DeleteDoc(docid string, revid string) (string, error) {
body := Body{"_deleted": true, "_rev": revid}
body := Body{BodyDeleted: true, BodyRev: revid}
return db.Put(docid, body)
}

Expand All @@ -1277,7 +1277,7 @@ func (db *Database) getChannelsAndAccess(doc *document, body Body, revID string)
expiry *uint32,
oldJson string,
err error) {
base.Debugf(base.KeyCRUD, "Invoking sync on doc %q rev %s", base.UD(doc.ID), body["_rev"])
base.Debugf(base.KeyCRUD, "Invoking sync on doc %q rev %s", base.UD(doc.ID), body[BodyRev])

// Get the parent revision, to pass to the sync function:
var oldJsonBytes []byte
Expand Down
6 changes: 3 additions & 3 deletions db/crud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func TestRevisionStorageConflictAndTombstones(t *testing.T) {
log.Printf("Create tombstone 3-b")
rev3b_body := Body{}
rev3b_body["version"] = "3b"
rev3b_body["_deleted"] = true
rev3b_body[BodyDeleted] = true
assertNoError(t, db.PutExistingRev("doc1", rev3b_body, []string{"3-b", "2-b"}, false), "add 3-b (tombstone)")

// Retrieve tombstone
Expand Down Expand Up @@ -180,7 +180,7 @@ func TestRevisionStorageConflictAndTombstones(t *testing.T) {
rev3c_body := Body{}
rev3c_body["version"] = "3c"
rev3c_body["key1"] = prop_1000_bytes
rev3c_body["_deleted"] = true
rev3c_body[BodyDeleted] = true
assertNoError(t, db.PutExistingRev("doc1", rev3c_body, []string{"3-c", "2-c"}, false), "add 3-c (large tombstone)")

// Validate the tombstone is not stored inline (due to small size)
Expand Down Expand Up @@ -295,7 +295,7 @@ func TestRevisionStoragePruneTombstone(t *testing.T) {
rev3b_body := Body{}
rev3b_body["version"] = "3b"
rev3b_body["key1"] = prop_1000_bytes
rev3b_body["_deleted"] = true
rev3b_body[BodyDeleted] = true
assertNoError(t, db.PutExistingRev("doc1", rev3b_body, []string{"3-b", "2-b"}, false), "add 3-b (tombstone)")

// Retrieve tombstone
Expand Down
Loading

0 comments on commit 35f7ac6

Please sign in to comment.