コード例 #1
0
        private ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            if (dto.EditData == null && dto.EditDataRaw == null)
            {
                throw new InvalidOperationException("No data for media " + dto.Id);
            }

            bool published         = true;
            var  deserializedMedia = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

            var p = new ContentData
            {
                Name         = dto.EditName,
                Published    = published,
                TemplateId   = -1,
                VersionId    = dto.VersionId,
                VersionDate  = dto.EditVersionDate,
                WriterId     = dto.CreatorId,                  // what-else?
                Properties   = deserializedMedia.PropertyData, // TODO: We don't want to allocate empty arrays
                CultureInfos = deserializedMedia.CultureData
            };

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit
            {
                Node          = n,
                ContentTypeId = dto.ContentTypeId,
                PublishedData = p
            };

            return(s);
        }
コード例 #2
0
        private ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            if (dto.EditData == null && dto.EditDataRaw == null)
            {
                throw new InvalidOperationException("No data for media " + dto.Id);
            }

            bool published         = true;
            var  deserializedMedia = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

            var p = new ContentData(
                dto.EditName,
                null,
                dto.VersionId,
                dto.EditVersionDate,
                dto.CreatorId,
                -1,
                published,
                deserializedMedia?.PropertyData,
                deserializedMedia?.CultureData);

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit(n, dto.ContentTypeId, null, p);

            return(s);
        }
コード例 #3
0
    public void RefreshMember(IMember member)
    {
        IContentCacheDataSerializer serializer =
            _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Member);

        OnRepositoryRefreshed(serializer, member, false);
    }
コード例 #4
0
    public IEnumerable <ContentNodeKit> GetTypeMediaSources(IEnumerable <int> ids)
    {
        if (!ids.Any())
        {
            yield break;
        }

        Sql <ISqlContext>?sql = SqlMediaSourcesSelect()
                                .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media))
                                .WhereIn <ContentDto>(x => x.ContentTypeId, ids)
                                .Append(SqlOrderByLevelIdSortOrder(SqlContext));

        // Use a more efficient COUNT query
        Sql <ISqlContext> sqlCountQuery = SqlMediaSourcesCount()
                                          .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media))
                                          .WhereIn <ContentDto>(x => x.ContentTypeId, ids);
        Sql <ISqlContext>?sqlCount =
            SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl");

        IContentCacheDataSerializer serializer =
            _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media);

        // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout.
        // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that.
        foreach (ContentSourceDto row in Database.QueryPaged <ContentSourceDto>(_nucacheSettings.Value.SqlPageSize, sql, sqlCount))
        {
            yield return(CreateMediaNodeKit(row, serializer));
        }
    }
コード例 #5
0
    // assumes media tree lock
    private void RebuildMediaDbCache(IContentCacheDataSerializer serializer, int groupSize, IReadOnlyCollection <int>?contentTypeIds)
    {
        Guid mediaObjectType = Constants.ObjectTypes.Media;

        // remove all - if anything fails the transaction will rollback
        if (contentTypeIds == null || contentTypeIds.Count == 0)
        {
            // must support SQL-CE
            Database.Execute(
                @"DELETE FROM cmsContentNu
WHERE cmsContentNu.nodeId IN (
    SELECT id FROM umbracoNode WHERE umbracoNode.nodeObjectType=@objType
)",
                new { objType = mediaObjectType });
        }
        else
        {
            // assume number of ctypes won't blow IN(...)
            // must support SQL-CE
            Database.Execute(
                $@"DELETE FROM cmsContentNu
WHERE cmsContentNu.nodeId IN (
    SELECT id FROM umbracoNode
    JOIN {Constants.DatabaseSchema.Tables.Content} ON {Constants.DatabaseSchema.Tables.Content}.nodeId=umbracoNode.id
    WHERE umbracoNode.nodeObjectType=@objType
    AND {Constants.DatabaseSchema.Tables.Content}.contentTypeId IN (@ctypes)
)",
                new { objType = mediaObjectType, ctypes = contentTypeIds });
        }

        // insert back - if anything fails the transaction will rollback
        IQuery <IMedia> query = SqlContext.Query <IMedia>();

        if (contentTypeIds != null && contentTypeIds.Count > 0)
        {
            query = query.WhereIn(x => x.ContentTypeId, contentTypeIds); // assume number of ctypes won't blow IN(...)
        }

        long pageIndex = 0;
        long processed = 0;
        long total;

        do
        {
            // the tree is locked, counting and comparing to total is safe
            IEnumerable <IMedia> descendants =
                _mediaRepository.GetPage(query, pageIndex++, groupSize, out total, null, Ordering.By("Path"));
            var items = descendants.Select(m => GetDto(m, false, serializer)).ToList();
            Database.BulkInsertRecords(items);
            processed += items.Count;
        }while (processed < total);
    }
コード例 #6
0
        public void Rebuild(
            IReadOnlyCollection <int> contentTypeIds = null,
            IReadOnlyCollection <int> mediaTypeIds   = null,
            IReadOnlyCollection <int> memberTypeIds  = null)
        {
            IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(
                ContentCacheDataSerializerEntityType.Document
                | ContentCacheDataSerializerEntityType.Media
                | ContentCacheDataSerializerEntityType.Member);

            RebuildContentDbCache(serializer, _nucacheSettings.Value.SqlPageSize, contentTypeIds);
            RebuildMediaDbCache(serializer, _nucacheSettings.Value.SqlPageSize, mediaTypeIds);
            RebuildMemberDbCache(serializer, _nucacheSettings.Value.SqlPageSize, memberTypeIds);
        }
コード例 #7
0
        private void OnRepositoryRefreshed(IContentCacheDataSerializer serializer, IContentBase content, bool published)
        {
            // use a custom SQL to update row version on each update
            // db.InsertOrUpdate(dto);
            ContentNuDto dto = GetDto(content, published, serializer);

            Database.InsertOrUpdate(
                dto,
                "SET data=@data, dataRaw=@dataRaw, rv=rv+1 WHERE nodeId=@id AND published=@published",
                new
            {
                dataRaw   = dto.RawData ?? Array.Empty <byte>(),
                data      = dto.Data,
                id        = dto.NodeId,
                published = dto.Published
            });
        }
コード例 #8
0
        public void RefreshContent(IContent content)
        {
            IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document);

            // always refresh the edited data
            OnRepositoryRefreshed(serializer, content, false);

            if (content.PublishedState == PublishedState.Unpublishing)
            {
                // if unpublishing, remove published data from table
                Database.Execute("DELETE FROM cmsContentNu WHERE nodeId=@id AND published=1", new { id = content.Id });
            }
            else if (content.PublishedState == PublishedState.Publishing)
            {
                // if publishing, refresh the published data
                OnRepositoryRefreshed(serializer, content, true);
            }
        }
コード例 #9
0
    public ContentNodeKit GetMediaSource(IScope scope, int id)
    {
        Sql <ISqlContext>?sql = SqlMediaSourcesSelect()
                                .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media))
                                .Append(SqlWhereNodeId(SqlContext, id))
                                .Append(SqlOrderByLevelIdSortOrder(scope.SqlContext));

        ContentSourceDto?dto = scope.Database.Fetch <ContentSourceDto>(sql).FirstOrDefault();

        if (dto == null)
        {
            return(ContentNodeKit.Empty);
        }

        IContentCacheDataSerializer serializer =
            _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media);

        return(CreateMediaNodeKit(dto, serializer));
    }
コード例 #10
0
        private ContentNodeKit CreateContentNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            ContentData d = null;
            ContentData p = null;

            if (dto.Edited)
            {
                if (dto.EditData == null && dto.EditDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu edited content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu edited content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = false;
                    var  deserializedContent = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

                    d = new ContentData
                    {
                        Name         = dto.EditName,
                        Published    = published,
                        TemplateId   = dto.EditTemplateId,
                        VersionId    = dto.VersionId,
                        VersionDate  = dto.EditVersionDate,
                        WriterId     = dto.EditWriterId,
                        Properties   = deserializedContent.PropertyData, // TODO: We don't want to allocate empty arrays
                        CultureInfos = deserializedContent.CultureData,
                        UrlSegment   = deserializedContent.UrlSegment
                    };
                }
            }

            if (dto.Published)
            {
                if (dto.PubData == null && dto.PubDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu published content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu published content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = true;
                    var  deserializedContent = serializer.Deserialize(dto, dto.PubData, dto.PubDataRaw, published);

                    p = new ContentData
                    {
                        Name         = dto.PubName,
                        UrlSegment   = deserializedContent.UrlSegment,
                        Published    = published,
                        TemplateId   = dto.PubTemplateId,
                        VersionId    = dto.VersionId,
                        VersionDate  = dto.PubVersionDate,
                        WriterId     = dto.PubWriterId,
                        Properties   = deserializedContent.PropertyData, // TODO: We don't want to allocate empty arrays
                        CultureInfos = deserializedContent.CultureData
                    };
                }
            }

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit
            {
                Node          = n,
                ContentTypeId = dto.ContentTypeId,
                DraftData     = d,
                PublishedData = p
            };

            return(s);
        }
コード例 #11
0
        private ContentNuDto GetDto(IContentBase content, bool published, IContentCacheDataSerializer serializer)
        {
            // should inject these in ctor
            // BUT for the time being we decide not to support ConvertDbToXml/String
            // var propertyEditorResolver = PropertyEditorResolver.Current;
            // var dataTypeService = ApplicationContext.Current.Services.DataTypeService;
            var propertyData = new Dictionary <string, PropertyData[]>();

            foreach (IProperty prop in content.Properties)
            {
                var pdatas = new List <PropertyData>();
                foreach (IPropertyValue pvalue in prop.Values)
                {
                    // sanitize - properties should be ok but ... never knows
                    if (!prop.PropertyType.SupportsVariation(pvalue.Culture, pvalue.Segment))
                    {
                        continue;
                    }

                    // note: at service level, invariant is 'null', but here invariant becomes 'string.Empty'
                    var value = published ? pvalue.PublishedValue : pvalue.EditedValue;
                    if (value != null)
                    {
                        pdatas.Add(new PropertyData {
                            Culture = pvalue.Culture ?? string.Empty, Segment = pvalue.Segment ?? string.Empty, Value = value
                        });
                    }
                }

                propertyData[prop.Alias] = pdatas.ToArray();
            }

            var cultureData = new Dictionary <string, CultureVariation>();

            // sanitize - names should be ok but ... never knows
            if (content.ContentType.VariesByCulture())
            {
                ContentCultureInfosCollection infos = content is IContent document
                    ? published
                        ? document.PublishCultureInfos
                        : document.CultureInfos
                    : content.CultureInfos;

                // ReSharper disable once UseDeconstruction
                foreach (ContentCultureInfos cultureInfo in infos)
                {
                    var cultureIsDraft = !published && content is IContent d && d.IsCultureEdited(cultureInfo.Culture);
                    cultureData[cultureInfo.Culture] = new CultureVariation
                    {
                        Name       = cultureInfo.Name,
                        UrlSegment = content.GetUrlSegment(_shortStringHelper, _urlSegmentProviders, cultureInfo.Culture),
                        Date       = content.GetUpdateDate(cultureInfo.Culture) ?? DateTime.MinValue,
                        IsDraft    = cultureIsDraft
                    };
                }
            }

            // the dictionary that will be serialized
            var contentCacheData = new ContentCacheDataModel
            {
                PropertyData = propertyData,
                CultureData  = cultureData,
                UrlSegment   = content.GetUrlSegment(_shortStringHelper, _urlSegmentProviders)
            };

            var serialized = serializer.Serialize(ReadOnlyContentBaseAdapter.Create(content), contentCacheData, published);

            var dto = new ContentNuDto
            {
                NodeId    = content.Id,
                Published = published,
                Data      = serialized.StringData,
                RawData   = serialized.ByteData
            };

            return(dto);
        }
コード例 #12
0
        // assumes content tree lock
        private void RebuildContentDbCache(IContentCacheDataSerializer serializer, int groupSize, IReadOnlyCollection <int> contentTypeIds)
        {
            Guid contentObjectType = Constants.ObjectTypes.Document;

            // remove all - if anything fails the transaction will rollback
            if (contentTypeIds == null || contentTypeIds.Count == 0)
            {
                // must support SQL-CE
                Database.Execute(
                    @"DELETE FROM cmsContentNu
WHERE cmsContentNu.nodeId IN (
    SELECT id FROM umbracoNode WHERE umbracoNode.nodeObjectType=@objType
)",
                    new { objType = contentObjectType });
            }
            else
            {
                // assume number of ctypes won't blow IN(...)
                // must support SQL-CE
                Database.Execute(
                    $@"DELETE FROM cmsContentNu
WHERE cmsContentNu.nodeId IN (
    SELECT id FROM umbracoNode
    JOIN {Constants.DatabaseSchema.Tables.Content} ON {Constants.DatabaseSchema.Tables.Content}.nodeId=umbracoNode.id
    WHERE umbracoNode.nodeObjectType=@objType
    AND {Constants.DatabaseSchema.Tables.Content}.contentTypeId IN (@ctypes)
)",
                    new { objType = contentObjectType, ctypes = contentTypeIds });
            }

            // insert back - if anything fails the transaction will rollback
            IQuery <IContent> query = SqlContext.Query <IContent>();

            if (contentTypeIds != null && contentTypeIds.Count > 0)
            {
                query = query.WhereIn(x => x.ContentTypeId, contentTypeIds); // assume number of ctypes won't blow IN(...)
            }

            long pageIndex = 0;
            long processed = 0;
            long total;

            do
            {
                // the tree is locked, counting and comparing to total is safe
                IEnumerable <IContent> descendants = _documentRepository.GetPage(query, pageIndex++, groupSize, out total, null, Ordering.By("Path"));
                var items = new List <ContentNuDto>();
                var count = 0;
                foreach (IContent c in descendants)
                {
                    // always the edited version
                    items.Add(GetDto(c, false, serializer));

                    // and also the published version if it makes any sense
                    if (c.Published)
                    {
                        items.Add(GetDto(c, true, serializer));
                    }

                    count++;
                }

                Database.BulkInsertRecords(items);
                processed += count;
            } while (processed < total);
        }
コード例 #13
0
        private ContentNodeKit CreateContentNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            ContentData?d = null;
            ContentData?p = null;

            if (dto.Edited)
            {
                if (dto.EditData == null && dto.EditDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu edited content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu edited content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = false;
                    var  deserializedContent = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

                    d = new ContentData(
                        dto.EditName,
                        deserializedContent?.UrlSegment,
                        dto.VersionId,
                        dto.EditVersionDate,
                        dto.EditWriterId,
                        dto.EditTemplateId,
                        published,
                        deserializedContent?.PropertyData,
                        deserializedContent?.CultureData);
                }
            }

            if (dto.Published)
            {
                if (dto.PubData == null && dto.PubDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu published content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu published content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = true;
                    var  deserializedContent = serializer.Deserialize(dto, dto.PubData, dto.PubDataRaw, published);

                    p = new ContentData(
                        dto.PubName,
                        deserializedContent?.UrlSegment,
                        dto.VersionId,
                        dto.PubVersionDate,
                        dto.PubWriterId,
                        dto.PubTemplateId,
                        published,
                        deserializedContent?.PropertyData,
                        deserializedContent?.CultureData);
                }
            }

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit(n, dto.ContentTypeId, d, p);

            return(s);
        }