/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"> </param>
		/// <param name="modifiedProperties"></param>
		protected override void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// check if the property is not modified
			int newOrder;
			if (!modifiedProperties.TryGet(context, PropertyName, out newOrder))
				return;

			// check if the record contains a pointer
			NodePointer pointer;
			if (!record.TryGet(context, "pointer", out pointer))
				throw new InvalidOperationException("Could not update this record because it did not contain a pointer");

			// don't update order for root  nodes
			if (pointer.Depth == 1)
				return;

			// do not allow values smaller than 1
			if (newOrder < 1)
				throw new InvalidOperationException("Can not set orders smaller than 1");

			// assemble parameter
			var newOrderParameterName = queryBuilder.AddParameter("newOrder", newOrder, DbType.Int32);
			var oldOrderParameterName = queryBuilder.AddParameter("oldOrder", record.Get<int>(context, PropertyName), DbType.Int32);
			var parentIdParameterName = queryBuilder.AddParameter("parentId", pointer.Parent.Id, DbType.Int32);

			// update the orders before updating the order of the current node
			queryBuilder.PrependQuery(string.Format("UPDATE [Nodes] SET [order] = [order] + 1 WHERE (parentId = {0}) AND ([order] < {1} AND [order] >= {2})", parentIdParameterName, oldOrderParameterName, newOrderParameterName));
			queryBuilder.PrependQuery(string.Format("UPDATE [Nodes] SET [order] = [order] - 1 WHERE (parentId = {0}) AND ([order] > {1} AND [order] <= {2})", parentIdParameterName, oldOrderParameterName, newOrderParameterName));

			// update the column
			queryBuilder.AddColumnValue(PropertyName, newOrderParameterName);
		}
        /// <summary>
        /// This method is called just after a node is updated by the repository.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="properties">The properties which were set to the updated <paramref name="record"/>.</param>
        protected override void DoAfterUpdate(IMansionContext context, Record record, IPropertyBag properties)
        {
            // get the propagate property names
            var propagatePropertyNames = properties.Names.Where(x => x.StartsWith(PropagatePrefix, StringComparison.OrdinalIgnoreCase));

            // get the property names who's value is true
            var propagatedNowProperties = propagatePropertyNames.Where(x => properties.Get(context, x, false));

            // loop over all the updated properties and propagated properties
            foreach (var propagatePropertyName in propagatedNowProperties)
            {
                // get the name of the property being propagated
                var propagatedPropertyName = propagatePropertyName.Substring(PropagatePrefix.Length);

                // get the propagated property value
                var propagatedPropertyValue = properties.Get<object>(context, propagatedPropertyName);

                // retrieve all the children nodes and update them all
                foreach (var childNode in context.Repository.RetrieveNodeset(context, new PropertyBag
                                                                                      {
                                                                                      	{"parentSource", record},
                                                                                      	{"depth", "any"}
                                                                                      }).Nodes)
                {
                    context.Repository.UpdateNode(context, childNode, new PropertyBag
                                                                      {
                                                                      	{propagatedPropertyName, propagatedPropertyValue}
                                                                      });
                }
            }
        }
		/// <summary>
		/// Prepares an insert query.
		/// </summary>
		/// <param name="context"></param>
		/// <param name="connection">The connection.</param>
		/// <param name="transaction">The transaction.</param>
		/// <param name="record"></param>
		/// <returns></returns>
		public void Prepare(IMansionContext context, SqlConnection connection, SqlTransaction transaction, Record record)
		{
			// validate arguments
			if (connection == null)
				throw new ArgumentNullException("connection");
			if (transaction == null)
				throw new ArgumentNullException("transaction");
			if (record == null)
				throw new ArgumentNullException("record");

			// retrieve the schema
			var type = typeService.Load(context, record.Type);
			var schema = Resolver.Resolve(context, type);

			// create the commands
			command = connection.CreateCommand();
			command.CommandType = CommandType.Text;
			command.Transaction = transaction;

			// check if the record contains a pointer
			NodePointer pointer;
			if (record.TryGet(context, "pointer", out pointer))
			{
				command.CommandText += string.Format(@"DELETE FROM [{0}] WHERE [{0}].[parentPointer] LIKE @pointer;", schema.RootTable.Name);
				command.Parameters.AddWithValue("pointer", pointer.PointerString + NodePointer.PointerSeparator + "%");
			}

			command.CommandText += string.Format(@"DELETE FROM [{0}] WHERE [{0}].[id] = @id;", schema.RootTable.Name);
			command.Parameters.AddWithValue("id", record.Id);
		}
        /// <summary>
        /// This method is called just before a node is updated by the repository.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="properties">The updated properties of the node.</param>
        protected override void DoBeforeUpdate(IMansionContext context, Record record, IPropertyBag properties)
        {
            // if the name has not changed we are not interested
            string newName;
            if (!properties.TryGet(context, "name", out newName))
                return;

            // if the name has not changed after normalization we are not interested
            newName = TagUtilities.Normalize(newName);
            if (record.Get(context, "name", string.Empty).Equals(newName))
            {
                properties.Remove("name");
                return;
            }
            properties.Set("name", newName);

            // if the tag is renamed to another already existing tag, move all content to that existing tag and delete this one
            Node existingTag;
            var tagIndexNode = TagUtilities.RetrieveTagIndexNode(context);
            if (TagUtilities.TryRetrieveTagNode(context, tagIndexNode, newName, out existingTag))
            {
                // TODO: move all content to the existing tag

                // TODO: delete this tag
            }
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"> </param>
		/// <param name="modifiedProperties"></param>
		protected override void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// create paremeter
			var idParameterName = queryBuilder.AddParameter("id", record.Id, DbType.Int32);

			// add where clause
			queryBuilder.AppendWhereClause("[id] = " + idParameterName);
		}
Example #6
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"> </param>
		/// <param name="modifiedProperties"></param>
		protected override void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// get the parameter name
			var parameterName = queryBuilder.AddParameter("id", record.Id, DbType.Int32);

			// nothing to update, just tell what
			queryBuilder.AppendWhereClause("[id] = " + parameterName);
		}
		/// <summary>
		/// Indexes the given <paramref name="record"/> into this engine.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which to index.</param>
		protected override void DoIndex(IMansionContext context, Record record)
		{
			// check if ElasticSearch is disabled
			if (!Configuration.IsEnabled)
				return;

			// index the record
			indexer.Index(context, record);
		}
		/// <summary>
		/// Deletes the given <paramref name="record"/> from this engine.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which to delete.</param>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> or <paramref name="record"/> is null.</exception>
		protected override void DoDelete(IMansionContext context, Record record)
		{
			// check if ElasticSearch is disabled
			if (!Configuration.IsEnabled)
				return;

			// delete the record from the index
			indexer.Delete(context, record);
		}
        /// <summary>
        /// This method is called just before a node is updated by the repository.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="properties">The updated properties of the node.</param>
        protected override void DoBeforeUpdate(IMansionContext context, Record record, IPropertyBag properties)
        {
            // get the variables
            string currentTheme;
            var hasCurrentTheme = record.TryGet(context, "theme", out currentTheme) && !string.IsNullOrEmpty(currentTheme);
            string newTheme;
            var hasNewTheme = properties.TryGet(context, "theme", out newTheme) && !string.IsNullOrEmpty(newTheme);

            // do nothing when the page does not have a theme yet
            if (!hasCurrentTheme)
                return;

            // retrieve the schema of the current theme
            var currentThemeSchema = ColumnSchema.GetSchema(context, currentTheme);

            // retrieve the blocks of this page
            var repository = context.Repository;
            var blockNodeset = repository.RetrieveNodeset(context, new PropertyBag
                                                                   {
                                                                   	{"baseType", "Block"},
                                                                   	{"parentSource", record}
                                                                   });

            // check if a new theme is selected
            if (hasNewTheme)
            {
                // retrieve the schema of the new theme
                var newThemeSchema = ColumnSchema.GetSchema(context, newTheme);

                // loop through the blocks to find obsolete ones
                foreach (var blockNode in blockNodeset.Nodes)
                {
                    // get the column of this block
                    var column = blockNode.Get<string>(context, "column");

                    // check if this block lived in the old theme
                    if (!currentThemeSchema.ContainsColumn(column))
                        continue;

                    // check if the column exists in the new theme as well
                    if (newThemeSchema.ContainsColumn(column))
                        continue;

                    // block is obsolete delete it
                    repository.DeleteNode(context, blockNode);
                }
            }
            else
            {
                // theme is removed, delete all the theme blocks
                foreach (var blockNode in blockNodeset.Nodes.Where(candidate => currentThemeSchema.ContainsColumn(candidate.Get<string>(context, "column"))))
                    repository.DeleteNode(context, blockNode);
            }

            base.DoBeforeUpdate(context, record, properties);
        }
		/// <summary>
		/// Updates an existing <paramref name="record"/> in this repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which will be updated.</param>
		/// <param name="properties">The updated properties.</param>
		protected override Record DoUpdate(IMansionContext context, Record record, IPropertyBag properties)
		{
			// update the node
			repository.Update(context, record, properties);

			// merge the properties
			record.Merge(properties);

			// return the updated node
			return record;
		}
		/// <summary>
		/// Deletes the given <paramref name="record"/> from this engine.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which to delete.</param>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> or <paramref name="record"/> is null.</exception>
		public void Delete(IMansionContext context, Record record)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (record == null)
				throw new ArgumentNullException("record");

			// invoke template method
			DoDelete(context, record);
		}
Example #12
0
		/// <summary>
		/// Generates the update statement for this table.
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"> </param>
		/// <param name="modifiedProperties"></param>
		protected override void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// create a table modification query
			var tableModificationQuery = new ModificationQueryBuilder(queryBuilder);
			foreach (var column in Columns)
				column.ToUpdateStatement(context, tableModificationQuery, record, modifiedProperties);

			// if there are no modified column add table modification query to the master query builder
			if (tableModificationQuery.HasModifiedColumns)
				queryBuilder.AppendQuery(tableModificationQuery.ToUpdateStatement(Name));
		}
Example #13
0
        /// <summary>
        /// This method is called when an property which is not on the node is accessed. Useful for lazy loading properties.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="propertyName">The name of the property being retrieved.</param>
        /// <param name="value">The missing value</param>
        protected override bool DoTryResolveMissingProperty(IMansionContext context, Record record, string propertyName, out object value)
        {
            // we do not care about any property except _tags
            if (!"_tags".Equals(propertyName, StringComparison.OrdinalIgnoreCase))
            {
                value = null;
                return false;
            }

            // initialize the _tags attribute
            value = TagUtilities.ToNames(context, record);
            return true;
        }
		/// <summary>
		/// Updates an existing <paramref name="record"/> in this repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which will be updated.</param>
		/// <param name="properties">The updated properties.</param>
		/// <returns>Returns the updated <see cref="Record"/>.</returns>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/>, <paramref name="record"/> or <paramref name="properties"/> is null.</exception>
		public Record Update(IMansionContext context, Record record, IPropertyBag properties)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (record == null)
				throw new ArgumentNullException("record");
			if (properties == null)
				throw new ArgumentNullException("properties");

			// invoke template method
			return DoUpdate(context, record, properties);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"> </param>
		/// <param name="modifiedProperties"></param>
		protected override void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// assemble the extended properties
			var extendedProperties = new PropertyBag(record);
			extendedProperties.Merge(modifiedProperties);

			// remove all properties starting with an underscore
			var unstoredPropertyNames = extendedProperties.Names.Where(candidate => candidate.StartsWith("_")).ToList();
			foreach (var propertyName in unstoredPropertyNames)
				extendedProperties.Remove(propertyName);

			// get the conversion service
			var conversionService = context.Nucleus.ResolveSingle<IConversionService>();

			// set the column value
			queryBuilder.AddColumnValue("extendedProperties", conversionService.Convert<byte[]>(context, extendedProperties), DbType.Binary);
		}
		/// <summary>
		/// This method is called just before a node is updated by the repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record"> </param>
		/// <param name="properties">The updated properties of the node.</param>
		protected override void DoBeforeUpdate(IMansionContext context, Record record, IPropertyBag properties)
		{
			base.DoBeforeUpdate(context, record, properties);

			// check if the identifier was updated
			string identifier;
			if (!properties.TryGet(context, "identifier", out identifier))
				return;
			identifier = identifier.Trim().ToLower();
			properties.Set("identifier", identifier);

			// only update the name with the identifier if the previous name was also derived from the identifier
			if (record.Get(context, "name", string.Empty).Equals(record.Get(context, "identifier", string.Empty)))
			{
				var name = properties.Get(context, "name", identifier).Trim().ToLower();
				properties.Set("name", name);
			}
		}
		/// <summary>
		/// This method is called just after a node is created by the repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record"> </param>
		/// <param name="properties">The properties from which the <paramref name="record"/> was constructed.</param>
		protected override void DoAfterCreate(IMansionContext context, Record record, IPropertyBag properties)
		{
			base.DoAfterCreate(context, record, properties);

			// check if a preferred term was specified
			Guid newPreferredTermGuid;
			if (!record.TryGet(context, "preferredTermGuid", out newPreferredTermGuid) || newPreferredTermGuid == Guid.Empty)
				return;

			// retrieve the preferredTermNode
			var newPreferredTermNode = context.Repository.RetrieveSingleNode(context, newPreferredTermGuid);
			if (newPreferredTermNode == null)
				return;

			// store the guid in the synonymGuids field
			context.Repository.UpdateNode(context, newPreferredTermNode, new PropertyBag {
				{"synonymGuids", newPreferredTermNode.Get(context, "synonymGuids", string.Empty).AppendNeedle(record.Get<string>(context, "guid"))}
			});
		}
        /// <summary>
        /// This method is called just before a node is updated by the repository.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="properties">The updated properties of the node.</param>
        protected override void DoBeforeUpdate(IMansionContext context, Record record, IPropertyBag properties)
        {
            // check if the layout was not modified
            string newLayoutName;
            if (!properties.TryGet(context, "layout", out newLayoutName))
                return;

            // check if there was no old layout
            string oldLayoutName;
            if (!record.TryGet(context, "layout", out oldLayoutName))
                return;

            // get the schemas
            var newColumnSchema = ColumnSchema.GetSchema(context, newLayoutName);
            var oldColumnSchema = ColumnSchema.GetSchema(context, oldLayoutName);

            // retrieve the blocks of this page
            var repository = context.Repository;
            var blockNodeset = repository.RetrieveNodeset(context, new PropertyBag
                                                                   {
                                                                   	{"baseType", "Block"},
                                                                   	{"parentSource", record}
                                                                   });

            // loop through all the nodes
            foreach (var blockNode in blockNodeset.Nodes)
            {
                // check if this block was not in a column of the old schema so it wont have to move to the new schema
                var columnName = blockNode.Get<string>(context, "column");
                if (!oldColumnSchema.ContainsColumn(columnName))
                    continue;

                // check if the column is in the new schema as well so it wont have to move
                if (newColumnSchema.ContainsColumn(columnName))
                    continue;

                // move the block to the default column
                repository.UpdateNode(context, blockNode, new PropertyBag
                                                          {
                                                          	{"column", newColumnSchema.DefaultColumn}
                                                          });
            }
        }
        /// <summary>
        /// This method is called just after a node is created by the repository.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="properties">The properties from which the <paramref name="record"/> was constructed.</param>
        protected override void DoAfterCreate(IMansionContext context, Record record, IPropertyBag properties)
        {
            // retrieve the content index root node
            var contentIndexRootNode = context.Repository.RetrieveContentIndexRootNode(context);

            // get the node
            var node = record as Node;
            if (node == null)
                throw new InvalidOperationException("Record is not a node");

            // create a new node on this node
            context.Repository.CreateNode(context, node, new PropertyBag
                                                     {
                                                     	{"type", "TemplatePage"},
                                                     	{"name", "Default detail page"},
                                                     	{"contentSourceGuid", contentIndexRootNode.PermanentId},
                                                     	{"layout", node.Get<string>(context, "layout")},
                                                     });
        }
		/// <summary>
		/// This method is called just before a node is updated by the repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record"> </param>
		/// <param name="properties">The updated properties of the node.</param>
		protected override void DoBeforeUpdate(IMansionContext context, Record record, IPropertyBag properties)
		{
			base.DoBeforeUpdate(context, record, properties);

			// check if the preferred term has changed
			Guid newPreferredTermGuid;
			if (!properties.TryGet(context, "preferredTermGuid", out newPreferredTermGuid))
				return;

			// delete the old link if it exists
			var recordGuidString = record.Get<string>(context, "guid");
			Guid currentPreferredTermGuid;
			if (record.TryGet(context, "preferredTermGuid", out currentPreferredTermGuid) && currentPreferredTermGuid != Guid.Empty)
			{
				// retrieve the old record
				var currentPreferredTermNode = context.Repository.RetrieveSingleNode(context, currentPreferredTermGuid);

				// remove the link, if the target was found
				if (currentPreferredTermNode != null)
				{
					// store the guid in the synonymGuids field
					context.Repository.UpdateNode(context, currentPreferredTermNode, new PropertyBag {
						{"synonymGuids", currentPreferredTermNode.Get(context, "synonymGuids", string.Empty).RemoveNeedle(recordGuidString)}
					});
				}
			}

			// check if there is no new synonym
			if (newPreferredTermGuid == Guid.Empty)
				return;

			// retrieve the preferredTermNode
			var newPreferredTermNode = context.Repository.RetrieveSingleNode(context, newPreferredTermGuid);
			if (newPreferredTermNode == null)
				return;

			// store the guid in the synonymGuids field
			context.Repository.UpdateNode(context, newPreferredTermNode, new PropertyBag {
				{"synonymGuids", newPreferredTermNode.Get(context, "synonymGuids", string.Empty).AppendNeedle(recordGuidString)}
			});
		}
        /// <summary>
        /// This method is called just after a node is created by the repository.
        /// </summary>
        /// <param name="context">The <see cref="IMansionContext"/>.</param>
        /// <param name="record"> </param>
        /// <param name="properties">The properties from which the <paramref name="record"/> was constructed.</param>
        protected override void DoAfterCreate(IMansionContext context, Record record, IPropertyBag properties)
        {
            // get the node
            var node = record as Node;
            if (node == null)
                throw new InvalidOperationException("Record is not a node");

            // get the layout schema
            string layoutName;
            if (!node.TryGet(context, "layout", out layoutName))
                throw new InvalidOperationException(string.Format("Template page {0} ({1}) does not have a layout", node.Pointer.PathString, node.Pointer.PointerString));
            var layoutSchema = ColumnSchema.GetSchema(context, layoutName);

            // add the content detail block to the primary column
            context.Repository.CreateNode(context, node, new PropertyBag
                                                         {
                                                         	{"name", "Content Detail Block"},
                                                         	{"type", "ContentDetailBlock"},
                                                         	{"approved", true},
                                                         	{"column", layoutSchema.DefaultColumn}
                                                         });
        }
		/// <summary>
		/// Prepares an insert query.
		/// </summary>
		/// <param name="context"></param>
		/// <param name="connection">The connection.</param>
		/// <param name="transaction">The transaction.</param>
		/// <param name="record"></param>
		/// <param name="modifiedProperties"></param>
		/// <returns></returns>
		public void Prepare(IMansionContext context, SqlConnection connection, SqlTransaction transaction, Record record, IPropertyBag modifiedProperties)
		{
			// validate arguments
			if (connection == null)
				throw new ArgumentNullException("connection");
			if (transaction == null)
				throw new ArgumentNullException("transaction");
			if (record == null)
				throw new ArgumentNullException("record");
			if (modifiedProperties == null)
				throw new ArgumentNullException("modifiedProperties");

			// set the modified date
			modifiedProperties.TrySet("modified", DateTime.Now);

			// retrieve the type
			var type = typeService.Load(context, record.Type);

			// retrieve the schema
			var schema = Resolver.Resolve(context, type);

			// set the full text property
			SqlServerUtilities.PopulateFullTextColumn(context, type, modifiedProperties, record);

			// create the commandse
			command = connection.CreateCommand();
			command.CommandType = CommandType.Text;
			command.Transaction = transaction;

			// prepare the query
			var queryBuilder = new ModificationQueryBuilder(command);

			// loop through all the tables in the schema and let them prepare for update
			foreach (var table in schema.Tables)
				table.ToUpdateStatement(context, queryBuilder, record, modifiedProperties);

			// finish the insert statement
			command.CommandText = queryBuilder.ToStatement();
		}
Example #23
0
		/// <summary>
		/// Generates the update statement for this table.
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"></param>
		/// <param name="modifiedProperties"></param>
		protected virtual void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			throw new NotSupportedException();
		}
		/// <summary>
		/// Deletes an existing <paramref name="record"/> from this repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which will be deleted.</param>
		protected abstract void DoDelete(IMansionContext context, Record record);
		/// <summary>
		/// Updates an existing <paramref name="record"/> in this repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which will be updated.</param>
		/// <param name="properties">The updated properties.</param>
		protected abstract void DoUpdate(IMansionContext context, Record record, IPropertyBag properties);
		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"> </param>
		/// <param name="modifiedProperties"></param>
		protected override void DoToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// allow update of relational column on special cases, most likely used when fixing the repository integrity
			if (modifiedProperties.Get(context, "_allowRelationPropertiesUpdate", false))
			{
				string name;
				if (modifiedProperties.TryGet(context, "name", out name))
					queryBuilder.AddColumnValue("name", name, DbType.String);
				string type;
				if (modifiedProperties.TryGet(context, "type", out type))
					queryBuilder.AddColumnValue("type", type, DbType.String);
				int depth;
				if (modifiedProperties.TryGet(context, "depth", out depth))
					queryBuilder.AddColumnValue("depth", depth, DbType.Int32);
				int parentId;
				if (modifiedProperties.TryGet(context, "parentId", out parentId))
					queryBuilder.AddColumnValue("parentId", parentId, DbType.Int32);
				string parentPointer;
				if (modifiedProperties.TryGet(context, "parentPointer", out parentPointer))
					queryBuilder.AddColumnValue("parentPointer", parentPointer, DbType.String);
				string parentPath;
				if (modifiedProperties.TryGet(context, "parentPath", out parentPath))
					queryBuilder.AddColumnValue("parentPath", parentPath, DbType.String);
				string parentStructure;
				if (modifiedProperties.TryGet(context, "parentStructure", out parentStructure))
					queryBuilder.AddColumnValue("parentStructure", parentStructure, DbType.String);
				return;
			}

			// make sure the relational intgrety is not comprimised
			if (modifiedProperties.Names.Intersect(ReservedPropertyName, StringComparer.OrdinalIgnoreCase).Any())
				throw new InvalidOperationException("The relational properties can not be changed");

			// get the pointer
			NodePointer pointer;
			if (!record.TryGet(context, "pointer", out pointer))
				throw new InvalidOperationException("Could not update this record because it did not contain a pointer");

			//  add the id an pointer parameters
			var idParameterName = queryBuilder.AddParameter("id", pointer.Id, DbType.Int32);
			var pointerParameterName = queryBuilder.AddParameter("pointer", pointer.PointerString + "-%", DbType.String);

			// check if the name changed
			string newName;
			if (modifiedProperties.TryGetAndRemove(context, "name", out newName))
			{
				newName = newName.Trim();
				if (string.IsNullOrEmpty(newName))
					throw new InvalidOperationException("Can not update column name with empty string");
				if (newName.Contains(NodePointer.PathSeparator))
					throw new InvalidOperationException(string.Format("Name '{0}' contains invalid characters", newName));
				if (!pointer.Name.Equals(newName))
				{
					// add the name column modification
					queryBuilder.AddColumnValue("name", newName, DbType.String);

					// update the paths
					var oldPathLengthParameterName = queryBuilder.AddParameter("oldPathLength", pointer.PathString.Length + 1, DbType.String);
					var newPathParameterName = queryBuilder.AddParameter("newPath", NodePointer.Rename(pointer, newName).PathString + NodePointer.PathSeparator, DbType.String);
					queryBuilder.AppendQuery(string.Format(@" UPDATE [Nodes] SET [parentPath] = {0} + RIGHT( [parentPath], LEN( [parentPath] ) - {1} ) WHERE ( [parentId] = {2} OR [parentPointer] LIKE {3} )", newPathParameterName, oldPathLengthParameterName, idParameterName, pointerParameterName));
				}
			}

			// check if the type changed
			string newType;
			if (modifiedProperties.TryGetAndRemove(context, "type", out newType))
			{
				newType = newType.Trim();
				if (string.IsNullOrEmpty(newType))
					throw new InvalidOperationException("Can not update column type with empty string");
				if (newType.Contains(NodePointer.StructureSeparator))
					throw new InvalidOperationException(string.Format("Type '{0}' contains invalid characters", newType));
				if (!string.IsNullOrEmpty(newType) && !pointer.Type.Equals(newType, StringComparison.OrdinalIgnoreCase))
				{
					// add the name column modification
					queryBuilder.AddColumnValue("type", newType, DbType.String);

					// update the structures
					var newStructureParameterName = queryBuilder.AddParameter("newStructure", NodePointer.ChangeType(pointer, newType).StructureString + NodePointer.StructureSeparator, DbType.String);
					var oldStructureLengthParameterName = queryBuilder.AddParameter("oldStructureLength", pointer.StructureString.Length + 1, DbType.Int32);
					queryBuilder.AppendQuery(string.Format("UPDATE [Nodes] SET [parentStructure] = {0} + RIGHT( [parentStructure], LEN( [parentStructure] ) - {1} ) WHERE ( [parentId] = {2} OR [parentPointer] LIKE {3} )", newStructureParameterName, oldStructureLengthParameterName, idParameterName, pointerParameterName));
				}
			}
		}
		/// <summary>
		/// Indexes the given <paramref name="record"/> into this engine.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which to index.</param>
		protected abstract void DoIndex(IMansionContext context, Record record);
		/// <summary>
		/// Deletes an existing <paramref name="record"/> from this repository.
		/// </summary>
		/// <param name="context">The <see cref="IMansionContext"/>.</param>
		/// <param name="record">The <see cref="Record"/> which will be deleted.</param>
		protected override void DoDelete(IMansionContext context, Record record)
		{
			repository.Delete(context, record);
		}
Example #29
0
 /// <summary>
 /// This method is called just before a node is updated by the repository.
 /// </summary>
 /// <param name="context">The <see cref="IMansionContext"/>.</param>
 /// <param name="record"> </param>
 /// <param name="properties">The updated properties of the node.</param>
 protected override void DoBeforeUpdate(IMansionContext context, Record record, IPropertyBag properties)
 {
     TagUtilities.ToGuids(context, properties);
 }
Example #30
0
		/// <summary>
		/// Generates the update statement for this table.
		/// </summary>
		/// <param name="context"></param>
		/// <param name="queryBuilder"></param>
		/// <param name="record"></param>
		/// <param name="modifiedProperties"></param>
		public void ToUpdateStatement(IMansionContext context, ModificationQueryBuilder queryBuilder, Record record, IPropertyBag modifiedProperties)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (queryBuilder == null)
				throw new ArgumentNullException("queryBuilder");
			if (record == null)
				throw new ArgumentNullException("record");
			if (modifiedProperties == null)
				throw new ArgumentNullException("modifiedProperties");

			// invoke template method
			DoToUpdateStatement(context, queryBuilder, record, modifiedProperties);
		}