/// <summary> /// Modifies a Message. /// </summary> /// <param name="page">The Page.</param> /// <param name="id">The ID of the Message to modify.</param> /// <param name="username">The Username.</param> /// <param name="subject">The Subject.</param> /// <param name="dateTime">The Date/Time.</param> /// <param name="body">The Body.</param> /// <returns>True if the Message is modified successfully.</returns> /// <exception cref="ArgumentNullException">If <paramref name="page"/>, <paramref name="username"/>, <paramref name="subject"/> or <paramref name="body"/> are <c>null</c>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="id"/> is less than zero.</exception> /// <exception cref="ArgumentException">If <paramref name="username"/> or <paramref name="subject"/> are empty.</exception> public bool ModifyMessage(PageInfo page, int id, string username, string subject, DateTime dateTime, string body) { if(page == null) throw new ArgumentNullException("page"); if(id < 0) throw new ArgumentOutOfRangeException("id", "Invalid Message ID"); if(username == null) throw new ArgumentNullException("username"); if(username.Length == 0) throw new ArgumentException("Username cannot be empty", "username"); if(subject == null) throw new ArgumentNullException("subject"); if(subject.Length == 0) throw new ArgumentException("Subject cannot be empty", "subject"); if(body == null) throw new ArgumentNullException("body"); // body can be empty string nspace, name; NameTools.ExpandFullName(page.FullName, out nspace, out name); if( string.IsNullOrEmpty(nspace)||string.IsNullOrEmpty(nspace.Trim())) nspace = " "; ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); Message[] messages = GetMessages(transaction, page); if(messages == null) { RollbackTransaction(transaction); return false; } Message oldMessage = FindMessage(messages, id); if(oldMessage == null) { RollbackTransaction(transaction); return false; } UnindexMessage(page, oldMessage.ID, oldMessage.Subject, oldMessage.DateTime, oldMessage.Body, transaction); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Message", new string[] { "Username", "Subject", "DateTime", "Body" }, new string[] { "Username", "Subject", "DateTime", "Body" }); query = queryBuilder.Where(query, "Page", WhereOperator.Equals, "Page"); query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace"); query = queryBuilder.AndWhere(query, "Id", WhereOperator.Equals, "Id"); List<Parameter> parameters = new List<Parameter>(7); parameters.Add(new Parameter(ParameterType.String, "Username", username)); parameters.Add(new Parameter(ParameterType.String, "Subject", subject)); parameters.Add(new Parameter(ParameterType.DateTime, "DateTime", dateTime)); parameters.Add(new Parameter(ParameterType.String, "Body", body)); parameters.Add(new Parameter(ParameterType.String, "Page", name)); parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace)); parameters.Add(new Parameter(ParameterType.Int16, "Id", id)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) { IndexMessage(page, id, subject, dateTime, body, transaction); CommitTransaction(transaction); return true; } else { RollbackTransaction(transaction); return false; } }
/// <summary> /// Renames a namespace. /// </summary> /// <param name="nspace">The namespace to rename.</param> /// <param name="newName">The new name of the namespace.</param> /// <returns>The correct <see cref="T:NamespaceInfo"/> object.</returns> /// <exception cref="ArgumentNullException">If <paramref name="nspace"/> or <paramref name="newName"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="newName"/> is empty.</exception> public NamespaceInfo RenameNamespace(NamespaceInfo nspace, string newName) { if(nspace==null) throw new ArgumentNullException("nspace"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); if(GetNamespace(transaction, nspace.Name) == null) { RollbackTransaction(transaction); return null; } foreach(PageInfo page in GetPages(transaction, nspace)) { PageContent content = GetContent(transaction, page, CurrentRevision); if(content != null) { UnindexPage(content, transaction); } Message[] messages = GetMessages(transaction, page); if(messages != null) { foreach(Message msg in messages) { UnindexMessageTree(page, msg, transaction); } } } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Namespace", new string[] { "Name" }, new string[] { "NewName" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "OldName"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "NewName", newName)); parameters.Add(new Parameter(ParameterType.String, "OldName", nspace.Name)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows > 0) { NamespaceInfo result = GetNamespace(transaction, newName); foreach(PageInfo page in GetPages(transaction, result)) { PageContent content = GetContent(transaction, page, CurrentRevision); if(content != null) { IndexPage(content, transaction); } Message[] messages = GetMessages(transaction, page); if(messages != null) { foreach(Message msg in messages) { IndexMessageTree(page, msg, transaction); } } } CommitTransaction(transaction); return result; } else { RollbackTransaction(transaction); return null; } }
/// <summary> /// Renames a Page. /// </summary> /// <param name="page">The Page to rename.</param> /// <param name="newName">The new Name.</param> /// <returns>The correct <see cref="T:PageInfo"/> object.</returns> /// <exception cref="ArgumentNullException">If <paramref name="page"/> or <paramref name="newName"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="newName"/> is empty.</exception> public PageInfo RenamePage(PageInfo page, string newName) { if(page == null) throw new ArgumentNullException("page"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); // Check // 1. Page is default page of its namespace // 2. New name already exists ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); if(GetPage(transaction, page.FullName) == null) { RollbackTransaction(transaction); return null; } if(IsDefaultPage(transaction, page)) { RollbackTransaction(transaction); return null; } if(GetPage(transaction, NameTools.GetFullName(NameTools.GetNamespace(page.FullName), NameTools.GetLocalName(newName))) != null) { RollbackTransaction(transaction); return null; } PageContent currentContent = GetContent(transaction, page, CurrentRevision); UnindexPage(currentContent, transaction); foreach(Message msg in GetMessages(transaction, page)) { UnindexMessageTree(page, msg, transaction); } string nspace, name; NameTools.ExpandFullName(page.FullName, out nspace, out name); if( string.IsNullOrEmpty(nspace)||string.IsNullOrEmpty(nspace.Trim())) nspace = " "; CategoryInfo[] currCategories = GetCategories(transaction, nspace == " " ? null : GetNamespace(transaction, nspace)); string lowerPageName = page.FullName.ToLowerInvariant(); List<string> pageCategories = new List<string>(10); foreach(CategoryInfo cat in currCategories) { if(Array.Find(cat.Pages, (s) => { return s.ToLowerInvariant() == lowerPageName; }) != null) { pageCategories.Add(NameTools.GetLocalName(cat.FullName)); } } RebindPage(transaction, page, new string[0]); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Page", new string[] { "Name" }, new string[] { "NewName" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "OldName"); query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace"); List<Parameter> parameters = new List<Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "NewName", newName)); parameters.Add(new Parameter(ParameterType.String, "OldName", name)); parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows > 0) { PageInfo result = new PageInfo(NameTools.GetFullName(nspace, newName), this, page.CreationDateTime); RebindPage(transaction, result, pageCategories.ToArray()); PageContent newContent = GetContent(transaction, result, CurrentRevision); IndexPage(newContent, transaction); foreach(Message msg in GetMessages(transaction, result)) { IndexMessageTree(result, msg, transaction); } CommitTransaction(transaction); return result; } else { RollbackTransaction(transaction); return null; } }
/// <summary> /// Removes a Message. /// </summary> /// <param name="transaction">A database transaction.</param> /// <param name="page">The Page.</param> /// <param name="id">The ID of the Message to remove.</param> /// <param name="removeReplies">A value specifying whether or not to remove the replies.</param> /// <returns>True if the Message is removed successfully.</returns> private bool RemoveMessage(DbTransaction transaction, PageInfo page, int id, bool removeReplies) { string nspace, name; NameTools.ExpandFullName(page.FullName, out nspace, out name); if( string.IsNullOrEmpty(nspace)||string.IsNullOrEmpty(nspace.Trim())) nspace = " "; Message[] messages = GetMessages(transaction, page); if(messages == null) return false; Message message = FindMessage(messages, id); if(message == null) return false; Message parent = FindAnchestor(messages, id); int parentId = parent != null ? parent.ID : -1; UnindexMessage(page, message.ID, message.Subject, message.DateTime, message.Body, transaction); if(removeReplies) { // Recursively remove all replies BEFORE removing parent (depth-first) foreach(Message reply in message.Replies) { if(!RemoveMessage(transaction, page, reply.ID, true)) return false; } } // Remove this message ICommandBuilder builder = GetCommandBuilder(); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.DeleteFrom("Message"); query = queryBuilder.Where(query, "Page", WhereOperator.Equals, "Page"); query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace"); query = queryBuilder.AndWhere(query, "Id", WhereOperator.Equals, "Id"); List<Parameter> parameters = new List<Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "Page", name)); parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace)); parameters.Add(new Parameter(ParameterType.Int16, "Id", (short)id)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(!removeReplies && rows == 1) { // Update replies' parent id query = queryBuilder.Update("Message", new string[] { "Parent" }, new string[] { "NewParent" }); query = queryBuilder.Where(query, "Page", WhereOperator.Equals, "Page"); query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace"); query = queryBuilder.AndWhere(query, "Parent", WhereOperator.Equals, "OldParent"); parameters = new List<Parameter>(4); if(parentId != -1) parameters.Add(new Parameter(ParameterType.Int16, "NewParent", parentId)); else parameters.Add(new Parameter(ParameterType.Int16, "NewParent", DBNull.Value)); parameters.Add(new Parameter(ParameterType.String, "Page", name)); parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace)); parameters.Add(new Parameter(ParameterType.Int16, "OldParent", (short)id)); command = builder.GetCommand(transaction, query, parameters); rows = ExecuteNonQuery(command, false); } return rows > 0; }
/// <summary> /// Modifies a user group. /// </summary> /// <param name="group">The group to modify.</param> /// <param name="description">The new description of the group.</param> /// <returns>The correct <see cref="T:UserGroup"/> object or <c>null</c>.</returns> /// <exception cref="ArgumentNullException">If <b>group</b> or <b>description</b> are <c>null</c>.</exception> public UserGroup ModifyUserGroup(UserGroup group, string description) { if(group == null) throw new ArgumentNullException("group"); if(description == null) throw new ArgumentNullException("description"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("UserGroup", new string[] { "Description" }, new string[] { "Description" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "Description", description)); parameters.Add(new Parameter(ParameterType.String, "Name", group.Name)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) { UserGroup result = new UserGroup(group.Name, description, this); result.Users = GetUserGroupUsers(transaction, group.Name); CommitTransaction(transaction); return result; } else { RollbackTransaction(transaction); return null; } }
/// <summary> /// Renames a Category. /// </summary> /// <param name="category">The Category to rename.</param> /// <param name="newName">The new Name.</param> /// <returns>The correct CategoryInfo object.</returns> /// <exception cref="ArgumentNullException">If <paramref name="category"/> or <paramref name="newName"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="newName"/> is empty.</exception> public CategoryInfo RenameCategory(CategoryInfo category, string newName) { if(category == null) throw new ArgumentNullException("category"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); string nspace = null; string name = null; NameTools.ExpandFullName(category.FullName, out nspace, out name); if( string.IsNullOrEmpty(nspace)||string.IsNullOrEmpty(nspace.Trim())) nspace = " "; ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Category", new string[] { "Name" }, new string[] { "NewName" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "OldName"); query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace"); List<Parameter> parameters = new List<Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "NewName", newName)); parameters.Add(new Parameter(ParameterType.String, "OldName", name)); parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows > 0) { CategoryInfo result = GetCategory(transaction, NameTools.GetFullName(nspace, newName)); CommitTransaction(transaction); return result; } else { RollbackTransaction(transaction); return null; } }
/// <summary> /// Renames or moves a File. /// </summary> /// <param name="oldFullName">The old full name of the File.</param> /// <param name="newFullName">The new full name of the File.</param> /// <returns><c>true</c> if the File is renamed, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">If <paramref name="oldFullName"/> or <paramref name="newFullName"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="oldFullName"/> or <paramref name="newFullName"/> are empty, or if the old file does not exist, or if the new file already exist.</exception> public bool RenameFile(string oldFullName, string newFullName) { if(oldFullName == null) throw new ArgumentNullException("oldFullName"); if(oldFullName.Length == 0) throw new ArgumentException("Old Full Name cannot be empty", "oldFullName"); if(newFullName == null) throw new ArgumentNullException("newFullName"); if(newFullName.Length == 0) throw new ArgumentException("New Full Name cannot be empty", "newFullName"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); if(!FileExists(transaction, oldFullName)) { RollbackTransaction(transaction); throw new ArgumentException("File does not exist", "oldFullName"); } if(FileExists(transaction, newFullName)) { RollbackTransaction(transaction); throw new ArgumentException("File already exists", "newFullPath"); } string oldDirectory, newDirectory, oldFilename, newFilename; SplitFileFullName(oldFullName, out oldDirectory, out oldFilename); SplitFileFullName(newFullName, out newDirectory, out newFilename); string query = queryBuilder.Update("File", new string[] { "Name" }, new string[] { "NewName" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "OldName"); query = queryBuilder.AndWhere(query, "Directory", WhereOperator.Equals, "OldDirectory"); List<Parameter> parameters = new List<Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "NewName", newFilename)); parameters.Add(new Parameter(ParameterType.String, "OldName", oldFilename)); parameters.Add(new Parameter(ParameterType.String, "OldDirectory", oldDirectory)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) CommitTransaction(transaction); else RollbackTransaction(transaction); return rows == 1; }
/// <summary> /// Renames a ACL resource. /// </summary> /// <param name="resource">The resource to rename.</param> /// <param name="newName">The new name of the resource.</param> /// <returns><c>true</c> if one or more entries weere updated, <c>false</c> otherwise.</returns> private bool RenameAclResource(string resource, string newName) { ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("AclEntry", new[] { "Resource" }, new[] { "ResourceNew" }); query = queryBuilder.Where(query, "Resource", WhereOperator.Equals, "ResourceOld"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "ResourceNew", newName)); parameters.Add(new Parameter(ParameterType.String, "ResourceOld", resource)); DbCommand command = builder.GetCommand(transaction, query, parameters); if(ExecuteNonQuery(command, false) <= 0) { RollbackTransaction(transaction); return false; } CommitTransaction(transaction); return true; }
/// <summary> /// Stores a file. /// </summary> /// <param name="fullName">The full name of the file.</param> /// <param name="sourceStream">A Stream object used as <b>source</b> of a byte stream, /// i.e. the method reads from the Stream and stores the content properly.</param> /// <param name="overwrite"><c>true</c> to overwrite an existing file.</param> /// <returns><c>true</c> if the File is stored, <c>false</c> otherwise.</returns> /// <remarks>If <b>overwrite</b> is <c>false</c> and File already exists, the method returns <c>false</c>.</remarks> /// <exception cref="ArgumentNullException">If <paramref name="fullName"/> or <paramref name="sourceStream"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="fullName"/> is empty or <paramref name="sourceStream"/> does not support reading.</exception> public bool StoreFile(string fullName, System.IO.Stream sourceStream, bool overwrite) { if(fullName == null) throw new ArgumentNullException("fullName"); if(fullName.Length == 0) throw new ArgumentException("Full Name cannot be empty", "fullName"); if(sourceStream == null) throw new ArgumentNullException("sourceStream"); if(!sourceStream.CanRead) throw new ArgumentException("Cannot read from Source Stream", "sourceStream"); string directory, filename; SplitFileFullName(fullName, out directory, out filename); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); bool fileExists = FileExists(transaction, fullName); if(fileExists && !overwrite) { RollbackTransaction(transaction); return false; } // To achieve decent performance, an UPDATE query is issued if the file exists, // otherwise an INSERT query is issued string query; List<Parameter> parameters; byte[] fileData = null; int size = Tools.ReadStream(sourceStream, ref fileData, MaxFileSize); if(size < 0) { RollbackTransaction(transaction); throw new ArgumentException("Source Stream contains too much data", "sourceStream"); } if(fileExists) { query = queryBuilder.Update("File", new string[] { "Size", "LastModified", "Data" }, new string[] { "Size", "LastModified", "Data" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); query = queryBuilder.AndWhere(query, "Directory", WhereOperator.Equals, "Directory"); parameters = new List<Parameter>(5); parameters.Add(new Parameter(ParameterType.Int64, "Size", (long)size)); parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", DateTime.Now)); parameters.Add(new Parameter(ParameterType.ByteArray, "Data", fileData)); parameters.Add(new Parameter(ParameterType.String, "Name", filename)); parameters.Add(new Parameter(ParameterType.String, "Directory", directory)); } else { query = queryBuilder.InsertInto("File", new string[] { "Name", "Directory", "Size", "Downloads", "LastModified", "Data" }, new string[] { "Name", "Directory", "Size", "Downloads", "LastModified", "Data" }); parameters = new List<Parameter>(6); parameters.Add(new Parameter(ParameterType.String, "Name", filename)); parameters.Add(new Parameter(ParameterType.String, "Directory", directory)); parameters.Add(new Parameter(ParameterType.Int64, "Size", (long)size)); parameters.Add(new Parameter(ParameterType.Int32, "Downloads", 0)); parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", DateTime.Now)); parameters.Add(new Parameter(ParameterType.ByteArray, "Data", fileData)); } DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) CommitTransaction(transaction); else RollbackTransaction(transaction); return rows == 1; }
/// <summary> /// Sets the number of times a file was retrieved. /// </summary> /// <param name="fullName">The full name of the file.</param> /// <param name="count">The count to set.</param> /// <exception cref="ArgumentNullException">If <paramref name="fullName"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="fullName"/> is empty.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="count"/> is less than zero.</exception> public void SetFileRetrievalCount(string fullName, int count) { if(fullName == null) throw new ArgumentNullException("fullName"); if(fullName.Length == 0) throw new ArgumentException("Full Name cannot be empty", "fullName"); if(count < 0) throw new ArgumentOutOfRangeException("count", "Count must be greater than or equal to zero"); ICommandBuilder builder = GetCommandBuilder(); QueryBuilder queryBuilder = new QueryBuilder(builder); string directory, filename; SplitFileFullName(fullName, out directory, out filename); string query = queryBuilder.Update("File", new string[] { "Downloads" }, new string[] { "Downloads" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); query = queryBuilder.AndWhere(query, "Directory", WhereOperator.Equals, "Directory"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "Name", filename)); parameters.Add(new Parameter(ParameterType.String, "Directory", directory)); parameters.Add(new Parameter(ParameterType.Int32, "Downloads", count)); DbCommand command = builder.GetCommand(connString, query, parameters); ExecuteNonQuery(command); }
/// <summary> /// Notifies the Provider that a Page has been renamed. /// </summary> /// <param name="oldPage">The old Page Info object.</param> /// <param name="newPage">The new Page Info object.</param> /// <exception cref="ArgumentNullException">If <paramref name="oldPage"/> or <paramref name="newPage"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If the new page is already in use.</exception> public void NotifyPageRenaming(PageInfo oldPage, PageInfo newPage) { if(oldPage == null) throw new ArgumentNullException("oldPage"); if(newPage == null) throw new ArgumentNullException("newPage"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); if(ListPageAttachments(transaction, newPage).Length > 0) { RollbackTransaction(transaction); throw new ArgumentException("New Page already exists", "newPage"); } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Attachment", new string[] { "Page" }, new string[] { "NewPage" }); query = queryBuilder.Where(query, "Page", WhereOperator.Equals, "OldPage"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "NewPage", newPage.FullName)); parameters.Add(new Parameter(ParameterType.String, "OldPage", oldPage.FullName)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows != -1) CommitTransaction(transaction); else RollbackTransaction(transaction); }
/// <summary> /// Renames a Page Attachment. /// </summary> /// <param name="pageInfo">The Page Info that owns the Attachment.</param> /// <param name="oldName">The old name of the Attachment.</param> /// <param name="newName">The new name of the Attachment.</param> /// <returns><c>true</c> if the Attachment is renamed, false otherwise.</returns> /// <exception cref="ArgumentNullException">If <paramref name="pageInfo"/>, <paramref name="oldName"/> or <paramref name="newName"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="pageInfo"/>, <paramref name="oldName"/> or <paramref name="newName"/> are empty, /// or if the page or old attachment do not exist, or the new attachment name already exists.</exception> public bool RenamePageAttachment(PageInfo pageInfo, string oldName, string newName) { if(pageInfo == null) throw new ArgumentNullException("pageInfo"); if(oldName == null) throw new ArgumentNullException("oldName"); if(oldName.Length == 0) throw new ArgumentException("Old Name cannot be empty", "oldName"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); if(!AttachmentExists(transaction, pageInfo, oldName)) { RollbackTransaction(transaction); throw new ArgumentException("Attachment does not exist", "name"); } if(AttachmentExists(transaction, pageInfo, newName)) { RollbackTransaction(transaction); throw new ArgumentException("Attachment already exists", "name"); } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Attachment", new string[] { "Name" }, new string[] { "NewName" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "OldName"); query = queryBuilder.AndWhere(query, "Page", WhereOperator.Equals, "Page"); List<Parameter> parameters = new List<Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "NewName", newName)); parameters.Add(new Parameter(ParameterType.String, "OldName", oldName)); parameters.Add(new Parameter(ParameterType.String, "Page", pageInfo.FullName)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) CommitTransaction(transaction); else RollbackTransaction(transaction); return rows == 1; }
/// <summary> /// Sets the number of times a page attachment was retrieved. /// </summary> /// <param name="pageInfo">The page.</param> /// <param name="name">The name of the attachment.</param> /// <param name="count">The count to set.</param> /// <exception cref="ArgumentNullException">If <paramref name="pageInfo"/> or <paramref name="name"/> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="name"/> is empty.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="count"/> is less than zero.</exception> public void SetPageAttachmentRetrievalCount(PageInfo pageInfo, string name, int count) { if(pageInfo == null) throw new ArgumentNullException("pageInfo"); if(name == null) throw new ArgumentNullException("name"); if(name.Length == 0) throw new ArgumentException("Name cannot be empty"); if(count < 0) throw new ArgumentOutOfRangeException("Count must be greater than or equal to zero", "count"); ICommandBuilder builder = GetCommandBuilder(); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Attachment", new string[] { "Downloads" }, new string[] { "Downloads" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); query = queryBuilder.AndWhere(query, "Page", WhereOperator.Equals, "Page"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "Name", name)); parameters.Add(new Parameter(ParameterType.String, "Page", pageInfo.FullName)); parameters.Add(new Parameter(ParameterType.Int32, "Downloads", count)); DbCommand command = builder.GetCommand(connString, query, parameters); ExecuteNonQuery(command); }
/// <summary> /// Sets the default page of a namespace. /// </summary> /// <param name="nspace">The namespace of which to set the default page.</param> /// <param name="page">The page to use as default page, or <c>null</c>.</param> /// <returns>The correct <see cref="T:NamespaceInfo"/> object.</returns> /// <exception cref="ArgumentNullException">If <paramref name="nspace"/> is <c>null</c>.</exception> public NamespaceInfo SetNamespaceDefaultPage(NamespaceInfo nspace, PageInfo page) { if( nspace==null) throw new ArgumentNullException("nspace"); // Namespace existence is verified by the affected rows (should be 1) ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); if(page != null && GetPage(transaction, page.FullName) == null) { RollbackTransaction(transaction); return null; } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Namespace", new string[] { "DefaultPage" }, new string[] { "DefaultPage" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); List<Parameter> parameters = new List<Parameter>(2); if(page == null) parameters.Add(new Parameter(ParameterType.String, "DefaultPage", DBNull.Value)); else parameters.Add(new Parameter(ParameterType.String, "DefaultPage", NameTools.GetLocalName(page.FullName))); parameters.Add(new Parameter(ParameterType.String, "Name", nspace.Name)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) { CommitTransaction(transaction); return new NamespaceInfo(nspace.Name, this, page); } else { RollbackTransaction(transaction); return null; } }
/// <summary> /// Renames or moves a Directory. /// </summary> /// <param name="transaction">The current transaction to use.</param> /// <param name="oldFullPath">The old full path of the Directory.</param> /// <param name="newFullPath">The new full path of the Directory.</param> /// <returns><c>true</c> if the Directory is renamed, <c>false</c> otherwise.</returns> private bool RenameDirectory(DbTransaction transaction, string oldFullPath, string newFullPath) { string[] directories = ListDirectories(transaction, oldFullPath); foreach(string dir in directories) { string trimmed = dir.Trim('/'); string name = trimmed.Substring(trimmed.LastIndexOf("/") + 1); string newFullPathSub = PrepareDirectory(newFullPath + name); RenameDirectory(dir, newFullPathSub); } ICommandBuilder builder = GetCommandBuilder(); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Directory", new string[] { "FullPath" }, new string[] { "NewDirectory1" }); query = queryBuilder.Where(query, "FullPath", WhereOperator.Equals, "OldDirectory1"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "NewDirectory1", newFullPath)); parameters.Add(new Parameter(ParameterType.String, "OldDirectory1", oldFullPath)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); return rows > 0; }
/// <summary> /// Updates all outgoing links data for a page rename. /// </summary> /// <param name="oldName">The old page name.</param> /// <param name="newName">The new page name.</param> /// <returns><c>true</c> if the data is updated, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">If <b>oldName</b> or <b>newName</b> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <b>oldName</b> or <b>newName</b> are empty.</exception> public bool UpdateOutgoingLinksForRename(string oldName, string newName) { if(oldName == null) throw new ArgumentNullException("oldName"); if(oldName.Length == 0) throw new ArgumentException("Old Name cannot be empty", "oldName"); if(newName == null) throw new ArgumentNullException("newName"); if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName"); // 1. Rename sources // 2. Rename destinations ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("OutgoingLink", new string[] { "Source" }, new string[] { "NewSource" }); query = queryBuilder.Where(query, "Source", WhereOperator.Equals, "OldSource"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "NewSource", newName)); parameters.Add(new Parameter(ParameterType.String, "OldSource", oldName)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == -1) { RollbackTransaction(transaction); return false; } bool somethingUpdated = rows > 0; query = queryBuilder.Update("OutgoingLink", new string[] { "Destination" }, new string[] { "NewDestination" }); query = queryBuilder.Where(query, "Destination", WhereOperator.Equals, "OldDestination"); parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "NewDestination", newName)); parameters.Add(new Parameter(ParameterType.String, "OldDestination", oldName)); command = builder.GetCommand(transaction, query, parameters); rows = ExecuteNonQuery(command, false); if(rows >= 0) CommitTransaction(transaction); else RollbackTransaction(transaction); return somethingUpdated || rows > 0; }
/// <summary> /// Moves a page from its namespace into another. /// </summary> /// <param name="page">The page to move.</param> /// <param name="destination">The destination namespace (<c>null</c> for the root).</param> /// <param name="copyCategories">A value indicating whether to copy the page categories in the destination /// namespace, if not already available.</param> /// <returns>The correct instance of <see cref="T:PageInfo"/>.</returns> /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <c>null</c>.</exception> public PageInfo MovePage(PageInfo page, NamespaceInfo destination, bool copyCategories) { if(page == null) throw new ArgumentNullException("page"); // Check: // 1. Same namespace - ROOT, SUB (explicit check) // 2. Destination existence (update query affects 0 rows because it would break a FK) // 3. Page existence in target (update query affects 0 rows because it would break a FK) // 4. Page is default page of its namespace (explicit check) string destinationName = destination != null ? destination.Name : " "; string sourceName = null; string pageName = null; NameTools.ExpandFullName(page.FullName, out sourceName, out pageName); if(sourceName == null) sourceName = " "; ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); if(destinationName.ToLowerInvariant() == sourceName.ToLowerInvariant()) return null; if(IsDefaultPage(transaction, page)) { RollbackTransaction(transaction); return null; } PageContent currentContent = GetContent(transaction, page, CurrentRevision); if(currentContent != null) { UnindexPage(currentContent, transaction); foreach(Message msg in GetMessages(transaction, page)) { UnindexMessageTree(page, msg, transaction); } } CategoryInfo[] currCategories = GetCategories(transaction, (sourceName == " "||sourceName=="") ? null : GetNamespace(transaction, sourceName)); // Remove bindings RebindPage(transaction, page, new string[0]); string[] newCategories = new string[0]; if(copyCategories) { // Retrieve categories for page // Copy missing ones in destination string lowerPageName = page.FullName.ToLowerInvariant(); List<string> pageCategories = new List<string>(10); foreach(CategoryInfo cat in currCategories) { if(Array.Find(cat.Pages, (s) => { return s.ToLowerInvariant() == lowerPageName; }) != null) { pageCategories.Add(NameTools.GetLocalName(cat.FullName)); } } // Create categories into destination without checking existence (AddCategory will return null) string tempName = destinationName == " " ? null : destinationName; newCategories = new string[pageCategories.Count]; for(int i = 0; i < pageCategories.Count; i++) { string catName = NameTools.GetFullName(tempName, pageCategories[i]); if(GetCategory(transaction, catName) == null) { CategoryInfo added = AddCategory(tempName, pageCategories[i]); } newCategories[i] = catName; } } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("Page", new string[] { "Namespace" }, new string[] { "Destination" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Source"); List<Parameter> parameters = new List<Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "Destination", destinationName)); parameters.Add(new Parameter(ParameterType.String, "Name", pageName)); parameters.Add(new Parameter(ParameterType.String, "Source", sourceName)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows > 0) { PageInfo result = new PageInfo(NameTools.GetFullName(destinationName, pageName), this, page.CreationDateTime); // Re-bind categories if(copyCategories) { bool rebound = RebindPage(transaction, result, newCategories); if(!rebound) { RollbackTransaction(transaction); return null; } } PageContent newContent = GetContent(transaction, result, CurrentRevision); IndexPage(newContent, transaction); foreach(Message msg in GetMessages(transaction, result)) { IndexMessageTree(result, msg, transaction); } CommitTransaction(transaction); return result; } else { RollbackTransaction(transaction); return null; } }
/// <summary> /// Sets the status of a plugin. /// </summary> /// <param name="typeName">The Type name of the plugin.</param> /// <param name="enabled">The plugin status.</param> /// <returns><c>true</c> if the status is stored, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">If <b>typeName</b> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <b>typeName</b> is empty.</exception> public bool SetPluginStatus(string typeName, bool enabled) { if(typeName == null) throw new ArgumentNullException("typeName"); if(typeName.Length == 0) throw new ArgumentException("Type Name cannot be empty", "typeName"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); PreparePluginStatusRow(transaction, typeName); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.Update("PluginStatus", new string[] { "Enabled" }, new string[] { "Enabled" }); query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name"); List<Parameter> parameters = new List<Parameter>(2); parameters.Add(new Parameter(ParameterType.Int32, "Enabled", enabled?1:0)); parameters.Add(new Parameter(ParameterType.String, "Name", typeName)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) CommitTransaction(transaction); else RollbackTransaction(transaction); return rows == 1; }
/// <summary> /// Modifies a User. /// </summary> /// <param name="user">The Username of the user to modify.</param> /// <param name="newDisplayName">The new display name (can be <c>null</c>).</param> /// <param name="newPassword">The new Password (<c>null</c> or blank to keep the current password).</param> /// <param name="newEmail">The new Email address.</param> /// <param name="newActive">A value indicating whether the account is active.</param> /// <returns>The correct <see cref="T:UserInfo"/> object or <c>null</c>.</returns> /// <exception cref="ArgumentNullException">If <b>user</b> or <b>newEmail</b> are <c>null</c>.</exception> /// <exception cref="ArgumentException">If <b>newEmail</b> is empty.</exception> public UserInfo ModifyUser(UserInfo user, string newDisplayName, string newPassword, string newEmail, bool newActive) { if(user == null) throw new ArgumentNullException("user"); if(newEmail == null) throw new ArgumentNullException("newEmail"); if(newEmail.Length == 0) throw new ArgumentException("New Email cannot be empty", "newEmail"); ICommandBuilder builder = GetCommandBuilder(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = ""; if(string.IsNullOrEmpty(newPassword)) { query = queryBuilder.Update("User", new string[] { "DisplayName", "Email", "Active", }, new string[] { "DisplayName", "Email", "Active", }); } else { query = queryBuilder.Update("User", new string[] { "PasswordHash", "DisplayName", "Email", "Active", }, new string[] { "PasswordHash", "DisplayName", "Email", "Active", }); } query = queryBuilder.Where(query, "Username", WhereOperator.Equals, "Username"); List<Parameter> parameters = new List<Parameter>(5); if(!string.IsNullOrEmpty(newPassword)) { parameters.Add(new Parameter(ParameterType.String, "PasswordHash", Hash.Compute(newPassword))); } if(string.IsNullOrEmpty(newDisplayName)) parameters.Add(new Parameter(ParameterType.String, "DisplayName", DBNull.Value)); else parameters.Add(new Parameter(ParameterType.String, "DisplayName", newDisplayName)); parameters.Add(new Parameter(ParameterType.String, "Email", newEmail)); parameters.Add(new Parameter(ParameterType.Int32, "Active", newActive?1:0)); parameters.Add(new Parameter(ParameterType.String, "Username", user.Username)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = ExecuteNonQuery(command, false); if(rows == 1) { UserInfo result = new UserInfo(user.Username, newDisplayName, newEmail, newActive, user.DateTime, this); result.Groups = GetUserGroups(transaction, user.Username); CommitTransaction(transaction); return result; } else { RollbackTransaction(transaction); return null; } }