本文整理汇总了C#中Couchbase.Lite.Internal.RevisionInternal.GetAttachments方法的典型用法代码示例。如果您正苦于以下问题:C# RevisionInternal.GetAttachments方法的具体用法?C# RevisionInternal.GetAttachments怎么用?C# RevisionInternal.GetAttachments使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Couchbase.Lite.Internal.RevisionInternal
的用法示例。
在下文中一共展示了RevisionInternal.GetAttachments方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ForceInsert
/// <exception cref="Couchbase.Lite.CouchbaseLiteException">When attempting to add an invalid revision</exception>
internal void ForceInsert(RevisionInternal inRev, IList<string> revHistory, Uri source)
{
if (revHistory == null) {
revHistory = new List<string>(0);
}
var rev = inRev.CopyWithDocID(inRev.GetDocId(), inRev.GetRevId());
rev.SetSequence(0);
string revID = rev.GetRevId();
if (!IsValidDocumentId(rev.GetDocId()) || revID == null) {
throw new CouchbaseLiteException(StatusCode.BadId);
}
if (revHistory.Count == 0) {
revHistory.Add(revID);
} else if (revID != revHistory[0]) {
throw new CouchbaseLiteException(StatusCode.BadId);
}
if (inRev.GetAttachments() != null) {
var updatedRev = inRev.CopyWithDocID(inRev.GetDocId(), inRev.GetRevId());
string prevRevID = revHistory.Count >= 2 ? revHistory[1] : null;
Status status = new Status();
if (!ProcessAttachmentsForRevision(updatedRev, prevRevID, status)) {
throw new CouchbaseLiteException(status.Code);
}
inRev = updatedRev;
}
StoreValidation validationBlock = null;
if (Shared != null && Shared.HasValues("validation", Name)) {
validationBlock = ValidateRevision;
}
var insertStatus = Storage.ForceInsert(inRev, revHistory, validationBlock, source);
if(insertStatus.IsError) {
throw new CouchbaseLiteException(insertStatus.Code);
}
}
示例2: GetAttachmentsFromDoc
internal IDictionary<string, object> GetAttachmentsFromDoc(string docId, string revId, Status status)
{
var rev = new RevisionInternal(docId, revId, false);
try {
LoadRevisionBody(rev);
} catch(CouchbaseLiteException e) {
status.Code = e.CBLStatus.Code;
return null;
}
return rev.GetAttachments();
}
示例3: GetAttachmentForRevision
internal AttachmentInternal GetAttachmentForRevision(RevisionInternal rev, string name, Status status = null)
{
Debug.Assert(name != null);
var attachments = rev.GetAttachments();
if (attachments == null) {
try {
rev = LoadRevisionBody(rev);
} catch(CouchbaseLiteException e) {
if (status != null) {
status.Code = e.CBLStatus.Code;
}
return null;
}
attachments = rev.GetAttachments();
if (attachments == null) {
status.Code = StatusCode.NotFound;
return null;
}
}
return AttachmentForDict(attachments.Get(name).AsDictionary<string, object>(), name, status);
}
示例4: MultipartWriterForRev
internal MultipartWriter MultipartWriterForRev(RevisionInternal rev, string contentType)
{
var writer = new MultipartWriter(contentType, null);
writer.SetNextPartHeaders(new Dictionary<string, string> { { "Content-Type", "application/json" } });
writer.AddData(rev.GetBody().AsJson());
var attachments = rev.GetAttachments();
if (attachments == null) {
return writer;
}
foreach (var entry in attachments) {
var attachment = entry.Value.AsDictionary<string, object>();
if (attachment != null && attachment.GetCast<bool>("follows", false)) {
var disposition = String.Format("attachment; filename={0}", Quote(entry.Key));
writer.SetNextPartHeaders(new Dictionary<string, string> { { "Content-Disposition", disposition } });
Status status = new Status();
var attachObj = AttachmentForDict(attachment, entry.Key, status);
if (attachObj == null) {
return null;
}
var fileURL = attachObj.ContentUrl;
if (fileURL != null) {
writer.AddFileUrl(fileURL);
} else {
writer.AddStream(attachObj.ContentStream);
}
}
}
return writer;
}
示例5: ProcessAttachmentsForRevision
internal bool ProcessAttachmentsForRevision(RevisionInternal rev, string prevRevId, Status status)
{
if (status == null) {
status = new Status();
}
status.Code = StatusCode.Ok;
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;
}
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 e) {
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)) {
status.Code = StatusCode.AttachmentError;
return null;
}
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, attachInfo);
} 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, status);
if(parentAttachments == null) {
if(status.Code == StatusCode.Ok || status.Code == StatusCode.NotFound) {
status.Code = StatusCode.BadAttachment;
}
return null;
}
}
var parentAttachment = parentAttachments == null ? null : parentAttachments.Get(name).AsDictionary<string, object>();
if(parentAttachment == null) {
status.Code = StatusCode.BadAttachment;
return null;
}
return parentAttachment;
}
// Set or validate the revpos:
if(attachment.RevPos == 0) {
attachment.RevPos = generation;
} else if(attachment.RevPos >= generation) {
status.Code = StatusCode.BadAttachment;
return null;
}
Debug.Assert(attachment.IsValid);
return attachment.AsStubDictionary();
});
}
示例6: ForceInsert
public void ForceInsert(RevisionInternal inRev, IList<string> revHistory, StoreValidation validationBlock, Uri source)
{
if (_config.HasFlag(C4DatabaseFlags.ReadOnly)) {
throw new CouchbaseLiteException("Attempting to write to a readonly database", StatusCode.Forbidden);
}
var json = Manager.GetObjectMapper().WriteValueAsString(inRev.GetProperties(), true);
var change = default(DocumentChange);
RunInTransaction(() =>
{
// First get the CBForest doc:
WithC4Document(inRev.GetDocId(), null, false, true, doc =>
{
ForestDBBridge.Check(err => Native.c4doc_insertRevisionWithHistory(doc, json, inRev.IsDeleted(),
inRev.GetAttachments() != null, revHistory.ToArray(), err));
// Save updated doc back to the database:
var isWinner = SaveDocument(doc, revHistory[0], inRev.GetProperties());
inRev.SetSequence((long)doc->sequence);
change = ChangeWithNewRevision(inRev, isWinner, doc, source);
});
return true;
});
if (change != null && Delegate != null) {
Delegate.DatabaseStorageChanged(change);
}
}
示例7: PutRevision
public RevisionInternal PutRevision(string inDocId, string inPrevRevId, IDictionary<string, object> properties,
bool deleting, bool allowConflict, StoreValidation validationBlock)
{
if(_config.HasFlag(C4DatabaseFlags.ReadOnly)) {
throw new CouchbaseLiteException("Attempting to write to a readonly database", StatusCode.Forbidden);
}
var json = default(string);
if (properties != null) {
json = Manager.GetObjectMapper().WriteValueAsString(Database.StripDocumentJSON(properties), true);
} else {
json = "{}";
}
if (inDocId == null) {
inDocId = Misc.CreateGUID();
}
var putRev = default(RevisionInternal);
var change = default(DocumentChange);
var success = RunInTransaction(() =>
{
var docId = inDocId;
var prevRevId = inPrevRevId;
var transactionSuccess = false;
WithC4Document(docId, null, false, true, doc =>
{
if(prevRevId != null) {
// Updating an existing revision; make sure it exists and is a leaf:
ForestDBBridge.Check(err => Native.c4doc_selectRevision(doc, prevRevId, false, err));
if(!allowConflict && !doc->selectedRev.IsLeaf) {
throw new CouchbaseLiteException(StatusCode.Conflict);
}
} else {
// No parent revision given:
if(deleting) {
// Didn't specify a revision to delete: NotFound or a Conflict, depending
throw new CouchbaseLiteException(doc->Exists ? StatusCode.Conflict : StatusCode.NotFound);
}
// If doc exists, current rev must be in a deleted state or there will be a conflict:
if(Native.c4doc_selectCurrentRevision(doc)) {
if(doc->selectedRev.IsDeleted) {
// New rev will be child of the tombstone:
prevRevId = (string)doc->revID;
} else {
throw new CouchbaseLiteException(StatusCode.Conflict);
}
}
}
// Compute the new revID. (Can't be done earlier because prevRevID may have changed.)
var newRevID = Delegate != null ? Delegate.GenerateRevID(Encoding.UTF8.GetBytes(json), deleting, prevRevId) : null;
if(newRevID == null) {
throw new CouchbaseLiteException(StatusCode.BadId);
}
putRev = new RevisionInternal(docId, newRevID, deleting);
if(properties != null) {
properties["_id"] = docId;
properties["_rev"] = newRevID;
putRev.SetProperties(properties);
}
// Run any validation blocks:
if(validationBlock != null) {
var prevRev = default(RevisionInternal);
if(prevRevId != null) {
prevRev = new RevisionInternal(docId, prevRevId, doc->selectedRev.IsDeleted);
}
var status = validationBlock(putRev, prevRev, prevRevId);
if(status.IsError) {
throw new CouchbaseLiteException(String.Format("{0} failed validation", putRev),
status.Code);
}
}
// Add the revision to the database:
ForestDBBridge.Check(err => Native.c4doc_insertRevision(doc, newRevID, json, deleting,
putRev.GetAttachments() != null, allowConflict, err));
var isWinner = SaveDocument(doc, newRevID, properties);
putRev.SetSequence((long)doc->sequence);
change = ChangeWithNewRevision(putRev, isWinner, doc, null);
transactionSuccess = true;
});
return transactionSuccess;
});
if (!success) {
return null;
}
if (Delegate != null && change != null) {
Delegate.DatabaseStorageChanged(change);
}
return putRev;
}
示例8: GetAttachmentForRevision
internal AttachmentInternal GetAttachmentForRevision(RevisionInternal rev, string name)
{
Debug.Assert(name != null);
var attachments = rev.GetAttachments();
if (attachments == null) {
rev = LoadRevisionBody(rev);
attachments = rev.GetAttachments();
if (attachments == null) {
return null;
}
}
return AttachmentForDict(attachments.Get(name).AsDictionary<string, object>(), name);
}
示例9: ForceInsert
/// <exception cref="Couchbase.Lite.CouchbaseLiteException">When attempting to add an invalid revision</exception>
internal void ForceInsert(RevisionInternal inRev, IList<string> revHistory, Uri source)
{
if (!IsOpen) {
throw new CouchbaseLiteException("DB is closed", StatusCode.DbError);
}
if (revHistory == null) {
revHistory = new List<string>(0);
}
var rev = inRev.CopyWithDocID(inRev.GetDocId(), inRev.GetRevId());
rev.SetSequence(0);
string revID = rev.GetRevId();
if (!Document.IsValidDocumentId(rev.GetDocId()) || revID == null) {
throw new CouchbaseLiteException(StatusCode.BadId);
}
if (revHistory.Count == 0) {
revHistory.Add(revID);
} else if (revID != revHistory[0]) {
throw new CouchbaseLiteException(StatusCode.BadId);
}
if (inRev.GetAttachments() != null) {
var updatedRev = inRev.CopyWithDocID(inRev.GetDocId(), inRev.GetRevId());
ProcessAttachmentsForRevision(updatedRev, revHistory.Skip(1).Take(revHistory.Count-1).ToList());
inRev = updatedRev;
}
StoreValidation validationBlock = null;
if (Shared != null && Shared.HasValues("validation", Name)) {
validationBlock = ValidateRevision;
}
Storage.ForceInsert(inRev, revHistory, validationBlock, source);
}
示例10: GetAttachmentsFromDoc
internal IDictionary<string, object> GetAttachmentsFromDoc(string docId, string revId)
{
var rev = new RevisionInternal(docId, revId, false);
LoadRevisionBody(rev);
return rev.GetAttachments();
}
示例11: 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();
});
}
示例12: GetMultipartWriter
private MultipartWriter GetMultipartWriter(RevisionInternal rev, string boundary)
{
// Find all the attachments with "follows" instead of a body, and put 'em in a multipart stream.
// It's important to scan the _attachments entries in the same order in which they will appear
// in the JSON, because CouchDB expects the MIME bodies to appear in that same order
var bodyStream = default(MultipartWriter);
var attachments = rev.GetAttachments();
foreach (var a in attachments) {
var attachment = a.Value.AsDictionary<string, object>();
if (attachment != null && attachment.GetCast<bool>("follows")) {
if (bodyStream == null) {
// Create the HTTP multipart stream:
bodyStream = new MultipartWriter("multipart/related", boundary);
bodyStream.SetNextPartHeaders(new Dictionary<string, string> {
{ "Content-Type", "application/json" }
});
// Use canonical JSON encoder so that _attachments keys will be written in the
// same order that this for loop is processing the attachments.
var json = Manager.GetObjectMapper().WriteValueAsBytes(rev.GetProperties(), true);
if (CanSendCompressedRequests) {
bodyStream.AddGZippedData(json);
} else {
bodyStream.AddData(json);
}
}
// Add attachment as another MIME part:
var disposition = String.Format("attachment; filename={0}", Misc.QuoteString(a.Key));
var contentType = attachment.GetCast<string>("type");
var contentEncoding = attachment.GetCast<string>("encoding");
bodyStream.SetNextPartHeaders(new NonNullDictionary<string, string> {
{ "Content-Disposition", disposition },
{ "Content-Type", contentType },
{ "Content-Encoding", contentEncoding }
});
var attachmentObj = default(AttachmentInternal);
try {
attachmentObj = LocalDatabase.AttachmentForDict(attachment, a.Key);
} catch(CouchbaseLiteException) {
return null;
}
bodyStream.AddStream(attachmentObj.ContentStream, attachmentObj.Length);
}
}
return bodyStream;
}
示例13: ProcessAttachmentsForRevision
internal bool ProcessAttachmentsForRevision(RevisionInternal rev, IList<RevisionID> ancestry)
{
var revAttachments = rev.GetAttachments();
if(revAttachments == null) {
return true; // no-op: no attachments
}
// Deletions can't have attachments:
if(rev.Deleted || 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 = rev.Generation;
IDictionary<string, object> parentAttachments = null;
return rev.MutateAttachments((name, attachInfo) =>
{
AttachmentInternal attachment = null;
try {
attachment = new AttachmentInternal(name, attachInfo);
} catch(CouchbaseLiteException) {
Log.To.Database.W(TAG, "Error creating attachment object for '{0}' ('{1}'), " +
"returning null", new SecureLogString(name, LogMessageSensitivity.PotentiallyInsecure),
new SecureLogJsonString(attachInfo, LogMessageSensitivity.PotentiallyInsecure));
return null;
}
if(attachment.EncodedContent != null) {
// If there's inline attachment data, decode and store it:
BlobKey blobKey = new BlobKey();
try {
Attachments.StoreBlob(attachment.EncodedContent.ToArray(), blobKey);
} catch(CouchbaseLiteException) {
Log.To.Database.E(TAG, "Failed to write attachment '{0}' to disk, rethrowing...", name);
throw;
} catch(Exception e) {
throw Misc.CreateExceptionAndLog(Log.To.Database, e, TAG,
"Exception during attachment writing '{0}'",
new SecureLogString(name, LogMessageSensitivity.PotentiallyInsecure));
}
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.DocID, 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.DocID, ancestry);
if(ancestorAttachment != null) {
return ancestorAttachment;
}
throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadAttachment, TAG,
"Unable to find 'stub' attachment {0} in history (1)",
new SecureLogString(name, LogMessageSensitivity.PotentiallyInsecure));
}
}
var parentAttachment = parentAttachments == null ? null : parentAttachments.Get(name).AsDictionary<string, object>();
if(parentAttachment == null) {
throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadAttachment, TAG,
"Unable to find 'stub' attachment {0} in history (2)",
new SecureLogString(name, LogMessageSensitivity.PotentiallyInsecure));
}
return parentAttachment;
}
// Set or validate the revpos:
if(attachment.RevPos == 0) {
attachment.RevPos = generation;
} else if(attachment.RevPos > generation) {
throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadAttachment, TAG,
"Attachment specifies revision generation {0} but document is only at revision generation {1}",
attachment.RevPos, generation);
}
Debug.Assert(attachment.IsValid);
return attachment.AsStubDictionary();
});
}
示例14: ForceInsert
/// <exception cref="Couchbase.Lite.CouchbaseLiteException">When attempting to add an invalid revision</exception>
internal void ForceInsert(RevisionInternal inRev, IList<RevisionID> revHistory, Uri source)
{
if(!IsOpen) {
throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
"Cannot perform ForceInsert on a closed database");
}
if(revHistory == null) {
revHistory = new List<RevisionID>(0);
} else {
var tmp = revHistory.ToList();
revHistory = tmp;
}
var rev = new RevisionInternal(inRev);
rev.Sequence = 0;
RevisionID revID = rev.RevID;
if(!Document.IsValidDocumentId(rev.DocID) || revID == null) {
if(rev == null) {
throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadId, TAG,
"Cannot force insert a revision with a null revision ID");
}
throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadId, TAG,
"{0} is not a valid document ID",
new SecureLogString(rev.DocID, LogMessageSensitivity.PotentiallyInsecure));
}
if(revHistory.Count == 0 || revID != revHistory[0]) {
revHistory.Insert(0, revID);
}
if(inRev.GetAttachments() != null) {
var updatedRev = new RevisionInternal(inRev);
ProcessAttachmentsForRevision(updatedRev, revHistory.Skip(1).Take(revHistory.Count - 1).ToList());
inRev = updatedRev;
}
StoreValidation validationBlock = null;
if(Shared != null && Shared.HasValues("validation", Name)) {
validationBlock = ValidateRevision;
}
Storage?.ForceInsert(inRev, revHistory, validationBlock, source);
}