Ejemplo n.º 1
0
 public void MarkAsRead(Account account)
 {
     if (account.id != this.owner.id)
     {
         throw new AccessDeniedException();
     }
     if (!this.isRead)
     {
         lock (MarkAsRead_locker) {
             //so we can safely decrease ReadPrivateMessages counter
             //Note that this code implicitly uses assumption of single-instance Common.dll; race condition is possible with more than one server
             if (!this.isRead)
             {
                 AccountIndicator indicator = AccountIndicator.LoadByAccount(this.owner);
                 ChangeSetUtil.ApplyChanges(
                     new UpdateChange(
                         TableSpec.instance,
                         new Dictionary <string, AbstractFieldValue> {
                     { TableSpec.FIELD_ISREAD, new ScalarFieldValue("1") },
                 },
                         this.id
                         ),
                     new UpdateChange(
                         AccountIndicator.TableSpec.instance,
                         new Dictionary <string, AbstractFieldValue> {
                     { AccountIndicator.TableSpec.FIELD_UNREADPRIVATEMESSAGES, new IncrementFieldValue(IncrementFieldValue.DECREMENTOR) },
                 },
                         indicator.id
                         )
                     );
             }
         }
     }
 }
Ejemplo n.º 2
0
 public Account createAccount(string code, string name, string password, string ip, string registrationEmail)
 {
     lock (this.createAccount_locker) {
         if (this.isUsed)
         {
             throw new FLocalException("Invite is already used");
         }
         if (this.code != code)
         {
             throw new FLocalException("Wrong code");
         }
         var rawChanges    = Account.getNewAccountChanges(name, password, ip, registrationEmail);
         var accountInsert = rawChanges.Key;
         var changes       = new List <AbstractChange>(rawChanges.Value);
         changes.Add(
             new UpdateChange(
                 TableSpec.instance,
                 new Dictionary <string, AbstractFieldValue> {
             { TableSpec.FIELD_ISUSED, new ScalarFieldValue("1") },
             { TableSpec.FIELD_GUESTID, new ReferenceFieldValue(accountInsert) },
         },
                 this.id
                 )
             );
         ChangeSetUtil.ApplyChanges(changes.ToArray());
         return(Account.LoadById(accountInsert.getId().Value));
     }
 }
Ejemplo n.º 3
0
        public static Poll Create(User poster, bool isDetailed, bool isMultiOption, string titleUbb, List <string> optionsUbb)
        {
            List <XElement> options = new List <XElement>();

            for (int i = 0; i < optionsUbb.Count; i++)
            {
                options.Add(
                    new XElement(
                        "option",
                        new XAttribute("id", i + 1),
                        new XAttribute("name", UBBParser.UBBToIntermediate(optionsUbb[i]))
                        )
                    );
            }
            AbstractChange pollInsert = new InsertChange(
                TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_ISDETAILED, new ScalarFieldValue(isDetailed ? "1" : "0") },
                { TableSpec.FIELD_ISMULTIOPTION, new ScalarFieldValue(isMultiOption ? "1" : "0") },
                { TableSpec.FIELD_POSTERID, new ScalarFieldValue(poster.id.ToString()) },
                { TableSpec.FIELD_POSTDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
                { TableSpec.FIELD_TITLE, new ScalarFieldValue(UBBParser.UBBToIntermediate(titleUbb)) },
                { TableSpec.FIELD_OPTIONS, new ScalarFieldValue((new XElement("options", options)).ToString()) },
            }
                );

            ChangeSetUtil.ApplyChanges(pollInsert);
            return(Poll.LoadById(pollInsert.getId().Value));
        }
Ejemplo n.º 4
0
 public void UpdateData(UserData newData)
 {
     if (newData.location.Length > 30)
     {
         throw new FLocalException("Location is too long");
     }
     if (newData.title.Length > 30)
     {
         throw new FLocalException("Title is too long");
     }
     if (newData.signatureUbb.Length > 1024)
     {
         throw new FLocalException("Signature is too long");
     }
     ChangeSetUtil.ApplyChanges(
         new UpdateChange(
             TableSpec.instance,
             new Dictionary <string, AbstractFieldValue> {
         { TableSpec.FIELD_LOCATION, new ScalarFieldValue(newData.location) },
         { TableSpec.FIELD_TITLE, new ScalarFieldValue(newData.title) },
         { TableSpec.FIELD_BIOGRAPHYUBB, new ScalarFieldValue(newData.biographyUbb) },
         { TableSpec.FIELD_BIOGRAPHY, new ScalarFieldValue(UBBParser.UBBToIntermediate(newData.biographyUbb)) },
         { TableSpec.FIELD_SIGNATUREUBB, new ScalarFieldValue(newData.signatureUbb) },
         { TableSpec.FIELD_SIGNATURE, new ScalarFieldValue(UBBParser.UBBToIntermediate(newData.signatureUbb)) },
     },
             this.id
             )
         );
 }
Ejemplo n.º 5
0
 public void markAsRead(Account account)
 {
     if (this.lastPostId.HasValue)
     {
         ChangeSetUtil.ApplyChanges(
             new InsertOrUpdateChange(
                 ReadMarkerTableSpec.instance,
                 new Dictionary <string, AbstractFieldValue> {
             { ReadMarkerTableSpec.FIELD_BOARDID, new ScalarFieldValue(this.id.ToString()) },
             { ReadMarkerTableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) },
             { ReadMarkerTableSpec.FIELD_LASTREADDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
         },
                 new Dictionary <string, AbstractFieldValue> {
             { ReadMarkerTableSpec.FIELD_LASTREADDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
         },
                 new ComplexCondition(
                     ConditionsJoinType.AND,
                     new ComparisonCondition(
                         ReadMarkerTableSpec.instance.getColumnSpec(ReadMarkerTableSpec.FIELD_BOARDID),
                         ComparisonType.EQUAL,
                         this.id.ToString()
                         ),
                     new ComparisonCondition(
                         ReadMarkerTableSpec.instance.getColumnSpec(ReadMarkerTableSpec.FIELD_ACCOUNTID),
                         ComparisonType.EQUAL,
                         account.id.ToString()
                         )
                     )
                 )
             );
     }
 }
Ejemplo n.º 6
0
        public static void Save(Account account, int postsPerPage, int threadsPerPage, int usersPerPage, int uploadsPerPage, Skin skin, ModernSkin modernSkin, Machichara machichara, int maxUploadImageWidth, int maxUploadImageHeight)
        {
            Dictionary <string, AbstractFieldValue> dataToUpdate = new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_POSTSPERPAGE, new ScalarFieldValue(postsPerPage.ToString()) },
                { TableSpec.FIELD_THREADSPERPAGE, new ScalarFieldValue(threadsPerPage.ToString()) },
                { TableSpec.FIELD_USERSPERPAGE, new ScalarFieldValue(usersPerPage.ToString()) },
                { TableSpec.FIELD_UPLOADSPERPAGE, new ScalarFieldValue(uploadsPerPage.ToString()) },
                { TableSpec.FIELD_SKINID, new ScalarFieldValue(skin.id.ToString()) },
                { TableSpec.FIELD_MODERNSKINID, new ScalarFieldValue(modernSkin.id.ToString()) },
                { TableSpec.FIELD_MACHICHARAID, new ScalarFieldValue(machichara.id.ToString()) },
                { TableSpec.FIELD_MAXUPLOADIMAGEWIDTH, new ScalarFieldValue(maxUploadImageWidth.ToString()) },
                { TableSpec.FIELD_MAXUPLOADIMAGEHEIGHT, new ScalarFieldValue(maxUploadImageHeight.ToString()) },
            };
            Dictionary <string, AbstractFieldValue> dataToInsert = new Dictionary <string, AbstractFieldValue>(dataToUpdate)
            {
                { TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) },
            };

            ChangeSetUtil.ApplyChanges(
                new InsertOrUpdateChange(
                    TableSpec.instance,
                    dataToInsert,
                    dataToUpdate,
                    new ComparisonCondition(
                        TableSpec.instance.getColumnSpec(TableSpec.FIELD_ACCOUNTID),
                        ComparisonType.EQUAL,
                        account.id.ToString()
                        )
                    )
                );
            if (LoadByAccount(account) is AnonymousUserSettings)
            {
                ClearCacheByAccount(account);
            }
        }
Ejemplo n.º 7
0
        public static Account createAccount(string name, string password, string ip, string registrationEmail)
        {
            var rawChanges    = Account.getNewAccountChanges(name, password, ip, registrationEmail);
            var accountInsert = rawChanges.Key;
            var changes       = rawChanges.Value;

            ChangeSetUtil.ApplyChanges(changes);
            return(Account.LoadById(accountInsert.getId().Value));
        }
Ejemplo n.º 8
0
 public void updateRegistrationEmail(string newEmail)
 {
     ChangeSetUtil.ApplyChanges(new AbstractChange[] {
         new UpdateChange(
             TableSpec.instance,
             new Dictionary <string, AbstractFieldValue>()
         {
             {
                 TableSpec.FIELD_REGISTRATIONEMAIL,
                 new ScalarFieldValue(newEmail)
             },
         },
             this.id
             )
     });
 }
Ejemplo n.º 9
0
 public void incrementViewsCounter()
 {
     ChangeSetUtil.ApplyChanges(new AbstractChange[] {
         new UpdateChange(
             TableSpec.instance,
             new Dictionary <string, AbstractFieldValue>()
         {
             {
                 TableSpec.FIELD_TOTALVIEWS,
                 new IncrementFieldValue()
             }
         },
             this.id
             )
     });
 }
Ejemplo n.º 10
0
 public void migrate(string newPassword, string ip, string registrationEmail)
 {
     checkNewPassword(newPassword);
     if (!this.needsMigration)
     {
         throw new FLocalException("Already migrated");
     }
     ChangeSetUtil.ApplyChanges(new AbstractChange[] {
         new UpdateChange(
             TableSpec.instance,
             new Dictionary <string, AbstractFieldValue>()
         {
             {
                 TableSpec.FIELD_PASSWORDHASH,
                 new ScalarFieldValue(this.hashPasswordLegacy(newPassword))
             },
             {
                 TableSpec.FIELD_NEEDSMIGRATION,
                 new ScalarFieldValue("0")
             },
             {
                 TableSpec.FIELD_IPADDRESS,
                 new ScalarFieldValue(ip)
             },
             {
                 TableSpec.FIELD_REGISTRATIONEMAIL,
                 new ScalarFieldValue(registrationEmail)
             },
         },
             this.id
             ),
         new UpdateChange(
             User.TableSpec.instance,
             new Dictionary <string, AbstractFieldValue> {
             { User.TableSpec.FIELD_SHOWPOSTSTOUSERS, new ScalarFieldValue(User.ENUM_SHOWPOSTSTOUSERS_ALL) },
         },
             this.user.id
             ),
         new InsertChange(
             AvatarsSettings.TableSpec.instance,
             new Dictionary <string, AbstractFieldValue> {
             { AvatarsSettings.TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(this.id.ToString()) },
             { AvatarsSettings.TableSpec.FIELD_AVATARS, new ScalarFieldValue(this.user.avatarId.HasValue ? this.user.avatarId.ToString() : "") },
         }
             )
     });
 }
Ejemplo n.º 11
0
 public void updatePassword(string newPassword)
 {
     checkNewPassword(newPassword);
     ChangeSetUtil.ApplyChanges(new AbstractChange[] {
         new UpdateChange(
             TableSpec.instance,
             new Dictionary <string, AbstractFieldValue>()
         {
             {
                 TableSpec.FIELD_PASSWORDHASH,
                 new ScalarFieldValue(this.hashPasswordLegacy(newPassword))
             },
         },
             this.id
             )
     });
 }
Ejemplo n.º 12
0
        public void SetAvatar(Upload avatar)
        {
            if ((avatar != null) && (avatar.size > Upload.AVATAR_MAX_FILESIZE))
            {
                throw new FLocalException("Avatar is too big (max. 80KB allowed)");
            }

            ChangeSetUtil.ApplyChanges(
                new UpdateChange(
                    TableSpec.instance,
                    new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_AVATARID, new ScalarFieldValue((avatar != null) ? avatar.id.ToString() : null) },
            },
                    this.id
                    )
                );
        }
Ejemplo n.º 13
0
        public Post Reply(User poster, string title, string body, PostLayer desiredLayer, DateTime date, int?forcedPostId)
        {
            if (this.thread.isLocked && poster.name != Config.instance.AdminUserName)
            {
                throw new FLocalException("thread locked");
            }

            PostLayer actualLayer = poster.getActualLayer(this.thread.board, desiredLayer);

            Post newPost;

            lock (this.thread.locker) {
                var changes = Thread.getNewPostChanges(this.thread.board, this.threadId, this, poster, actualLayer, title, body, date, forcedPostId);
                ChangeSetUtil.ApplyChanges(changes.Value.ToArray());

                newPost = Post.LoadById(changes.Key.getId().Value);
            }
            return(newPost);
        }
Ejemplo n.º 14
0
        public void GiveVote(User user, HashSet <int> options)
        {
            foreach (int option in options)
            {
                if (!this.options.ContainsKey(option))
                {
                    throw new CriticalException("invalid option");
                }
            }
            AbstractFieldValue voteInfo = new ScalarFieldValue(
                new XElement("votes",
                             from option in options select new XElement("vote", new XAttribute("optionId", option))
                             ).ToString()
                );

            ChangeSetUtil.ApplyChanges(
                new InsertOrUpdateChange(
                    Vote.TableSpec.instance,
                    new Dictionary <string, AbstractFieldValue> {
                { Vote.TableSpec.FIELD_POLLID, new ScalarFieldValue(this.id.ToString()) },
                { Vote.TableSpec.FIELD_USERID, new ScalarFieldValue(user.id.ToString()) },
                { Vote.TableSpec.FIELD_VOTEINFO, voteInfo }
            },
                    new Dictionary <string, AbstractFieldValue> {
                { Vote.TableSpec.FIELD_VOTEINFO, voteInfo },
            },
                    new ComplexCondition(
                        ConditionsJoinType.AND,
                        new ComparisonCondition(
                            Vote.TableSpec.instance.getColumnSpec(Vote.TableSpec.FIELD_POLLID),
                            ComparisonType.EQUAL,
                            this.id.ToString()
                            ),
                        new ComparisonCondition(
                            Vote.TableSpec.instance.getColumnSpec(Vote.TableSpec.FIELD_USERID),
                            ComparisonType.EQUAL,
                            user.id.ToString()
                            )
                        )
                    )
                );
        }
Ejemplo n.º 15
0
        private static void Save(Account account, HashSet <int> avatars)
        {
            Dictionary <string, AbstractFieldValue> dataToUpdate = new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_AVATARS, new ScalarFieldValue(avatars.Join(",")) },
            };
            Dictionary <string, AbstractFieldValue> dataToInsert = new Dictionary <string, AbstractFieldValue>(dataToUpdate)
            {
                { TableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) },
            };

            ChangeSetUtil.ApplyChanges(
                new InsertOrUpdateChange(
                    TableSpec.instance,
                    dataToInsert,
                    dataToUpdate,
                    new ComparisonCondition(
                        TableSpec.instance.getColumnSpec(TableSpec.FIELD_ACCOUNTID),
                        ComparisonType.EQUAL,
                        account.id.ToString()
                        )
                    )
                );
        }
Ejemplo n.º 16
0
        public void forceMarkAsRead(Account account, Post maxPost)
        {
            var actualLastRead = new Box <string>();

            ChangeSetUtil.ApplyChanges(
                new InsertOrUpdateChange(
                    ReadMarkerTableSpec.instance,
                    new Dictionary <string, AbstractFieldValue> {
                { ReadMarkerTableSpec.FIELD_ACCOUNTID, new ScalarFieldValue(account.id.ToString()) },
                { ReadMarkerTableSpec.FIELD_THREADID, new ScalarFieldValue(this.id.ToString()) },
                { ReadMarkerTableSpec.FIELD_POSTID, new ScalarFieldValue(maxPost.id.ToString()) },
            },
                    new Dictionary <string, AbstractFieldValue> {
                { ReadMarkerTableSpec.FIELD_POSTID, new IncrementFieldValue(IncrementFieldValue.GREATEST(maxPost.id), actualLastRead) },
            },
                    this.getReadmarkerSearchCondition(account)
                    )
                );
            int actualLastReadId = 0;

            int.TryParse(actualLastRead.value, out actualLastReadId);
            this.lastReadId_Reset(account, actualLastReadId);
        }
Ejemplo n.º 17
0
        public static TexImage Save(string text)
        {
            string hash = Util.md5(text);

            try {
                return(TexImage.LoadById(
                           int.Parse(
                               Config.instance.mainConnection.LoadIdByField(
                                   TableSpec.instance.getColumnSpec(TableSpec.FIELD_HASH),
                                   hash
                                   )
                               )
                           ));
            } catch (NotFoundInDBException) {
            }

            User   uploader             = User.LoadByName("Mr. TeX compiler");
            Upload file                 = UploadManager.SafeUploadFile(Compiler.GetPngStream(text), "tex-" + hash + ".png", uploader);
            InsertOrUpdateChange change = new InsertOrUpdateChange(
                TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_HASH, new ScalarFieldValue(hash) },
                { TableSpec.FIELD_TEXT, new ScalarFieldValue(text) },
                { TableSpec.FIELD_UPLOADID, new ScalarFieldValue(file.id.ToString()) },
            },
                new Dictionary <string, AbstractFieldValue>(),
                new ComparisonCondition(
                    TableSpec.instance.getColumnSpec(TableSpec.FIELD_HASH),
                    ComparisonType.EQUAL,
                    hash
                    )
                );

            ChangeSetUtil.ApplyChanges(change);
            return(TexImage.LoadById(change.getId().Value));
        }
Ejemplo n.º 18
0
        public static void ImportUsers(int startFromPage)
        {
            for (int i = startFromPage; i < 1000; i++)
            {
                System.Console.Write("[" + i + "]");
                foreach (string userName in ShallerGateway.getUserNames(i))
                {
                    User user;
                    try {
                        User.LoadByName(userName);
                        System.Console.Write("-");
                    } catch (NotFoundInDBException) {
                        Dictionary <string, string> userData = ShallerGateway.getUserInfo(userName);
                        AbstractChange addUser = new InsertChange(
                            User.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                            { User.TableSpec.FIELD_NAME, new ScalarFieldValue(userName) },
                            { User.TableSpec.FIELD_REGDATE, new ScalarFieldValue(DateTime.Parse(userData["regDate"]).ToUTCString()) },
                            { User.TableSpec.FIELD_LOCATION, new ScalarFieldValue(userData["location"]) },
                            { User.TableSpec.FIELD_SHOWPOSTSTOUSERS, new ScalarFieldValue("All") },
                            { User.TableSpec.FIELD_SIGNATURE, new ScalarFieldValue(userData["signature"]) },
                            { User.TableSpec.FIELD_SIGNATUREUBB, new ScalarFieldValue(userData["signature"]) },
                            { User.TableSpec.FIELD_TITLE, new ScalarFieldValue(userData["title"]) },
                            { User.TableSpec.FIELD_TOTALPOSTS, new ScalarFieldValue("0") },
                            { User.TableSpec.FIELD_USERGROUPID, new ScalarFieldValue("1") },
                            { User.TableSpec.FIELD_BIOGRAPHY, new ScalarFieldValue(userData["biography"]) },
                            { User.TableSpec.FIELD_BIOGRAPHYUBB, new ScalarFieldValue(userData["biography"]) },
                        }
                            );
                        AbstractChange addAccount = new InsertChange(
                            Account.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                            { Account.TableSpec.FIELD_NAME, new ScalarFieldValue(userName.ToLower()) },
                            { Account.TableSpec.FIELD_NEEDSMIGRATION, new ScalarFieldValue("1") },
                            { Account.TableSpec.FIELD_PASSWORDHASH, new ScalarFieldValue("*") },
                            { Account.TableSpec.FIELD_IPADDRESS, new ScalarFieldValue("127.0.0.1") },
                            { Account.TableSpec.FIELD_ISSTATUSHIDDEN, new ScalarFieldValue("0") },
                            { Account.TableSpec.FIELD_ISDETAILEDSTATUSHIDDEN, new ScalarFieldValue("0") },
                            { Account.TableSpec.FIELD_REGISTRATIONEMAIL, new ScalarFieldValue("[email protected]") },
                            { Account.TableSpec.FIELD_USERID, new ReferenceFieldValue(addUser) },
                        }
                            );
                        AbstractChange addIndicator = new InsertChange(
                            AccountIndicator.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                            { AccountIndicator.TableSpec.FIELD_ACCOUNTID, new ReferenceFieldValue(addAccount) },
                            { AccountIndicator.TableSpec.FIELD_PRIVATEMESSAGES, new ScalarFieldValue("0") },
                            { AccountIndicator.TableSpec.FIELD_UNREADPRIVATEMESSAGES, new ScalarFieldValue("0") },
                        }
                            );
                        ChangeSetUtil.ApplyChanges(addUser, addAccount, addIndicator);

                        user = User.LoadById(addUser.getId().Value);
                        System.Console.Write(".");

                        if (userData["avatar"] != null && userData["avatar"] != "")
                        {
                            Upload   avatar;
                            string[] nameParts = userData["avatar"].Split('.');
                            if (nameParts.Length != 2)
                            {
                                throw new FLocalException("wrong avatar filename '" + userData["avatar"] + "'");
                            }
                            int      oldAvatarId = int.Parse(nameParts[0]);
                            FileInfo avatarInfo  = ShallerGateway.getFileInfo("user/" + userData["avatar"]);
                            try {
                                avatar = UploadManager.UploadFile(avatarInfo.dataStream, avatarInfo.fileName, avatarInfo.lastModified, user, 900000 + oldAvatarId);
                            } catch (UploadManager.AlreadyUploadedException e) {
                                avatar = Upload.LoadById(e.uploadId);
                            }
                            ChangeSetUtil.ApplyChanges(
                                new UpdateChange(
                                    User.TableSpec.instance,
                                    new Dictionary <string, AbstractFieldValue> {
                                { User.TableSpec.FIELD_AVATARID, new ScalarFieldValue(avatar.id.ToString()) }
                            },
                                    user.id
                                    )
                                );
                            System.Console.Write("a");
                        }
                    }
                }
            }
        }
Ejemplo n.º 19
0
        public static void RecalculateRestrictions(Board board, User user)
        {
            List <Punishment> punishments = (from punishment in Punishment.getEffectivePunishments(user, board) where punishment.punishmentType.weight > 0 orderby punishment.expires descending select punishment).ToList();

            Dictionary <int, DateTime> layer2expirationDate = new Dictionary <int, DateTime>();

            foreach (var layer in PostLayer.allLayers)
            {
                if (!layer.maxPunishments.HasValue)
                {
                    continue;
                }

                bool     restricted     = false;
                int      accumulated    = 0;
                DateTime?expirationDate = null;
                foreach (var punishment in punishments)
                {
                    accumulated += punishment.punishmentType.weight;
                    if (accumulated >= layer.maxPunishments.Value)
                    {
                        expirationDate = punishment.expires;
                        restricted     = true;
                        break;
                    }
                }

                if (restricted)
                {
                    layer2expirationDate[layer.id] = expirationDate.Value;
                }
            }

            string data = (from kvp in layer2expirationDate select string.Format("{0}:{1}", kvp.Key, kvp.Value.Ticks)).Join(";");

            ChangeSetUtil.ApplyChanges(
                new InsertOrUpdateChange(
                    TableSpec.instance,
                    new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_BOARDID, new ScalarFieldValue(board.id.ToString()) },
                { TableSpec.FIELD_USERID, new ScalarFieldValue(user.id.ToString()) },
                { TableSpec.FIELD_DATA, new ScalarFieldValue(data) },
            },
                    new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_DATA, new ScalarFieldValue(data) },
            },
                    new ComplexCondition(
                        ConditionsJoinType.AND,
                        new ComparisonCondition(
                            TableSpec.instance.getColumnSpec(TableSpec.FIELD_BOARDID),
                            ComparisonType.EQUAL,
                            board.id.ToString()
                            ),
                        new ComparisonCondition(
                            TableSpec.instance.getColumnSpec(TableSpec.FIELD_USERID),
                            ComparisonType.EQUAL,
                            user.id.ToString()
                            )
                        )
                    )
                );
        }
Ejemplo n.º 20
0
        public static PMMessage SendPMMessage(Account sender, Account receiver, string title, string bodyUBB)
        {
            string         bodyIntermediate = UBBParser.UBBToIntermediate(bodyUBB);
            AbstractChange insertPmReceiver = new InsertChange(
                PMMessage.TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { PMMessage.TableSpec.FIELD_OWNERID, new ScalarFieldValue(receiver.id.ToString()) },
                { PMMessage.TableSpec.FIELD_INTERLOCUTORID, new ScalarFieldValue(sender.id.ToString()) },
                { PMMessage.TableSpec.FIELD_DIRECTION, new ScalarFieldValue(PMMessage.ENUM_DIRECTION_INCOMING) },
                { PMMessage.TableSpec.FIELD_POSTDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
                { PMMessage.TableSpec.FIELD_TITLE, new ScalarFieldValue(title) },
                { PMMessage.TableSpec.FIELD_BODY, new ScalarFieldValue(bodyIntermediate) },
                { PMMessage.TableSpec.FIELD_BODYUBB, new ScalarFieldValue(bodyUBB) },
                { PMMessage.TableSpec.FIELD_INCOMINGPMID, new ScalarFieldValue(null) },
                { PMMessage.TableSpec.FIELD_ISREAD, new ScalarFieldValue("0") },
            }
                );
            AbstractChange insertPmSender = new InsertChange(
                PMMessage.TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { PMMessage.TableSpec.FIELD_OWNERID, new ScalarFieldValue(sender.id.ToString()) },
                { PMMessage.TableSpec.FIELD_INTERLOCUTORID, new ScalarFieldValue(receiver.id.ToString()) },
                { PMMessage.TableSpec.FIELD_DIRECTION, new ScalarFieldValue(PMMessage.ENUM_DIRECTION_OUTGOING) },
                { PMMessage.TableSpec.FIELD_POSTDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
                { PMMessage.TableSpec.FIELD_TITLE, new ScalarFieldValue(title) },
                { PMMessage.TableSpec.FIELD_BODY, new ScalarFieldValue(bodyIntermediate) },
                { PMMessage.TableSpec.FIELD_BODYUBB, new ScalarFieldValue(bodyUBB) },
                { PMMessage.TableSpec.FIELD_INCOMINGPMID, new ReferenceFieldValue(insertPmReceiver) },
                { PMMessage.TableSpec.FIELD_ISREAD, new ScalarFieldValue("1") },
            }
                );
            AbstractChange updateConversationSender = new InsertOrUpdateChange(
                TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_OWNERID, new ScalarFieldValue(sender.id.ToString()) },
                { TableSpec.FIELD_INTERLOCUTORID, new ScalarFieldValue(receiver.id.ToString()) },
                { TableSpec.FIELD_TOTALMESSAGES, new ScalarFieldValue("1") },
                { TableSpec.FIELD_LASTMESSAGEID, new ReferenceFieldValue(insertPmSender) },
                { TableSpec.FIELD_LASTMESSAGEDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
                { TableSpec.FIELD_LASTREADMESSAGEID, new ReferenceFieldValue(insertPmSender) },
            },
                new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_TOTALMESSAGES, new IncrementFieldValue() },
                { TableSpec.FIELD_LASTMESSAGEID, new TwoWayReferenceFieldValue(insertPmSender, TwoWayReferenceFieldValue.GREATEST) },
                { TableSpec.FIELD_LASTMESSAGEDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
            },
                new ComplexCondition(
                    ConditionsJoinType.AND,
                    new ComparisonCondition(
                        TableSpec.instance.getColumnSpec(TableSpec.FIELD_OWNERID),
                        ComparisonType.EQUAL,
                        sender.id.ToString()
                        ),
                    new ComparisonCondition(
                        TableSpec.instance.getColumnSpec(TableSpec.FIELD_INTERLOCUTORID),
                        ComparisonType.EQUAL,
                        receiver.id.ToString()
                        )
                    )
                );
            AbstractChange updateConversationReceiver = new InsertOrUpdateChange(
                TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_OWNERID, new ScalarFieldValue(receiver.id.ToString()) },
                { TableSpec.FIELD_INTERLOCUTORID, new ScalarFieldValue(sender.id.ToString()) },
                { TableSpec.FIELD_TOTALMESSAGES, new ScalarFieldValue("1") },
                { TableSpec.FIELD_LASTMESSAGEID, new ReferenceFieldValue(insertPmReceiver) },
                { TableSpec.FIELD_LASTMESSAGEDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
                { TableSpec.FIELD_LASTREADMESSAGEID, new ScalarFieldValue(null) },
            },
                new Dictionary <string, AbstractFieldValue> {
                { TableSpec.FIELD_TOTALMESSAGES, new IncrementFieldValue() },
                { TableSpec.FIELD_LASTMESSAGEID, new TwoWayReferenceFieldValue(insertPmReceiver, TwoWayReferenceFieldValue.GREATEST) },
                { TableSpec.FIELD_LASTMESSAGEDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
            },
                new ComplexCondition(
                    ConditionsJoinType.AND,
                    new ComparisonCondition(
                        TableSpec.instance.getColumnSpec(TableSpec.FIELD_OWNERID),
                        ComparisonType.EQUAL,
                        receiver.id.ToString()
                        ),
                    new ComparisonCondition(
                        TableSpec.instance.getColumnSpec(TableSpec.FIELD_INTERLOCUTORID),
                        ComparisonType.EQUAL,
                        sender.id.ToString()
                        )
                    )
                );
            AbstractChange updateIndicatorReceiver = new UpdateChange(
                AccountIndicator.TableSpec.instance,
                new Dictionary <string, AbstractFieldValue> {
                { AccountIndicator.TableSpec.FIELD_PRIVATEMESSAGES, new IncrementFieldValue() },
                { AccountIndicator.TableSpec.FIELD_UNREADPRIVATEMESSAGES, new IncrementFieldValue() },
            },
                AccountIndicator.LoadByAccount(receiver).id
                );

            ChangeSetUtil.ApplyChanges(
                insertPmReceiver,
                insertPmSender,
                updateConversationReceiver,
                updateConversationSender,
                updateIndicatorReceiver
                );
            return(PMMessage.LoadById(insertPmSender.getId().Value));
        }
Ejemplo n.º 21
0
 public void markAsRead(Account account, PMMessage minMessage, PMMessage maxMessage)
 {
     if (this.ownerId != account.id)
     {
         throw new AccessDeniedException();
     }
     ChangeSetUtil.ApplyChanges(new AbstractChange[] {
         new UpdateChange(
             TableSpec.instance,
             new Dictionary <string, AbstractFieldValue> {
             {
                 TableSpec.FIELD_LASTREADMESSAGEID,
                 new IncrementFieldValue(
                     s => {
                     if ((s == null) || (s == ""))
                     {
                         s = "0";                                                 //workaround
                     }
                     if (maxMessage.id < int.Parse(s))
                     {
                         return((s == "0") ? null : s);                                                //if some newer posts were already read
                     }
                     long count = Config.instance.mainConnection.GetCountByConditions(
                         PMMessage.TableSpec.instance,
                         new ComplexCondition(
                             ConditionsJoinType.AND,
                             new ComparisonCondition(
                                 PMMessage.TableSpec.instance.getColumnSpec(PMMessage.TableSpec.FIELD_OWNERID),
                                 ComparisonType.EQUAL,
                                 this.ownerId.ToString()
                                 ),
                             new ComparisonCondition(
                                 PMMessage.TableSpec.instance.getColumnSpec(PMMessage.TableSpec.FIELD_INTERLOCUTORID),
                                 ComparisonType.EQUAL,
                                 this.interlocutorId.ToString()
                                 ),
                             new ComparisonCondition(
                                 PMMessage.TableSpec.instance.getIdSpec(),
                                 ComparisonType.GREATERTHAN,
                                 s
                                 ),
                             new ComparisonCondition(
                                 PMMessage.TableSpec.instance.getIdSpec(),
                                 ComparisonType.LESSTHAN,
                                 minMessage.id.ToString()
                                 )
                             )
                         );
                     if (count > 0)
                     {
                         return((s == "0") ? null : s);                                                //if there are some unread posts earlier than minPost
                     }
                     else
                     {
                         return(maxMessage.id.ToString());
                     }
                 }
                     )
             }
         },
             this.id
             )
     });
 }
Ejemplo n.º 22
0
        public void markAsRead(Account account, Post minPost, Post maxPost)
        {
            Box <string> actualLastRead = new Box <string>();

            ChangeSetUtil.ApplyChanges(
                new InsertOrUpdateChange(
                    ReadMarkerTableSpec.instance,
                    new Dictionary <string, AbstractFieldValue> {
                {
                    ReadMarkerTableSpec.FIELD_THREADID,
                    new ScalarFieldValue(this.id.ToString())
                },
                {
                    ReadMarkerTableSpec.FIELD_ACCOUNTID,
                    new ScalarFieldValue(account.id.ToString())
                },
                {
                    ReadMarkerTableSpec.FIELD_POSTID,
                    new ScalarFieldValue(
                        (minPost.id <= this.firstPostId)
                                                                ?
                        maxPost.id.ToString()
                                                                :
                        null
                        )
                },
            },
                    new Dictionary <string, AbstractFieldValue> {
                {
                    ReadMarkerTableSpec.FIELD_POSTID,
                    new IncrementFieldValue(
                        s => {
                        if ((s == null) || (s == ""))
                        {
                            s = "0";                                                     //workaround
                        }
                        if (maxPost.id < int.Parse(s))
                        {
                            return((s == "0") ? null : s);                                                    //if some newer posts were already read
                        }
                        long count = Config.instance.mainConnection.GetCountByConditions(
                            Post.TableSpec.instance,
                            new ComplexCondition(
                                ConditionsJoinType.AND,
                                new ComparisonCondition(
                                    Post.TableSpec.instance.getColumnSpec(Post.TableSpec.FIELD_THREADID),
                                    ComparisonType.EQUAL,
                                    this.id.ToString()
                                    ),
                                new ComparisonCondition(
                                    Post.TableSpec.instance.getIdSpec(),
                                    ComparisonType.GREATERTHAN,
                                    s
                                    ),
                                new ComparisonCondition(
                                    Post.TableSpec.instance.getIdSpec(),
                                    ComparisonType.LESSTHAN,
                                    minPost.id.ToString()
                                    )
                                )
                            );
                        if (count > 0)
                        {
                            return((s == "0") ? null : s);                                                    //if there are some unread posts earlier than minPost
                        }
                        else
                        {
                            return(maxPost.id.ToString());
                        }
                    },
                        actualLastRead
                        )
                }
            },
                    this.getReadmarkerSearchCondition(account)
                    )
                );
            int actualLastReadId = 0;

            int.TryParse(actualLastRead.value, out actualLastReadId);
            this.lastReadId_Reset(account, actualLastReadId);
        }
Ejemplo n.º 23
0
        public static void processDB(string filename)
        {
            try {
                Dictionary <int, Action> inserts        = new Dictionary <int, Action>();
                HashSet <int>            discussionsIds = new HashSet <int>();
                using (StreamReader reader = new StreamReader(filename)) {
                    int i = 0;
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine().Trim();
                        if (line == "")
                        {
                            continue;
                        }
                        if (i % 1000 == 0)
                        {
                            System.Console.Write("[" + (int)(i / 1000) + "]");
                        }
                        Dictionary <string, string> data;
                        try {
                            data = DictionaryConverter.FromDump(line);
                        } catch (Exception e) {
                            System.Console.Error.WriteLine("Error while trying to parse line: " + e.GetType().FullName + ": " + e.Message);
                            System.Console.Error.WriteLine(e.StackTrace);
                            continue;
                        }
                        int postId = int.Parse(data["Number"]);
                        try {
                            if (inserts.ContainsKey(postId))
                            {
                                System.Console.Write("-");
                            }
                            else if (Config.instance.mainConnection.GetCountByConditions(Post.TableSpec.instance, new ComparisonCondition(Post.TableSpec.instance.getIdSpec(), ComparisonType.EQUAL, postId.ToString())) > 0)
                            {
/*							Post post = Post.LoadById(postId);
 *                                                      if(post.title.StartsWith("%") || post.title.StartsWith("Re%3A") || post.body.StartsWith("%") || (post.thread.firstPost.id == post.id && post.thread.title.StartsWith("%"))) {
 *                                                              string title = data["Subject"];
 *                                                              string body = data["Body"];
 *                                                              inserts[postId] = () => {
 *                                                                      List<AbstractChange> changes = new List<AbstractChange> {
 *                                                                              new UpdateChange(
 *                                                                                      Post.TableSpec.instance,
 *                                                                                      new Dictionary<string, AbstractFieldValue> {
 *                                                                                              { Post.TableSpec.FIELD_TITLE, new ScalarFieldValue(title) },
 *                                                                                              { Post.TableSpec.FIELD_BODY, new ScalarFieldValue(body) },
 *                                                                                      },
 *                                                                                      post.id
 *                                                                              )
 *                                                                      };
 *                                                                      if(post.thread.firstPost.id == post.id) {
 *                                                                              changes.Add(
 *                                                                                      new UpdateChange(
 *                                                                                              Thread.TableSpec.instance,
 *                                                                                              new Dictionary<string, AbstractFieldValue> {
 *                                                                                                      { Thread.TableSpec.FIELD_TITLE, new ScalarFieldValue(title) },
 *                                                                                              },
 *                                                                                              post.thread.id
 *                                                                                      )
 *                                                                              );
 *                                                                      }
 *
 *                                                                      ChangeSetUtil.ApplyChanges(changes.ToArray());
 *                                                              };
 *                                                              Console.Write("+");
 *                                                      } else {
 *                                                              Console.Write("-");
 *                                                      }*/
                                System.Console.Write("-");
                            }
                            else
                            {
                                int localMain = int.Parse(data["Local_Main"]);
                                int main      = int.Parse(data["Main"]);
                                int UnixTime;
                                try {
                                    UnixTime = int.Parse(data["UnixTime"]);
                                } catch (OverflowException) {
                                    UnixTime = 1000 * 1000 * 1000;
                                }
                                if (UnixTime <= 0)
                                {
                                    UnixTime = 1000 * 1000 * 1000;
                                }
                                DateTime date = UNIX.AddSeconds(UnixTime).ToLocalTime();
                                User     user;
                                string   username = data["Username"];
                                try {
                                    user = User.LoadByName(username);
                                } catch (NotFoundInDBException) {
                                    System.Console.Error.WriteLine("Cannot find user '" + username + "'; creating one...");
                                    ChangeSetUtil.ApplyChanges(
                                        new InsertChange(
                                            User.TableSpec.instance,
                                            new Dictionary <string, AbstractFieldValue> {
                                        { User.TableSpec.FIELD_NAME, new ScalarFieldValue(username) },
                                        { User.TableSpec.FIELD_REGDATE, new ScalarFieldValue(date.ToUTCString()) },
                                        { User.TableSpec.FIELD_SHOWPOSTSTOUSERS, new ScalarFieldValue(User.ENUM_SHOWPOSTSTOUSERS_ALL) },
                                        { User.TableSpec.FIELD_BIOGRAPHY, new ScalarFieldValue("") },
                                        { User.TableSpec.FIELD_BIOGRAPHYUBB, new ScalarFieldValue("") },
                                        { User.TableSpec.FIELD_LOCATION, new ScalarFieldValue("") },
                                        { User.TableSpec.FIELD_SIGNATURE, new ScalarFieldValue("") },
                                        { User.TableSpec.FIELD_SIGNATUREUBB, new ScalarFieldValue("") },
                                        { User.TableSpec.FIELD_TITLE, new ScalarFieldValue("") },
                                        { User.TableSpec.FIELD_TOTALPOSTS, new ScalarFieldValue("0") },
                                        { User.TableSpec.FIELD_USERGROUPID, new ScalarFieldValue("1") },
                                    }
                                            )
                                        );
                                    user = User.LoadByName(data["Username"]);
                                }
                                string    title = data["Subject"];
                                string    body  = data["Body"];
                                PostLayer layer = PostLayer.LoadById(1);
                                if (data.ContainsKey("Layer"))
                                {
                                    layer = PostLayer.LoadById(int.Parse(data["Layer"]));
                                }
                                inserts[postId] = () => {
                                    bool isDiscussion = false;
                                    if (postId == main || postId == localMain)
                                    {
                                        //first post in the thread
                                        string legacyBoardName;
                                        if (discussions.ContainsKey(main) || (localMain != 0 && (localMain != postId || localMain != main)))
                                        {
                                            discussionsIds.Add(main);
                                            legacyBoardName = discussions[main];
                                            isDiscussion    = true;
                                        }
                                        else
                                        {
                                            legacyBoardName = data["Board"];
                                        }
                                        Board board;
                                        try {
                                            board = Board.LoadByLegacyName(legacyBoardName);
                                        } catch (NotFoundInDBException) {
                                            throw new ApplicationException("Cannot find board '" + legacyBoardName + "'");
                                        }
                                        board.CreateThread(user, title, body, layer, date, postId);
                                    }
                                    else
                                    {
                                        int parentId = int.Parse(data["Parent"]);
                                        if (parentId == 0)
                                        {
                                            parentId = localMain;
                                            if (parentId == 0)
                                            {
                                                parentId = main;
                                            }
                                        }
                                        Post parent;
                                        try {
                                            parent = Post.LoadById(parentId);
                                        } catch (NotFoundInDBException) {
                                            throw new ApplicationException("Cannot find parent post #" + parentId);
                                        }

                                        if (!isDiscussion && parent.thread.firstPostId != localMain)
                                        {
                                            System.Console.Write("d");
                                        }
                                        else
                                        {
                                            parent.Reply(user, title, body, layer, date, postId);
                                        }
                                    }
                                };
                                System.Console.Write("+");
                            }
                        } catch (Exception e) {
                            System.Console.Error.WriteLine("Cannot process post #" + postId + ": " + e.GetType().FullName + ": " + e.Message);
                            System.Console.Error.WriteLine(e.StackTrace);
                            System.Console.Write("!");
//						Console.ReadLine();
                        } finally {
                            i++;
                            if ((i % 50000) == 0)
                            {
                                Web.Core.RegistryCleaner.CleanRegistry <int, Post>();
                                Web.Core.RegistryCleaner.CleanRegistry <int, Thread>();
                                GC.Collect();
                                System.Console.Error.WriteLine();
                                System.Console.Error.WriteLine("Registry cleaned; garbage collected");
                                System.Console.Error.WriteLine();
                            }
                        }
                    }
                }

                System.Console.WriteLine();
                System.Console.WriteLine("Finished parsing");
                System.Console.WriteLine("Total inserts: " + inserts.Count);
                System.Console.ReadLine();
                int j = 0;
                foreach (var insert in inserts)
                {
                    if (j % 1000 == 0)
                    {
                        System.Console.Write("[" + (int)(j / 1000) + "]");
                    }
                    try {
                        insert.Value();
                        System.Console.Write("+");
                    } catch (Exception e) {
                        System.Console.Error.WriteLine("Cannot process post #" + insert.Key + ": " + e.GetType().FullName + ": " + e.Message);
                        System.Console.Error.WriteLine(e.StackTrace);
                        System.Console.Write("!");
//						Console.ReadLine();
                    } finally {
                        j++;
                    }
                }

                System.Console.WriteLine("Not found discussions:");
                foreach (int discussionId in discussionsIds.OrderBy(id => id))
                {
                    System.Console.WriteLine(discussionId);
                }
            } catch (Exception e) {
                System.Console.Error.WriteLine(e.GetType().FullName + ": " + e.Message);
                System.Console.Error.WriteLine(e.StackTrace);
            }
        }
Ejemplo n.º 24
0
        private readonly object Edit_locker = new object();         //TODO: move locking to DB
        public void Edit(User user, string newTitle, string newBody, PostLayer newDesiredLayer)
        {
            if (this.poster.id != user.id)
            {
                throw new AccessDeniedException();
            }
            PostLayer actualLayer = poster.getActualLayer(this.thread.board, newDesiredLayer);

            if (actualLayer.id < this.layer.id)
            {
                actualLayer = this.layer;
            }
            lock (this.Edit_locker) {
                DateTime date = DateTime.Now;

                HashSet <int> newMentionedUsersIds = new HashSet <int>();
                if (this.parentPostId != null && this.parentPost.poster.id != this.poster.id)
                {
                    newMentionedUsersIds.Add(this.parentPost.poster.id);
                }
                string newBodyIntermediate = UBBParser.UBBToIntermediate(
                    new DelegatePostParsingContext(mentionedUser => newMentionedUsersIds.Add(mentionedUser.id)),
                    newBody
                    );

                List <AbstractChange> changes = new List <AbstractChange> {
                    new InsertChange(
                        Revision.TableSpec.instance,
                        new Dictionary <string, AbstractFieldValue> {
                        { Revision.TableSpec.FIELD_POSTID, new ScalarFieldValue(this.id.ToString()) },
                        { Revision.TableSpec.FIELD_CHANGEDATE, new ScalarFieldValue(date.ToUTCString()) },
                        { Revision.TableSpec.FIELD_TITLE, new ScalarFieldValue(newTitle) },
                        { Revision.TableSpec.FIELD_BODY, new ScalarFieldValue(newBody) },
                        { Revision.TableSpec.FIELD_NUMBER, new ScalarFieldValue((this.revision + 1).ToString()) },
                    }
                        ),
                    new UpdateChange(
                        TableSpec.instance,
                        new Dictionary <string, AbstractFieldValue> {
                        { TableSpec.FIELD_TITLE, new ScalarFieldValue(newTitle) },
                        { TableSpec.FIELD_BODY, new ScalarFieldValue(newBodyIntermediate) },
                        { TableSpec.FIELD_LASTCHANGEDATE, new ScalarFieldValue(date.ToUTCString()) },
                        { TableSpec.FIELD_REVISION, new IncrementFieldValue() },
                        { TableSpec.FIELD_LAYERID, new ScalarFieldValue(actualLayer.id.ToString()) },
                    },
                        this.id
                        )
                };
                if (this.thread.firstPost.id == this.id)
                {
                    changes.Add(
                        new UpdateChange(
                            Thread.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                        { TableSpec.FIELD_TITLE, new ScalarFieldValue(newTitle) },
                    },
                            this.thread.id
                            )
                        );
                }
                foreach (var mentionedUserId in newMentionedUsersIds.Except(this.mentionedUsersIds))
                {
                    changes.Add(
                        new InsertChange(
                            Mention.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                        { Mention.TableSpec.FIELD_MENTIONEDUSERID, new ScalarFieldValue(mentionedUserId.ToString()) },
                        { Mention.TableSpec.FIELD_POSTID, new ScalarFieldValue(this.id.ToString()) },
                        { Mention.TableSpec.FIELD_DATE, new ScalarFieldValue(date.ToUTCString()) },
                    }
                            )
                        );
                }
                ChangeSetUtil.ApplyChanges(changes.ToArray());
            }
        }
Ejemplo n.º 25
0
        public void Punish(Account account, PunishmentType type, string comment, PunishmentTransfer.NewTransferInfo?transferInfo, PunishmentLayerChange.NewLayerChangeInfo?layerChangeInfo)
        {
            if (string.IsNullOrEmpty(comment))
            {
                throw new FLocalException("Comment is empty");
            }

            if (!Moderator.isModerator(account, this.thread))
            {
                throw new FLocalException(account.id + " is not a moderator in board " + this.thread.board.id);
            }

            if (!Moderator.isTrueModerator(account, this.thread.board))
            {
                if (type.weight != 0)
                {
                    throw new FLocalException("You cannot set punishments with weight != 0");
                }
                if (transferInfo.HasValue && !transferInfo.Value.newBoard.isTransferTarget)
                {
                    throw new FLocalException("You cannot transfer in '" + transferInfo.Value.newBoard.name + "'");
                }
            }

            lock (this.Punish_Locker) {
                lock (this.thread.locker) {
                    IEnumerable <AbstractChange> changes = (
                        from punishment in this.punishments
                        select(AbstractChange) new UpdateChange(
                            Punishment.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                        { Punishment.TableSpec.FIELD_ISWITHDRAWED, new ScalarFieldValue("1") },
                    },
                            punishment.id
                            )
                        );

                    InsertChange layerChangeInsert = null;
                    if (layerChangeInfo.HasValue)
                    {
                        var _layerChangeInfo = layerChangeInfo.Value;

                        if (_layerChangeInfo.newLayer.name == PostLayer.NAME_HIDDEN)
                        {
                            throw new FLocalException("You cannot hide posts");
                        }

                        layerChangeInsert = new InsertChange(
                            PunishmentLayerChange.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                            { PunishmentLayerChange.TableSpec.FIELD_OLDLAYERID, new ScalarFieldValue(this.layerId.ToString()) },
                            { PunishmentLayerChange.TableSpec.FIELD_NEWLAYERID, new ScalarFieldValue(_layerChangeInfo.newLayerId.ToString()) },
                            { PunishmentLayerChange.TableSpec.FIELD_ISSUBTHREADCHANGE, new ScalarFieldValue(_layerChangeInfo.isSubthreadChange.ToDBString()) },
                        }
                            );
                        changes.Union(layerChangeInsert);

                        List <Post> postsAffected;
                        if (_layerChangeInfo.isSubthreadChange)
                        {
                            postsAffected = this.ToSequence(post => post.subPosts).OrderBy(post => post.id).ToList();
                        }
                        else
                        {
                            postsAffected = new List <Post>();
                            postsAffected.Add(this);
                        }

                        changes = changes.Union(
                            from post in postsAffected
                            select(AbstractChange) new UpdateChange(
                                Post.TableSpec.instance,
                                new Dictionary <string, AbstractFieldValue> {
                            { Post.TableSpec.FIELD_LAYERID, new ScalarFieldValue(_layerChangeInfo.newLayerId.ToString()) },
                        },
                                post.id
                                )
                            );
                    }

                    InsertChange transferInsert = null;
                    if (transferInfo.HasValue)
                    {
                        var _transferInfo = transferInfo.Value;

                        transferInsert = new InsertChange(
                            PunishmentTransfer.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                            { PunishmentTransfer.TableSpec.FIELD_OLDBOARDID, new ScalarFieldValue(this.thread.boardId.ToString()) },
                            { PunishmentTransfer.TableSpec.FIELD_NEWBOARDID, new ScalarFieldValue(_transferInfo.newBoardId.ToString()) },
                            { PunishmentTransfer.TableSpec.FIELD_ISSUBTHREADTRANSFER, new ScalarFieldValue(_transferInfo.isSubthreadTransfer.ToDBString()) },
                            { PunishmentTransfer.TableSpec.FIELD_OLDPARENTPOSTID, new ScalarFieldValue(this.parentPostId.HasValue ? this.parentPostId.ToString() : null) },
                        }
                            );
                        changes = changes.Union(transferInsert);

                        Post lastAffectedPost;
                        int  totalAffectedPosts;

                        if (!this.parentPostId.HasValue)
                        {
                            if (!_transferInfo.isSubthreadTransfer)
                            {
                                throw new FLocalException("You cannot move the first post in thread");
                            }
                            else
                            {
                                lastAffectedPost   = this.thread.lastPost;
                                totalAffectedPosts = this.thread.totalPosts;
                                changes            = changes.Union(
                                    new UpdateChange(
                                        Thread.TableSpec.instance,
                                        new Dictionary <string, AbstractFieldValue> {
                                    { Thread.TableSpec.FIELD_BOARDID, new ScalarFieldValue(_transferInfo.newBoardId.ToString()) },
                                },
                                        this.thread.id
                                        )
                                    );
                            }
                        }
                        else
                        {
                            List <Post> postsAffected;
                            if (_transferInfo.isSubthreadTransfer)
                            {
                                postsAffected = this.ToSequence(post => post.subPosts).OrderBy(post => post.id).ToList();
                            }
                            else
                            {
                                postsAffected = new List <Post>();
                                postsAffected.Add(this);
                            }

                            lastAffectedPost   = postsAffected.Last();
                            totalAffectedPosts = postsAffected.Count;

                            InsertChange threadCreate = new InsertChange(
                                Thread.TableSpec.instance,
                                new Dictionary <string, AbstractFieldValue> {
                                { Thread.TableSpec.FIELD_BOARDID, new ScalarFieldValue(_transferInfo.newBoardId.ToString()) },
                                { Thread.TableSpec.FIELD_FIRSTPOSTID, new ScalarFieldValue(this.id.ToString()) },
                                { Thread.TableSpec.FIELD_ISANNOUNCEMENT, new ScalarFieldValue("0") },
                                { Thread.TableSpec.FIELD_ISLOCKED, new ScalarFieldValue("0") },
                                { Thread.TableSpec.FIELD_LASTPOSTDATE, new ScalarFieldValue(lastAffectedPost.postDate.ToUTCString()) },
                                { Thread.TableSpec.FIELD_LASTPOSTID, new ScalarFieldValue(lastAffectedPost.id.ToString()) },
                                { Thread.TableSpec.FIELD_TITLE, new ScalarFieldValue(this.title) },
                                { Thread.TableSpec.FIELD_TOPICSTARTERID, new ScalarFieldValue(this.posterId.ToString()) },
                                { Thread.TableSpec.FIELD_TOTALPOSTS, new ScalarFieldValue(totalAffectedPosts.ToString()) },
                                { Thread.TableSpec.FIELD_TOTALVIEWS, new ScalarFieldValue("0") },
                            }
                                );
                            changes = changes.Union(threadCreate);

                            changes = changes.Union(
                                from post in postsAffected
                                select(AbstractChange) new UpdateChange(
                                    TableSpec.instance,
                                    new Dictionary <string, AbstractFieldValue> {
                                { TableSpec.FIELD_THREADID, new ReferenceFieldValue(threadCreate) },
                            },
                                    post.id
                                    )
                                );

                            if (!_transferInfo.isSubthreadTransfer)
                            {
                                changes = changes.Union(
                                    from post in this.subPosts
                                    select(AbstractChange) new UpdateChange(
                                        TableSpec.instance,
                                        new Dictionary <string, AbstractFieldValue> {
                                    { TableSpec.FIELD_PARENTPOSTID, new ScalarFieldValue(this.parentPostId.ToString()) },
                                },
                                        post.id
                                        )
                                    );
                            }
                        }

                        changes = changes.Union(
                            from board in this.thread.board.boardAndParents
                            select(AbstractChange) new UpdateChange(
                                Board.TableSpec.instance,
                                new Dictionary <string, AbstractFieldValue> {
                            { Board.TableSpec.FIELD_TOTALPOSTS, new IncrementFieldValue(IncrementFieldValue.DECREMENTOR_CUSTOM(totalAffectedPosts)) },
                            { Board.TableSpec.FIELD_TOTALTHREADS, new IncrementFieldValue(IncrementFieldValue.DECREMENTOR_CUSTOM(this.parentPostId.HasValue ? 0 : 1)) },
                        },
                                board.id
                                )
                            );

                        changes = changes.Union(
                            from board in _transferInfo.newBoard.boardAndParents
                            select(AbstractChange) new UpdateChange(
                                Board.TableSpec.instance,
                                new Dictionary <string, AbstractFieldValue> {
                            { Board.TableSpec.FIELD_TOTALPOSTS, new IncrementFieldValue(IncrementFieldValue.INCREMENTOR_CUSTOM(totalAffectedPosts)) },
                            { Board.TableSpec.FIELD_TOTALTHREADS, new IncrementFieldValue() },
                            { Board.TableSpec.FIELD_LASTPOSTID, new IncrementFieldValue(IncrementFieldValue.GREATEST(lastAffectedPost.id)) },
                        },
                                board.id
                                )
                            );

                        changes = changes.Union(
                            new UpdateChange(
                                TableSpec.instance,
                                new Dictionary <string, AbstractFieldValue> {
                            { TableSpec.FIELD_PARENTPOSTID, new ScalarFieldValue(null) },
                        },
                                this.id
                                )
                            );

                        if (this.parentPostId.HasValue)
                        {
                            changes = changes.Union(
                                new UpdateChange(
                                    Thread.TableSpec.instance,
                                    new Dictionary <string, AbstractFieldValue> {
                                { Thread.TableSpec.FIELD_TOTALPOSTS, new IncrementFieldValue(IncrementFieldValue.DECREMENTOR_CUSTOM(totalAffectedPosts)) },
                            },
                                    this.threadId
                                    )
                                );
                        }
                    }

                    changes = changes.Union(
                        new UpdateChange(
                            TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                        { TableSpec.FIELD_TOTALPUNISHMENTS, new IncrementFieldValue() },
                    },
                            this.id
                            ),
                        new InsertChange(
                            Punishment.TableSpec.instance,
                            new Dictionary <string, AbstractFieldValue> {
                        { Punishment.TableSpec.FIELD_POSTID, new ScalarFieldValue(this.id.ToString()) },
                        { Punishment.TableSpec.FIELD_OWNERID, new ScalarFieldValue(this.poster.id.ToString()) },
                        { Punishment.TableSpec.FIELD_ORIGINALBOARDID, new ScalarFieldValue(this.thread.board.id.ToString()) },
                        { Punishment.TableSpec.FIELD_MODERATORID, new ScalarFieldValue(account.id.ToString()) },
                        { Punishment.TableSpec.FIELD_PUNISHMENTDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
                        { Punishment.TableSpec.FIELD_PUNISHMENTTYPE, new ScalarFieldValue(type.id.ToString()) },
                        { Punishment.TableSpec.FIELD_ISWITHDRAWED, new ScalarFieldValue("0") },
                        { Punishment.TableSpec.FIELD_COMMENT, new ScalarFieldValue(comment) },
                        { Punishment.TableSpec.FIELD_EXPIRES, new ScalarFieldValue(DateTime.Now.Add(type.timeSpan).ToUTCString()) },
                        { Punishment.TableSpec.FIELD_TRANSFERID, (transferInsert != null) ? (AbstractFieldValue) new ReferenceFieldValue(transferInsert) : (AbstractFieldValue) new ScalarFieldValue(null) },
                        { Punishment.TableSpec.FIELD_LAYERCHANGEID, (layerChangeInsert != null) ? (AbstractFieldValue) new ReferenceFieldValue(layerChangeInsert) : (AbstractFieldValue) new ScalarFieldValue(null) },
                    }
                            )
                        );

                    ChangeSetUtil.ApplyChanges(changes.ToArray());

                    this.punishments_Reset();

                    Account posterAccount = null;
                    try {
                        posterAccount = Account.LoadByUser(this.poster);
                    } catch (NotFoundInDBException) {
                    }

                    if ((posterAccount != null) && (posterAccount.id != account.id) && !posterAccount.needsMigration)
                    {
                        PMMessage newMessage = PMConversation.SendPMMessage(
                            account,
                            posterAccount,
                            this.title,
                            String.Format("{0}{3}[post]{2}[/post]{3}{1}", type.description, comment, this.id, Util.EOL)
                            );
                        newMessage.conversation.markAsRead(account, newMessage, newMessage);
                    }

                    HashSet <int> punishmentsBoards = new HashSet <int>(from punishment in this.punishments select punishment.originalBoardId);
                    foreach (int boardId in punishmentsBoards)
                    {
                        Restriction.RecalculateRestrictions(Board.LoadById(boardId), this.poster);
                    }
                }
            }
        }