本文整理汇总了C#中Couchbase.Lite.Internal.RevisionInternal.IsDeleted方法的典型用法代码示例。如果您正苦于以下问题:C# RevisionInternal.IsDeleted方法的具体用法?C# RevisionInternal.IsDeleted怎么用?C# RevisionInternal.IsDeleted使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Couchbase.Lite.Internal.RevisionInternal
的用法示例。
在下文中一共展示了RevisionInternal.IsDeleted方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: PutRevision
/// <summary>Stores a new (or initial) revision of a document.</summary>
/// <remarks>
/// Stores a new (or initial) revision of a document.
/// This is what's invoked by a PUT or POST. As with those, the previous revision ID must be supplied when necessary and the call will fail if it doesn't match.
/// </remarks>
/// <param name="oldRev">The revision to add. If the docID is null, a new UUID will be assigned. Its revID must be null. It must have a JSON body.
/// </param>
/// <param name="prevRevId">The ID of the revision to replace (same as the "?rev=" parameter to a PUT), or null if this is a new document.
/// </param>
/// <param name="allowConflict">If false, an error status 409 will be returned if the insertion would create a conflict, i.e. if the previous revision already has a child.
/// </param>
/// <param name="resultStatus">On return, an HTTP status code indicating success or failure.
/// </param>
/// <returns>A new RevisionInternal with the docID, revID and sequence filled in (but no body).
/// </returns>
/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
internal RevisionInternal PutRevision(RevisionInternal oldRev, String prevRevId, Boolean allowConflict, Status resultStatus)
{
// prevRevId is the rev ID being replaced, or nil if an insert
var docId = oldRev.GetDocId();
var deleted = oldRev.IsDeleted();
if ((oldRev == null) || ((prevRevId != null) && (docId == null)) || (deleted && (docId == null)) || ((docId != null) && !IsValidDocumentId(docId)))
{
throw new CouchbaseLiteException(StatusCode.BadRequest);
}
BeginTransaction();
Cursor cursor = null;
var inConflict = false;
RevisionInternal winningRev = null;
RevisionInternal newRev = null;
// PART I: In which are performed lookups and validations prior to the insert...
var docNumericID = (docId != null) ? GetDocNumericID(docId) : 0;
var parentSequence = 0L;
string oldWinningRevID = null;
try
{
var oldWinnerWasDeletion = false;
var wasConflicted = false;
if (docNumericID > 0)
{
var outIsDeleted = new AList<bool>();
var outIsConflict = new AList<bool>();
try
{
oldWinningRevID = WinningRevIDOfDoc(docNumericID, outIsDeleted, outIsConflict);
oldWinnerWasDeletion |= outIsDeleted.Count > 0;
wasConflicted |= outIsConflict.Count > 0;
}
catch (Exception e)
{
Sharpen.Runtime.PrintStackTrace(e);
}
}
if (prevRevId != null)
{
// Replacing: make sure given prevRevID is current & find its sequence number:
if (docNumericID <= 0)
{
var msg = string.Format("No existing revision found with doc id: {0}", docId);
throw new CouchbaseLiteException(msg, StatusCode.NotFound);
}
parentSequence = GetSequenceOfDocument(docNumericID, prevRevId, !allowConflict);
if (parentSequence == 0)
{
// Not found: either a 404 or a 409, depending on whether there is any current revision
if (!allowConflict && ExistsDocumentWithIDAndRev(docId, null))
{
var msg = string.Format("Conflicts not allowed and there is already an existing doc with id: {0}", docId);
throw new CouchbaseLiteException(msg, StatusCode.Conflict);
}
else
{
var msg = string.Format("No existing revision found with doc id: {0}", docId);
throw new CouchbaseLiteException(msg, StatusCode.NotFound);
}
}
if (_validations != null && _validations.Count > 0)
{
// Fetch the previous revision and validate the new one against it:
var oldRevCopy = oldRev.CopyWithDocID(oldRev.GetDocId(), null);
var prevRev = new RevisionInternal(docId, prevRevId, false, this);
ValidateRevision(oldRevCopy, prevRev, prevRevId);
}
}
else
{
// Inserting first revision.
if (deleted && (docId != null))
{
// Didn't specify a revision to delete: 404 or a 409, depending
if (ExistsDocumentWithIDAndRev(docId, null))
{
throw new CouchbaseLiteException(StatusCode.Conflict);
}
else
{
throw new CouchbaseLiteException(StatusCode.NotFound);
//.........这里部分代码省略.........
示例2: TestRevisionWithNull
public void TestRevisionWithNull()
{
RevisionInternal revisionWitDeletedNull = new RevisionInternal(new Dictionary<string, Object>
{
{"_id", Guid.NewGuid().ToString()},
{"_rev", "1-23243234"},
{"_deleted", null}
});
RevisionInternal revisionWithDeletedFalse = new RevisionInternal(new Dictionary<string, Object>
{
{"_id", Guid.NewGuid().ToString()},
{"_rev", "1-23243234"},
{"_deleted", false}
});
RevisionInternal revisionWithDeletedTrue = new RevisionInternal(new Dictionary<string, Object>
{
{"_id", Guid.NewGuid().ToString()},
{"_rev", "1-23243234"},
{"_deleted", true}
});
RevisionInternal revisionWithDeletedString = new RevisionInternal(new Dictionary<string, Object>
{
{"_id", Guid.NewGuid().ToString()},
{"_rev", "1-23243234"},
{"_deleted", "foo"}
});
Assert.IsFalse(revisionWitDeletedNull.IsDeleted());
Assert.IsFalse(revisionWithDeletedFalse.IsDeleted());
Assert.IsFalse(revisionWithDeletedString.IsDeleted());
Assert.IsTrue(revisionWithDeletedTrue.IsDeleted());
}
开发者ID:transformersprimeabcxyz,项目名称:_TO-DO-couchbase-lite-net-couchbase,代码行数:36,代码来源:RevisionsTest.cs
示例3: ExtraPropertiesForRevision
/// <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 IDictionary<String, Object> ExtraPropertiesForRevision(RevisionInternal rev, DocumentContentOptions contentOptions)
{
var docId = rev.GetDocId();
var revId = rev.GetRevId();
var sequenceNumber = rev.GetSequence();
Debug.Assert((revId != null));
Debug.Assert((sequenceNumber > 0));
// Get attachment metadata, and optionally the contents:
IDictionary<string, object> attachmentsDict = null;
if (!contentOptions.HasFlag(DocumentContentOptions.NoAttachments))
{
attachmentsDict = GetAttachmentsDictForSequenceWithContent (sequenceNumber, contentOptions);
}
// Get more optional stuff to put in the properties:
//OPT: This probably ends up making redundant SQL queries if multiple options are enabled.
var localSeq = -1L;
if (contentOptions.HasFlag(DocumentContentOptions.IncludeLocalSeq))
{
localSeq = sequenceNumber;
}
IDictionary<string, object> revHistory = null;
if (contentOptions.HasFlag(DocumentContentOptions.IncludeRevs))
{
revHistory = GetRevisionHistoryDict(rev);
}
IList<object> revsInfo = null;
if (contentOptions.HasFlag(DocumentContentOptions.IncludeRevsInfo))
{
revsInfo = new AList<object>();
var revHistoryFull = GetRevisionHistory(rev);
foreach (RevisionInternal historicalRev in revHistoryFull)
{
var revHistoryItem = new Dictionary<string, object>();
var status = "available";
if (historicalRev.IsDeleted())
{
status = "deleted";
}
if (historicalRev.IsMissing())
{
status = "missing";
}
revHistoryItem.Put("rev", historicalRev.GetRevId());
revHistoryItem["status"] = status;
revsInfo.AddItem(revHistoryItem);
}
}
IList<string> conflicts = null;
if (contentOptions.HasFlag(DocumentContentOptions.IncludeConflicts))
{
var revs = GetAllRevisionsOfDocumentID(docId, true);
if (revs.Count > 1)
{
conflicts = new AList<string>();
foreach (RevisionInternal savedRev in revs)
{
if (!(savedRev.Equals(rev) || savedRev.IsDeleted()))
{
conflicts.AddItem(savedRev.GetRevId());
}
}
}
}
var result = new Dictionary<string, object>();
result["_id"] = docId;
result["_rev"] = revId;
if (rev.IsDeleted())
{
result["_deleted"] = true;
}
if (attachmentsDict != null)
{
result["_attachments"] = attachmentsDict;
}
if (localSeq > -1)
{
result["_local_seq"] = localSeq;
}
if (revHistory != null)
{
result["_revisions"] = revHistory;
}
if (revsInfo != null)
{
result["_revs_info"] = revsInfo;
}
if (conflicts != null)
//.........这里部分代码省略.........
示例4: ProcessAttachmentsForRevision
/// <summary>
/// Given a newly-added revision, adds the necessary attachment rows to the sqliteDb and
/// stores inline attachments into the blob store.
/// </summary>
/// <remarks>
/// Given a newly-added revision, adds the necessary attachment rows to the sqliteDb and
/// stores inline attachments into the blob store.
/// </remarks>
/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
internal void ProcessAttachmentsForRevision(IDictionary<string, AttachmentInternal> attachments, RevisionInternal rev, long parentSequence)
{
Debug.Assert((rev != null));
var newSequence = rev.GetSequence();
Debug.Assert((newSequence > parentSequence));
var generation = rev.GetGeneration();
Debug.Assert((generation > 0));
// If there are no attachments in the new rev, there's nothing to do:
IDictionary<string, object> revAttachments = null;
var properties = rev.GetProperties ();
if (properties != null) {
revAttachments = properties.Get("_attachments").AsDictionary<string, object>();
}
if (revAttachments == null || revAttachments.Count == 0 || rev.IsDeleted()) {
return;
}
foreach (string name in revAttachments.Keys)
{
var attachment = attachments.Get(name);
if (attachment != null)
{
// Determine the revpos, i.e. generation # this was added in. Usually this is
// implicit, but a rev being pulled in replication will have it set already.
if (attachment.RevPos == 0)
{
attachment.RevPos = generation;
}
else
{
if (attachment.RevPos > generation)
{
Log.W(TAG, string.Format("Attachment {0} {1} has unexpected revpos {2}, setting to {3}", rev, name, attachment.RevPos, generation));
attachment.RevPos = generation;
}
}
}
}
}
示例5: GetAttachmentsFromRevision
/// <summary>
/// Given a revision, read its _attachments dictionary (if any), convert each attachment to a
/// AttachmentInternal object, and return a dictionary mapping names->CBL_Attachments.
/// </summary>
/// <remarks>
/// Given a revision, read its _attachments dictionary (if any), convert each attachment to a
/// AttachmentInternal object, and return a dictionary mapping names->CBL_Attachments.
/// </remarks>
/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
internal IDictionary<String, AttachmentInternal> GetAttachmentsFromRevision(RevisionInternal rev)
{
var revAttachments = rev.GetPropertyForKey("_attachments").AsDictionary<string, object>();
if (revAttachments == null || revAttachments.Count == 0 || rev.IsDeleted())
{
return new Dictionary<string, AttachmentInternal>();
}
var attachments = new Dictionary<string, AttachmentInternal>();
foreach (var name in revAttachments.Keys)
{
var attachInfo = revAttachments.Get(name).AsDictionary<string, object>();
var contentType = (string)attachInfo.Get("content_type");
var attachment = new AttachmentInternal(name, contentType);
var newContentBase64 = (string)attachInfo.Get("data");
if (newContentBase64 != null)
{
// If there's inline attachment data, decode and store it:
byte[] newContents;
try
{
newContents = StringUtils.ConvertFromUnpaddedBase64String (newContentBase64);
}
catch (IOException e)
{
throw new CouchbaseLiteException(e, StatusCode.BadEncoding);
}
attachment.Length = newContents.Length;
var outBlobKey = new BlobKey();
var storedBlob = Attachments.StoreBlob(newContents, outBlobKey);
attachment.BlobKey = outBlobKey;
if (!storedBlob)
{
throw new CouchbaseLiteException(StatusCode.AttachmentError);
}
}
else
{
if (attachInfo.ContainsKey("follows") && ((bool)attachInfo.Get("follows")))
{
// "follows" means the uploader provided the attachment in a separate MIME part.
// This means it's already been registered in _pendingAttachmentsByDigest;
// I just need to look it up by its "digest" property and install it into the store:
InstallAttachment(attachment, attachInfo);
}
else
{
// This item is just a stub; validate and skip it
if (((bool)attachInfo.Get("stub")) == false)
{
throw new CouchbaseLiteException("Expected this attachment to be a stub", StatusCode.
BadAttachment);
}
var revPos = Convert.ToInt64(attachInfo.Get("revpos"));
if (revPos <= 0)
{
throw new CouchbaseLiteException("Invalid revpos: " + revPos, StatusCode.BadAttachment);
}
continue;
}
}
// Handle encoded attachment:
string encodingStr = (string)attachInfo.Get("encoding");
if (encodingStr != null && encodingStr.Length > 0)
{
if (Runtime.EqualsIgnoreCase(encodingStr, "gzip"))
{
attachment.Encoding = AttachmentEncoding.GZIP;
}
else
{
throw new CouchbaseLiteException("Unnkown encoding: " + encodingStr, StatusCode.BadEncoding
);
}
attachment.EncodedLength = attachment.Length;
if (attachInfo.ContainsKey("length"))
{
attachment.Length = attachInfo.GetCast<long>("length");
}
}
if (attachInfo.ContainsKey("revpos"))
{
var revpos = Convert.ToInt32(attachInfo.Get("revpos"));
attachment.RevPos = revpos;
}
attachments[name] = attachment;
}
return attachments;
}
示例6: InsertRevision
internal Int64 InsertRevision(RevisionInternal rev, long docNumericID, long parentSequence, bool current, bool hasAttachments, IEnumerable<byte> data)
{
var rowId = 0L;
try
{
var args = new ContentValues();
args["doc_id"] = docNumericID;
args.Put("revid", rev.GetRevId());
if (parentSequence != 0)
{
args["parent"] = parentSequence;
}
args["current"] = current;
args["deleted"] = rev.IsDeleted();
args["no_attachments"] = !hasAttachments;
if (data != null)
{
args["json"] = data.ToArray();
}
rowId = StorageEngine.Insert("revs", null, args);
rev.SetSequence(rowId);
}
catch (Exception e)
{
Log.E(Tag, "Error inserting revision", e);
}
return rowId;
}
示例7: PutLocalRevision
internal RevisionInternal PutLocalRevision(RevisionInternal revision, string prevRevID)
{
var docID = revision.GetDocId();
if (!docID.StartsWith ("_local/", StringComparison.InvariantCultureIgnoreCase))
{
throw new CouchbaseLiteException(StatusCode.BadRequest);
}
if (!revision.IsDeleted())
{
// PUT:
string newRevID;
var json = EncodeDocumentJSON(revision);
if (prevRevID != null)
{
var generation = RevisionInternal.GenerationFromRevID(prevRevID);
if (generation == 0)
{
throw new CouchbaseLiteException(StatusCode.BadRequest);
}
newRevID = Sharpen.Extensions.ToString(++generation) + "-local";
var values = new ContentValues();
values["revid"] = newRevID;
values["json"] = json;
var whereArgs = new [] { docID, prevRevID };
try
{
var rowsUpdated = StorageEngine.Update("localdocs", values, "docid=? AND revid=?", whereArgs);
if (rowsUpdated == 0)
{
throw new CouchbaseLiteException(StatusCode.Conflict);
}
}
catch (SQLException e)
{
throw new CouchbaseLiteException(e, StatusCode.InternalServerError);
}
}
else
{
newRevID = "1-local";
var values = new ContentValues();
values["docid"] = docID;
values["revid"] = newRevID;
values["json"] = json;
try
{
StorageEngine.InsertWithOnConflict("localdocs", null, values, ConflictResolutionStrategy.Ignore);
}
catch (SQLException e)
{
throw new CouchbaseLiteException(e, StatusCode.InternalServerError);
}
}
return revision.CopyWithDocID(docID, newRevID);
}
else
{
// DELETE:
DeleteLocalDocument(docID, prevRevID);
return revision;
}
}
示例8: VerifyHistory
private static void VerifyHistory(Database db, RevisionInternal rev, IList<string
> history)
{
RevisionInternal gotRev = db.GetDocumentWithIDAndRev(rev.GetDocId(), null, EnumSet
.NoneOf<Database.TDContentOptions>());
NUnit.Framework.Assert.AreEqual(rev, gotRev);
NUnit.Framework.Assert.AreEqual(rev.GetProperties(), gotRev.GetProperties());
IList<RevisionInternal> revHistory = db.GetRevisionHistory(gotRev);
NUnit.Framework.Assert.AreEqual(history.Count, revHistory.Count);
for (int i = 0; i < history.Count; i++)
{
RevisionInternal hrev = revHistory[i];
NUnit.Framework.Assert.AreEqual(rev.GetDocId(), hrev.GetDocId());
NUnit.Framework.Assert.AreEqual(history[i], hrev.GetRevId());
NUnit.Framework.Assert.IsFalse(rev.IsDeleted());
}
}
示例9: ProcessAttachmentsForRevision
internal bool ProcessAttachmentsForRevision(RevisionInternal rev, IList<string> ancestry)
{
var revAttachments = rev.GetAttachments();
if (revAttachments == null) {
return true; // no-op: no attachments
}
// Deletions can't have attachments:
if (rev.IsDeleted() || revAttachments.Count == 0) {
var body = rev.GetProperties();
body.Remove("_attachments");
rev.SetProperties(body);
return true;
}
var prevRevId = ancestry != null && ancestry.Count > 0 ? ancestry[0] : null;
int generation = RevisionInternal.GenerationFromRevID(prevRevId) + 1;
IDictionary<string, object> parentAttachments = null;
return rev.MutateAttachments((name, attachInfo) =>
{
AttachmentInternal attachment = null;
try {
attachment = new AttachmentInternal(name, attachInfo);
} catch(CouchbaseLiteException) {
return null;
}
if(attachment.EncodedContent != null) {
// If there's inline attachment data, decode and store it:
BlobKey blobKey = new BlobKey();
if(!Attachments.StoreBlob(attachment.EncodedContent.ToArray(), blobKey)) {
throw new CouchbaseLiteException(
String.Format("Failed to write attachment ' {0}'to disk", name), StatusCode.AttachmentError);
}
attachment.BlobKey = blobKey;
} else if(attachInfo.GetCast<bool>("follows")) {
// "follows" means the uploader provided the attachment in a separate MIME part.
// This means it's already been registered in _pendingAttachmentsByDigest;
// I just need to look it up by its "digest" property and install it into the store:
InstallAttachment(attachment);
} else if(attachInfo.GetCast<bool>("stub")) {
// "stub" on an incoming revision means the attachment is the same as in the parent.
if(parentAttachments == null && prevRevId != null) {
parentAttachments = GetAttachmentsFromDoc(rev.GetDocId(), prevRevId);
if(parentAttachments == null) {
if(Attachments.HasBlobForKey(attachment.BlobKey)) {
// Parent revision's body isn't known (we are probably pulling a rev along
// with its entire history) but it's OK, we have the attachment already
return attachInfo;
}
var ancestorAttachment = FindAttachment(name, attachment.RevPos, rev.GetDocId(), ancestry);
if(ancestorAttachment != null) {
return ancestorAttachment;
}
throw new CouchbaseLiteException(
String.Format("Unable to find 'stub' attachment {0} in history", name), StatusCode.BadAttachment);
}
}
var parentAttachment = parentAttachments == null ? null : parentAttachments.Get(name).AsDictionary<string, object>();
if(parentAttachment == null) {
throw new CouchbaseLiteException(
String.Format("Unable to find 'stub' attachment {0} in history", name), StatusCode.BadAttachment);
}
return parentAttachment;
}
// Set or validate the revpos:
if(attachment.RevPos == 0) {
attachment.RevPos = generation;
} else if(attachment.RevPos > generation) {
throw new CouchbaseLiteException(
String.Format("Attachment specifies revision generation {0} but document is only at revision generation {1}",
attachment.RevPos, generation), StatusCode.BadAttachment);
}
Debug.Assert(attachment.IsValid);
return attachment.AsStubDictionary();
});
}
示例10: GetAttachmentsFromRevision
internal IDictionary<string, AttachmentInternal> GetAttachmentsFromRevision(RevisionInternal
rev)
{
IDictionary<string, object> revAttachments = (IDictionary<string, object>)rev.GetPropertyForKey
("_attachments");
if (revAttachments == null || revAttachments.Count == 0 || rev.IsDeleted())
{
return new Dictionary<string, AttachmentInternal>();
}
IDictionary<string, AttachmentInternal> attachments = new Dictionary<string, AttachmentInternal
>();
foreach (string name in revAttachments.Keys)
{
IDictionary<string, object> attachInfo = (IDictionary<string, object>)revAttachments
.Get(name);
string contentType = (string)attachInfo.Get("content_type");
AttachmentInternal attachment = new AttachmentInternal(name, contentType);
string newContentBase64 = (string)attachInfo.Get("data");
if (newContentBase64 != null)
{
// If there's inline attachment data, decode and store it:
byte[] newContents;
try
{
newContents = Base64.Decode(newContentBase64);
}
catch (IOException e)
{
throw new CouchbaseLiteException(e, Status.BadEncoding);
}
attachment.SetLength(newContents.Length);
BlobKey outBlobKey = new BlobKey();
bool storedBlob = GetAttachments().StoreBlob(newContents, outBlobKey);
attachment.SetBlobKey(outBlobKey);
if (!storedBlob)
{
throw new CouchbaseLiteException(Status.StatusAttachmentError);
}
}
else
{
if (attachInfo.ContainsKey("follows") && ((bool)attachInfo.Get("follows")) == true)
{
// "follows" means the uploader provided the attachment in a separate MIME part.
// This means it's already been registered in _pendingAttachmentsByDigest;
// I just need to look it up by its "digest" property and install it into the store:
InstallAttachment(attachment, attachInfo);
}
else
{
// This item is just a stub; validate and skip it
if (((bool)attachInfo.Get("stub")) == false)
{
throw new CouchbaseLiteException("Expected this attachment to be a stub", Status.
BadAttachment);
}
int revPos = ((int)attachInfo.Get("revpos"));
if (revPos <= 0)
{
throw new CouchbaseLiteException("Invalid revpos: " + revPos, Status.BadAttachment
);
}
continue;
}
}
// Handle encoded attachment:
string encodingStr = (string)attachInfo.Get("encoding");
if (encodingStr != null && encodingStr.Length > 0)
{
if (Sharpen.Runtime.EqualsIgnoreCase(encodingStr, "gzip"))
{
attachment.SetEncoding(AttachmentInternal.AttachmentEncoding.AttachmentEncodingGZIP
);
}
else
{
throw new CouchbaseLiteException("Unnkown encoding: " + encodingStr, Status.BadEncoding
);
}
attachment.SetEncodedLength(attachment.GetLength());
if (attachInfo.ContainsKey("length"))
{
Number attachmentLength = (Number)attachInfo.Get("length");
attachment.SetLength(attachmentLength);
}
}
if (attachInfo.ContainsKey("revpos"))
{
attachment.SetRevpos((int)attachInfo.Get("revpos"));
}
else
{
attachment.SetRevpos(1);
}
attachments.Put(name, attachment);
}
return attachments;
}
示例11: PutLocalRevision
public RevisionInternal PutLocalRevision(RevisionInternal revision, string prevRevID
)
{
string docID = revision.GetDocId();
if (!docID.StartsWith("_local/"))
{
throw new CouchbaseLiteException(Status.BadRequest);
}
if (!revision.IsDeleted())
{
// PUT:
byte[] json = EncodeDocumentJSON(revision);
string newRevID;
if (prevRevID != null)
{
int generation = RevisionInternal.GenerationFromRevID(prevRevID);
if (generation == 0)
{
throw new CouchbaseLiteException(Status.BadRequest);
}
newRevID = Sharpen.Extensions.ToString(++generation) + "-local";
ContentValues values = new ContentValues();
values.Put("revid", newRevID);
values.Put("json", json);
string[] whereArgs = new string[] { docID, prevRevID };
try
{
int rowsUpdated = database.Update("localdocs", values, "docid=? AND revid=?", whereArgs
);
if (rowsUpdated == 0)
{
throw new CouchbaseLiteException(Status.Conflict);
}
}
catch (SQLException e)
{
throw new CouchbaseLiteException(e, Status.InternalServerError);
}
}
else
{
newRevID = "1-local";
ContentValues values = new ContentValues();
values.Put("docid", docID);
values.Put("revid", newRevID);
values.Put("json", json);
try
{
database.InsertWithOnConflict("localdocs", null, values, SQLiteStorageEngine.ConflictIgnore
);
}
catch (SQLException e)
{
throw new CouchbaseLiteException(e, Status.InternalServerError);
}
}
return revision.CopyWithDocID(docID, newRevID);
}
else
{
// DELETE:
DeleteLocalDocument(docID, prevRevID);
return revision;
}
}
示例12: PutRevision
public RevisionInternal PutRevision(RevisionInternal oldRev, string prevRevId, bool
allowConflict, Status resultStatus)
{
// prevRevId is the rev ID being replaced, or nil if an insert
string docId = oldRev.GetDocId();
bool deleted = oldRev.IsDeleted();
if ((oldRev == null) || ((prevRevId != null) && (docId == null)) || (deleted && (
docId == null)) || ((docId != null) && !IsValidDocumentId(docId)))
{
throw new CouchbaseLiteException(Status.BadRequest);
}
BeginTransaction();
Cursor cursor = null;
bool inConflict = false;
RevisionInternal winningRev = null;
RevisionInternal newRev = null;
//// PART I: In which are performed lookups and validations prior to the insert...
long docNumericID = (docId != null) ? GetDocNumericID(docId) : 0;
long parentSequence = 0;
string oldWinningRevID = null;
try
{
bool oldWinnerWasDeletion = false;
bool wasConflicted = false;
if (docNumericID > 0)
{
IList<bool> outIsDeleted = new AList<bool>();
IList<bool> outIsConflict = new AList<bool>();
try
{
oldWinningRevID = WinningRevIDOfDoc(docNumericID, outIsDeleted, outIsConflict);
if (outIsDeleted.Count > 0)
{
oldWinnerWasDeletion = true;
}
if (outIsConflict.Count > 0)
{
wasConflicted = true;
}
}
catch (Exception e)
{
Sharpen.Runtime.PrintStackTrace(e);
}
}
if (prevRevId != null)
{
// Replacing: make sure given prevRevID is current & find its sequence number:
if (docNumericID <= 0)
{
string msg = string.Format("No existing revision found with doc id: %s", docId);
throw new CouchbaseLiteException(msg, Status.NotFound);
}
string[] args = new string[] { System.Convert.ToString(docNumericID), prevRevId };
string additionalWhereClause = string.Empty;
if (!allowConflict)
{
additionalWhereClause = "AND current=1";
}
cursor = database.RawQuery("SELECT sequence FROM revs WHERE doc_id=? AND revid=? "
+ additionalWhereClause + " LIMIT 1", args);
if (cursor.MoveToNext())
{
parentSequence = cursor.GetLong(0);
}
if (parentSequence == 0)
{
// Not found: either a 404 or a 409, depending on whether there is any current revision
if (!allowConflict && ExistsDocumentWithIDAndRev(docId, null))
{
string msg = string.Format("Conflicts not allowed and there is already an existing doc with id: %s"
, docId);
throw new CouchbaseLiteException(msg, Status.Conflict);
}
else
{
string msg = string.Format("No existing revision found with doc id: %s", docId);
throw new CouchbaseLiteException(msg, Status.NotFound);
}
}
if (validations != null && validations.Count > 0)
{
// Fetch the previous revision and validate the new one against it:
RevisionInternal prevRev = new RevisionInternal(docId, prevRevId, false, this);
ValidateRevision(oldRev, prevRev);
}
// Make replaced rev non-current:
ContentValues updateContent = new ContentValues();
updateContent.Put("current", 0);
database.Update("revs", updateContent, "sequence=" + parentSequence, null);
}
else
{
// Inserting first revision.
if (deleted && (docId != null))
{
// Didn't specify a revision to delete: 404 or a 409, depending
if (ExistsDocumentWithIDAndRev(docId, null))
{
throw new CouchbaseLiteException(Status.Conflict);
//.........这里部分代码省略.........
示例13: InsertRevision
public long InsertRevision(RevisionInternal rev, long docNumericID, long parentSequence
, bool current, byte[] data)
{
long rowId = 0;
try
{
ContentValues args = new ContentValues();
args.Put("doc_id", docNumericID);
args.Put("revid", rev.GetRevId());
if (parentSequence != 0)
{
args.Put("parent", parentSequence);
}
args.Put("current", current);
args.Put("deleted", rev.IsDeleted());
args.Put("json", data);
rowId = database.Insert("revs", null, args);
rev.SetSequence(rowId);
}
catch (Exception e)
{
Log.E(Database.Tag, "Error inserting revision", e);
}
return rowId;
}
示例14: ExtraPropertiesForRevision
public IDictionary<string, object> ExtraPropertiesForRevision(RevisionInternal rev
, EnumSet<Database.TDContentOptions> contentOptions)
{
string docId = rev.GetDocId();
string revId = rev.GetRevId();
long sequenceNumber = rev.GetSequence();
System.Diagnostics.Debug.Assert((revId != null));
System.Diagnostics.Debug.Assert((sequenceNumber > 0));
// Get attachment metadata, and optionally the contents:
IDictionary<string, object> attachmentsDict = GetAttachmentsDictForSequenceWithContent
(sequenceNumber, contentOptions);
// Get more optional stuff to put in the properties:
//OPT: This probably ends up making redundant SQL queries if multiple options are enabled.
long localSeq = null;
if (contentOptions.Contains(Database.TDContentOptions.TDIncludeLocalSeq))
{
localSeq = sequenceNumber;
}
IDictionary<string, object> revHistory = null;
if (contentOptions.Contains(Database.TDContentOptions.TDIncludeRevs))
{
revHistory = GetRevisionHistoryDict(rev);
}
IList<object> revsInfo = null;
if (contentOptions.Contains(Database.TDContentOptions.TDIncludeRevsInfo))
{
revsInfo = new AList<object>();
IList<RevisionInternal> revHistoryFull = GetRevisionHistory(rev);
foreach (RevisionInternal historicalRev in revHistoryFull)
{
IDictionary<string, object> revHistoryItem = new Dictionary<string, object>();
string status = "available";
if (historicalRev.IsDeleted())
{
status = "deleted";
}
if (historicalRev.IsMissing())
{
status = "missing";
}
revHistoryItem.Put("rev", historicalRev.GetRevId());
revHistoryItem.Put("status", status);
revsInfo.AddItem(revHistoryItem);
}
}
IList<string> conflicts = null;
if (contentOptions.Contains(Database.TDContentOptions.TDIncludeConflicts))
{
RevisionList revs = GetAllRevisionsOfDocumentID(docId, true);
if (revs.Count > 1)
{
conflicts = new AList<string>();
foreach (RevisionInternal historicalRev in revs)
{
if (!historicalRev.Equals(rev))
{
conflicts.AddItem(historicalRev.GetRevId());
}
}
}
}
IDictionary<string, object> result = new Dictionary<string, object>();
result.Put("_id", docId);
result.Put("_rev", revId);
if (rev.IsDeleted())
{
result.Put("_deleted", true);
}
if (attachmentsDict != null)
{
result.Put("_attachments", attachmentsDict);
}
if (localSeq != null)
{
result.Put("_local_seq", localSeq);
}
if (revHistory != null)
{
result.Put("_revisions", revHistory);
}
if (revsInfo != null)
{
result.Put("_revs_info", revsInfo);
}
if (conflicts != null)
{
result.Put("_conflicts", conflicts);
}
return result;
}
示例15: Winner
internal RevisionInternal Winner(Int64 docNumericID, String oldWinningRevID, Boolean oldWinnerWasDeletion, RevisionInternal newRev)
{
if (oldWinningRevID == null)
{
return newRev;
}
var newRevID = newRev.GetRevId();
if (!newRev.IsDeleted())
{
if (oldWinnerWasDeletion || RevisionInternal.CBLCompareRevIDs(newRevID, oldWinningRevID) > 0)
{
return newRev;
}
}
else
{
// this is now the winning live revision
if (oldWinnerWasDeletion)
{
if (RevisionInternal.CBLCompareRevIDs(newRevID, oldWinningRevID) > 0)
{
return newRev;
}
}
else
{
// doc still deleted, but this beats previous deletion rev
// Doc was alive. How does this deletion affect the winning rev ID?
var outIsDeleted = new AList<bool>();
var outIsConflict = new AList<bool>();
var winningRevID = WinningRevIDOfDoc(docNumericID, outIsDeleted, outIsConflict);
if (!winningRevID.Equals(oldWinningRevID))
{
if (winningRevID.Equals(newRev.GetRevId()))
{
return newRev;
}
else
{
var deleted = false;
var winningRev = new RevisionInternal(newRev.GetDocId(), winningRevID, deleted, this);
return winningRev;
}
}
}
}
return null;
}