Esempio n. 1
0
        /// <summary>
        /// Initialises a new instance of the <see cref="AttachmentTypeMapping{TDocument,TAttachment}" /> class.
        /// </summary>
        /// <param name="attachmentName">The attachment name.</param>
        /// <param name="documentMapping">The document mapping.</param>
        /// <param name="reader">The attachment reader.</param>
        /// <param name="writer">The attachment writer.</param>
        internal AttachmentTypeMapping(
            string attachmentName,
            DocumentTypeMapping <TDocument> documentMapping,
            Func <Stream, TAttachment> reader,
            Func <TAttachment, Stream> writer)
        {
            if (attachmentName == null)
            {
                throw new ArgumentNullException(nameof(attachmentName));
            }
            if (documentMapping == null)
            {
                throw new ArgumentNullException(nameof(documentMapping));
            }
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            AttachmentName  = attachmentName;
            DocumentMapping = documentMapping;
            Reader          = reader;
            Writer          = writer;
        }
        public IQueryable <TDbDocument> CreateQuery <TDocument>(
            DocumentTypeMapping <TDocument> mapping,
            string query,
            IEnumerable <DbParameter> parameters = null)
        {
            FeedOptions queryOptions = new FeedOptions
            {
                MaxItemCount = -1,
                EnableCrossPartitionQuery = true
            };

            var contentKey = CreateContentKey(mapping);

            string selectStatement = $"SELECT * FROM {DbAccess.DbConfig.CollectionName} as c WHERE is_defined(c.{contentKey})";

            if (query != null)
            {
                // Perform substitution on references to the internal document. '[x].' is replaced while excluding
                // occurrences in a string.
                string substitutedClause = Regex.Replace(query, "\\[x\\]\\.(?=[^']*(?:'[^']*'[^']*)*$)", $"c.{contentKey}.");

                selectStatement = $"{selectStatement} AND ({substitutedClause})";
            }

            if (!DbAccess.QueryPolicy.IsQueryValid(selectStatement))
            {
                throw new NebulaStoreException("Failed to create document query");
            }

            var querySpec = CreateQuerySpec(selectStatement, parameters);

            return(MakeClientCall(
                       () => DbAccess.DbClient.CreateDocumentQuery <TDbDocument>(CollectionUri, querySpec, queryOptions),
                       "Failed to create document query"));
        }
Esempio n. 3
0
        protected bool TryGetDocumentContent <TDocument>(
            DbDocument document,
            DocumentTypeMapping <TDocument> mapping,
            out TDocument result,
            out DocumentReadFailureDetails failure)
        {
            try
            {
                result = document.GetPropertyValue <TDocument>(CreateContentKey(mapping));
            }
            catch (JsonSerializationException e)
            {
                result  = default(TDocument);
                failure = new DocumentReadFailureDetails("Failed to deserialise document", e.Message);
                return(false);
            }

            if (result == null)
            {
                failure = new DocumentReadFailureDetails("Failed to deserialise document", "Missing document content body");
                return(false);
            }

            failure = null;
            return(true);
        }
        /// <summary>
        /// Initialises a new instance of the <see cref="AttachmentTypeMappingBuilder{TDocument,TAttachment}"/> class.
        /// </summary>
        /// <param name="attachmentName">The attachment name.</param>
        /// <param name="documentMapping">The document type mapping.</param>
        internal AttachmentTypeMappingBuilder(string attachmentName, DocumentTypeMapping <TDocument> documentMapping)
        {
            if (attachmentName == null)
            {
                throw new ArgumentNullException(nameof(attachmentName));
            }
            if (documentMapping == null)
            {
                throw new ArgumentNullException(nameof(documentMapping));
            }

            _attachmentName  = attachmentName;
            _documentMapping = documentMapping;
        }
        protected string CreateDbRecordId <TDocument>(DocumentTypeMapping <TDocument> mapping, params string[] values)
        {
            if (values.Length == 0)
            {
                throw new ArgumentException("At least one value required", nameof(values));
            }

            // The db record id must be globally unique. That is ensured by generating a GUID here that is based off
            // a string that includes the service name, store name and document name as well as the document id and
            // version. Having the id generated deterministically like this allows us to ensure that multiple clients
            // for the same store, fails when racing on updating a particular document (with the same id).

            var prefix = CreateContentKey(mapping);

            return(GuidUtility.Create(GuidUtility.UrlNamespace, prefix + "_" + string.Join("_", values)).ToString());
        }
        protected void SetDocumentContentFromExisting <TDocument>(
            DbDocument dbDocument,
            DbDocument existingDocument,
            DocumentTypeMapping <TDocument> mapping)
        {
            var contentKey   = CreateContentKey(mapping);
            var contentValue = existingDocument.GetPropertyValue <object>(contentKey);

            try
            {
                dbDocument.SetPropertyValue(contentKey, contentValue);
            }
            catch (JsonException e)
            {
                throw new NebulaStoreException("Failed to serialise document content", e);
            }
        }
 protected string CreateContentKey <TDocument>(DocumentTypeMapping <TDocument> mapping)
 {
     return(_dbAccess.ConfigManager.CreateDocumentContentKey(_config.StoreName, mapping.DocumentName));
 }
 protected void SetDocumentContent <TDocument>(DbDocument dbDocument, TDocument content, DocumentTypeMapping <TDocument> mapping)
 {
     try
     {
         dbDocument.SetPropertyValue(CreateContentKey(mapping), content);
     }
     catch (JsonException e)
     {
         throw new NebulaStoreException("Failed to serialise document content", e);
     }
 }