Changeset 43


Ignore:
Timestamp:
05/30/08 02:37:46 (4 years ago)
Author:
antonbatenev.ya.ru
Message:

Доделана быстрая загрузка самого большого форума (.NET)

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/avalon.sql

    r41 r43  
    33-- Host: localhost    Database: avalon 
    44-- ------------------------------------------------------ 
    5 -- Server version       5.0.45 
     5-- Server version       5.0.51a 
    66 
    77/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 
     
    3131 
    3232DROP TABLE IF EXISTS `forum`; 
     33SET @saved_cs_client     = @@character_set_client; 
     34SET character_set_client = utf8; 
    3335CREATE TABLE `forum` ( 
    3436  `id` int(11) NOT NULL COMMENT 'id', 
     
    4143  PRIMARY KEY  (`id`) 
    4244) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='список форумов'; 
     45SET character_set_client = @saved_cs_client; 
    4346 
    4447-- 
     
    4750 
    4851DROP TABLE IF EXISTS `group`; 
     52SET @saved_cs_client     = @@character_set_client; 
     53SET character_set_client = utf8; 
    4954CREATE TABLE `group` ( 
    5055  `id` int(11) NOT NULL COMMENT 'id', 
     
    5358  PRIMARY KEY  (`id`) 
    5459) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='список групп форумов'; 
     60SET character_set_client = @saved_cs_client; 
    5561 
    5662-- 
     
    5965 
    6066DROP TABLE IF EXISTS `message`; 
     67SET @saved_cs_client     = @@character_set_client; 
     68SET character_set_client = utf8; 
    6169CREATE TABLE `message` ( 
    6270  `id` int(11) NOT NULL COMMENT 'id сообщения', 
     
    8290  KEY `ix_id_forum` USING BTREE (`id_forum`) 
    8391) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='сообщения'; 
     92SET character_set_client = @saved_cs_client; 
    8493 
    8594-- 
     
    8897 
    8998DROP TABLE IF EXISTS `message_topic`; 
     99SET @saved_cs_client     = @@character_set_client; 
     100SET character_set_client = utf8; 
    90101CREATE TABLE `message_topic` ( 
    91102  `id_message` int(11) NOT NULL COMMENT 'id сообщения', 
    92   `id_topic` int(11) NOT NULL COMMENT 'id темы', 
    93   `id_parent` int(11) NOT NULL COMMENT 'id родительского сообщения', 
    94   `id_user` int(11) NOT NULL COMMENT 'id автора', 
    95   `id_forum` int(11) NOT NULL COMMENT 'id форума', 
    96   `subject` varchar(100) NOT NULL COMMENT 'тема сообщения', 
    97   `message_name` varchar(100) NOT NULL COMMENT 'имя сообщения', 
    98   `user_nick` varchar(100) NOT NULL COMMENT 'имя автора сообщения', 
    99   `id_article` int(11) NOT NULL COMMENT 'id статьи, если сообщение является статьей или 0', 
     103  `id_forum` int(11) NOT NULL COMMENT 'id форума', 
    100104  `message_date` datetime NOT NULL COMMENT 'дата создания сообщения', 
    101   `update_date` datetime NOT NULL COMMENT 'дата обновления сообщения или 0', 
    102   `user_role` varchar(50) NOT NULL COMMENT 'статус автора сообщения', 
    103   `user_title` varchar(100) NOT NULL COMMENT 'повязка пользователя', 
    104   `user_title_color` int(11) NOT NULL COMMENT 'цвет повязки пользователя', 
    105   `last_moderated` datetime NOT NULL COMMENT 'дата последнего переноса сообщения', 
    106   `has_child` tinyint(1) NOT NULL COMMENT 'флаг наличия дочерних сообщений', 
    107105  PRIMARY KEY  (`id_message`), 
    108106  KEY `ix_id_forum` (`id_forum`), 
    109107  CONSTRAINT `fk_message_topic_message` FOREIGN KEY (`id_message`) REFERENCES `message` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
    110108) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='список топиков'; 
     109SET character_set_client = @saved_cs_client; 
    111110 
    112111-- 
     
    115114 
    116115DROP TABLE IF EXISTS `moderate`; 
     116SET @saved_cs_client     = @@character_set_client; 
     117SET character_set_client = utf8; 
    117118CREATE TABLE `moderate` ( 
    118119  `id_message` int(11) NOT NULL COMMENT 'id сообщения', 
     
    122123  PRIMARY KEY  USING BTREE (`id_message`,`id_user`) 
    123124) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='таблица бомбочек'; 
     125SET character_set_client = @saved_cs_client; 
    124126 
    125127-- 
     
    128130 
    129131DROP TABLE IF EXISTS `rating`; 
     132SET @saved_cs_client     = @@character_set_client; 
     133SET character_set_client = utf8; 
    130134CREATE TABLE `rating` ( 
    131135  `id_message` int(11) NOT NULL COMMENT 'id сообщения', 
     
    137141  PRIMARY KEY  (`id_message`,`id_user`) 
    138142) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='таблица рейтинга'; 
     143SET character_set_client = @saved_cs_client; 
    139144 
    140145-- 
     
    143148 
    144149DROP TABLE IF EXISTS `row_version`; 
     150SET @saved_cs_client     = @@character_set_client; 
     151SET character_set_client = utf8; 
    145152CREATE TABLE `row_version` ( 
    146153  `key` varchar(100) NOT NULL COMMENT 'ключ версии', 
     
    148155  PRIMARY KEY  (`key`) 
    149156) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='версии данных'; 
     157SET character_set_client = @saved_cs_client; 
    150158 
    151159-- 
     
    154162 
    155163DROP TABLE IF EXISTS `subscribed`; 
     164SET @saved_cs_client     = @@character_set_client; 
     165SET character_set_client = utf8; 
    156166CREATE TABLE `subscribed` ( 
    157167  `id_forum` int(11) NOT NULL COMMENT 'id форума', 
     
    159169  PRIMARY KEY  (`id_forum`) 
    160170) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='список форумов, на которые подписан пользователь'; 
     171SET character_set_client = @saved_cs_client; 
    161172 
    162173-- 
     
    165176 
    166177DROP TABLE IF EXISTS `unread`; 
     178SET @saved_cs_client     = @@character_set_client; 
     179SET character_set_client = utf8; 
    167180CREATE TABLE `unread` ( 
    168181  `id_message` int(11) NOT NULL COMMENT 'id непрочитанного сообщения', 
     
    172185  PRIMARY KEY  (`id_message`) 
    173186) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='список непрочитанных сообщений'; 
     187SET character_set_client = @saved_cs_client; 
    174188 
    175189-- 
     
    178192 
    179193DROP TABLE IF EXISTS `user`; 
     194SET @saved_cs_client     = @@character_set_client; 
     195SET character_set_client = utf8; 
    180196CREATE TABLE `user` ( 
    181197  `id` int(11) NOT NULL COMMENT 'id пользователя', 
     
    190206  PRIMARY KEY  (`id`) 
    191207) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='список пользователей'; 
     208SET character_set_client = @saved_cs_client; 
    192209 
    193210-- 
     
    206223/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 
    207224 
    208 -- Dump completed on 2008-05-29 16:40:23 
     225-- Dump completed on 2008-05-29 22:33:45 
  • trunk/form_main.cpp

    r40 r43  
    221221        // необходимо повторить операцию N раз, т.к. могут быть, например, оборваные ветки 
    222222 
    223         int from = 2966468; 
     223        int from = 2967176; 
    224224 
    225225        int count_per_request = 1000; 
    226226 
    227         while (from < 2967180) 
     227        while (from < 2970235) 
    228228        { 
    229229                // формирование списка загрузки 
  • trunk/message_tree.cpp

    r42 r43  
    1313{ 
    1414        // дескриптор сообщения 
    15         AMessageInfoEx MessageInfo; 
    16  
    17         // флаг наличия загрузки информации 
     15        ATopicInfo Info;  // актуально только для топиков, а для сообщений AMessageInfoEx 
     16 
     17        // флаг наличия загрузки информации (актуально только для топиков) 
    1818        bool IsInfoLoaded; 
    1919 
    20         // флаг того, что загружены дочерние сообщения 
     20        // флаг того, что загружены дочерние сообщения (актуально только для топиков) 
    2121        bool IsChildLoaded; 
     22 
     23        // количество непрочитанных дочерних 
     24        int UnreadChildCount; 
     25 
     26        // загружено ли тело сообщения 
     27        bool IsBodyLoaded; 
    2228}; 
    2329//---------------------------------------------------------------------------------------------- 
     
    6470//---------------------------------------------------------------------------------------------- 
    6571 
     72void AMessageTree::resizeEvent (QResizeEvent* event) 
     73{ 
     74        ScrollTopics(); 
     75 
     76        QTreeWidget::resizeEvent(event); 
     77} 
     78//---------------------------------------------------------------------------------------------- 
     79 
    6680void AMessageTree::Save () 
    6781{ 
     
    98112void AMessageTree::ChangeForum (const AForumInfo* forum_info) 
    99113{ 
    100         if (forum_info == NULL) 
    101                 m_id_forum = 0; 
     114        m_id_forum = 0; 
    102115 
    103116        clear(); 
     
    115128        } 
    116129 
     130        // вывод наименования форума в хедер 
     131        headerItem()->setText(0, forum_info->Name); 
     132 
     133        // получение хранилища 
     134        std::auto_ptr<IStorage> storage(AStorageFactory::GetStorage()); 
     135 
     136        if (storage.get() == NULL) 
     137        { 
     138                QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 
     139                return; 
     140        } 
     141 
     142        // получение топиков 
     143        QList<int> topic_list; 
     144 
     145        if (storage->GetForumTopicList(forum_info->ID, topic_list, NULL) == false) 
     146        { 
     147                storage->ShowError(m_parent); 
     148                return; 
     149        } 
     150 
     151        // установка топиков 
     152        QList<QTreeWidgetItem*> items; 
     153 
     154        for (int i = 0; i < topic_list.count(); i++) 
     155        { 
     156                MessageTreeWidgetItem* item = new MessageTreeWidgetItem(); 
     157 
     158                AMessageInfoGUI* info = item->PTag(); 
     159 
     160                info->Info.ID          = topic_list[i]; 
     161                info->IsInfoLoaded     = false; 
     162                info->IsChildLoaded    = false; 
     163                info->UnreadChildCount = 0; 
     164                info->IsBodyLoaded     = false; 
     165 
     166                items.append(item); 
     167        } 
     168 
     169        // отображение 
     170        addTopLevelItems(items); 
     171 
    117172        // сохраняем для скролла 
    118173        m_id_forum = forum_info->ID; 
    119174 
    120         // вывод наименования форума в хедер 
    121         headerItem()->setText(0, forum_info->Name); 
    122  
    123         // получение хранилища 
    124         std::auto_ptr<IStorage> storage(AStorageFactory::GetStorage()); 
    125  
    126         if (storage.get() == NULL) 
    127         { 
    128                 QMessageBox::critical(m_parent, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 
    129                 return; 
    130         } 
    131  
    132         // получение топиков 
    133         QList<int> topic_list; 
    134  
    135         if (storage->GetForumTopicList(forum_info->ID, topic_list, NULL) == false) 
    136         { 
    137                 storage->ShowError(m_parent); 
    138                 return; 
    139         } 
    140  
    141         // установка топиков 
    142         QList<QTreeWidgetItem*> items; 
    143  
    144         for (int i = 0; i < topic_list.count(); i++) 
    145         { 
    146                 MessageTreeWidgetItem* item = new MessageTreeWidgetItem(); 
    147  
    148                 AMessageInfoGUI* info = item->PTag(); 
    149  
    150                 info->MessageInfo.ID = topic_list[i]; 
    151                 info->IsInfoLoaded   = false; 
    152                 info->IsChildLoaded  = false; 
    153  
    154                 items.append(item); 
    155         } 
    156  
    157         // отображение 
    158         addTopLevelItems(items); 
    159  
    160175        // загрузка видимых топиков 
    161176        ScrollTopics(); 
     
    174189                return; 
    175190 
    176         QTreeWidgetItem* top_item = itemAt(1, 1); 
    177  
    178         // поиск верхнего видимого элемента 
     191        // верхний видимый элемент 
     192        QTreeWidgetItem* top_item = itemAt(1, 5); 
     193 
    179194        if (top_item == NULL) 
    180195                return; 
    181196 
     197        while (top_item->parent() != NULL) 
     198                top_item = top_item->parent(); 
     199 
    182200        int from_index = indexOfTopLevelItem(top_item); 
    183 ((QMainWindow*)m_parent)->setWindowTitle(QString::number(from_index)); 
    184         int size = topLevelItemCount(); 
    185  
    186         for (int i = 0; i < size; i++) 
    187         { 
    188                 MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(topLevelItem(i)); 
    189  
    190                 QRect rect = visualItemRect(item); 
    191  
    192                 if (rect.top() < 0) 
    193                 { 
    194                         from_index = i; 
    195                         continue; 
    196                 } 
    197  
    198                 break; 
    199         } 
    200  
    201         // поиск нижнего видимого элемента 
    202         int tree_height = height(); 
    203  
    204         AMessageInfoExList            list; 
     201 
     202        // нижний видимый элемент 
     203        QTreeWidgetItem* bottom_item = itemAt(1, height() - 5); 
     204 
     205        int to_index = topLevelItemCount(); 
     206 
     207        if (bottom_item != NULL) 
     208        { 
     209                while (bottom_item->parent() != NULL) 
     210                        bottom_item = bottom_item->parent(); 
     211 
     212                to_index = indexOfTopLevelItem(bottom_item) + 1; 
     213 
     214                if (to_index < from_index) 
     215                        to_index = from_index + 100; // ~56 элементов влезет по высоте на стандартный экран 1280x1024 
     216 
     217                if (to_index > topLevelItemCount()) 
     218                        to_index = topLevelItemCount(); 
     219        } 
     220 
     221        // поиск еще не агруженных элементов 
     222        ATopicInfoList                list; 
    205223        QList<MessageTreeWidgetItem*> items; 
    206224 
    207         while (from_index < size) 
     225        while (from_index < to_index) 
    208226        { 
    209227                MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(topLevelItem(from_index)); 
    210228 
    211                 QRect rect = visualItemRect(item); 
    212  
    213                 if (rect.top() > tree_height) 
    214                         break; 
    215  
    216229                if (item->PTag()->IsInfoLoaded == false) 
    217230                { 
    218                         AMessageInfoEx info; 
    219  
    220                         info.ID = item->PTag()->MessageInfo.ID; 
     231                        ATopicInfo info; 
     232 
     233                        info.ID = item->PTag()->Info.ID; 
    221234 
    222235                        list.append(info); 
     
    226239                from_index++; 
    227240        } 
    228 /* 
     241 
    229242        // загрузка топиков, которые не загружены 
    230243        if (list.count() > 0) 
     
    248261                for (int i = 0; i < list.count(); i++) 
    249262                { 
    250                         AMessageInfoEx info = list.at(i); 
     263                        ATopicInfo info = list.at(i); 
    251264 
    252265                        for (int j = 0; j < items.count(); j++) 
     
    254267                                MessageTreeWidgetItem* item = items[j]; 
    255268 
    256                                 if (item->PTag()->MessageInfo.ID == info.ID) 
     269                                if (item->PTag()->Info.ID == info.ID) 
    257270                                { 
    258                                         item->PTag()->MessageInfo = info; 
     271                                        AMessageInfoGUI* item_info = item->PTag(); 
     272 
     273                                        item_info->Info             = info; 
     274                                        item_info->IsInfoLoaded     = true; 
     275                                        item_info->IsChildLoaded    = false; 
     276                                        item_info->UnreadChildCount = 0; 
     277                                        item_info->IsBodyLoaded     = false; 
    259278 
    260279                                        item->setText(0, info.Subject); 
     
    269288                                        if (info.IsRead == true) 
    270289                                                item->setIcon(0, m_message_read); 
     290                                        else if (info.HasUnreadChild == true) 
     291                                                item->setIcon(0, m_child_unread); 
    271292                                        else 
    272293                                                item->setIcon(0, m_message_unread); 
     294 
     295                                        if (info.HasChild == true) 
     296                                                item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); 
    273297 
    274298                                        break; 
     
    276300                        } 
    277301                } 
    278         }*/ 
     302        } 
    279303} 
    280304//---------------------------------------------------------------------------------------------- 
     
    282306void AMessageTree::expand_item (QTreeWidgetItem* item_expanded) 
    283307{ 
    284 /* 
    285308        if (item_expanded == NULL) 
    286309                return; 
     
    288311        MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(item_expanded); 
    289312 
    290         if (item->PTag()->HasChild == true && item->PTag()->IsChildLoaded == false) 
     313        if (item->PTag()->Info.HasChild == true && item->PTag()->IsChildLoaded == false) 
    291314        { 
    292315                // получение хранилища 
     
    302325                AMessageInfoExList list; 
    303326 
    304                 if (storage->GetTopicMessageList(item->PTag()->ID, list, NULL) == false) 
     327                if (storage->GetTopicMessageList(item->PTag()->Info.ID, list, NULL) == false) 
    305328                { 
    306329                        storage->ShowError(m_parent); 
     
    318341                        ExpandUnreadChild(item); 
    319342        } 
    320 */ 
    321343} 
    322344//---------------------------------------------------------------------------------------------- 
     
    324346void AMessageTree::ExpandUnreadChild (QTreeWidgetItem* widget_item) 
    325347{ 
    326 /* 
    327348        MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 
    328349 
     
    335356                expandItem(item); 
    336357        } 
    337 */ 
    338 } 
    339 //---------------------------------------------------------------------------------------------- 
    340 /* 
     358} 
     359//---------------------------------------------------------------------------------------------- 
     360 
    341361void AMessageTree::BuildTree (QTreeWidgetItem* parent, AMessageInfoExList* list) 
    342362{ 
     363 
    343364        MessageTreeWidgetItem* parent_item = static_cast<MessageTreeWidgetItem*>(parent); 
    344365 
     
    347368        int index     = 0; 
    348369        int size      = list->size(); 
    349         int id_parent = parent_item->PTag()->ID; 
     370        int id_parent = parent_item->PTag()->Info.ID; 
    350371 
    351372        while (index < size) 
     
    357378                        MessageTreeWidgetItem* item = new MessageTreeWidgetItem(parent_item); 
    358379 
    359                         info.IsMessageLoaded  = false; 
    360                         info.IsChildLoaded    = true; 
    361                         info.HasChild         = false; 
    362                         info.UnreadChildCount = 0; 
    363  
    364                         item->SetTag(info); 
     380                        AMessageInfoGUI* item_info = item->PTag(); 
     381 
     382                        // AMessageInfo 
     383                        item_info->Info.ID               = info.ID; 
     384                        item_info->Info.IDTopic          = info.IDTopic; 
     385                        item_info->Info.IDParent         = info.IDParent; 
     386                        item_info->Info.IDUser           = info.IDUser; 
     387                        item_info->Info.IDForum          = info.IDForum; 
     388                        item_info->Info.Subject          = info.Subject; 
     389                        item_info->Info.MessageName      = info.MessageName; 
     390                        item_info->Info.UserNick         = info.UserNick; 
     391                        item_info->Info.IDArticle        = info.IDArticle; 
     392                        item_info->Info.MessageDate      = info.MessageDate; 
     393                        item_info->Info.UpdateDate       = info.UpdateDate; 
     394                        item_info->Info.UserRole         = info.UserRole; 
     395                        item_info->Info.UserTitle        = info.UserTitle; 
     396                        item_info->Info.UserTitleColor   = info.UserTitleColor; 
     397                        item_info->Info.LastModerated    = info.LastModerated; 
     398 
     399                        // AMessageInfoEx 
     400                        item_info->Info.IsRead           = info.IsRead; 
     401 
     402                        // ATopicInfo 
     403                        item_info->Info.HasChild         = false; 
     404 
     405                        // AMessageInfoGUI 
     406                        item_info->IsInfoLoaded          = true; 
     407                        item_info->IsChildLoaded         = true; 
     408                        item_info->UnreadChildCount      = 0; 
     409                        item_info->IsBodyLoaded          = false; 
    365410 
    366411                        item->setText(0, info.Subject); 
     
    391436                                while (temp_item != NULL) 
    392437                                { 
    393                                         if (set_icon == true && temp_item->PTag()->IsRead == true) 
     438                                        if (set_icon == true && temp_item->PTag()->Info.IsRead == true) 
    394439                                                temp_item->setIcon(0, m_child_unread); 
    395440                                        else 
     
    410455        for (int i = 0; i < size; i++) 
    411456                BuildTree(to_build.at(i), list); 
    412 }*/ 
     457} 
    413458//---------------------------------------------------------------------------------------------- 
    414459 
     
    435480void AMessageTree::selection_changed () 
    436481{ 
    437 /* 
    438482        MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(GetSelectedItem()); 
    439483 
     
    441485                return; 
    442486 
    443         if (item->PTag()->IsMessageLoaded == false) 
     487        if (item->PTag()->IsBodyLoaded == false) 
    444488        { 
    445489                // TODO загрузить сообщение 
     
    457501                QString body; 
    458502 
    459                 if (storage->GetMessageInfo(item->PTag()->ID, body, NULL) == false) 
     503                if (storage->GetMessageBody(item->PTag()->Info.ID, body, NULL) == false) 
    460504                { 
    461505                        storage->ShowError(m_parent); 
     
    463507                } 
    464508 
    465                 item->PTag()->IsMessageLoaded = true; 
    466                 item->PTag()->Message = body; 
    467         } 
    468  
    469         AMessageInfo message = item->Tag(); 
    470  
    471         m_message_view->SetMessage(message); 
    472  
    473         if (item->PTag()->IsRead == false) 
     509                item->PTag()->IsBodyLoaded = true; 
     510                item->PTag()->Info.Message = body; 
     511        } 
     512 
     513        AMessageInfoGUI message = item->Tag(); 
     514 
     515        m_message_view->SetMessage(message.Info); 
     516 
     517        if (item->PTag()->Info.IsRead == false) 
    474518                m_timer.start(1500); 
    475519        else 
    476520                m_timer.stop(); 
    477 */ 
    478521} 
    479522//---------------------------------------------------------------------------------------------- 
     
    481524void AMessageTree::MakeItemAsRead (QTreeWidgetItem* widget_item) 
    482525{ 
    483 /* 
    484526        MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 
    485527 
    486         AMessageInfoEx* info = item->PTag(); 
     528        AMessageInfoGUI* info = item->PTag(); 
    487529 
    488530        // пометить как прочитаное в хранилище 
     
    495537        } 
    496538 
    497         if (storage->SetIDsAsRead(QList<int>() << info->ID, idsMessage, true, QDateTime(), NULL) == false) 
     539        if (storage->SetIDsAsRead(QList<int>() << info->Info.ID, idsMessage, true, QDateTime(), NULL) == false) 
    498540        { 
    499541                storage->ShowError(m_parent); 
     
    502544 
    503545        // пометка как прочитанного в дереве сообщений 
    504         if (info->IsRead == true) 
    505                 return; 
    506  
    507         info->IsRead = true; 
     546        if (info->Info.IsRead == true) 
     547                return; 
     548 
     549        info->Info.IsRead = true; 
    508550 
    509551        if (info->UnreadChildCount != 0) 
     
    516558        while (parent_item != NULL) 
    517559        { 
    518                 AMessageInfoEx* parent_info = parent_item->PTag(); 
     560                AMessageInfoGUI* parent_info = parent_item->PTag(); 
    519561 
    520562                parent_info->UnreadChildCount--; 
    521563 
    522                 if (parent_info->IsRead == true && parent_info->UnreadChildCount == 0) 
     564                if (parent_info->Info.IsRead == true && parent_info->UnreadChildCount == 0) 
    523565                        parent_item->setIcon(0, m_message_read); 
    524566 
     
    528570        // уменьшение количества непрочитанных в дереве форума 
    529571        m_forum_tree->ChangeUnreadCount(-1); 
    530 */ 
    531 } 
    532 //---------------------------------------------------------------------------------------------- 
     572} 
     573//---------------------------------------------------------------------------------------------- 
  • trunk/message_tree.h

    r41 r43  
    5656 
    5757                // построение ветки 
    58                 //void BuildTree (QTreeWidgetItem* parent, AMessageInfoExList* list); 
     58                void BuildTree (QTreeWidgetItem* parent, AMessageInfoExList* list); 
    5959 
    6060                // пометка сообщения как прочитанного 
     
    7373                void selection_changed (); 
    7474                void timer_on_timer    (); 
     75 
     76        protected: 
     77 
     78                void resizeEvent (QResizeEvent* event); 
    7579}; 
    7680//---------------------------------------------------------------------------------------------- 
  • trunk/message_view.h

    r29 r43  
    3030        protected: 
    3131 
    32                 void virtual resizeEvent (QResizeEvent* event); 
     32                void resizeEvent (QResizeEvent* event); 
    3333 
    3434        private: 
  • trunk/model/message.h

    r41 r43  
    6060typedef struct AMessageInfoEx : AMessageInfo 
    6161{ 
    62         bool IsRead;   // прочитано ли сообщение 
    63         bool HasChild; // есть ли дочерние сообщения 
     62        bool IsRead; // прочитано ли сообщение 
    6463}; 
    6564//---------------------------------------------------------------------------------------------- 
     
    6867typedef QList<AMessageInfoEx> AMessageInfoExList; 
    6968//---------------------------------------------------------------------------------------------- 
     69// информация о топике 
     70//---------------------------------------------------------------------------------------------- 
     71typedef struct ATopicInfo : AMessageInfoEx 
     72{ 
     73        bool HasChild;       // есть ли дочерние сообщения 
     74        bool HasUnreadChild; // есть ли дочерние непрочитанные сообщения 
     75}; 
     76//---------------------------------------------------------------------------------------------- 
     77// список сообщений для отображения в дереве 
     78//---------------------------------------------------------------------------------------------- 
     79typedef QList<ATopicInfo> ATopicInfoList; 
     80//---------------------------------------------------------------------------------------------- 
    7081#endif 
  • trunk/storage/istorage.h

    r41 r43  
    6363                virtual bool GetForumTopicList (int id_forum, QList<int>& list, IProgress* progress = NULL) = 0; 
    6464 
    65 /* 
     65                // заполняет полную информацию о топиках 
     66                virtual bool GetTopicInfo (ATopicInfoList& list, IProgress* progress = NULL) = 0; 
     67 
    6668                // возвращает список сообщений в топике (родительской ветке) 
    67                 // должны быть заполнены все поля 
    6869                virtual bool GetTopicMessageList (int id_topic, AMessageInfoExList& list, IProgress* progress = NULL) = 0; 
    69 */ 
    70                 // заполняет полную информацию о топиках 
    71                 virtual bool GetTopicInfo (AMessageInfoExList& list, IProgress* progress = NULL) = 0; 
     70 
     71                // возвращает текст сообщения 
     72                virtual bool GetMessageBody (int id_message, QString& body, IProgress* progress = NULL) = 0; 
    7273 
    7374                // пометить группу сущностей как прочитанное/непрочитанное 
  • trunk/storage/mysql_storage.cpp

    r41 r43  
    10241024        } 
    10251025 
     1026        // запрос для вставки в список топиков 
     1027        sql  = ""; 
     1028        sql += "INSERT INTO `message_topic`\n"; 
     1029        sql += "(\n"; 
     1030        sql += "        `id_message`,\n"; 
     1031        sql += "        `id_forum`,\n"; 
     1032        sql += "        `message_date`\n"; 
     1033        sql += ")\n"; 
     1034        sql += "VALUES\n"; 
     1035        sql += "(\n"; 
     1036        sql += "        :id_message,\n"; 
     1037        sql += "        :id_forum,\n"; 
     1038        sql += "        :message_date\n"; 
     1039        sql += ")\n"; 
     1040        sql += "ON DUPLICATE KEY UPDATE\n"; 
     1041        sql += "        `id_forum`         = :u_id_forum,\n"; 
     1042        sql += "        `message_date`     = :u_message_date\n"; 
     1043 
     1044        std::auto_ptr<AQuery> query_insert_message_topic(CreateQuery(sql)); 
     1045 
     1046        if (query_insert_message_topic.get() == NULL) 
     1047        { 
     1048                QString msg = AMySQLDatabase::LastError(); 
     1049 
     1050                Rollback(); 
     1051 
     1052                return ReturnError(msg); 
     1053        } 
     1054 
    10261055        // запрос для вставки в список непрочитанных сообщений 
    10271056        sql  = ""; 
     
    11181147                } 
    11191148 
     1149                // сообщения с нулевым форумом в списке топиков не требуются 
     1150                if (info.IDTopic == 0 && info.IDForum != 0) 
     1151                { 
     1152                        query_insert_message_topic->bindValue(":id_message",     info.ID); 
     1153                        query_insert_message_topic->bindValue(":id_forum",       info.IDForum); 
     1154                        query_insert_message_topic->bindValue(":message_date",   info.MessageDate); 
     1155 
     1156                        query_insert_message_topic->bindValue(":u_id_forum",     info.IDForum); 
     1157                        query_insert_message_topic->bindValue(":u_message_date", info.MessageDate); 
     1158 
     1159                        if (query_insert_message_topic->exec() == false) 
     1160                        { 
     1161                                Rollback(); 
     1162 
     1163                                return ReturnError(query_insert_message_topic->LastError()); 
     1164                        } 
     1165                } 
     1166 
    11201167                // странно, но бывают сообщения с нулевым форумом, 
    11211168                // которые потом будут вечно храниться в unread 
    1122                 if (info.IDForum != 0) 
     1169                if (info.IDForum != 0 && save_row_version == true) 
    11231170                { 
    11241171                        query_insert_unread->bindValue(":id_message",     info.ID); 
     
    15571604} 
    15581605//---------------------------------------------------------------------------------------------- 
    1559 /* 
    1560 bool AMySQLStorage::GetTopicMessageList (int id_topic, AMessageInfoExList& list, IProgress* progress) 
     1606 
     1607bool AMySQLStorage::GetTopicInfo (ATopicInfoList& list, IProgress* progress) 
    15611608{ 
    15621609        if (progress != NULL) 
    15631610                progress->OnProgress(0); 
    15641611 
     1612        // заполнение id-шников сообщений, которые требуется получить 
     1613        QString ids; 
     1614 
     1615        for (int i = 0; i < list.count(); i++) 
     1616        { 
     1617                ids += QString::number(list[i].ID); 
     1618 
     1619                if (i < list.count() - 1) 
     1620                        ids += ", "; 
     1621        } 
     1622 
    15651623        QString sql; 
    15661624 
    15671625        // 
    1568         // получение сообщений топика 
     1626        // получение инфы топика 
    15691627        // 
    15701628 
     
    15891647        sql += "        `message`\n"; 
    15901648        sql += "WHERE\n"; 
    1591         sql += "        `id_topic` = " + QString::number(id_topic) + "\n"; 
    1592         sql += "ORDER BY\n"; 
    1593         sql += "        `message_date` DESC"; 
    1594  
    1595         std::auto_ptr<AQuery> query_select(CreateQuery(sql, false)); 
    1596  
    1597         if (query_select.get() == NULL) 
    1598                 return ReturnError(AMySQLDatabase::LastError()); 
    1599  
    1600         if (query_select->exec() == false) 
    1601                 return ReturnError(query_select->LastError()); 
    1602  
    1603         while (query_select->next()) 
    1604         { 
    1605                 AMessageInfoEx info; 
    1606  
    1607                 info.IsRead         = true; 
    1608                 info.HasUnreadChild = false; 
    1609  
    1610                 info.ID             = query_select->value(0).toInt(); 
    1611                 info.IDTopic        = query_select->value(1).toInt(); 
    1612                 info.IDParent       = query_select->value(2).toInt(); 
    1613                 info.IDUser         = query_select->value(3).toInt(); 
    1614                 info.IDForum        = query_select->value(4).toInt(); 
    1615                 info.Subject        = query_select->value(5).toString(); 
    1616                 info.MessageName    = query_select->value(6).toString(); 
    1617                 info.UserNick       = query_select->value(7).toString(); 
    1618                 info.IDArticle      = query_select->value(8).toInt(); 
    1619                 info.MessageDate    = query_select->value(9).toDateTime(); 
    1620                 info.UpdateDate     = query_select->value(10).toDateTime(); 
    1621                 info.UserRole       = query_select->value(11).toString(); 
    1622                 info.UserTitle      = query_select->value(12).toString(); 
    1623                 info.UserTitleColor = query_select->value(13).toInt(); 
    1624                 info.LastModerated  = query_select->value(14).toDateTime(); 
    1625                 info.HasChild       = query_select->value(15).toInt(); 
    1626  
    1627                 list.append(info); 
    1628         } 
    1629  
    1630         // 
    1631         // непрочитанные сообщения 
    1632         // 
    1633  
    1634         sql  = ""; 
    1635         sql += "SELECT\n"; 
    1636         sql += "        `id_message`\n"; 
    1637         sql += "FROM\n"; 
    1638         sql += "        `unread`\n"; 
    1639         sql += "WHERE\n"; 
    1640         sql += "        `id_topic` = " + QString::number(id_topic) + "\n"; 
    1641         sql += "ORDER BY\n"; 
    1642         sql += "        `message_date`"; 
    1643  
    1644         std::auto_ptr<AQuery> query_select_unread(CreateQuery(sql, false)); 
    1645  
    1646         if (query_select_unread.get() == NULL) 
    1647                 return ReturnError(AMySQLDatabase::LastError()); 
    1648  
    1649         if (query_select_unread->exec() == false) 
    1650                 return ReturnError(query_select_unread->LastError()); 
    1651  
    1652         while (query_select_unread->next()) 
    1653         { 
    1654                 int id = query_select_unread->value(0).toInt(); 
    1655  
    1656                 for (int i = 0; i < list.count(); i++) 
    1657                         if (list[i].ID == id) 
    1658                         { 
    1659                                 list[i].IsRead = false; 
    1660                                 list.move(i, 0); 
    1661                                 break; 
    1662                         } 
    1663         } 
    1664  
    1665         return ReturnSuccess(); 
    1666 } 
    1667 //---------------------------------------------------------------------------------------------- 
    1668 */ 
    1669  
    1670 bool AMySQLStorage::GetTopicInfo (AMessageInfoExList& list, IProgress* progress) 
    1671 { 
    1672         if (progress != NULL) 
    1673                 progress->OnProgress(0); 
    1674  
    1675         // заполнение id-шников сообщений, которые требуется получить 
    1676         QString ids; 
    1677  
    1678         for (int i = 0; i < list.count(); i++) 
    1679         { 
    1680                 ids += QString::number(list[i].ID); 
    1681  
    1682                 if (i < list.count() - 1) 
    1683                         ids += ", "; 
    1684         } 
    1685  
    1686         QString sql; 
    1687  
    1688         // 
    1689         // получение инфы топика 
    1690         // 
    1691  
    1692         sql += "SELECT\n"; 
    1693         sql += "        `id_message`,\n"; 
    1694         sql += "        `id_topic`,\n"; 
    1695         sql += "        `id_parent`,\n"; 
    1696         sql += "        `id_user`,\n"; 
    1697         sql += "        `id_forum`,\n"; 
    1698         sql += "        `subject`,\n"; 
    1699         sql += "        `message_name`,\n"; 
    1700         sql += "        `user_nick`,\n"; 
    1701         sql += "        `id_article`,\n"; 
    1702         sql += "        `message_date`,\n"; 
    1703         sql += "        `update_date`,\n"; 
    1704         sql += "        `user_role`,\n"; 
    1705         sql += "        `user_title`,\n"; 
    1706         sql += "        `user_title_color`,\n"; 
    1707         sql += "        `last_moderated`,\n"; 
    1708         sql += "        `has_child`\n"; 
    1709         sql += "FROM\n"; 
    1710         sql += "        `message_topic`\n"; 
    1711         sql += "WHERE\n"; 
    1712         sql += "        `id_message` IN (" + ids + ")"; 
     1649        sql += "        `id` IN (" + ids + ")"; 
    17131650 
    17141651        std::auto_ptr<AQuery> query_select(CreateQuery(sql, false)); 
     
    17441681 
    17451682                                list[i].IsRead         = true; 
     1683                                list[i].HasUnreadChild = false; 
    17461684 
    17471685                                break; 
     
    17801718                        } 
    17811719        } 
     1720 
     1721        // 
     1722        // получение списка непрочитаных дочерних 
     1723        // 
     1724 
     1725        sql  = ""; 
     1726        sql += "SELECT\n"; 
     1727        sql += "        `id_topic`\n"; 
     1728        sql += "FROM\n"; 
     1729        sql += "        `unread`\n"; 
     1730        sql += "WHERE\n"; 
     1731        sql += "        `id_topic` IN (" + ids + ")\n"; 
     1732        sql += "GROUP BY\n"; 
     1733        sql += "        `id_topic`\n"; 
     1734 
     1735        std::auto_ptr<AQuery> query_select_unread_child(CreateQuery(sql, false)); 
     1736 
     1737        if (query_select_unread_child.get() == NULL) 
     1738                return ReturnError(AMySQLDatabase::LastError()); 
     1739 
     1740        if (query_select_unread_child->exec() == false) 
     1741                return ReturnError(query_select_unread_child->LastError()); 
     1742 
     1743        while (query_select_unread_child->next()) 
     1744        { 
     1745                int id = query_select_unread_child->value(0).toInt(); 
     1746 
     1747                for (int i = 0; i < list.count(); i++) 
     1748                        if (id == list[i].ID) 
     1749                        { 
     1750                                list[i].HasUnreadChild = true; 
     1751                                break; 
     1752                        } 
     1753        } 
     1754 
     1755        return ReturnSuccess(); 
     1756} 
     1757//---------------------------------------------------------------------------------------------- 
     1758 
     1759bool AMySQLStorage::GetTopicMessageList (int id_topic, AMessageInfoExList& list, IProgress* progress) 
     1760{ 
     1761        if (progress != NULL) 
     1762                progress->OnProgress(0); 
     1763 
     1764        QString sql; 
     1765 
     1766        // 
     1767        // получение сообщений топика 
     1768        // 
     1769 
     1770        sql += "SELECT\n"; 
     1771        sql += "        `id`,\n"; 
     1772        sql += "        `id_topic`,\n"; 
     1773        sql += "        `id_parent`,\n"; 
     1774        sql += "        `id_user`,\n"; 
     1775        sql += "        `id_forum`,\n"; 
     1776        sql += "        `subject`,\n"; 
     1777        sql += "        `message_name`,\n"; 
     1778        sql += "        `user_nick`,\n"; 
     1779        sql += "        `id_article`,\n"; 
     1780        sql += "        `message_date`,\n"; 
     1781        sql += "        `update_date`,\n"; 
     1782        sql += "        `user_role`,\n"; 
     1783        sql += "        `user_title`,\n"; 
     1784        sql += "        `user_title_color`,\n"; 
     1785        sql += "        `last_moderated`\n"; 
     1786        sql += "FROM\n"; 
     1787        sql += "        `message`\n"; 
     1788        sql += "WHERE\n"; 
     1789        sql += "        `id_topic` = " + QString::number(id_topic) + "\n"; 
     1790        sql += "ORDER BY\n"; 
     1791        sql += "        `message_date` DESC"; 
     1792 
     1793        std::auto_ptr<AQuery> query_select(CreateQuery(sql, false)); 
     1794 
     1795        if (query_select.get() == NULL) 
     1796                return ReturnError(AMySQLDatabase::LastError()); 
     1797 
     1798        if (query_select->exec() == false) 
     1799                return ReturnError(query_select->LastError()); 
     1800 
     1801        while (query_select->next()) 
     1802        { 
     1803                AMessageInfoEx info; 
     1804 
     1805                info.ID             = query_select->value(0).toInt(); 
     1806                info.IDTopic        = query_select->value(1).toInt(); 
     1807                info.IDParent       = query_select->value(2).toInt(); 
     1808                info.IDUser         = query_select->value(3).toInt(); 
     1809                info.IDForum        = query_select->value(4).toInt(); 
     1810                info.Subject        = query_select->value(5).toString(); 
     1811                info.MessageName    = query_select->value(6).toString(); 
     1812                info.UserNick       = query_select->value(7).toString(); 
     1813                info.IDArticle      = query_select->value(8).toInt(); 
     1814                info.MessageDate    = query_select->value(9).toDateTime(); 
     1815                info.UpdateDate     = query_select->value(10).toDateTime(); 
     1816                info.UserRole       = query_select->value(11).toString(); 
     1817                info.UserTitle      = query_select->value(12).toString(); 
     1818                info.UserTitleColor = query_select->value(13).toInt(); 
     1819                info.LastModerated  = query_select->value(14).toDateTime(); 
     1820 
     1821                info.IsRead         = true; 
     1822 
     1823                list.append(info); 
     1824        } 
     1825 
     1826        // 
     1827        // непрочитанные сообщения 
     1828        // 
     1829 
     1830        sql  = ""; 
     1831        sql += "SELECT\n"; 
     1832        sql += "        `id_message`\n"; 
     1833        sql += "FROM\n"; 
     1834        sql += "        `unread`\n"; 
     1835        sql += "WHERE\n"; 
     1836        sql += "        `id_topic` = " + QString::number(id_topic) + "\n"; 
     1837        sql += "ORDER BY\n"; 
     1838        sql += "        `message_date`"; 
     1839 
     1840        std::auto_ptr<AQuery> query_select_unread(CreateQuery(sql, false)); 
     1841 
     1842        if (query_select_unread.get() == NULL) 
     1843                return ReturnError(AMySQLDatabase::LastError()); 
     1844 
     1845        if (query_select_unread->exec() == false) 
     1846                return ReturnError(query_select_unread->LastError()); 
     1847 
     1848        while (query_select_unread->next()) 
     1849        { 
     1850                int id = query_select_unread->value(0).toInt(); 
     1851 
     1852                for (int i = 0; i < list.count(); i++) 
     1853                        if (list[i].ID == id) 
     1854                        { 
     1855                                list[i].IsRead = false; 
     1856                                //list.move(i, 0); 
     1857                                break; 
     1858                        } 
     1859        } 
     1860 
     1861        return ReturnSuccess(); 
     1862} 
     1863//---------------------------------------------------------------------------------------------- 
     1864 
     1865bool AMySQLStorage::GetMessageBody (int id_message, QString& body, IProgress* progress) 
     1866{ 
     1867        if (progress != NULL) 
     1868                progress->OnProgress(0); 
     1869 
     1870        QString sql; 
     1871 
     1872        // 
     1873        // получение сообщений топика 
     1874        // 
     1875 
     1876        sql += "SELECT\n"; 
     1877        sql += "        `message`\n"; 
     1878        sql += "FROM\n"; 
     1879        sql += "        `message`\n"; 
     1880        sql += "WHERE\n"; 
     1881        sql += "        `id` = " + QString::number(id_message); 
     1882 
     1883        std::auto_ptr<AQuery> query_select(CreateQuery(sql, false)); 
     1884 
     1885        if (query_select.get() == NULL) 
     1886                return ReturnError(AMySQLDatabase::LastError()); 
     1887 
     1888        if (query_select->exec() == false) 
     1889                return ReturnError(query_select->LastError()); 
     1890 
     1891        while (query_select->next()) 
     1892                body = query_select->value(0).toString(); 
    17821893 
    17831894        return ReturnSuccess(); 
  • trunk/storage/mysql_storage.h

    r41 r43  
    6262                // возвращает список топиков (родительских веток) для форума 
    6363                bool GetForumTopicList (int id_forum, QList<int>& list, IProgress* progress = NULL); 
    64 /* 
     64 
     65                // заполняет полную информацию о топиках 
     66                bool GetTopicInfo (ATopicInfoList& list, IProgress* progress = NULL); 
     67 
    6568                // возвращает список сообщений в топике (родительской ветке) 
    6669                bool GetTopicMessageList (int id_topic, AMessageInfoExList& list, IProgress* progress = NULL); 
    67 */ 
    68                 // заполняет полную информацию о топиках 
    69                 bool GetTopicInfo (AMessageInfoExList& list, IProgress* progress = NULL); 
     70 
     71                // возвращает текст сообщения 
     72                bool GetMessageBody (int id_message, QString& body, IProgress* progress = NULL); 
    7073 
    7174                // пометить группу сущностей как прочитанное/непрочитанное 
Note: See TracChangeset for help on using the changeset viewer.