/// <summary>Inserts the _id, _rev and _attachments properties into the JSON data and stores it in rev. /// </summary> /// <remarks> /// Inserts the _id, _rev and _attachments properties into the JSON data and stores it in rev. /// Rev must already have its revID and sequence properties set. /// </remarks> internal void ExpandStoredJSONIntoRevisionWithAttachments(IEnumerable<Byte> json, RevisionInternal rev, DocumentContentOptions contentOptions) { var extra = ExtraPropertiesForRevision(rev, contentOptions); if (json != null && json.Any()) { rev.SetJson(AppendDictToJSON(json, extra)); } else { rev.SetProperties(extra); if (json == null) { rev.SetMissing(true); } } }
public void ExpandStoredJSONIntoRevisionWithAttachments(byte[] json, RevisionInternal rev, EnumSet<Database.TDContentOptions> contentOptions) { IDictionary<string, object> extra = ExtraPropertiesForRevision(rev, contentOptions ); if (json != null) { rev.SetJson(AppendDictToJSON(json, extra)); } else { rev.SetProperties(extra); } }
private void ImportDoc(string docID, long docNumericID) { // CREATE TABLE revs ( // sequence INTEGER PRIMARY KEY AUTOINCREMENT, // doc_id INTEGER NOT NULL REFERENCES docs(doc_id) ON DELETE CASCADE, // revid TEXT NOT NULL COLLATE REVID, // parent INTEGER REFERENCES revs(sequence) ON DELETE SET NULL, // current BOOLEAN, // deleted BOOLEAN DEFAULT 0, // json BLOB, // no_attachments BOOLEAN, // UNIQUE (doc_id, revid) ); sqlite3_stmt revQuery = null; PrepareSQL(ref revQuery, "SELECT sequence, revid, parent, current, deleted, json" + " FROM revs WHERE doc_id=? ORDER BY sequence"); raw.sqlite3_bind_int64(revQuery, 1, docNumericID); var tree = new Dictionary<long, IList<object>>(); int err; while (raw.SQLITE_ROW == (err = raw.sqlite3_step(revQuery))) { long sequence = raw.sqlite3_column_int64(revQuery, 0); string revID = raw.sqlite3_column_text(revQuery, 1); long parentSeq = raw.sqlite3_column_int64(revQuery, 2); bool current = raw.sqlite3_column_int(revQuery, 3) != 0; if (current) { // Add a leaf revision: bool deleted = raw.sqlite3_column_int(revQuery, 4) != 0; IEnumerable<byte> json = raw.sqlite3_column_blob(revQuery, 5); if (json == null) { json = Encoding.UTF8.GetBytes("{}"); } var nuJson = new List<byte>(json); try { AddAttachmentsToSequence(sequence, nuJson); } catch(CouchbaseLiteException) { Log.W(TAG, "Failed to add attachments to sequence {0}", sequence); raw.sqlite3_finalize(revQuery); throw; } catch(Exception e) { raw.sqlite3_finalize(revQuery); throw new CouchbaseLiteException(String.Format( "Error adding attachments to sequence {0}", sequence), e) { Code = StatusCode.DbError }; } json = nuJson; RevisionInternal rev = new RevisionInternal(docID, revID, deleted); rev.SetJson(json); var history = new List<string>(); history.Add(revID); while (parentSeq > 0) { var ancestor = tree.Get(parentSeq); Debug.Assert(ancestor != null, String.Format("Couldn't find parent sequence of {0} (doc {1})", parentSeq, docID)); history.Add((string)ancestor[0]); parentSeq = (long)ancestor[1]; } Log.D(TAG, "Upgrading doc {0} history {1}", rev, Manager.GetObjectMapper().WriteValueAsString(history)); try { _db.ForceInsert(rev, history, null); } catch (CouchbaseLiteException) { Log.W(TAG, "Failed to insert revision {0} into target database", rev); raw.sqlite3_finalize(revQuery); throw; } catch(Exception e) { raw.sqlite3_finalize(revQuery); throw new CouchbaseLiteException(String.Format( "Error inserting revision {0} into target database", rev), e) { Code = StatusCode.Exception }; } NumRevs++; } else { tree[sequence] = new List<object> { revID, parentSeq }; } } raw.sqlite3_finalize(revQuery); ++NumDocs; if (err != raw.SQLITE_OK) { var s = SqliteErrToStatus(err); if (s.IsError) { throw new CouchbaseLiteException(s.Code); } } }
/// <summary>Inserts the _id, _rev and _attachments properties into the JSON data and stores it in rev. /// </summary> /// <remarks> /// Inserts the _id, _rev and _attachments properties into the JSON data and stores it in rev. /// Rev must already have its revID and sequence properties set. /// </remarks> internal void ExpandStoredJSONIntoRevisionWithAttachments(IEnumerable<Byte> json, RevisionInternal rev, EnumSet<TDContentOptions> contentOptions) { var extra = ExtraPropertiesForRevision(rev, contentOptions); if (json != null) { rev.SetJson(AppendDictToJSON(json, extra)); } else { rev.SetProperties(extra); } }
/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception> internal SavedRevision PutProperties(IDictionary<String, Object> properties, String prevID, Boolean allowConflict) { string newId = null; if (properties != null && properties.ContainsKey("_id")) { newId = (string)properties.Get("_id"); } if (newId != null && !newId.Equals(Id, StringCompare.IgnoreCase)) { Log.W(Database.Tag, String.Format("Trying to put wrong _id to this: {0} properties: {1}", this, properties)); // TODO: Make sure all string formats use .NET codes, and not Java. } // Process _attachments dict, converting CBLAttachments to dicts: IDictionary<string, object> attachments = null; if (properties != null && properties.ContainsKey("_attachments")) { attachments = (IDictionary<string, object>)properties.Get("_attachments"); } if (attachments != null && attachments.Count > 0) { var updatedAttachments = Attachment.InstallAttachmentBodies(attachments, Database); properties["_attachments"] = updatedAttachments; } var hasTrueDeletedProperty = false; if (properties != null) { hasTrueDeletedProperty = properties.Get("_deleted") != null && ((bool)properties.Get("_deleted")); } var deleted = (properties == null) || hasTrueDeletedProperty; var rev = new RevisionInternal(Id, null, deleted, Database); if (deleted) rev.SetJson(Encoding.UTF8.GetBytes("{}")); if (properties != null) { rev.SetProperties(properties); } var newRev = Database.PutRevision(rev, prevID, allowConflict); if (newRev == null) { return null; } return new SavedRevision(this, newRev); }