コード例 #1
0
ファイル: DocumentDb.cs プロジェクト: kotorihq/kotori-core
        async Task <Entities.Document> ReindexDocumentAsync(Entities.Document document, long index)
        {
            var q = new DynamicQuery
                    (
                "select * from c where c.entity = @entity and c.instance = @instance " +
                "and c.projectId = @projectId and c.documentId = @documentId order by c.date.epoch desc",
                new
            {
                entity     = Entities.DocumentVersion.Entity,
                instance   = document.Instance,
                projectId  = document.ProjectId,
                documentId = document.Identifier
            }
                    );

            var documentVersions = await GetDocumentVersionsAsync(q).ConfigureAwait(false);

            var docv  = new List <Task>();
            var di    = new Uri(document.Identifier).ToKotoriDocumentIdentifier();
            var docId = di.ProjectId.ToKotoriDocumentUri(di.DocumentType, di.DocumentTypeId, di.DocumentId, index).ToString();

            foreach (var dv in documentVersions)
            {
                dv.DocumentId = docId;
                docv.Add(_repoDocumentVersion.UpsertAsync(dv));
            }

            Task.WaitAll(docv.ToArray());

            document.Identifier = docId;

            return(await _repoDocument.ReplaceAsync(document).ConfigureAwait(false));
        }
コード例 #2
0
ファイル: DocumentDb.cs プロジェクト: kotorihq/kotori-core
        async Task <bool> DeleteDocumentAsync(Entities.Document document)
        {
            var metaObj = JObject.FromObject(document.Meta);
            Dictionary <string, object> meta2 = metaObj.ToObject <Dictionary <string, object> >();

            await DeleteDocumentVersionsAsync(document).ConfigureAwait(false);

            var result = await _repoDocument.DeleteAsync(document.Id).ConfigureAwait(false);

            var nonIndexedFields = new List <string>();

            if (meta2 != null)
            {
                foreach (var key in meta2.Keys)
                {
                    var q = new DynamicQuery
                            (
                        "select count(1) as number from c where c.entity = @entity and c.instance = @instance " +
                        $"and c.projectId = @projectId and is_defined(c.meta[\"{key}\"])",
                        new
                    {
                        entity    = Entities.Document.Entity,
                        instance  = document.Instance,
                        projectId = document.ProjectId
                    }
                            );

                    var sql = q.ToSqlQuery();

                    var counts = await _repoDocumentCount.GetListAsync(q).ConfigureAwait(false);

                    var n = counts.Sum(x => x.Number);

                    if (n == 0)
                    {
                        nonIndexedFields.Add(key);
                    }
                }

                if (nonIndexedFields.Any())
                {
                    var docType = await FindDocumentTypeAsync(document.Instance, new Uri(document.ProjectId), new Uri(document.DocumentTypeId)).ConfigureAwait(false);

                    if (docType != null)
                    {
                        var indexes = docType.Indexes.ToList();

                        indexes.RemoveAll(i => nonIndexedFields.Any(i2 => i2.Equals(i.From, StringComparison.OrdinalIgnoreCase)));

                        docType.Indexes = indexes;

                        await _repoDocumentType.ReplaceAsync(docType).ConfigureAwait(false);
                    }
                }
            }

            return(result);
        }
コード例 #3
0
ファイル: DocumentDb.cs プロジェクト: kotorihq/kotori-core
        async Task <bool> DeleteDocumentVersionsAsync(Entities.Document document)
        {
            var q = new DynamicQuery
                    (
                "select c.id as Id from c where c.entity = @entity and c.instance = @instance " +
                "and c.projectId = @projectId and c.documentId = @documentId",
                new
            {
                entity     = Entities.DocumentVersion.Entity,
                instance   = document.Instance,
                projectId  = document.ProjectId,
                documentId = document.Identifier
            }
                    );

            var items = await _repoDynamic.GetListAsync(q).ConfigureAwait(false);

            foreach (var item in items)
            {
                await _repoDynamic.DeleteAsync(item.Id).ConfigureAwait(false);
            }

            return(true);
        }
コード例 #4
0
ファイル: DocumentDb.cs プロジェクト: kotorihq/kotori-core
        async Task <Entities.Document> UpsertDocumentAsync(Entities.Document document)
        {
            await CreateDocumentVersionAsync(document).ConfigureAwait(false);

            return(await _repoDocument.UpsertAsync(document).ConfigureAwait(false));
        }
コード例 #5
0
ファイル: DocumentDb.cs プロジェクト: kotorihq/kotori-core
        internal async Task <Entities.Document> FindDocumentByIdAsync(string instance, Uri projectId, Uri documentId, long?version)
        {
            // get actual version
            if (version == null)
            {
                var q = new DynamicQuery
                        (
                    "select * from c where c.entity = @entity and c.instance = @instance and c.projectId = @projectId and c.identifier = @identifier",
                    new
                {
                    entity = Entities.Document.Entity,
                    instance,
                    projectId  = projectId.ToString(),
                    identifier = documentId.ToString()
                }
                        );

                var document = await _repoDocument.GetFirstOrDefaultAsync(q).ConfigureAwait(false);

                return(document);
            }

            // get document from snapshot
            var q2 = new DynamicQuery
                     (
                "select * from c where c.entity = @entity and c.instance = @instance and c.projectId = @projectId and c.documentId = @identifier and c.version = @version",
                new
            {
                entity = Entities.DocumentVersion.Entity,
                instance,
                projectId  = projectId.ToString(),
                identifier = documentId.ToString(),
                version
            }
                     );

            var x = q2.ToSqlQuerySpec().ToSqlQuery();

            var documentVersion = await _repoDocumentVersion.GetFirstOrDefaultAsync(q2).ConfigureAwait(false);

            if (documentVersion == null)
            {
                return(null);
            }

            var newDocument = new Entities.Document
                              (
                documentVersion.Instance,
                documentVersion.ProjectId,
                documentVersion.DocumentId,
                documentVersion.DocumentTypeId,
                documentVersion.Hash,
                documentVersion.Document.Slug,
                documentVersion.Document.OriginalMeta,
                documentVersion.Document.Meta,
                documentVersion.Document.Content,
                documentVersion.Document.Date == null ? (DateTime?)null : documentVersion.Document.Date.DateTime,
                documentVersion.Document.Draft,
                documentVersion.Version
                              );

            return(newDocument);
        }
コード例 #6
0
        public async Task <OperationResult> UpsertDocumentAsync(IUpsertDocument command)
        {
            var projectUri      = command.ProjectId.ToKotoriProjectUri();
            var documentTypeUri = command.ProjectId.ToKotoriDocumentTypeUri(command.DocumentType, command.DocumentTypeId);
            var documentUri     = command.ProjectId.ToKotoriDocumentUri(command.DocumentType, command.DocumentTypeId, command.DocumentId, command.Index);

            var project = await FindProjectAsync(command.Instance, projectUri).ConfigureAwait(false);

            if (project == null)
            {
                throw new KotoriProjectException(command.ProjectId, "Project does not exist.")
                      {
                          StatusCode = System.Net.HttpStatusCode.NotFound
                      }
            }
            ;

            if (command.DocumentType == Enums.DocumentType.Content)
            {
                var result = await UpsertDocumentHelperAsync
                             (
                    command.CreateOnly,
                    command.Instance,
                    command.ProjectId,
                    command.DocumentType,
                    command.DocumentTypeId,
                    command.DocumentId,
                    command.Index,
                    command.Content,
                    command.Date,
                    command.Draft
                             ).ConfigureAwait(false);

                return(result);
            }

            if (command.DocumentType == Enums.DocumentType.Data)
            {
                var idx       = command.Index;
                var data      = new Data(command.DocumentId, command.Content);
                var documents = data.GetDocuments();

                var sql = DocumentDbHelpers.CreateDynamicQueryForDocumentSearch
                          (
                    command.Instance,
                    projectUri,
                    documentTypeUri,
                    null,
                    "count(1) as number",
                    null,
                    null,
                    true,
                    true
                          );

                var count = await CountDocumentsAsync(sql).ConfigureAwait(false);

                if (idx == null)
                {
                    idx = count;
                }

                if (idx > count)
                {
                    throw new KotoriDocumentException(command.DocumentId, $"When creating data document at a particular index, your index must be 0 - {count}.");
                }

                OperationResult lastResult = null;

                for (var dc = 0; dc < documents.Count; dc++)
                {
                    var jo  = JObject.FromObject(documents[dc]);
                    var dic = jo.ToObject <Dictionary <string, object> >();
                    var doc = Markdown.ConstructDocument(dic, null);

                    var finalIndex = idx == null ? dc : idx + dc;

                    lastResult = await UpsertDocumentHelperAsync(
                        command.CreateOnly,
                        command.Instance,
                        command.ProjectId,
                        command.DocumentType,
                        command.DocumentTypeId,
                        command.DocumentId,
                        finalIndex,
                        doc,
                        command.Date,
                        command.Draft
                        );
                }

                return(lastResult);
            }

            throw new KotoriDocumentException(command.DocumentId, "Unknown document type.");
        }

        async Task <OperationResult> UpsertDocumentHelperAsync(bool createOnly, string instance, string projectId, Enums.DocumentType documentType, string documentTypeId, string documentId, long?index, string content, DateTime?date, bool?draft)
        {
            var projectUri      = projectId.ToKotoriProjectUri();
            var documentTypeUri = projectId.ToKotoriDocumentTypeUri(documentType, documentTypeId);
            var documentUri     = projectId.ToKotoriDocumentUri(documentType, documentTypeId, documentId, index);
            var documentType2   = await FindDocumentTypeAsync(instance, projectUri, documentTypeUri).ConfigureAwait(false);

            var transformation  = new Transformation(documentTypeUri.ToKotoriDocumentTypeIdentifier().DocumentTypeId, documentType2?.Transformations);
            var document        = new Markdown(documentUri.ToKotoriDocumentIdentifier(), content, transformation, date, draft);
            var documentTypeId2 = documentTypeUri.ToKotoriDocumentTypeIdentifier();

            IDocumentResult documentResult = null;

            documentResult = document.Process();

            if (documentType == Enums.DocumentType.Content)
            {
                var slug = await FindDocumentBySlugAsync(instance, projectUri, documentResult.Slug, documentUri).ConfigureAwait(false);

                if (slug != null)
                {
                    throw new KotoriDocumentException(documentId, $"Slug '{documentResult.Slug}' is already being used for another document.");
                }
            }

            documentType2 = await UpsertDocumentTypeAsync
                            (
                instance,
                documentTypeId2,
                new UpdateToken <dynamic>(DocumentHelpers.CleanUpMeta(documentResult.Meta), false),
                new UpdateToken <string>(null, true)
                            ).ConfigureAwait(false);

            transformation = new Transformation(documentTypeUri.ToKotoriDocumentTypeIdentifier().DocumentTypeId, documentType2.Transformations);
            document       = new Markdown(documentUri.ToKotoriDocumentIdentifier(), content, transformation, date, draft);
            documentResult = document.Process();

            var d = await FindDocumentByIdAsync(instance, projectUri, documentUri, null).ConfigureAwait(false);

            var isNew = d == null;
            var id    = d?.Id;

            if (!isNew)
            {
                if (createOnly &&
                    documentType == Enums.DocumentType.Content)
                {
                    throw new KotoriDocumentException(documentId, "Document cannot be created. It already exists.");
                }
            }

            long version = 0;

            if (d != null)
            {
                version = d.Version + 1;
            }

            d = new Entities.Document
                (
                instance,
                projectUri.ToString(),
                documentUri.ToString(),
                documentTypeUri.ToString(),
                documentResult.Hash,
                documentResult.Slug,
                documentResult.OriginalMeta,
                documentResult.Meta,
                documentResult.Content,
                documentResult.Date,
                documentResult.Draft,
                version
                )
            {
                Id = id
            };

            var newDocument = await UpsertDocumentAsync(d).ConfigureAwait(false);

            var result = new OperationResult(newDocument, isNew);

            return(result);
        }
    }