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(); }
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(); }
/// <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); }
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); }
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(); }
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(); }