public bool LockMailbox(int mailbox_id, Int64 utc_ticks_time, bool is_additional_proccessed_check_needed, DbManager external_db)
        {
            var update_query = new SqlUpdate(MailboxTable.name)
                .Set(MailboxTable.Columns.time_checked, utc_ticks_time)
                .Set(MailboxTable.Columns.is_processed, true)
                .Where(MailboxTable.Columns.id, mailbox_id);

            if (is_additional_proccessed_check_needed)
            {
                update_query = update_query
                               .Where(MailboxTable.Columns.is_processed, false)
                               .Where(MailboxTable.Columns.is_removed, false);
            }

            if (external_db == null)
            {
                using (var db = GetDb())
                {
                    return db.ExecuteNonQuery(update_query) > 0;
                }
            }

            return external_db.ExecuteNonQuery(update_query) > 0;
        }
        public bool LockMailbox(int mailboxId, bool isAdditionalProccessedCheckNeeded, DbManager dbManager)
        {
            _log.Debug("LockMailbox(MailboxId = {0}, checkAnotherProcess = {1})", mailboxId, isAdditionalProccessedCheckNeeded);
            
            var utcNow = DateTime.UtcNow;

            bool success;

            var updateQuery = new SqlUpdate(MailboxTable.name)
                .Set(MailboxTable.Columns.date_checked, utcNow)
                .Set(MailboxTable.Columns.is_processed, true)
                .Where(MailboxTable.Columns.id, mailboxId);

            if (isAdditionalProccessedCheckNeeded)
            {
                updateQuery = updateQuery
                               .Where(MailboxTable.Columns.is_processed, false)
                               .Where(MailboxTable.Columns.is_removed, false);
            }

            if (dbManager == null)
            {
                using (var db = GetDb())
                {
                    success = db.ExecuteNonQuery(updateQuery) > 0;
                }
            }
            else
            {
                success = dbManager.ExecuteNonQuery(updateQuery) > 0;    
            }

            _log.Debug("LockMailbox(MailboxId = {0}) {1}", mailboxId, success ? "SUCCEEDED" : "FAILED");

            return success;
        }
        public void SetConversationsImportanceFlags(int tenant, string user, bool important, List<int> ids)
        {
            var chains_info_query = new SqlQuery(MailTable.name)
                .Select(MailTable.Columns.chain_id)
                .Select(MailTable.Columns.folder)
                .Select(MailTable.Columns.id_mailbox)
                .Where(GetUserWhere(user, tenant))
                .Where(new InExp(MailTable.Columns.id, ids.Select(x => (object)x).ToArray()));

            var update_mail_query = new SqlUpdate(MailTable.name)
                .Set(MailTable.Columns.importance, important)
                .Where(GetUserWhere(user, tenant));

            using (var db = GetDb())
            {
                using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted))
                {
                    var chains_info = db.ExecuteList(chains_info_query)
                                        .ConvertAll(i => new ChainInfo{
                                            id = (string)i[0],
                                            folder = Convert.ToInt32(i[1]),
                                            mailbox = Convert.ToInt32(i[2])});

                    chains_info = chains_info.Distinct().ToList();

                    if(!chains_info.Any())
                        throw new Exception("no chain messages belong to current user");

                    var where_chain_builder = new StringBuilder("(");
                    for (int i = 0; i < chains_info.Count; ++i)
                    {
                        var chain = chains_info[i];

                        if(i > 0)
                        {
                            where_chain_builder.Append(" or ");
                        }

                        where_chain_builder.AppendFormat("({0} = '{1}' and {2} = {3}", MailTable.Columns.chain_id, chain.id,
                                                                                        MailTable.Columns.id_mailbox, chain.mailbox);

                        if (chain.folder == MailFolder.Ids.inbox || chain.folder == MailFolder.Ids.sent)
                        {
                            where_chain_builder.AppendFormat(" and ({0} = {1} or {0} = {2}))", MailTable.Columns.folder,
                                                                MailFolder.Ids.inbox, MailFolder.Ids.sent);
                        }
                        else
                        {
                            where_chain_builder.AppendFormat(" and {0} = {1})", MailTable.Columns.folder, chain.folder);
                        }
                    }
                    where_chain_builder.Append(")");

                    db.ExecuteNonQuery(update_mail_query.Where(new SqlExp(where_chain_builder.ToString())));

                    foreach (var message in ids)
                    {
                        UpdateMessageChainImportanceFlag(db, tenant, user, message);
                    }

                    tx.Commit();
                }
            }
        }
        public void SetMailboxAuthError(MailBox mailbox, bool isError)
        {
            using (var db = GetDb())
            {
                var updateQuery = new SqlUpdate(MailboxTable.name)
                    .Where(MailboxTable.Columns.id, mailbox.MailBoxId)
                    .Where(MailboxTable.Columns.id_user, mailbox.UserId)
                    .Where(MailboxTable.Columns.id_tenant, mailbox.TenantId);

                if (isError)
                {
                    mailbox.AuthErrorDate = DateTime.UtcNow;
                    updateQuery.Where(MailboxTable.Columns.date_auth_error, null)
                               .Set(MailboxTable.Columns.date_auth_error, mailbox.AuthErrorDate.Value);
                }
                else
                {
                    updateQuery.Set(MailboxTable.Columns.date_auth_error, null);
                    mailbox.AuthErrorDate = null;
                }

                db.ExecuteNonQuery(updateQuery);
            }
        }
        public void DisableMailboxes(int tenant, string user = "")
        {
            using (var db = GetDb())
            {
                var updateAccountQuery = new SqlUpdate(MailboxTable.name)
                    .Where(MailboxTable.Columns.id_tenant, tenant)
                    .Where(MailboxTable.Columns.is_removed, false)
                    .Where(MailboxTable.Columns.enabled, true)
                    .Set(MailboxTable.Columns.is_processed, false)
                    .Set(MailboxTable.Columns.enabled, false);

                if (!string.IsNullOrEmpty(user))
                    updateAccountQuery.Where(MailboxTable.Columns.id_user, user);

                db.ExecuteNonQuery(updateAccountQuery);
            }
        }
        public void SetAuthError(MailBox mailbox, bool error)
        {
            using (var db = GetDb())
            {
                var instr = new SqlUpdate(MailboxTable.name)
                    .Where(MailboxTable.Columns.id, mailbox.MailBoxId)
                    .Where(MailboxTable.Columns.id_user, mailbox.UserId)
                    .Where(MailboxTable.Columns.id_tenant, mailbox.TenantId);

                db.ExecuteNonQuery(error
                                       ? instr.Where(MailboxTable.Columns.auth_error, null)
                                              .Set(MailboxTable.Columns.auth_error, DateTime.UtcNow.Ticks)
                                       : instr.Set(MailboxTable.Columns.auth_error, null));

                if (mailbox.AuthError == MailBox.AuthProblemType.NoProblems)
                    return;

                switch (mailbox.AuthError)
                {
                    case MailBox.AuthProblemType.ConnectError:
                        CreateAuthErrorWarningAlert(mailbox.TenantId, mailbox.UserId, mailbox.MailBoxId);
                        break;
                    case MailBox.AuthProblemType.TooManyErrors:
                        CreateAuthErrorDisableAlert(mailbox.TenantId, mailbox.UserId, mailbox.MailBoxId);
                        EnableMaibox(mailbox, false);
                        break;
                    default:
                        return;
                }


            }
        }
 public void SetAuthError(MailBox mailbox, bool error)
 {
     using (var db = GetDb())
     {
         var instr = new SqlUpdate(MAIL_MAILBOX)
                 .Where(MailBoxFields.id, mailbox.MailBoxId)
                 .Where(MailBoxFields.id_user, mailbox.UserId)
                 .Where(MailBoxFields.id_tenant, mailbox.TenantId);
         db.ExecuteNonQuery(error
                                ? instr.Where(MailBoxFields.auth_error, null)
                                       .Set(MailBoxFields.auth_error, DateTime.UtcNow.Ticks)
                                : instr.Set(MailBoxFields.auth_error, null));
     }
 }
        public void SetConversationsImportanceFlags(int tenant, string user, bool important, List<int> ids)
        {
            var chainsInfoQuery = new SqlQuery(MailTable.name)
                .Select(MailTable.Columns.chain_id)
                .Select(MailTable.Columns.folder)
                .Select(MailTable.Columns.id_mailbox)
                .Where(GetUserWhere(user, tenant))
                .Where(Exp.In(MailTable.Columns.id, ids.Select(x => (object)x).ToArray()));

            var updateMailQuery = new SqlUpdate(MailTable.name)
                .Set(MailTable.Columns.importance, important)
                .Where(GetUserWhere(user, tenant));

            using (var db = GetDb())
            {
                using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted))
                {
                    var chainsInfo = db.ExecuteList(chainsInfoQuery)
                                        .ConvertAll(i => new ChainInfo{
                                            id = (string)i[0],
                                            folder = Convert.ToInt32(i[1]),
                                            mailbox = Convert.ToInt32(i[2])});

                    chainsInfo = chainsInfo.Distinct().ToList();

                    if(!chainsInfo.Any())
                        throw new Exception("no chain messages belong to current user");

                    var where = Exp.Empty;
                    foreach (var chain in chainsInfo)
                    {
                        var innerWhere = Exp.Eq(MailTable.Columns.chain_id, chain.id) & Exp.Eq(MailTable.Columns.id_mailbox, chain.mailbox);

                        if (chain.folder == MailFolder.Ids.inbox || chain.folder == MailFolder.Ids.sent)
                        {
                            innerWhere &= (Exp.Eq(MailTable.Columns.folder, MailFolder.Ids.inbox) | Exp.Eq(MailTable.Columns.folder, MailFolder.Ids.sent));
                        }
                        else
                        {
                            innerWhere &= Exp.Eq(MailTable.Columns.folder, chain.folder);
                        }

                        @where |= innerWhere;
                    }

                    db.ExecuteNonQuery(updateMailQuery.Where(where));

                    foreach (var message in ids)
                    {
                        UpdateMessageChainImportanceFlag(db, tenant, user, message);
                    }

                    tx.Commit();
                }
            }
        }