Updates or creates a document. The new body's BodyRev property must match the current revision's, if any.
(ctx context.Context, docid string, body Body)
| 1138 | // Updates or creates a document. |
| 1139 | // The new body's BodyRev property must match the current revision's, if any. |
| 1140 | func (db *DatabaseCollectionWithUser) Put(ctx context.Context, docid string, body Body) (newRevID string, doc *Document, err error) { |
| 1141 | |
| 1142 | delete(body, BodyId) |
| 1143 | |
| 1144 | // Get the revision ID to match, and the new generation number: |
| 1145 | matchRev, _ := body[BodyRev].(string) |
| 1146 | generation, _ := ParseRevID(ctx, matchRev) |
| 1147 | if generation < 0 { |
| 1148 | return "", nil, base.HTTPErrorf(http.StatusBadRequest, "Invalid revision ID") |
| 1149 | } |
| 1150 | generation++ |
| 1151 | delete(body, BodyRev) |
| 1152 | |
| 1153 | // remove CV before RevTreeID generation |
| 1154 | matchCV, _ := body[BodyCV].(string) |
| 1155 | delete(body, BodyCV) |
| 1156 | |
| 1157 | // Not extracting it yet because we need this property around to generate a RevTreeID |
| 1158 | deleted, _ := body[BodyDeleted].(bool) |
| 1159 | |
| 1160 | expiry, err := body.ExtractExpiry() |
| 1161 | if err != nil { |
| 1162 | return "", nil, base.HTTPErrorf(http.StatusBadRequest, "Invalid expiry: %v", err) |
| 1163 | } |
| 1164 | |
| 1165 | // Create newDoc which will be used to pass around Body |
| 1166 | newDoc := &Document{ |
| 1167 | ID: docid, |
| 1168 | } |
| 1169 | |
| 1170 | // Pull out attachments |
| 1171 | newDoc.SetAttachments(GetBodyAttachments(body)) |
| 1172 | delete(body, BodyAttachments) |
| 1173 | |
| 1174 | delete(body, BodyRevisions) |
| 1175 | |
| 1176 | err = validateAPIDocUpdate(body) |
| 1177 | if err != nil { |
| 1178 | return "", nil, err |
| 1179 | } |
| 1180 | |
| 1181 | docUpdateEvent := NewVersion |
| 1182 | allowImport := db.UseXattrs() |
| 1183 | updateRevCache := true |
| 1184 | doc, newRevID, err = db.updateAndReturnDoc(ctx, newDoc.ID, allowImport, &expiry, nil, docUpdateEvent, nil, false, updateRevCache, func(doc *Document) (resultDoc *Document, resultAttachmentData updatedAttachments, createNewRevIDSkipped bool, updatedExpiry *uint32, resultErr error) { |
| 1185 | var isSgWrite bool |
| 1186 | var crc32Match bool |
| 1187 | |
| 1188 | // Is this doc an sgWrite? |
| 1189 | if doc != nil { |
| 1190 | isSgWrite, crc32Match, _ = doc.IsSGWrite(ctx, nil) |
| 1191 | if crc32Match { |
| 1192 | db.dbStats().Database().Crc32MatchCount.Add(1) |
| 1193 | } |
| 1194 | } |
| 1195 | |
| 1196 | // (Be careful: this block can be invoked multiple times if there are races!) |
| 1197 | // If the existing doc isn't an SG write, import prior to updating |
no test coverage detected