InsertInto() public method

Builds an INSERT INTO query.
public InsertInto ( string table, string columns, string parameters ) : string
table string The destination table.
columns string The columns names.
parameters string The parameters names.
return string
Esempio n. 1
0
        /// <summary>
        /// Records a message to the System Log.
        /// </summary>
        /// <param name="message">The Log Message.</param>
        /// <param name="entryType">The Type of the Entry.</param>
        /// <param name="user">The User.</param>
        /// <param name="wiki">The wiki, <c>null</c> if is an application level log.</param>
        /// <remarks>This method <b>should not</b> write messages to the Log using the method IHost.LogEntry.
        /// This method should also never throw exceptions (except for parameter validation).</remarks>
        /// <exception cref="ArgumentNullException">If <b>message</b> or <b>user</b> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <b>message</b> or <b>user</b> are empty.</exception>
        public void LogEntry(string message, EntryType entryType, string user, string wiki)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (message.Length == 0)
            {
                throw new ArgumentException("Message cannot be empty", "message");
            }
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }
            if (user.Length == 0)
            {
                throw new ArgumentException("User cannot be empty", "user");
            }

            ICommandBuilder builder      = GetCommandBuilder();
            QueryBuilder    queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.InsertInto("Log",
                                                   new string[] { "DateTime", "EntryType", "User", "Message", "Wiki" }, new string[] { "DateTime", "EntryType", "User", "Message", "Wiki" });

            List <Parameter> parameters = new List <Parameter>(5);

            parameters.Add(new Parameter(ParameterType.DateTime, "DateTime", DateTime.UtcNow));
            parameters.Add(new Parameter(ParameterType.Char, "EntryType", EntryTypeToChar(entryType)));
            parameters.Add(new Parameter(ParameterType.String, "User", Sanitize(user)));
            parameters.Add(new Parameter(ParameterType.String, "Message", Sanitize(message)));
            parameters.Add(new Parameter(ParameterType.String, "Wiki", string.IsNullOrEmpty(wiki) ? "" : Sanitize(wiki)));

            try {
                DbCommand command = builder.GetCommand(connString, query, parameters);

                int rows = ExecuteNonQuery(command, true, false);

                // No transaction - accurate log sizing is not really a concern

                if (rows > -1)
                {
                    int logSize = LogSize;
                    if (logSize > int.Parse(host.GetGlobalSettingValue(GlobalSettingName.MaxLogSize)))
                    {
                        CutLog((int)(logSize * 0.75));
                    }
                }
            }
            catch { }
        }
Esempio n. 2
0
        /// <summary>
        /// Obtains the lock.
        /// </summary>
        /// <returns><c>true</c> if the lock has been obtained, <c>false</c> otherwise.</returns>
        public override bool Obtain()
        {
            ICommandBuilder builder     = _sqlStorageProviderUtility.GetCommandBuilder2();
            DbConnection    connection  = builder.GetConnection(_connString);
            DbTransaction   transaction = _sqlStorageProviderUtility.BeginTransaction(connection);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("SearchIndexLock");

            query = queryBuilder.Where(query, "Wiki", WhereOperator.Equals, "Wiki");
            query = queryBuilder.AndWhere(query, "Name", WhereOperator.Equals, "Name");

            List <Parameter> parameters = new List <Parameter>(2);

            parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki));
            parameters.Add(new Parameter(ParameterType.String, "Name", _name));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false);

            if (rows != 0)
            {
                _sqlStorageProviderUtility.RollbackTransaction(transaction);
                return(false);                // Deletion command failed (0 is the only accepted value)
            }

            query = queryBuilder.InsertInto("SearchIndexLock",
                                            new string[] { "wiki", "Name", "Value" }, new string[] { "Wiki", "Name", "Value" });
            parameters = new List <Parameter>(3);
            parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki));
            parameters.Add(new Parameter(ParameterType.String, "Name", _name));
            parameters.Add(new Parameter(ParameterType.String, "Value", "locked"));

            command = builder.GetCommand(transaction, query, parameters);

            rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false);

            if (rows == 1)
            {
                _sqlStorageProviderUtility.CommitTransaction(transaction);
            }
            else
            {
                _sqlStorageProviderUtility.RollbackTransaction(transaction);
            }

            return(rows == 1);
        }
        /// <summary>
        /// Binds a Page with one or more Categories.
        /// </summary>
        /// <param name="connection">A database connection.</param>
        /// <param name="page">The Page to bind.</param>
        /// <param name="categories">The Categories to bind the Page with.</param>
        /// <returns>True if the binding succeeded.</returns>
        /// <remarks>After a successful operation, the Page is bound with all and only the categories passed as argument.</remarks>
        private bool RebindPage(DbConnection connection, PageInfo page, string[] categories)
        {
            string nspace, name;
            NameTools.ExpandFullName(page.FullName, out nspace, out name);
            if(nspace == null) nspace = "";

            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("CategoryBinding");
            query = queryBuilder.Where(query, "Page", WhereOperator.Equals, "Page");
            query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace");

            List<Parameter> parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Page", name));
            parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace));

            DbCommand command = builder.GetCommand(connection, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows < 0) return false;

            if(categories.Length > 0) {
                string finalQuery = "";
                parameters = new List<Parameter>(categories.Length * 3);
                int count = 0;
                string countString;

                foreach(string cat in categories) {
                    countString = count.ToString();

                    query = queryBuilder.InsertInto("CategoryBinding", new string[] { "Namespace", "Category", "Page" },
                        new string[] { "Namespace" + countString, "Category" + countString, "Page" + countString });
                    finalQuery = queryBuilder.AppendForBatch(finalQuery, query);

                    parameters.Add(new Parameter(ParameterType.String, "Namespace" + countString, nspace));
                    parameters.Add(new Parameter(ParameterType.String, "Category" + countString, NameTools.GetLocalName(cat)));
                    parameters.Add(new Parameter(ParameterType.String, "Page" + countString, name));

                    count++;
                }

                command = builder.GetCommand(connection, finalQuery, parameters);

                rows = ExecuteNonQuery(command, false);

                return rows == categories.Length;
            }
            else return true;
        }
        /// <summary>
        /// Removes all messages for a page and stores the new messages.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="messages">The new messages to store.</param>
        /// <returns><c>true</c> if the messages are stored, <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="page"/> or <paramref name="messages"/> are <c>null</c>.</exception>
        public bool BulkStoreMessages(PageInfo page, Message[] messages)
        {
            if(page == null) throw new ArgumentNullException("page");
            if(messages == null) throw new ArgumentNullException("messages");

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            if(GetPage(transaction, page.FullName) == null) {
                RollbackTransaction(transaction);
                return false;
            }

            foreach(Message msg in GetMessages(transaction, page)) {
                UnindexMessageTree(page, msg, transaction);
            }

            string nspace, name;
            NameTools.ExpandFullName(page.FullName, out nspace, out name);
            if(nspace == null) nspace = "";

            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");

            List<Parameter> parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Page", name));
            parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            ExecuteNonQuery(command, false);

            List<Message> allMessages;
            List<int> parents;

            UnTreeMessages(messages, out allMessages, out parents, -1);

            string finalQuery = "";
            int count = 1;
            string countString;
            parameters = new List<Parameter>(MaxStatementsInBatch * 8);

            int rowsDone = 0;

            for(int i = 0; i < allMessages.Count; i++) {
                // Execute the batch in smaller chunks

                Message msg = allMessages[i];
                int parent = parents[i];

                countString = count.ToString();

                query = queryBuilder.InsertInto("Message", new string[] { "Page", "Namespace", "Id", "Parent", "Username", "Subject", "DateTime", "Body" },
                    new string[] { "Page" + countString, "Namespace" + countString, "Id" + countString, "Parent" + countString, "Username" + countString, "Subject" + countString, "DateTime" + countString, "Body" + countString });

                parameters.Add(new Parameter(ParameterType.String, "Page" + countString, name));
                parameters.Add(new Parameter(ParameterType.String, "Namespace" + countString, nspace));
                parameters.Add(new Parameter(ParameterType.Int16, "Id" + countString, (short)msg.ID));
                if(parent != -1) parameters.Add(new Parameter(ParameterType.Int16, "Parent" + countString, parent));
                else parameters.Add(new Parameter(ParameterType.Int16, "Parent" + countString, DBNull.Value));
                parameters.Add(new Parameter(ParameterType.String, "Username" + countString, msg.Username));
                parameters.Add(new Parameter(ParameterType.String, "Subject" + countString, msg.Subject));
                parameters.Add(new Parameter(ParameterType.DateTime, "DateTime" + countString, msg.DateTime));
                parameters.Add(new Parameter(ParameterType.String, "Body" + countString, msg.Body));

                finalQuery = queryBuilder.AppendForBatch(finalQuery, query);

                count++;

                if(count == MaxStatementsInBatch) {
                    command = builder.GetCommand(transaction, finalQuery, parameters);

                    rowsDone += ExecuteNonQuery(command, false);

                    finalQuery = "";
                    count = 1;
                    parameters.Clear();
                }
            }

            if(finalQuery.Length > 0) {
                command = builder.GetCommand(transaction, finalQuery, parameters);

                rowsDone += ExecuteNonQuery(command, false);
            }

            if(rowsDone == allMessages.Count) {
                foreach(Message msg in messages) {
                    IndexMessageTree(page, msg, transaction);
                }
                CommitTransaction(transaction);
                return true;
            }
            else {
                RollbackTransaction(transaction);
                return false;
            }
        }
        /// <summary>
        /// Adds a new Navigation Path.
        /// </summary>
        /// <param name="transaction">A database transaction.</param>
        /// <param name="nspace">The target namespace (<c>null</c> for the root).</param>
        /// <param name="name">The Name of the Path.</param>
        /// <param name="pages">The Pages array.</param>
        /// <returns>The correct <see cref="T:NavigationPath"/> object.</returns>
        private NavigationPath AddNavigationPath(DbTransaction transaction, string nspace, string name, PageInfo[] pages)
        {
            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query, finalQuery = "";
            List<Parameter> parameters = new List<Parameter>(3 * pages.Length);
            int count = 0;
            string countString;

            foreach(PageInfo page in pages) {
                countString = count.ToString();

                query = queryBuilder.InsertInto("NavigationPath", new string[] { "Name", "Namespace", "Page", "Number" },
                    new string[] { "Name" + countString, "Namespace" + countString, "Page" + countString, "Number" + countString });

                parameters.Add(new Parameter(ParameterType.String, "Name" + countString, name));
                parameters.Add(new Parameter(ParameterType.String, "Namespace" + countString, nspace));
                parameters.Add(new Parameter(ParameterType.String, "Page" + countString, NameTools.GetLocalName(page.FullName)));
                parameters.Add(new Parameter(ParameterType.Int32, "Number" + countString, (short)count));

                finalQuery = queryBuilder.AppendForBatch(finalQuery, query);

                count++;
            }

            DbCommand command = builder.GetCommand(transaction, finalQuery, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows == pages.Length) {
                NavigationPath result = new NavigationPath(NameTools.GetFullName(nspace, name), this);
                result.Pages = Array.ConvertAll<PageInfo, string>(pages, (x) => { return x.FullName; });
                return result;
            }
            else return null;
        }
        /// <summary>
        /// Adds a new namespace.
        /// </summary>
        /// <param name="name">The name of the namespace.</param>
        /// <returns>The correct <see cref="T:NamespaceInfo"/> object.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="name"/> is empty.</exception>
        public NamespaceInfo AddNamespace(string name)
        {
            if(name == null) throw new ArgumentNullException("name");
            if(name.Length == 0) throw new ArgumentException("Name cannot be empty", "name");

            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.InsertInto("Namespace", new string[] { "Name" }, new string[] { "Name" });

            List<Parameter> parameters = new List<Parameter>(1);
            parameters.Add(new Parameter(ParameterType.String, "Name", name));

            DbCommand command = builder.GetCommand(connString, query, parameters);

            int rows = ExecuteNonQuery(command);

            if(rows == 1) return new NamespaceInfo(name, this, null);
            else return null;
        }
        /// <summary>
        /// Adds a new Message to a Page.
        /// </summary>
        /// <param name="page">The Page.</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>
        /// <param name="parent">The Parent Message ID, or -1.</param>
        /// <returns>True if the Message is added 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="ArgumentException">If <paramref name="username"/> or <paramref name="subject"/> are empty.</exception>
        /// <exception cref="ArgumentOutOfRangeException">If <paramref name="parent"/> is less than -1.</exception>
        public bool AddMessage(PageInfo page, string username, string subject, DateTime dateTime, string body, int parent)
        {
            if(page == null) throw new ArgumentNullException("page");
            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
            if(parent < -1) throw new ArgumentOutOfRangeException("parent", "Invalid Parent Message ID");

            string nspace, name;
            NameTools.ExpandFullName(page.FullName, out nspace, out name);
            if(nspace == null) nspace = "";

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            if(parent != -1 && FindMessage(GetMessages(transaction, page), parent) == null) {
                RollbackTransaction(transaction);
                return false;
            }

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            short freeId = -1;

            string query = queryBuilder.SelectFrom("Message", new string[] { "Id" });
            query = queryBuilder.Where(query, "Page", WhereOperator.Equals, "Page");
            query = queryBuilder.AndWhere(query, "Namespace", WhereOperator.Equals, "Namespace");
            query = queryBuilder.OrderBy(query, new string[] { "Id" }, new Ordering[] { Ordering.Desc });

            List<Parameter> parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Page", name));
            parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            freeId = ExecuteScalar<short>(command, -1, false);

            if(freeId == -1) freeId = 0;
            else freeId++;

            query = queryBuilder.InsertInto("Message", new string[] { "Page", "Namespace", "Id", "Parent", "Username", "Subject", "DateTime", "Body" },
                new string[] { "Page", "Namespace", "Id", "Parent", "Username", "Subject", "DateTime", "Body" });

            parameters = new List<Parameter>(8);
            parameters.Add(new Parameter(ParameterType.String, "Page", name));
            parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace));
            parameters.Add(new Parameter(ParameterType.Int16, "Id", freeId));
            if(parent != -1) parameters.Add(new Parameter(ParameterType.Int16, "Parent", parent));
            else parameters.Add(new Parameter(ParameterType.Int16, "Parent", DBNull.Value));
            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));

            command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows == 1) {
                IndexMessage(page, freeId, subject, dateTime, body, transaction);

                CommitTransaction(transaction);
                return true;
            }
            else {
                RollbackTransaction(transaction);
                return false;
            }
        }
        /// <summary>
        /// Stores a Page Attachment.
        /// </summary>
        /// <param name="pageInfo">The Page Info that owns the Attachment.</param>
        /// <param name="name">The name of the Attachment, for example "myfile.jpg".</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 Attachment.</param>
        /// <returns><c>true</c> if the Attachment is stored, <c>false</c> otherwise.</returns>
        /// <remarks>If <b>overwrite</b> is <c>false</c> and Attachment already exists, the method returns <c>false</c>.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="pageInfo"/>, <paramref name="name"/> or <paramref name="sourceStream"/> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="name"/> is empty or if <paramref name="sourceStream"/> does not support reading.</exception>
        public bool StorePageAttachment(PageInfo pageInfo, string name, System.IO.Stream sourceStream, bool overwrite)
        {
            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", "name");
            if(sourceStream == null) throw new ArgumentNullException("sourceStream");
            if(!sourceStream.CanRead) throw new ArgumentException("Cannot read from Source Stream", "sourceStream");

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            bool attachmentExists = AttachmentExists(transaction, pageInfo, name);

            if(attachmentExists && !overwrite) {
                RollbackTransaction(transaction);
                return false;
            }

            // To achieve decent performance, an UPDATE query is issued if the attachment exists,
            // otherwise an INSERT query is issued

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query;
            List<Parameter> parameters;

            byte[] attachmentData = null;
            int size = Tools.ReadStream(sourceStream, ref attachmentData, MaxFileSize);
            if(size < 0) {
                RollbackTransaction(transaction);
                throw new ArgumentException("Source Stream contains too much data", "sourceStream");
            }

            if(attachmentExists) {
                query = queryBuilder.Update("Attachment", new string[] { "Size", "LastModified", "Data" }, new string[] { "Size", "LastModified", "Data" });
                query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name");
                query = queryBuilder.AndWhere(query, "Page", WhereOperator.Equals, "Page");

                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", attachmentData));
                parameters.Add(new Parameter(ParameterType.String, "Name", name));
                parameters.Add(new Parameter(ParameterType.String, "Page", pageInfo.FullName));
            }
            else {
                query = queryBuilder.InsertInto("Attachment", new string[] { "Name", "Page", "Size", "Downloads", "LastModified", "Data" },
                    new string[] { "Name", "Page", "Size", "Downloads", "LastModified", "Data" });

                parameters = new List<Parameter>(6);
                parameters.Add(new Parameter(ParameterType.String, "Name", name));
                parameters.Add(new Parameter(ParameterType.String, "Page", pageInfo.FullName));
                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", attachmentData));
            }

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);
            if(rows == 1) CommitTransaction(transaction);
            else RollbackTransaction(transaction);

            return rows == 1;
        }
        /// <summary>
        /// Stores the outgoing links of a page, overwriting existing data.
        /// </summary>
        /// <param name="page">The full name of the page.</param>
        /// <param name="outgoingLinks">The full names of the pages that <b>page</b> links to.</param>
        /// <returns><c>true</c> if the outgoing links are stored, <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">If <b>page</b> or <b>outgoingLinks</b> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <b>page</b> or <b>outgoingLinks</b> are empty.</exception>
        public bool StoreOutgoingLinks(string page, string[] outgoingLinks)
        {
            if(page == null) throw new ArgumentNullException("page");
            if(page.Length == 0) throw new ArgumentException("Page cannot be empty", "page");
            if(outgoingLinks == null) throw new ArgumentNullException("outgoingLinks");

            foreach(string link in outgoingLinks) {
                if(link == null) throw new ArgumentNullException("outgoingLinks");
                if(link.Length == 0) throw new ArgumentException("Link cannot be empty", "outgoingLinks");
            }

            // 1. Delete old values, if any
            // 2. Store new values

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("OutgoingLink");
            query = queryBuilder.Where(query, "Source", WhereOperator.Equals, "Source");

            List<Parameter> parameters = new List<Parameter>(1);
            parameters.Add(new Parameter(ParameterType.String, "Source", page));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            if(ExecuteNonQuery(command, false) < 0) {
                RollbackTransaction(transaction);
                return false;
            }

            foreach(string link in outgoingLinks) {
                query = queryBuilder.InsertInto("OutgoingLink", new string[] { "Source", "Destination" }, new string[] { "Source", "Destination" });

                parameters = new List<Parameter>(2);
                parameters.Add(new Parameter(ParameterType.String, "Source", page));
                parameters.Add(new Parameter(ParameterType.String, "Destination", link));

                command = builder.GetCommand(transaction, query, parameters);

                int rows = ExecuteNonQuery(command, false);

                if(rows != 1) {
                    RollbackTransaction(transaction);
                    return false;
                }
            }

            CommitTransaction(transaction);
            return true;
        }
        /// <summary>
        /// Stores the value of a Setting.
        /// </summary>
        /// <param name="name">The name of the Setting.</param>
        /// <param name="value">The value of the Setting. Value cannot contain CR and LF characters, which will be removed.</param>
        /// <returns>True if the Setting is stored, false otherwise.</returns>
        /// <remarks>This method stores the Value immediately.</remarks>
        public bool SetSetting(string name, string value)
        {
            if(name == null) throw new ArgumentNullException("name");
            if(name.Length == 0) throw new ArgumentException("Name cannot be empty", "name");

            // 1. Delete old value, if any
            // 2. Store new value

            // Nulls are converted to empty strings
            if(value == null) value = "";

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("Setting");
            query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name");

            List<Parameter> parameters = new List<Parameter>(1);
            parameters.Add(new Parameter(ParameterType.String, "Name", name));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows == -1) {
                RollbackTransaction(transaction);
                return false; // Deletion command failed (0-1 are OK)
            }

            query = queryBuilder.InsertInto("Setting",
                new string[] { "Name", "Value" }, new string[] { "Name", "Value" });
            parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Name", name));
            parameters.Add(new Parameter(ParameterType.String, "Value", value));

            command = builder.GetCommand(transaction, query, parameters);

            rows = ExecuteNonQuery(command, false);

            if(rows == 1) CommitTransaction(transaction);
            else RollbackTransaction(transaction);

            return rows == 1;
        }
        /// <summary>
        /// Sets a meta-data items' content.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="tag">The tag that specifies the context (usually the namespace).</param>
        /// <param name="content">The content.</param>
        /// <returns><c>true</c> if the content is set, <c>false</c> otherwise.</returns>
        public bool SetMetaDataItem(MetaDataItem item, string tag, string content)
        {
            if(tag == null) tag = "";
            if(content == null) content = "";

            // 1. Delete old value, if any
            // 2. Store new value

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("MetaDataItem");
            query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name");
            query = queryBuilder.AndWhere(query, "Tag", WhereOperator.Equals, "Tag");

            List<Parameter> parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Name", item.ToString()));
            parameters.Add(new Parameter(ParameterType.String, "Tag", tag));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows == -1) {
                RollbackTransaction(transaction);
                return false;
            }

            query = queryBuilder.InsertInto("MetaDataItem", new string[] { "Name", "Tag", "Data" }, new string[] { "Name", "Tag", "Content" });

            parameters = new List<Parameter>(3);
            parameters.Add(new Parameter(ParameterType.String, "Name", item.ToString()));
            parameters.Add(new Parameter(ParameterType.String, "Tag", tag));
            parameters.Add(new Parameter(ParameterType.String, "Content", content));

            command = builder.GetCommand(transaction, query, parameters);

            rows = ExecuteNonQuery(command, false);

            if(rows == 1) CommitTransaction(transaction);
            else RollbackTransaction(transaction);

            return rows == 1;
        }
        /// <summary>
        /// Records a message to the System Log.
        /// </summary>
        /// <param name="message">The Log Message.</param>
        /// <param name="entryType">The Type of the Entry.</param>
        /// <param name="user">The User.</param>
        /// <remarks>This method <b>should not</b> write messages to the Log using the method IHost.LogEntry.
        /// This method should also never throw exceptions (except for parameter validation).</remarks>
        /// <exception cref="ArgumentNullException">If <b>message</b> or <b>user</b> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <b>message</b> or <b>user</b> are empty.</exception>
        public void LogEntry(string message, EntryType entryType, string user)
        {
            if(message == null) throw new ArgumentNullException("message");
            if(message.Length == 0) throw new ArgumentException("Message cannot be empty", "message");
            if(user == null) throw new ArgumentNullException("user");
            if(user.Length == 0) throw new ArgumentException("User cannot be empty", "user");

            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.InsertInto("Log",
                new string[] { "DateTime", "EntryType", "User", "Message" }, new string[] { "DateTime", "EntryType", "User", "Message" });

            List<Parameter> parameters = new List<Parameter>(4);
            parameters.Add(new Parameter(ParameterType.DateTime, "DateTime", DateTime.Now));
            parameters.Add(new Parameter(ParameterType.Char, "EntryType", EntryTypeToChar(entryType)));
            parameters.Add(new Parameter(ParameterType.String, "User", Sanitize(user)));
            parameters.Add(new Parameter(ParameterType.String, "Message", Sanitize(message)));

            try {
                DbCommand command = builder.GetCommand(connString, query, parameters);

                ExecuteNonQuery(command, true);

                // No transaction - accurate log sizing is not really a concern

                int logSize = LogSize;
                if(logSize > int.Parse(host.GetSettingValue(SettingName.MaxLogSize))) {
                    CutLog((int)(logSize * 0.75));
                }
            }
            catch { }
        }
        /// <summary>
        /// Stores a ACL entry.
        /// </summary>
        /// <param name="entry">The entry to store.</param>
        /// <returns><c>true</c> if the entry was stored, <c>false</c> otherwise.</returns>
        private bool StoreEntry(AclEntry entry)
        {
            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.InsertInto("AclEntry", new string[] { "Resource", "Action", "Subject", "Value" }, new string[] { "Resource", "Action", "Subject", "Value" });

            List<Parameter> parameters = new List<Parameter>(3);
            parameters.Add(new Parameter(ParameterType.String, "Resource", entry.Resource));
            parameters.Add(new Parameter(ParameterType.String, "Action", entry.Action));
            parameters.Add(new Parameter(ParameterType.String, "Subject", entry.Subject));
            parameters.Add(new Parameter(ParameterType.Char, "Value", AclEntryValueToChar(entry.Value)));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            if(ExecuteNonQuery(command, false) != 1) {
                RollbackTransaction(transaction);
                return false;
            }

            CommitTransaction(transaction);

            return true;
        }
        /// <summary>
        /// Prepares the plugin status row, if necessary.
        /// </summary>
        /// <param name="transaction">A database transaction.</param>
        /// <param name="typeName">The Type name of the plugin.</param>
        private void PreparePluginStatusRow(DbTransaction transaction, string typeName)
        {
            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.SelectCountFrom("PluginStatus");
            query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name");

            List<Parameter> parameters = new List<Parameter>(1);
            parameters.Add(new Parameter(ParameterType.String, "Name", typeName));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteScalar<int>(command, -1, false);

            if(rows == -1) return;

            if(rows == 0) {
                // Insert a neutral row (enabled, empty config)

                query = queryBuilder.InsertInto("PluginStatus", new string[] { "Name", "Enabled", "Configuration" }, new string[] { "Name", "Enabled", "Configuration" });

                parameters = new List<Parameter>(3);
                parameters.Add(new Parameter(ParameterType.String, "Name", typeName));
                parameters.Add(new Parameter(ParameterType.Boolean, "Enabled", true));
                parameters.Add(new Parameter(ParameterType.String, "Configuration", ""));

                command = builder.GetCommand(transaction, query, parameters);

                ExecuteNonQuery(command, false);
            }
        }
        /// <summary>
        /// Saves data for a new document.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="content">The content words.</param>
        /// <param name="title">The title words.</param>
        /// <param name="keywords">The keywords.</param>
        /// <param name="state">A state object passed from the index (can be <c>null</c> or a <see cref="T:DbTransaction" />).</param>
        /// <returns>The number of stored occurrences.</returns>
        private int SaveDataForDocument(IDocument document, WordInfo[] content, WordInfo[] title, WordInfo[] keywords, object state)
        {
            // 1. Insert document
            // 2. Insert all new words
            // 3. Load all word IDs
            // 4. Insert mappings

            // On error, return without rolling back if state != null, rollback otherwise
            // On completion, commit if state == null

            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            DbTransaction transaction = null;
            if(state != null) transaction = (DbTransaction)state;
            else {
                DbConnection connection = builder.GetConnection(connString);
                transaction = BeginTransaction(connection);
            }

            uint freeDocumentId = GetFreeElementId(IndexElementType.Documents, transaction);
            uint freeWordId = GetFreeElementId(IndexElementType.Words, transaction);

            // Insert the document
            string query = queryBuilder.InsertInto("IndexDocument",
                new string[] { "Id", "Name", "Title", "TypeTag", "DateTime" },
                new string[] { "Id", "Name", "Title", "TypeTag", "DateTime" });

            List<Parameter> parameters = new List<Parameter>(5);
            parameters.Add(new Parameter(ParameterType.Int32, "Id", (int)freeDocumentId));
            parameters.Add(new Parameter(ParameterType.String, "Name", document.Name));
            parameters.Add(new Parameter(ParameterType.String, "Title", document.Title));
            parameters.Add(new Parameter(ParameterType.String, "TypeTag", document.TypeTag));
            parameters.Add(new Parameter(ParameterType.DateTime, "DateTime", document.DateTime));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            if(ExecuteNonQuery(command, false) != 1) {
                if(state == null) RollbackTransaction(transaction);
                return -1;
            }
            document.ID = freeDocumentId;

            List<WordInfo> allWords = new List<WordInfo>(content.Length + title.Length + keywords.Length);
            allWords.AddRange(content);
            allWords.AddRange(title);
            allWords.AddRange(keywords);

            List<WordInfo> existingWords = new List<WordInfo>(allWords.Count / 2);

            Dictionary<string, uint> wordIds = new Dictionary<string, uint>(1024);

            // Try to blindly insert all words (assumed to be lowercase and clean from diacritics)

            query = queryBuilder.InsertInto("IndexWord", new string[] { "Id", "Text" }, new string[] { "Id", "Text" });

            parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.Int32, "Id", 0));
            parameters.Add(new Parameter(ParameterType.String, "Text", ""));

            foreach(WordInfo word in allWords) {
                parameters[0].Value = (int)freeWordId;
                parameters[1].Value = word.Text;

                command = builder.GetCommand(transaction, query, parameters);

                if(ExecuteNonQuery(command, false, false) == 1) {
                    wordIds.Add(word.Text, freeWordId);
                    freeWordId++;
                }
                else {
                    existingWords.Add(word);
                }
            }

            // Load IDs of all existing words
            query = queryBuilder.SelectFrom("IndexWord", new string[] { "Id" });
            query = queryBuilder.Where(query, "Text", WhereOperator.Equals, "Text");

            parameters = new List<Parameter>(1);
            parameters.Add(new Parameter(ParameterType.String, "Text", ""));

            foreach(WordInfo word in existingWords) {
                parameters[0].Value = word.Text;

                command = builder.GetCommand(transaction, query, parameters);

                int id = ExecuteScalar<int>(command, -1, false);
                if(id == -1) {
                    if(state == null) RollbackTransaction(transaction);
                    return -1;
                }

                if(!wordIds.ContainsKey(word.Text)) {
                    wordIds.Add(word.Text, (uint)id);
                }
                else if(wordIds[word.Text] != (uint)id) throw new InvalidOperationException("Word ID mismatch");
            }

            // Insert all mappings
            query = queryBuilder.InsertInto("IndexWordMapping",
                new string[] { "Word", "Document", "FirstCharIndex", "WordIndex", "Location" },
                new string[] { "Word", "Document", "FirstCharIndex", "WordIndex", "Location" });

            parameters = new List<Parameter>(5);
            parameters.Add(new Parameter(ParameterType.Int32, "Word", 0));
            parameters.Add(new Parameter(ParameterType.Int32, "Document", (int)freeDocumentId));
            parameters.Add(new Parameter(ParameterType.Int16, "FirstCharIndex", 0));
            parameters.Add(new Parameter(ParameterType.Int16, "WordIndex", 0));
            parameters.Add(new Parameter(ParameterType.Byte, "Location", 0));

            foreach(WordInfo word in allWords) {
                parameters[0].Value = (int)wordIds[word.Text];
                parameters[1].Value = (int)freeDocumentId;
                parameters[2].Value = (short)word.FirstCharIndex;
                parameters[3].Value = (short)word.WordIndex;
                parameters[4].Value = word.Location.Location;

                command = builder.GetCommand(transaction, query, parameters);

                if(ExecuteNonQuery(command, false) != 1) {
                    if(state == null) RollbackTransaction(transaction);
                    return -1;
                }
            }

            if(state == null) CommitTransaction(transaction);

            return allWords.Count;
        }
        /// <summary>
        /// Stores the content for a revision.
        /// </summary>
        /// <param name="transaction">A database transaction.</param>
        /// <param name="content">The content.</param>
        /// <param name="revision">The revision.</param>
        /// <returns><c>true</c> if the content is stored, <c>false</c> otherwise.</returns>
        private bool SetContent(DbTransaction transaction, PageContent content, int revision)
        {
            string name, nspace;
            NameTools.ExpandFullName(content.PageInfo.FullName, out nspace, out name);
            if(nspace == null) nspace = "";

            ICommandBuilder builder = GetCommandBuilder();
            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.InsertInto("PageContent",
                new string[] { "Page", "Namespace", "Revision", "Title", "User", "LastModified", "Comment", "Content", "Description" },
                new string[] { "Page", "Namespace", "Revision", "Title", "User", "LastModified", "Comment", "Content", "Description" });

            List<Parameter> parameters = new List<Parameter>(9);
            parameters.Add(new Parameter(ParameterType.String, "Page", name));
            parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace));
            parameters.Add(new Parameter(ParameterType.Int16, "Revision", revision));
            parameters.Add(new Parameter(ParameterType.String, "Title", content.Title));
            parameters.Add(new Parameter(ParameterType.String, "User", content.User));
            parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", content.LastModified));
            if(!string.IsNullOrEmpty(content.Comment)) parameters.Add(new Parameter(ParameterType.String, "Comment", content.Comment));
            else parameters.Add(new Parameter(ParameterType.String, "Comment", DBNull.Value));
            parameters.Add(new Parameter(ParameterType.String, "Content", content.Content));
            if(!string.IsNullOrEmpty(content.Description)) parameters.Add(new Parameter(ParameterType.String, "Description", content.Description));
            else parameters.Add(new Parameter(ParameterType.String, "Description", DBNull.Value));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows != 1) return false;

            if(content.Keywords.Length > 0) {
                parameters = new List<Parameter>(content.Keywords.Length * 4);
                string fullQuery = "";
                int count = 0;
                string countString;
                foreach(string kw in content.Keywords) {
                    countString = count.ToString();

                    query = queryBuilder.InsertInto("PageKeyword", new string[] { "Page", "Namespace", "Revision", "Keyword" },
                        new string[] { "Page" + countString, "Namespace" + countString, "Revision" + countString, "Keyword" + countString });
                    fullQuery = queryBuilder.AppendForBatch(fullQuery, query);

                    parameters.Add(new Parameter(ParameterType.String, "Page" + countString, name));
                    parameters.Add(new Parameter(ParameterType.String, "Namespace" + countString, nspace));
                    parameters.Add(new Parameter(ParameterType.Int16, "Revision" + countString, revision));
                    parameters.Add(new Parameter(ParameterType.String, "Keyword" + countString, kw));

                    count++;
                }

                command = builder.GetCommand(transaction, fullQuery, parameters);

                rows = ExecuteNonQuery(command, false);

                return rows == content.Keywords.Length;
            }
            else return true;
        }
Esempio n. 17
0
        /// <summary>
        /// Closes the sql index output.
        /// </summary>
        public override void Close()
        {
            string fileName = _fileName;

            // make sure it's all written out
            _indexOutput.Flush();

            long originalLength = _indexOutput.Length();

            _indexOutput.Close();

            Stream fileStream = new StreamInput(CacheDirectory.OpenInput(fileName));

            try {
                // push the file stream up to the db.
                ICommandBuilder builder     = _sqlStorageProviderUtility.GetCommandBuilder2();
                DbConnection    connection  = builder.GetConnection(_connString);
                DbTransaction   transaction = _sqlStorageProviderUtility.BeginTransaction(connection);

                QueryBuilder queryBuilder = new QueryBuilder(builder);

                //bool fileExists = FileExists(transaction, _wiki, _fileName);

                // 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(fileStream, ref fileData, MaxFileSize);
                if (size < 0)
                {
                    _sqlStorageProviderUtility.RollbackTransaction(transaction);
                    throw new ArgumentException("Source Stream contains too much data", "sourceStream");
                }

                //if(fileExists) {
                //    query = queryBuilder.Update("SearchIndex", new string[] { "Size", "LastModified", "Data" }, new string[] { "Size", "LastModified", "Data" });
                //    query = queryBuilder.Where(query, "Wiki", WhereOperator.Equals, "Wiki");
                //    query = queryBuilder.AndWhere(query, "Name", WhereOperator.Equals, "Name");

                //    parameters = new List<Parameter>(5);
                //    parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki));
                //    parameters.Add(new Parameter(ParameterType.Int64, "Size", (long)originalLength));
                //    parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", DateTime.Now.ToUniversalTime()));
                //    parameters.Add(new Parameter(ParameterType.ByteArray, "Data", fileData));
                //    parameters.Add(new Parameter(ParameterType.String, "Name", _fileName));
                //}
                //else {
                query = queryBuilder.InsertInto("SearchIndex", new string[] { "Wiki", "Name", "Size", "LastModified", "Data" },
                                                new string[] { "Wiki", "Name", "Size", "LastModified", "Data" });

                parameters = new List <Parameter>(5);
                parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki));
                parameters.Add(new Parameter(ParameterType.String, "Name", _fileName));
                parameters.Add(new Parameter(ParameterType.Int64, "Size", (long)originalLength));
                parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", DateTime.Now.ToUniversalTime()));
                parameters.Add(new Parameter(ParameterType.ByteArray, "Data", fileData));
                //}

                DbCommand command = builder.GetCommand(transaction, query, parameters);

                int rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false);
                if (rows == 1)
                {
                    _sqlStorageProviderUtility.CommitTransaction(transaction);
                }
                else
                {
                    _sqlStorageProviderUtility.RollbackTransaction(transaction);
                }
            }
            finally {
                fileStream.Dispose();
            }

            // clean up
            _indexOutput = null;
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// Merges two Categories.
        /// </summary>
        /// <param name="source">The source Category.</param>
        /// <param name="destination">The destination Category.</param>
        /// <returns>The correct <see cref="T:CategoryInfo" /> object.</returns>
        /// <remarks>The destination Category remains, while the source Category is deleted, and all its Pages re-bound 
        /// in the destination Category.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="source"/> or <paramref name="destination"/> are <c>null</c>.</exception>
        public CategoryInfo MergeCategories(CategoryInfo source, CategoryInfo destination)
        {
            if(source == null) throw new ArgumentNullException("source");
            if(destination == null) throw new ArgumentNullException("destination");

            // 1. Check for same namespace
            // 2. Load all pages in source
            // 3. Load all pages in destination
            // 4. Merge lists in memory
            // 5. Delete all destination bindings
            // 6. Delete source cat
            // 7. Insert new bindings stored in memory

            string sourceNs = NameTools.GetNamespace(source.FullName);
            string destinationNs = NameTools.GetNamespace(destination.FullName);

            // If one is null and the other not null, fail
            if(sourceNs == null && destinationNs != null || sourceNs != null && destinationNs == null) return null;
            else {
                // Both non-null or both null
                if(sourceNs != null) {
                    // Both non-null, check names
                    NamespaceInfo tempSource = new NamespaceInfo(sourceNs, this, null);
                    NamespaceInfo tempDest = new NamespaceInfo(destinationNs, this, null);
                    // Different names, fail
                    if(new NamespaceComparer().Compare(tempSource, tempDest) != 0) return null;
                }
                // else both null, OK
            }

            string nspace = sourceNs != null ? sourceNs : "";

            ICommandBuilder builder = GetCommandBuilder();
            DbConnection connection = builder.GetConnection(connString);
            DbTransaction transaction = BeginTransaction(connection);

            CategoryInfo actualSource = GetCategory(transaction, source.FullName);
            CategoryInfo actualDestination = GetCategory(transaction, destination.FullName);

            if(actualSource == null) {
                RollbackTransaction(transaction);
                return null;
            }
            if(actualDestination == null) {
                RollbackTransaction(transaction);
                return null;
            }

            string destinationName = NameTools.GetLocalName(actualDestination.FullName);

            string[] mergedPages = MergeArrays(actualSource.Pages, actualDestination.Pages);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("CategoryBinding");
            query = queryBuilder.Where(query, "Namespace", WhereOperator.Equals, "Namespace");
            query = queryBuilder.AndWhere(query, "Category", WhereOperator.Equals, "Category");

            List<Parameter> parameters = new List<Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Namespace", nspace));
            parameters.Add(new Parameter(ParameterType.String, "Category", destinationName));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if(rows == -1) {
                RollbackTransaction(transaction);
                return null;
            }

            if(!RemoveCategory(transaction, source)) {
                RollbackTransaction(transaction);
                return null;
            }

            string finalQuery = "";
            parameters = new List<Parameter>(MaxStatementsInBatch * 3);
            rows = 0;
            int count = 1;
            string countString;

            foreach(string page in mergedPages) {
                // This batch is executed in small chunks (MaxStatementsInBatch) to avoid exceeding DB's max batch length/size

                countString = count.ToString();

                query = queryBuilder.InsertInto("CategoryBinding", new string[] { "Namespace", "Category", "Page" },
                    new string[] { "Namespace" + countString, "Category" + countString, "Page" + countString });
                finalQuery = queryBuilder.AppendForBatch(finalQuery, query);

                parameters.Add(new Parameter(ParameterType.String, "Namespace" + countString, nspace));
                parameters.Add(new Parameter(ParameterType.String, "Category" + countString, destinationName));
                parameters.Add(new Parameter(ParameterType.String, "Page" + countString, NameTools.GetLocalName(page)));

                count++;

                if(count == MaxStatementsInBatch) {
                    // Batch is complete -> execute
                    command = builder.GetCommand(transaction, finalQuery, parameters);
                    rows += ExecuteNonQuery(command, false);

                    count = 1;
                    finalQuery = "";
                    parameters.Clear();
                }
            }

            if(finalQuery.Length > 0) {
                // Execute remaining queries, if any
                command = builder.GetCommand(transaction, finalQuery, parameters);
                rows += ExecuteNonQuery(command, false);
            }

            if(rows == mergedPages.Length) {
                CommitTransaction(transaction);
                CategoryInfo result = new CategoryInfo(actualDestination.FullName, this);
                result.Pages = mergedPages;
                return result;
            }
            else {
                RollbackTransaction(transaction);
                return null;
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Stores the value of a Setting.
        /// </summary>
        /// <param name="name">The name of the Setting.</param>
        /// <param name="value">The value of the Setting. Value cannot contain CR and LF characters, which will be removed.</param>
        /// <returns>True if the Setting is stored, false otherwise.</returns>
        /// <remarks>This method stores the Value immediately.</remarks>
        public bool SetSetting(string name, string value)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            if (name.Length == 0)
            {
                throw new ArgumentException("Name cannot be empty", "name");
            }

            // 1. Delete old value, if any
            // 2. Store new value

            // Nulls are converted to empty strings
            if (value == null)
            {
                value = "";
            }

            ICommandBuilder builder     = GetCommandBuilder();
            DbConnection    connection  = builder.GetConnection(connString);
            DbTransaction   transaction = BeginTransaction(connection);

            QueryBuilder queryBuilder = new QueryBuilder(builder);

            string query = queryBuilder.DeleteFrom("GlobalSetting");

            query = queryBuilder.Where(query, "Name", WhereOperator.Equals, "Name");

            List <Parameter> parameters = new List <Parameter>(1);

            parameters.Add(new Parameter(ParameterType.String, "Name", name));

            DbCommand command = builder.GetCommand(transaction, query, parameters);

            int rows = ExecuteNonQuery(command, false);

            if (rows == -1)
            {
                RollbackTransaction(transaction);
                return(false);                // Deletion command failed (0-1 are OK)
            }

            query = queryBuilder.InsertInto("GlobalSetting",
                                            new string[] { "Name", "Value" }, new string[] { "Name", "Value" });
            parameters = new List <Parameter>(2);
            parameters.Add(new Parameter(ParameterType.String, "Name", name));
            parameters.Add(new Parameter(ParameterType.String, "Value", value));

            command = builder.GetCommand(transaction, query, parameters);

            rows = ExecuteNonQuery(command, false);

            if (rows == 1)
            {
                CommitTransaction(transaction);
            }
            else
            {
                RollbackTransaction(transaction);
            }

            return(rows == 1);
        }