public void testProperty()
 {
     //create instance of factory
     PropertyFactory f = new PropertyFactory();
     //create instance from factory
     Property p = f.create("Property");
     //check that it is right type
     Type t = new Property().GetType();
     Assert.IsInstanceOfType(t, p);
 }
        protected override void PersistUpdatedItem(IMedia entity)
        {
            //Updates Modified date
            ((Models.Media)entity).UpdatingEntity();

            //Ensure unique name on the same level
            entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name, entity.Id);

            //Look up parent to get and set the correct Path and update SortOrder if ParentId has changed
            if (((ICanBeDirty)entity).IsPropertyDirty("ParentId"))
            {
                var parent = Database.First <NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
                entity.Path  = string.Concat(parent.Path, ",", entity.Id);
                entity.Level = parent.Level + 1;
                var maxSortOrder =
                    Database.ExecuteScalar <int>(
                        "SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
                        new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
                entity.SortOrder = maxSortOrder + 1;
            }

            var factory = new MediaFactory(NodeObjectTypeId, entity.Id);
            //Look up Content entry to get Primary for updating the DTO
            var contentDto = Database.SingleOrDefault <ContentDto>("WHERE nodeId = @Id", new { Id = entity.Id });

            factory.SetPrimaryKey(contentDto.PrimaryKey);
            var dto = factory.BuildDto(entity);

            //Updates the (base) node data - umbracoNode
            var nodeDto = dto.ContentDto.NodeDto;
            var o       = Database.Update(nodeDto);

            //Only update this DTO if the contentType has actually changed
            if (contentDto.ContentTypeId != entity.ContentTypeId)
            {
                //Create the Content specific data - cmsContent
                var newContentDto = dto.ContentDto;
                Database.Update(newContentDto);
            }

            //Updates the current version - cmsContentVersion
            //Assumes a Version guid exists and Version date (modified date) has been set/updated
            Database.Update(dto);

            //Create the PropertyData for this version - cmsPropertyData
            var propertyFactory  = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
            var propertyDataDtos = propertyFactory.BuildDto(entity.Properties);
            var keyDictionary    = new Dictionary <int, int>();

            //Add Properties
            foreach (var propertyDataDto in propertyDataDtos)
            {
                if (propertyDataDto.Id > 0)
                {
                    Database.Update(propertyDataDto);
                }
                else
                {
                    int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
                    keyDictionary.Add(propertyDataDto.PropertyTypeId, primaryKey);
                }
            }

            //Update Properties with its newly set Id
            if (keyDictionary.Any())
            {
                foreach (var property in entity.Properties)
                {
                    property.Id = keyDictionary[property.PropertyTypeId];
                }
            }

            ((ICanBeDirty)entity).ResetDirtyProperties();
        }
Exemple #3
0
 public PropertyGateway(IUHContext uhContext, PropertyFactory factory)
 {
     _uhContext = uhContext;
     _factory   = factory;
 }
        protected override void PersistUpdatedItem(IContent entity)
        {
            var publishedState = ((Content)entity).PublishedState;

            //check if we need to create a new version
            bool shouldCreateNewVersion = entity.ShouldCreateNewVersion(publishedState);

            if (shouldCreateNewVersion)
            {
                //Updates Modified date and Version Guid
                ((Content)entity).UpdatingEntity();
            }
            else
            {
                entity.UpdateDate = DateTime.Now;
            }

            //Ensure unique name on the same level
            entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name, entity.Id);

            //Look up parent to get and set the correct Path and update SortOrder if ParentId has changed
            if (((ICanBeDirty)entity).IsPropertyDirty("ParentId"))
            {
                var parent = Database.First <NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
                entity.Path  = string.Concat(parent.Path, ",", entity.Id);
                entity.Level = parent.Level + 1;
                var maxSortOrder =
                    Database.ExecuteScalar <int>(
                        "SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId AND nodeObjectType = @NodeObjectType",
                        new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });
                entity.SortOrder = maxSortOrder + 1;

                //Question: If we move a node, should we update permissions to inherit from the new parent if the parent has permissions assigned?
                // if we do that, then we'd need to propogate permissions all the way downward which might not be ideal for many people.
                // Gonna just leave it as is for now, and not re-propogate permissions.
            }

            var factory = new ContentFactory(NodeObjectTypeId, entity.Id);
            //Look up Content entry to get Primary for updating the DTO
            var contentDto = Database.SingleOrDefault <ContentDto>("WHERE nodeId = @Id", new { Id = entity.Id });

            factory.SetPrimaryKey(contentDto.PrimaryKey);
            var dto = factory.BuildDto(entity);

            //Updates the (base) node data - umbracoNode
            var nodeDto = dto.ContentVersionDto.ContentDto.NodeDto;
            var o       = Database.Update(nodeDto);

            //Only update this DTO if the contentType has actually changed
            if (contentDto.ContentTypeId != entity.ContentTypeId)
            {
                //Create the Content specific data - cmsContent
                var newContentDto = dto.ContentVersionDto.ContentDto;
                Database.Update(newContentDto);
            }

            //If Published state has changed then previous versions should have their publish state reset.
            //If state has been changed to unpublished the previous versions publish state should also be reset.
            //if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
            if (entity.ShouldClearPublishedFlagForPreviousVersions(publishedState, shouldCreateNewVersion))
            {
                var publishedDocs = Database.Fetch <DocumentDto>("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true });
                foreach (var doc in publishedDocs)
                {
                    var docDto = doc;
                    docDto.Published = false;
                    Database.Update(docDto);
                }
            }

            //Look up (newest) entries by id in cmsDocument table to set newest = false
            var documentDtos = Database.Fetch <DocumentDto>("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true });

            foreach (var documentDto in documentDtos)
            {
                var docDto = documentDto;
                docDto.Newest = false;
                Database.Update(docDto);
            }

            var contentVersionDto = dto.ContentVersionDto;

            if (shouldCreateNewVersion)
            {
                //Create a new version - cmsContentVersion
                //Assumes a new Version guid and Version date (modified date) has been set
                Database.Insert(contentVersionDto);
                //Create the Document specific data for this version - cmsDocument
                //Assumes a new Version guid has been generated
                Database.Insert(dto);
            }
            else
            {
                //In order to update the ContentVersion we need to retreive its primary key id
                var contentVerDto = Database.SingleOrDefault <ContentVersionDto>("WHERE VersionId = @Version", new { Version = entity.Version });
                contentVersionDto.Id = contentVerDto.Id;

                Database.Update(contentVersionDto);
                Database.Update(dto);
            }

            //Create the PropertyData for this version - cmsPropertyData
            var propertyFactory  = new PropertyFactory(((Content)entity).ContentType, entity.Version, entity.Id);
            var propertyDataDtos = propertyFactory.BuildDto(entity.Properties);
            var keyDictionary    = new Dictionary <int, int>();

            //Add Properties
            foreach (var propertyDataDto in propertyDataDtos)
            {
                if (shouldCreateNewVersion == false && propertyDataDto.Id > 0)
                {
                    Database.Update(propertyDataDto);
                }
                else
                {
                    int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
                    keyDictionary.Add(propertyDataDto.PropertyTypeId, primaryKey);
                }
            }

            //Update Properties with its newly set Id
            if (keyDictionary.Any())
            {
                foreach (var property in entity.Properties)
                {
                    if (keyDictionary.ContainsKey(property.PropertyTypeId) == false)
                    {
                        continue;
                    }

                    property.Id = keyDictionary[property.PropertyTypeId];
                }
            }

            ((ICanBeDirty)entity).ResetDirtyProperties();
        }
        protected override void PersistNewItem(IMedia entity)
        {
            ((Models.Media)entity).AddingEntity();

            //Ensure unique name on the same level
            entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name);

            var factory = new MediaFactory(NodeObjectTypeId, entity.Id);
            var dto     = factory.BuildDto(entity);

            //NOTE Should the logic below have some kind of fallback for empty parent ids ?
            //Logic for setting Path, Level and SortOrder
            var parent    = Database.First <NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
            int level     = parent.Level + 1;
            int sortOrder =
                Database.ExecuteScalar <int>("SELECT COUNT(*) FROM umbracoNode WHERE parentID = @ParentId AND nodeObjectType = @NodeObjectType",
                                             new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });

            //Create the (base) node data - umbracoNode
            var nodeDto = dto.ContentDto.NodeDto;

            nodeDto.Path      = parent.Path;
            nodeDto.Level     = short.Parse(level.ToString(CultureInfo.InvariantCulture));
            nodeDto.SortOrder = sortOrder;
            var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto);

            //Update with new correct path
            nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId);
            Database.Update(nodeDto);

            //Update entity with correct values
            entity.Id        = nodeDto.NodeId; //Set Id on entity to ensure an Id is set
            entity.Path      = nodeDto.Path;
            entity.SortOrder = sortOrder;
            entity.Level     = level;

            //Create the Content specific data - cmsContent
            var contentDto = dto.ContentDto;

            contentDto.NodeId = nodeDto.NodeId;
            Database.Insert(contentDto);

            //Create the first version - cmsContentVersion
            //Assumes a new Version guid and Version date (modified date) has been set
            dto.NodeId = nodeDto.NodeId;
            Database.Insert(dto);

            //Create the PropertyData for this version - cmsPropertyData
            var propertyFactory  = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
            var propertyDataDtos = propertyFactory.BuildDto(entity.Properties);
            var keyDictionary    = new Dictionary <int, int>();

            //Add Properties
            foreach (var propertyDataDto in propertyDataDtos)
            {
                var primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
                keyDictionary.Add(propertyDataDto.PropertyTypeId, primaryKey);
            }

            //Update Properties with its newly set Id
            foreach (var property in entity.Properties)
            {
                property.Id = keyDictionary[property.PropertyTypeId];
            }

            ((ICanBeDirty)entity).ResetDirtyProperties();
        }
        protected override void PersistNewItem(IContent entity)
        {
            ((Content)entity).AddingEntity();

            //Ensure unique name on the same level
            entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name);

            var factory = new ContentFactory(NodeObjectTypeId, entity.Id);
            var dto     = factory.BuildDto(entity);

            //NOTE Should the logic below have some kind of fallback for empty parent ids ?
            //Logic for setting Path, Level and SortOrder
            var parent    = Database.First <NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
            int level     = parent.Level + 1;
            int sortOrder =
                Database.ExecuteScalar <int>("SELECT COUNT(*) FROM umbracoNode WHERE parentID = @ParentId AND nodeObjectType = @NodeObjectType",
                                             new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId });

            //Create the (base) node data - umbracoNode
            var nodeDto = dto.ContentVersionDto.ContentDto.NodeDto;

            nodeDto.Path      = parent.Path;
            nodeDto.Level     = short.Parse(level.ToString(CultureInfo.InvariantCulture));
            nodeDto.SortOrder = sortOrder;
            var o = Database.IsNew(nodeDto) ? Convert.ToInt32(Database.Insert(nodeDto)) : Database.Update(nodeDto);

            //Update with new correct path
            nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId);
            Database.Update(nodeDto);

            //Update entity with correct values
            entity.Id        = nodeDto.NodeId; //Set Id on entity to ensure an Id is set
            entity.Path      = nodeDto.Path;
            entity.SortOrder = sortOrder;
            entity.Level     = level;


            //Assign the same permissions to it as the parent node
            // http://issues.umbraco.org/issue/U4-2161
            var parentPermissions = GetPermissionsForEntity(entity.ParentId).ToArray();

            //if there are parent permissions then assign them, otherwise leave null and permissions will become the
            // user's default permissions.
            if (parentPermissions.Any())
            {
                var userPermissions = parentPermissions.Select(
                    permissionDto => new KeyValuePair <object, string>(
                        permissionDto.UserId,
                        permissionDto.Permission));
                AssignEntityPermissions(entity, userPermissions);
                //flag the entity's permissions changed flag so we can track those changes.
                //Currently only used for the cache refreshers to detect if we should refresh all user permissions cache.
                ((Content)entity).PermissionsChanged = true;
            }

            //Create the Content specific data - cmsContent
            var contentDto = dto.ContentVersionDto.ContentDto;

            contentDto.NodeId = nodeDto.NodeId;
            Database.Insert(contentDto);

            //Create the first version - cmsContentVersion
            //Assumes a new Version guid and Version date (modified date) has been set
            var contentVersionDto = dto.ContentVersionDto;

            contentVersionDto.NodeId = nodeDto.NodeId;
            Database.Insert(contentVersionDto);

            //Create the Document specific data for this version - cmsDocument
            //Assumes a new Version guid has been generated
            dto.NodeId = nodeDto.NodeId;
            Database.Insert(dto);

            //Create the PropertyData for this version - cmsPropertyData
            var propertyFactory  = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
            var propertyDataDtos = propertyFactory.BuildDto(entity.Properties);
            var keyDictionary    = new Dictionary <int, int>();

            //Add Properties
            foreach (var propertyDataDto in propertyDataDtos)
            {
                var primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
                keyDictionary.Add(propertyDataDto.PropertyTypeId, primaryKey);
            }

            //Update Properties with its newly set Id
            foreach (var property in entity.Properties)
            {
                property.Id = keyDictionary[property.PropertyTypeId];
            }

            ((ICanBeDirty)entity).ResetDirtyProperties();
        }
Exemple #7
0
        /// <summary>
        /// Gets the property collection for a query
        /// </summary>
        /// <param name="pagingSqlQuery"></param>
        /// <param name="documentDefs"></param>
        /// <returns></returns>
        protected IDictionary <Guid, PropertyCollection> GetPropertyCollection(
            PagingSqlQuery pagingSqlQuery,
            IReadOnlyCollection <DocumentDefinition> documentDefs)
        {
            if (documentDefs.Count == 0)
            {
                return(new Dictionary <Guid, PropertyCollection>());
            }

            //initialize to the query passed in
            var docSql = pagingSqlQuery.PrePagedSql;

            //we need to parse the original SQL statement and reduce the columns to just cmsContent.nodeId, cmsContentVersion.VersionId so that we can use
            // the statement to go get the property data for all of the items by using an inner join
            var parsedOriginalSql = "SELECT {0} " + docSql.SQL.Substring(docSql.SQL.IndexOf("FROM", StringComparison.Ordinal));

            if (pagingSqlQuery.HasPaging)
            {
                //if this is a paged query, build the paged query with the custom column substitution, then re-assign
                docSql            = pagingSqlQuery.BuildPagedQuery("{0}");
                parsedOriginalSql = docSql.SQL;
            }
            else if (parsedOriginalSql.InvariantContains("ORDER BY "))
            {
                //now remove everything from an Orderby clause and beyond if this is unpaged data
                parsedOriginalSql = parsedOriginalSql.Substring(0, parsedOriginalSql.LastIndexOf("ORDER BY ", StringComparison.Ordinal));
            }

            //This retrieves all pre-values for all data types that are referenced for all property types
            // that exist in the data set.
            //Benchmarks show that eagerly loading these so that we can lazily read the property data
            // below (with the use of Query intead of Fetch) go about 30% faster, so we'll eagerly load
            // this now since we cannot execute another reader inside of reading the property data.
            var preValsSql = new Sql(@"SELECT a.id, a.value, a.sortorder, a.alias, a.datatypeNodeId
FROM cmsDataTypePreValues a
WHERE EXISTS(
    SELECT DISTINCT b.id as preValIdInner
    FROM cmsDataTypePreValues b
	INNER JOIN cmsPropertyType
	ON b.datatypeNodeId = cmsPropertyType.dataTypeId
    INNER JOIN 
	    ("     + string.Format(parsedOriginalSql, "cmsContent.contentType") + @") as docData
    ON cmsPropertyType.contentTypeId = docData.contentType
    WHERE a.id = b.id)", docSql.Arguments);

            var allPreValues = Database.Fetch <DataTypePreValueDto>(preValsSql);

            //It's Important with the sort order here! We require this to be sorted by node id,
            // this is required because this data set can be huge depending on the page size. Due
            // to it's size we need to be smart about iterating over the property values to build
            // the document. Before we used to use Linq to get the property data for a given content node
            // and perform a Distinct() call. This kills performance because that would mean if we had 7000 nodes
            // and on each iteration we will perform a lookup on potentially 100,000 property rows against the node
            // id which turns out to be a crazy amount of iterations. Instead we know it's sorted by this value we'll
            // keep an index stored of the rows being read so we never have to re-iterate the entire data set
            // on each document iteration.
            var propSql = new Sql(@"SELECT cmsPropertyData.*
FROM cmsPropertyData
INNER JOIN cmsPropertyType
ON cmsPropertyData.propertytypeid = cmsPropertyType.id
INNER JOIN 
	("     + string.Format(parsedOriginalSql, "cmsContent.nodeId, cmsContentVersion.VersionId") + @") as docData
ON cmsPropertyData.versionId = docData.VersionId AND cmsPropertyData.contentNodeId = docData.nodeId
ORDER BY contentNodeId, versionId, propertytypeid
", docSql.Arguments);

            //This does NOT fetch all data into memory in a list, this will read
            // over the records as a data reader, this is much better for performance and memory,
            // but it means that during the reading of this data set, nothing else can be read
            // from SQL server otherwise we'll get an exception.
            var allPropertyData = Database.Query <PropertyDataDto>(propSql);

            var result = new Dictionary <Guid, PropertyCollection>();
            var propertiesWithTagSupport = new Dictionary <string, SupportTagsAttribute>();
            //used to track the resolved composition property types per content type so we don't have to re-resolve (ToArray) the list every time
            var resolvedCompositionProperties = new Dictionary <int, PropertyType[]>();

            //keep track of the current property data item being enumerated
            var propertyDataSetEnumerator = allPropertyData.GetEnumerator();
            var hasCurrent = false; // initially there is no enumerator.Current

            var comparer = new DocumentDefinitionComparer(SqlSyntax);

            try
            {
                //This must be sorted by node id because this is how we are sorting the query to lookup property types above,
                // which allows us to more efficiently iterate over the large data set of property values
                foreach (var def in documentDefs.OrderBy(x => x.Id).ThenBy(x => x.Version, comparer))
                {
                    // get the resolved properties from our local cache, or resolve them and put them in cache
                    PropertyType[] compositionProperties;
                    if (resolvedCompositionProperties.ContainsKey(def.Composition.Id))
                    {
                        compositionProperties = resolvedCompositionProperties[def.Composition.Id];
                    }
                    else
                    {
                        compositionProperties = def.Composition.CompositionPropertyTypes.ToArray();
                        resolvedCompositionProperties[def.Composition.Id] = compositionProperties;
                    }

                    // assemble the dtos for this def
                    // use the available enumerator.Current if any else move to next
                    var propertyDataDtos = new List <PropertyDataDto>();
                    while (hasCurrent || propertyDataSetEnumerator.MoveNext())
                    {
                        //Not checking null on VersionId because it can never be null - no idea why it's set to nullable
                        // ReSharper disable once PossibleInvalidOperationException
                        if (propertyDataSetEnumerator.Current.VersionId.Value == def.Version)
                        {
                            hasCurrent = false; // enumerator.Current is not available
                            propertyDataDtos.Add(propertyDataSetEnumerator.Current);
                        }
                        else
                        {
                            hasCurrent = true;  // enumerator.Current is available for another def
                            break;              // no more propertyDataDto for this def
                        }
                    }

                    var properties = PropertyFactory.BuildEntity(propertyDataDtos, compositionProperties, def.CreateDate, def.VersionDate).ToArray();

                    foreach (var property in properties)
                    {
                        //NOTE: The benchmarks run with and without the following code show very little change so this is not a perf bottleneck
                        var editor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias);

                        var tagSupport = propertiesWithTagSupport.ContainsKey(property.PropertyType.PropertyEditorAlias)
                            ? propertiesWithTagSupport[property.PropertyType.PropertyEditorAlias]
                            : TagExtractor.GetAttribute(editor);

                        if (tagSupport != null)
                        {
                            //add to local cache so we don't need to reflect next time for this property editor alias
                            propertiesWithTagSupport[property.PropertyType.PropertyEditorAlias] = tagSupport;

                            //this property has tags, so we need to extract them and for that we need the prevals which we've already looked up
                            var preValData = allPreValues.Where(x => x.DataTypeNodeId == property.PropertyType.DataTypeDefinitionId)
                                             .Distinct()
                                             .ToArray();

                            var asDictionary = preValData.ToDictionary(x => x.Alias, x => new PreValue(x.Id, x.Value, x.SortOrder));

                            var preVals = new PreValueCollection(asDictionary);

                            var contentPropData = new ContentPropertyData(property.Value, preVals);

                            TagExtractor.SetPropertyTags(property, contentPropData, property.Value, tagSupport);
                        }
                    }

                    if (result.ContainsKey(def.Version))
                    {
                        var msg = string.Format("The query returned multiple property sets for document definition {0}, {1}, {2}", def.Id, def.Version, def.Composition.Name);
                        if (ThrowOnWarning)
                        {
                            throw new InvalidOperationException(msg);
                        }
                        else
                        {
                            Logger.Warn <VersionableRepositoryBase <TId, TEntity> >(msg);
                        }
                    }
                    result[def.Version] = new PropertyCollection(properties);
                }
            }
            finally
            {
                propertyDataSetEnumerator.Dispose();
            }

            return(result);
        }
Exemple #8
0
        public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
        {
            this.sessionFactory = sessionFactory;


            name       = persistentClass.EntityName;
            rootName   = persistentClass.RootClazz.EntityName;
            entityType = TypeFactory.ManyToOne(name);
            type       = persistentClass.MappedClass;
            rootType   = persistentClass.RootClazz.MappedClass;
            rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName;

            identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass,
                                                                         sessionFactory.GetIdentifierGenerator(rootName));

            versioned = persistentClass.IsVersioned;

            bool lazyAvailable = persistentClass.HasPocoRepresentation &&
                                 FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
            bool hasLazy = false;

            propertySpan = persistentClass.PropertyClosureSpan;
            properties   = new StandardProperty[propertySpan];
            List <int> naturalIdNumbers = new List <int>();

            propertyNames                = new string[propertySpan];
            propertyTypes                = new IType[propertySpan];
            propertyUpdateability        = new bool[propertySpan];
            propertyInsertability        = new bool[propertySpan];
            insertInclusions             = new ValueInclusion[propertySpan];
            updateInclusions             = new ValueInclusion[propertySpan];
            nonlazyPropertyUpdateability = new bool[propertySpan];
            propertyCheckability         = new bool[propertySpan];
            propertyNullability          = new bool[propertySpan];
            propertyVersionability       = new bool[propertySpan];
            propertyLaziness             = new bool[propertySpan];
            cascadeStyles                = new CascadeStyle[propertySpan];

            int  i = 0;
            int  tempVersionProperty               = NoVersionIndex;
            bool foundCascade                      = false;
            bool foundCollection                   = false;
            bool foundMutable                      = false;
            bool foundInsertGeneratedValue         = false;
            bool foundUpdateGeneratedValue         = false;
            bool foundNonIdentifierPropertyNamedId = false;

            HasPocoRepresentation = persistentClass.HasPocoRepresentation;

            // NH: WARNING if we have to disable lazy/unproxy properties we have to do it in the whole process.
            lazy           = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
            lazyAvailable &= lazy;             // <== Disable lazy properties if the class is marked with lazy=false

            bool hadLazyProperties   = false;
            bool hadNoProxyRelations = false;

            foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
            {
                if (prop.IsLazy)
                {
                    hadLazyProperties = true;
                }
                if (prop.UnwrapProxy)
                {
                    hadNoProxyRelations = true;
                }

                // NH: A lazy property is a simple property marked with lazy=true
                bool islazyProperty = prop.IsLazy && lazyAvailable && (!prop.IsEntityRelation || prop.UnwrapProxy);
                // NH: A Relation (in this case many-to-one or one-to-one) marked as "no-proxy"
                var isUnwrapProxy = prop.UnwrapProxy && lazyAvailable;

                if (islazyProperty || isUnwrapProxy)
                {
                    // NH: verify property proxiability
                    var getter = prop.GetGetter(persistentClass.MappedClass);
                    if (getter.Method == null || getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false)
                    {
                        log.ErrorFormat("Lazy or no-proxy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name);
                    }
                }

                if (prop == persistentClass.Version)
                {
                    tempVersionProperty = i;
                    properties[i]       = PropertyFactory.BuildVersionProperty(prop, islazyProperty);
                }
                else
                {
                    properties[i] = PropertyFactory.BuildStandardProperty(prop, islazyProperty);
                }

                if (prop.IsNaturalIdentifier)
                {
                    naturalIdNumbers.Add(i);
                }

                if ("id".Equals(prop.Name))
                {
                    foundNonIdentifierPropertyNamedId = true;
                }

                if (islazyProperty)
                {
                    hasLazy = true;
                }
                if (isUnwrapProxy)
                {
                    hasUnwrapProxyForProperties = true;
                }

                propertyLaziness[i] = islazyProperty;

                propertyNames[i]                = properties[i].Name;
                propertyTypes[i]                = properties[i].Type;
                propertyNullability[i]          = properties[i].IsNullable;
                propertyUpdateability[i]        = properties[i].IsUpdateable;
                propertyInsertability[i]        = properties[i].IsInsertable;
                insertInclusions[i]             = DetermineInsertValueGenerationType(prop, properties[i]);
                updateInclusions[i]             = DetermineUpdateValueGenerationType(prop, properties[i]);
                propertyVersionability[i]       = properties[i].IsVersionable;
                nonlazyPropertyUpdateability[i] = properties[i].IsUpdateable && !islazyProperty;
                propertyCheckability[i]         = propertyUpdateability[i]
                                                  ||
                                                  (propertyTypes[i].IsAssociationType &&
                                                   ((IAssociationType)propertyTypes[i]).IsAlwaysDirtyChecked);

                cascadeStyles[i] = properties[i].CascadeStyle;

                if (properties[i].IsLazy)
                {
                    hasLazy = true;
                }

                if (properties[i].CascadeStyle != CascadeStyle.None)
                {
                    foundCascade = true;
                }

                if (IndicatesCollection(properties[i].Type))
                {
                    foundCollection = true;
                }

                if (propertyTypes[i].IsMutable && propertyCheckability[i])
                {
                    foundMutable = true;
                }

                if (insertInclusions[i] != ValueInclusion.None)
                {
                    foundInsertGeneratedValue = true;
                }

                if (updateInclusions[i] != ValueInclusion.None)
                {
                    foundUpdateGeneratedValue = true;
                }

                MapPropertyToIndex(prop, i);
                i++;
            }

            if (naturalIdNumbers.Count == 0)
            {
                naturalIdPropertyNumbers = null;
            }
            else
            {
                naturalIdPropertyNumbers = naturalIdNumbers.ToArray();
            }

            hasCascades = foundCascade;
            hasInsertGeneratedValues        = foundInsertGeneratedValue;
            hasUpdateGeneratedValues        = foundUpdateGeneratedValue;
            hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

            versionPropertyIndex = tempVersionProperty;
            hasLazyProperties    = hasLazy;

            if (hadLazyProperties && !hasLazy)
            {
                log.WarnFormat("Disabled lazy property fetching for {0} because it does not support lazy at the entity level", name);
            }
            if (hasLazy)
            {
                log.Info("lazy property fetching available for: " + name);
            }

            if (hadNoProxyRelations && !hasUnwrapProxyForProperties)
            {
                log.WarnFormat("Disabled ghost property fetching for {0} because it does not support lazy at the entity level", name);
            }
            if (hasUnwrapProxyForProperties)
            {
                log.Info("no-proxy property fetching available for: " + name);
            }

            mutable = persistentClass.IsMutable;

            if (!persistentClass.IsAbstract.HasValue)
            {
                // legacy behavior (with no abstract attribute specified)
                isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
            }
            else
            {
                isAbstract = persistentClass.IsAbstract.Value;
                if (!isAbstract && persistentClass.HasPocoRepresentation &&
                    ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
                {
                    //Modified by OneGeo: Concating the type without the null
                    log.Warn("entity [" + (type == null? persistentClass.EntityName : type.FullName)
                             + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
                }
            }
            selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
            dynamicUpdate      = persistentClass.DynamicUpdate;
            dynamicInsert      = persistentClass.DynamicInsert;

            polymorphic          = persistentClass.IsPolymorphic;
            explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
            inherited            = persistentClass.IsInherited;
            superclass           = inherited ? persistentClass.Superclass.EntityName : null;
            superclassType       = inherited ? persistentClass.Superclass.MappedClass : null;
            hasSubclasses        = persistentClass.HasSubclasses;

            optimisticLockMode = persistentClass.OptimisticLockMode;
            if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
            {
                //Modified by OneGeo: Concating the type without the null
                throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + (type == null ? persistentClass.EntityName : type.FullName));
            }

            hasCollections       = foundCollection;
            hasMutableProperties = foundMutable;

            foreach (Subclass obj in persistentClass.SubclassIterator)
            {
                subclassEntityNames.Add(obj.EntityName);
            }
            subclassEntityNames.Add(name);

            EntityMode = persistentClass.HasPocoRepresentation ? EntityMode.Poco : EntityMode.Map;

            var entityTuplizerFactory = new EntityTuplizerFactory();
            var tuplizerClassName     = persistentClass.GetTuplizerImplClassName(EntityMode);

            Tuplizer = tuplizerClassName == null
                                ? entityTuplizerFactory.BuildDefaultEntityTuplizer(EntityMode, this, persistentClass)
                                : entityTuplizerFactory.BuildEntityTuplizer(tuplizerClassName, this, persistentClass);
        }
Exemple #9
0
        protected override void PersistUpdatedItem(IMember entity)
        {
            var member = (Member)entity;

            // update
            member.UpdatingEntity();

            // ensure that strings don't contain characters that are invalid in xml
            // fixme - do we really want to keep doing this here?
            entity.SanitizeEntityPropertiesForXmlStorage();

            // if parent has changed, get path, level and sort order
            if (entity.IsPropertyDirty("ParentId"))
            {
                var parent = GetParentNodeDto(entity.ParentId);

                entity.Path      = string.Concat(parent.Path, ",", entity.Id);
                entity.Level     = parent.Level + 1;
                entity.SortOrder = GetNewChildSortOrder(entity.ParentId, 0);
            }

            // create the dto
            var dto = ContentBaseFactory.BuildDto(entity);

            // update the node dto
            var nodeDto = dto.ContentDto.NodeDto;

            Database.Update(nodeDto);

            // update the content dto
            Database.Update(dto.ContentDto);

            // update the content version dto
            Database.Update(dto.ContentVersionDto);

            // update the member dto
            // but only the changed columns, 'cos we cannot update password if empty
            var changedCols = new List <string>();

            if (entity.IsPropertyDirty("Email"))
            {
                changedCols.Add("Email");
            }

            if (entity.IsPropertyDirty("Username"))
            {
                changedCols.Add("LoginName");
            }

            // do NOT update the password if it has not changed or if it is null or empty
            if (entity.IsPropertyDirty("RawPasswordValue") && !string.IsNullOrWhiteSpace(entity.RawPasswordValue))
            {
                changedCols.Add("Password");
            }

            if (changedCols.Count > 0)
            {
                Database.Update(dto, changedCols);
            }

            // replace the property data
            var deletePropertyDataSql = SqlContext.Sql().Delete <PropertyDataDto>().Where <PropertyDataDto>(x => x.VersionId == member.VersionId);

            Database.Execute(deletePropertyDataSql);
            var propertyDataDtos = PropertyFactory.BuildDtos(member.ContentType.Variations, member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);

            foreach (var propertyDataDto in propertyDataDtos)
            {
                Database.Insert(propertyDataDto);
            }

            SetEntityTags(entity, _tagRepository);

            OnUowRefreshedEntity(new ScopedEntityEventArgs(AmbientScope, entity));

            entity.ResetDirtyProperties();
        }
Exemple #10
0
        protected override void PersistNewItem(IMember entity)
        {
            var member = (Member)entity;

            member.AddingEntity();

            // ensure that strings don't contain characters that are invalid in xml
            // fixme - do we really want to keep doing this here?
            entity.SanitizeEntityPropertiesForXmlStorage();

            // create the dto
            var dto = ContentBaseFactory.BuildDto(entity);

            // derive path and level from parent
            var parent = GetParentNodeDto(entity.ParentId);
            var level  = parent.Level + 1;

            // get sort order
            var sortOrder = GetNewChildSortOrder(entity.ParentId, 0);

            // persist the node dto
            var nodeDto = dto.ContentDto.NodeDto;

            nodeDto.Path      = parent.Path;
            nodeDto.Level     = Convert.ToInt16(level);
            nodeDto.SortOrder = sortOrder;

            // see if there's a reserved identifier for this unique id
            // and then either update or insert the node dto
            var id = GetReservedId(nodeDto.UniqueId);

            if (id > 0)
            {
                nodeDto.NodeId = id;
                nodeDto.Path   = string.Concat(parent.Path, ",", nodeDto.NodeId);
                nodeDto.ValidatePathWithException();
                Database.Update(nodeDto);
            }
            else
            {
                Database.Insert(nodeDto);

                // update path, now that we have an id
                nodeDto.Path = string.Concat(parent.Path, ",", nodeDto.NodeId);
                nodeDto.ValidatePathWithException();
                Database.Update(nodeDto);
            }

            // update entity
            entity.Id        = nodeDto.NodeId;
            entity.Path      = nodeDto.Path;
            entity.SortOrder = sortOrder;
            entity.Level     = level;

            // persist the content dto
            var contentDto = dto.ContentDto;

            contentDto.NodeId = nodeDto.NodeId;
            Database.Insert(contentDto);

            // persist the content version dto
            // assumes a new version id and version date (modified date) has been set
            var contentVersionDto = dto.ContentVersionDto;

            contentVersionDto.NodeId  = nodeDto.NodeId;
            contentVersionDto.Current = true;
            Database.Insert(contentVersionDto);
            member.VersionId = contentVersionDto.Id;

            // persist the member dto
            dto.NodeId = nodeDto.NodeId;

            // if the password is empty, generate one with the special prefix
            // this will hash the guid with a salt so should be nicely random
            if (entity.RawPasswordValue.IsNullOrWhiteSpace())
            {
                var aspHasher = new PasswordHasher();
                dto.Password            = Constants.Security.EmptyPasswordPrefix + aspHasher.HashPassword(Guid.NewGuid().ToString("N"));
                entity.RawPasswordValue = dto.Password;
            }

            Database.Insert(dto);

            // persist the property data
            var propertyDataDtos = PropertyFactory.BuildDtos(member.ContentType.Variations, member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _);

            foreach (var propertyDataDto in propertyDataDtos)
            {
                Database.Insert(propertyDataDto);
            }

            SetEntityTags(entity, _tagRepository);

            OnUowRefreshedEntity(new ScopedEntityEventArgs(AmbientScope, entity));

            entity.ResetDirtyProperties();
        }