/// <summary>
        /// Deletes a content type
        /// </summary>
        /// <param name="entity"></param>
        /// <remarks>
        /// First checks for children and removes those first
        /// </remarks>
        protected override void PersistDeletedItem(IContentType entity)
        {
            var query    = Query <IContentType>().Where(x => x.ParentId == entity.Id);
            var children = Get(query);

            if (children is not null)
            {
                foreach (var child in children)
                {
                    PersistDeletedItem(child);
                }
            }

            //Before we call the base class methods to run all delete clauses, we need to first
            // delete all of the property data associated with this document type. Normally this will
            // be done in the ContentTypeService by deleting all associated content first, but in some cases
            // like when we switch a document type, there is property data left over that is linked
            // to the previous document type. So we need to ensure it's removed.
            var sql = Sql()
                      .Select("DISTINCT " + Cms.Core.Constants.DatabaseSchema.Tables.PropertyData + ".propertytypeid")
                      .From <PropertyDataDto>()
                      .InnerJoin <PropertyTypeDto>()
                      .On <PropertyDataDto, PropertyTypeDto>(dto => dto.PropertyTypeId, dto => dto.Id)
                      .InnerJoin <ContentTypeDto>()
                      .On <ContentTypeDto, PropertyTypeDto>(dto => dto.NodeId, dto => dto.ContentTypeId)
                      .Where <ContentTypeDto>(dto => dto.NodeId == entity.Id);

            //Delete all PropertyData where propertytypeid EXISTS in the subquery above
            Database.Execute(SqlSyntax.GetDeleteSubquery(Cms.Core.Constants.DatabaseSchema.Tables.PropertyData, "propertytypeid", sql));

            base.PersistDeletedItem(entity);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Deletes a content type
        /// </summary>
        /// <param name="entity"></param>
        /// <remarks>
        /// First checks for children and removes those first
        /// </remarks>
        protected override void PersistDeletedItem(IContentType entity)
        {
            var query = Query <IContentType> .Builder.Where(x => x.ParentId == entity.Id);

            var children = GetByQuery(query);

            foreach (var child in children)
            {
                //NOTE: We must cast here so that it goes to the outter method to
                // ensure the cache is updated.
                PersistDeletedItem((IEntity)child);
            }

            //Before we call the base class methods to run all delete clauses, we need to first
            // delete all of the property data associated with this document type. Normally this will
            // be done in the ContentTypeService by deleting all associated content first, but in some cases
            // like when we switch a document type, there is property data left over that is linked
            // to the previous document type. So we need to ensure it's removed.
            var sql = new Sql().Select("DISTINCT cmsPropertyData.propertytypeid")
                      .From <PropertyDataDto>(SqlSyntax)
                      .InnerJoin <PropertyTypeDto>(SqlSyntax)
                      .On <PropertyDataDto, PropertyTypeDto>(SqlSyntax, dto => dto.PropertyTypeId, dto => dto.Id)
                      .InnerJoin <ContentTypeDto>(SqlSyntax)
                      .On <ContentTypeDto, PropertyTypeDto>(SqlSyntax, dto => dto.NodeId, dto => dto.ContentTypeId)
                      .Where <ContentTypeDto>(dto => dto.NodeId == entity.Id);

            //Delete all cmsPropertyData where propertytypeid EXISTS in the subquery above
            Database.Execute(SqlSyntax.GetDeleteSubquery("cmsPropertyData", "propertytypeid", sql));

            base.PersistDeletedItem(entity);
        }
Ejemplo n.º 3
0
        public void RebuildXmlStructures(Func <IContent, XElement> serializer, int groupSize = 5000, IEnumerable <int> contentTypeIds = null)
        {
            //Ok, now we need to remove the data and re-insert it, we'll do this all in one transaction too.
            using (var tr = Database.GetTransaction())
            {
                //Remove all the data first, if anything fails after this it's no problem the transaction will be reverted
                if (contentTypeIds == null)
                {
                    var subQuery = new Sql()
                                   .Select("DISTINCT cmsContentXml.nodeId")
                                   .From <ContentXmlDto>()
                                   .InnerJoin <DocumentDto>()
                                   .On <ContentXmlDto, DocumentDto>(left => left.NodeId, right => right.NodeId);

                    var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery);
                    Database.Execute(deleteSql);
                }
                else
                {
                    foreach (var id in contentTypeIds)
                    {
                        var id1      = id;
                        var subQuery = new Sql()
                                       .Select("cmsDocument.nodeId")
                                       .From <DocumentDto>()
                                       .InnerJoin <ContentDto>()
                                       .On <DocumentDto, ContentDto>(left => left.NodeId, right => right.NodeId)
                                       .Where <DocumentDto>(dto => dto.Published)
                                       .Where <ContentDto>(dto => dto.ContentTypeId == id1);

                        var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery);
                        Database.Execute(deleteSql);
                    }
                }

                //now insert the data, again if something fails here, the whole transaction is reversed
                if (contentTypeIds == null)
                {
                    var query = Query <IContent> .Builder.Where(x => x.Published == true);

                    RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize);
                }
                else
                {
                    foreach (var contentTypeId in contentTypeIds)
                    {
                        //copy local
                        var id    = contentTypeId;
                        var query = Query <IContent> .Builder.Where(x => x.Published == true && x.ContentTypeId == id && x.Trashed == false);

                        RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize);
                    }
                }

                tr.Complete();
            }
        }
Ejemplo n.º 4
0
        protected override void PersistDeletedItem(IContent entity)
        {
            //We need to clear out all access rules but we need to do this in a manual way since
            // nothing in that table is joined to a content id
            var subQuery = new Sql()
                           .Select("umbracoAccessRule.accessId")
                           .From <AccessRuleDto>(SqlSyntax)
                           .InnerJoin <AccessDto>(SqlSyntax)
                           .On <AccessRuleDto, AccessDto>(SqlSyntax, left => left.AccessId, right => right.Id)
                           .Where <AccessDto>(dto => dto.NodeId == entity.Id);

            Database.Execute(SqlSyntax.GetDeleteSubquery("umbracoAccessRule", "accessId", subQuery));

            //now let the normal delete clauses take care of everything else
            base.PersistDeletedItem(entity);
        }
Ejemplo n.º 5
0
        public override void Migrate()
        {
            //Clear all stylesheet data if the tables exist
            //tuple = tablename, indexname, columnname, unique
            var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
            var found   = indexes.FirstOrDefault(
                x => x.Item1.InvariantEquals("cmsPropertyData") &&
                x.Item2.InvariantEquals("IX_cmsPropertyData_1")
                //we're searching for the old index which is not unique
                && x.Item4 == false);

            if (found != null)
            {
                //Check for MySQL
                if (DatabaseType.IsMySql())
                {
                    //Use the special double nested sub query for MySQL since that is the only
                    //way delete sub queries works
                    var delPropQry = SqlSyntax.GetDeleteSubquery(
                        "cmsPropertyData",
                        "id",
                        Sql("SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL"),
                        WhereInType.NotIn);
                    Database.Execute(delPropQry.SQL);
                }
                else
                {
                    //NOTE: Even though the above will work for MSSQL, we are not going to execute the
                    // nested delete sub query logic since it will be slower and there could be a ton of property
                    // data here so needs to be as fast as possible.
                    Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)");
                }

                //we need to re create this index
                Delete.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData").Do();
                Create.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData")
                .OnColumn("nodeId").Ascending()
                .OnColumn("versionId").Ascending()
                .OnColumn("propertytypeid").Ascending()
                .WithOptions().NonClustered()
                .WithOptions().Unique()
                .Do();
            }
        }