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); }
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); }
public void RefreshMember(IMember member) { IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Member); OnRepositoryRefreshed(serializer, member, false); }
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)); } }
// 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); }
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); }
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 }); }
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); } }
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)); }
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); }
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); }
// 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); }
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); }