Changeset 37


Ignore:
Timestamp:
05/27/08 18:13:38 (4 years ago)
Author:
antonbatenev.ya.ru
Message:

добавление аццкой штуки под названием "вытянуть всю базу" ;)

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/form_main.cpp

    r32 r37  
    2626        // MenuService 
    2727        connect(MenuServiceSynchronize,         SIGNAL(triggered()), this, SLOT(MenuServiceSynchronize_triggered())); 
     28        connect(MenuServiceGetAllMessages,      SIGNAL(triggered()), this, SLOT(MenuServiceGetAllMessages_triggered())); 
    2829        connect(MenuServiceMarkAllAsRead,       SIGNAL(triggered()), this, SLOT(MenuServiceMarkAllAsRead_triggered())); 
    2930        connect(MenuServiceMarkPatrialAsRead,   SIGNAL(triggered()), this, SLOT(MenuServiceMarkPatrialAsRead_triggered())); 
     
    178179 
    179180                        // сохранение ответа 
    180                         if (storage->SetMessageList(list, row_version, NULL) == false) 
     181                        if (storage->SetMessageList(list, row_version, true, NULL) == false) 
    181182                        { 
    182183                                storage->ShowError(this); 
     
    189190                // перезагрузка количества непрочитаных сообщений 
    190191                ForumTree->ReloadUnread(); 
     192        } 
     193} 
     194//---------------------------------------------------------------------------------------------- 
     195 
     196void FormMain::MenuServiceGetAllMessages_triggered () 
     197{ 
     198        // основные настройки 
     199        QSettings settings; 
     200 
     201        QString rsdn_host = settings.value("rsdn/host", "www.rsdn.ru").toString(); 
     202        int     rsdn_port = settings.value("rsdn/port", "80").toInt(); 
     203 
     204        // получение хранилища 
     205        std::auto_ptr<IStorage> storage(AStorageFactory::GetStorage()); 
     206 
     207        if (storage.get() == NULL) 
     208        { 
     209                QMessageBox::critical(this, QString::fromUtf8("Ошибка!"), QString::fromUtf8("Не выбрано хранилище данных")); 
     210                return; 
     211        } 
     212 
     213        QString header; 
     214        QString data; 
     215 
     216        // 
     217        // синхронизация сообщений 
     218        // 
     219 
     220        // для того, чтобы загрузить весь список сообщений 
     221        // необходимо повторить операцию N раз, т.к. могут быть, например, оборваные ветки 
     222 
     223        int count = -1; 
     224        int from  = 0; 
     225 
     226        while (count != 0) 
     227        { 
     228                // формирование списка загрузки 
     229                QList<int> ids; 
     230 
     231                while (ids.count() < 1000) 
     232                { 
     233                        QList<int> exists; 
     234 
     235                        // получение уже загруженных id 
     236                        if (storage->GetMessageIds(from, from + 1000, exists, NULL) == false) 
     237                        { 
     238                                storage->ShowError(this); 
     239                                return; 
     240                        } 
     241 
     242                        // анализ существующих 
     243                        for (int i = from; i < from + 1000; i++) 
     244                        { 
     245                                int idx = exists.indexOf(i); 
     246 
     247                                if (idx != -1) 
     248                                { 
     249                                        exists.removeAt(idx); 
     250                                        continue; 
     251                                } 
     252 
     253                                ids.append(i); 
     254 
     255                                if (ids.count() == 1000) 
     256                                        break; 
     257                        } 
     258 
     259                        if (ids.count() > 0) 
     260                                from = ids[ids.count() - 1] + 1; 
     261                        else 
     262                                from += 1000; 
     263                } 
     264 
     265                // получение текста запроса 
     266                AWebservice::GetMessageListByID_WebserviceQuery(header, data, ids, NULL); 
     267 
     268                // запрос к вебсервису 
     269                std::auto_ptr<FormRequest> form(new FormRequest(this, rsdn_host, rsdn_port, header, data)); 
     270 
     271                if (form->exec() == QDialog::Accepted) 
     272                { 
     273                        QString answer = form->GetResponse(); 
     274 
     275                        // парсинг ответа 
     276                        ADataList list; 
     277 
     278                        QString result = AWebservice::GetMessageListByID_WebserviceParse(answer, list, NULL); 
     279 
     280                        if (result.length() > 0) 
     281                        { 
     282                                QMessageBox::critical(this, QString::fromUtf8("Ошибка!"), result); 
     283                                return; 
     284                        } 
     285 
     286                        // сохранение ответа 
     287                        ARowVersion row_version; 
     288 
     289                        if (storage->SetMessageList(list, row_version, false, NULL) == false) 
     290                        { 
     291                                storage->ShowError(this); 
     292                                return; 
     293                        } 
     294 
     295                        count = list.Message.count() + list.Rating.count() + list.Moderate.count(); 
     296                } 
     297                else 
     298                        return; 
    191299        } 
    192300} 
  • trunk/form_main.h

    r19 r37  
    3434                // MenuService 
    3535                void MenuServiceSynchronize_triggered         (); 
     36                void MenuServiceGetAllMessages_triggered      (); 
    3637                void MenuServiceMarkAllAsRead_triggered       (); 
    3738                void MenuServiceMarkPatrialAsRead_triggered   (); 
  • trunk/form_main_ui.cpp

    r28 r37  
    3535        MenuServiceSynchronize = MenuService->addAction(QString::fromUtf8("Синхронизировать")); 
    3636        MenuServiceSynchronize->setIcon(QIcon(":/icons/synchronize16.png")); 
     37 
     38        MenuServiceGetAllMessages = MenuService->addAction(QString::fromUtf8("Получить всю базу")); 
     39        MenuServiceGetAllMessages->setIcon(QIcon(":/icons/synchronize16.png")); 
    3740 
    3841        MenuService->addSeparator(); 
  • trunk/form_main_ui.h

    r2 r37  
    4040                QMenu*       MenuService; 
    4141                QAction*        MenuServiceSynchronize; 
     42                QAction*        MenuServiceGetAllMessages; 
    4243                QAction*        MenuServiceMarkAllAsRead; 
    4344                QAction*        MenuServiceMarkPatrialAsRead; 
  • trunk/storage/istorage.h

    r32 r37  
    5555 
    5656                // сохраняет список сообщений 
    57                 virtual bool SetMessageList (const ADataList& list, const ARowVersion& row_version, IProgress* progress = NULL) = 0; 
     57                virtual bool SetMessageList (const ADataList& list, const ARowVersion& row_version, bool save_row_version, IProgress* progress = NULL) = 0; 
    5858 
    5959                // возвращает количество непрочитанных сообщений для форумов 
     
    7979                // clean - очистить базу от "лишних" сообщений 
    8080                virtual bool Unsubscribe (const QList<int>& list, AIDSet type, bool clean, IProgress* progress = NULL) = 0; 
     81 
     82                // возвращает существующие id сообщений в заданном интервале 
     83                virtual bool GetMessageIds (int from_id, int to_id, QList<int>& list, IProgress* progress = NULL) = 0; 
    8184}; 
    8285//---------------------------------------------------------------------------------------------- 
  • trunk/storage/mysql_storage.cpp

    r36 r37  
    876876//---------------------------------------------------------------------------------------------- 
    877877 
    878 bool AMySQLStorage::SetMessageList (const ADataList& list, const ARowVersion& row_version, IProgress* progress) 
     878bool AMySQLStorage::SetMessageList (const ADataList& list, const ARowVersion& row_version, bool save_row_version, IProgress* progress) 
    879879{ 
    880880        if (progress != NULL) 
     
    890890        // 
    891891 
    892         sql += "INSERT INTO `row_version`\n"; 
    893         sql += "(\n"; 
    894         sql += "        `key`,\n"; 
    895         sql += "        `value`\n"; 
    896         sql += ")\n"; 
    897         sql += "VALUES\n"; 
    898         sql += "(\n"; 
    899         sql += "        :key,\n"; 
    900         sql += "        :value\n"; 
    901         sql += ")\n"; 
    902         sql += "ON DUPLICATE KEY UPDATE\n"; 
    903         sql += "        `value` = :u_value"; 
    904  
    905         std::auto_ptr<AQuery> query_insert_row(CreateQuery(sql)); 
    906  
    907         if (query_insert_row.get() == NULL) 
    908         { 
    909                 QString msg = AMySQLDatabase::LastError(); 
    910  
    911                 Rollback(); 
    912  
    913                 return ReturnError(msg); 
    914         } 
    915  
    916         query_insert_row->bindValue(":key",     "message"); 
    917         query_insert_row->bindValue(":value",   row_version.Message); 
    918         query_insert_row->bindValue(":u_value", row_version.Message); 
    919  
    920         if (query_insert_row->exec() == false) 
    921         { 
    922                 Rollback(); 
    923  
    924                 return ReturnError(query_insert_row->LastError()); 
    925         } 
    926  
    927         query_insert_row->bindValue(":key",     "rating"); 
    928         query_insert_row->bindValue(":value",   row_version.Rating); 
    929         query_insert_row->bindValue(":u_value", row_version.Rating); 
    930  
    931         if (query_insert_row->exec() == false) 
    932         { 
    933                 Rollback(); 
    934  
    935                 return ReturnError(query_insert_row->LastError()); 
    936         } 
    937  
    938         query_insert_row->bindValue(":key",     "moderate"); 
    939         query_insert_row->bindValue(":value",   row_version.Moderate); 
    940         query_insert_row->bindValue(":u_value", row_version.Moderate); 
    941  
    942         if (query_insert_row->exec() == false) 
    943         { 
    944                 Rollback(); 
    945  
    946                 return ReturnError(query_insert_row->LastError()); 
     892        if (save_row_version == true) 
     893        { 
     894                sql += "INSERT INTO `row_version`\n"; 
     895                sql += "(\n"; 
     896                sql += "        `key`,\n"; 
     897                sql += "        `value`\n"; 
     898                sql += ")\n"; 
     899                sql += "VALUES\n"; 
     900                sql += "(\n"; 
     901                sql += "        :key,\n"; 
     902                sql += "        :value\n"; 
     903                sql += ")\n"; 
     904                sql += "ON DUPLICATE KEY UPDATE\n"; 
     905                sql += "        `value` = :u_value"; 
     906 
     907                std::auto_ptr<AQuery> query_insert_row(CreateQuery(sql)); 
     908 
     909                if (query_insert_row.get() == NULL) 
     910                { 
     911                        QString msg = AMySQLDatabase::LastError(); 
     912 
     913                        Rollback(); 
     914 
     915                        return ReturnError(msg); 
     916                } 
     917 
     918                query_insert_row->bindValue(":key",     "message"); 
     919                query_insert_row->bindValue(":value",   row_version.Message); 
     920                query_insert_row->bindValue(":u_value", row_version.Message); 
     921 
     922                if (query_insert_row->exec() == false) 
     923                { 
     924                        Rollback(); 
     925 
     926                        return ReturnError(query_insert_row->LastError()); 
     927                } 
     928 
     929                query_insert_row->bindValue(":key",     "rating"); 
     930                query_insert_row->bindValue(":value",   row_version.Rating); 
     931                query_insert_row->bindValue(":u_value", row_version.Rating); 
     932 
     933                if (query_insert_row->exec() == false) 
     934                { 
     935                        Rollback(); 
     936 
     937                        return ReturnError(query_insert_row->LastError()); 
     938                } 
     939 
     940                query_insert_row->bindValue(":key",     "moderate"); 
     941                query_insert_row->bindValue(":value",   row_version.Moderate); 
     942                query_insert_row->bindValue(":u_value", row_version.Moderate); 
     943 
     944                if (query_insert_row->exec() == false) 
     945                { 
     946                        Rollback(); 
     947 
     948                        return ReturnError(query_insert_row->LastError()); 
     949                } 
    947950        } 
    948951 
     
    22542257} 
    22552258//---------------------------------------------------------------------------------------------- 
     2259 
     2260bool AMySQLStorage::GetMessageIds (int from_id, int to_id, QList<int>& list, IProgress* progress) 
     2261{ 
     2262        if (progress != NULL) 
     2263                progress->OnProgress(0); 
     2264 
     2265        QString sql; 
     2266 
     2267        sql += "SELECT\n"; 
     2268        sql += "        `id`\n"; 
     2269        sql += "FROM\n"; 
     2270        sql += "        `message`\n"; 
     2271        sql += "WHERE\n"; 
     2272        sql += "        `id` >= " + QString::number(from_id) + " AND\n"; 
     2273        sql += "        `id` <  " + QString::number(to_id); 
     2274 
     2275        std::auto_ptr<AQuery> query_select(CreateQuery(sql, false)); 
     2276 
     2277        if (query_select.get() == NULL) 
     2278                return ReturnError(AMySQLDatabase::LastError()); 
     2279 
     2280        if (query_select->exec() == false) 
     2281                return ReturnError(query_select->LastError()); 
     2282 
     2283        while (query_select->next()) 
     2284                list.append(query_select->value(0).toInt()); 
     2285 
     2286        return ReturnSuccess(); 
     2287 
     2288} 
     2289//---------------------------------------------------------------------------------------------- 
  • trunk/storage/mysql_storage.h

    r32 r37  
    5555 
    5656                // сохраняет список сообщений 
    57                 bool SetMessageList (const ADataList& list, const ARowVersion& row_version, IProgress* progress = NULL); 
     57                bool SetMessageList (const ADataList& list, const ARowVersion& row_version, bool save_row_version, IProgress* progress = NULL); 
    5858 
    5959                // возвращает количество непрочитанных сообщений для форумов 
     
    7979                // clean - очистить базу от "лишних" сообщений 
    8080                bool Unsubscribe (const QList<int>& list, AIDSet type, bool clean, IProgress* progress = NULL); 
     81 
     82                // возвращает существующие id сообщений в заданном интервале 
     83                bool GetMessageIds (int from_id, int to_id, QList<int>& list, IProgress* progress = NULL); 
    8184}; 
    8285//---------------------------------------------------------------------------------------------- 
  • trunk/webservice.cpp

    r36 r37  
    460460} 
    461461//---------------------------------------------------------------------------------------------- 
     462 
     463void AWebservice::GetMessageListByID_WebserviceQuery (QString& header, QString& data, const QList<int> ids, IProgress* progress) 
     464{ 
     465        if (progress != NULL) 
     466                progress->OnProgress(0); 
     467 
     468        QSettings settings; 
     469 
     470        QString rsdn_login    = settings.value("rsdn/login",    "").toString(); 
     471        QString rsdn_password = settings.value("rsdn/password", "").toString(); 
     472 
     473        data = ""; 
     474        data += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; 
     475        data += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n"; 
     476        data += "  <soap:Body>\r\n"; 
     477        data += "    <GetTopicByMessage xmlns=\"http://rsdn.ru/Janus/\">\r\n"; 
     478        data += "      <topicRequest>\r\n"; 
     479        data += (QString)"        <userName>" + rsdn_login + "</userName>\r\n"; 
     480        data += (QString)"        <password>" + rsdn_password + "</password>\r\n"; 
     481 
     482        // ID оборванных сообщений, то есть сообщений без родителя. 
     483        if (ids.count() > 0) 
     484        { 
     485                data += "        <messageIds>\r\n"; 
     486 
     487                for (int i = 0; i < ids.count(); i++) 
     488                        data += (QString)"          <int>" + QString::number(ids[i]) + "</int>\r\n"; 
     489 
     490                data += "        </messageIds>\r\n"; 
     491        } 
     492        else 
     493                data += "        <messageIds />\r\n"; 
     494 
     495        data += "      </topicRequest>\r\n"; 
     496        data += "    </GetTopicByMessage>\r\n"; 
     497        data += "  </soap:Body>\r\n"; 
     498        data += "</soap:Envelope>\r\n"; 
     499 
     500        header = ""; 
     501        header += "POST /ws/janusAT.asmx HTTP/1.1\r\n"; 
     502        header += "Host: rsdn.ru\r\n"; 
     503        header += "Content-Type: text/xml; charset=utf-8\r\n"; 
     504        header += (QString)"Content-Length: " + QString::number(data.length()) + "\r\n"; 
     505        header += "SOAPAction: \"http://rsdn.ru/Janus/GetTopicByMessage\"\r\n"; 
     506} 
     507//---------------------------------------------------------------------------------------------- 
     508 
     509QString AWebservice::GetMessageListByID_WebserviceParse (const QString& data, ADataList& list, IProgress* progress) 
     510{ 
     511        if (progress != NULL) 
     512                progress->OnProgress(0); 
     513 
     514        list.Rating.clear(); 
     515        list.Message.clear(); 
     516        list.Moderate.clear(); 
     517 
     518        int seed = 0; 
     519 
     520        QString message_info = GetNextBlock(&data, "<JanusMessageInfo>", "</JanusMessageInfo>", seed); 
     521 
     522        while (message_info.length()) 
     523        { 
     524                AMessageInfo info; 
     525 
     526                info.ID             = GetTextBetween(&message_info, "<messageId>",      "</messageId>").toInt(); 
     527                info.IDTopic        = GetTextBetween(&message_info, "<topicId>",        "</topicId>").toInt(); 
     528                info.IDParent       = GetTextBetween(&message_info, "<parentId>",       "</parentId>").toInt(); 
     529                info.IDUser         = GetTextBetween(&message_info, "<userId>",         "</userId>").toInt(); 
     530                info.IDForum        = GetTextBetween(&message_info, "<forumId>",        "</forumId>").toInt(); 
     531                info.Subject        = GetTextBetween(&message_info, "<subject>",        "</subject>"); 
     532                info.MessageName    = GetTextBetween(&message_info, "<messageName>",    "</messageName>"); 
     533                info.UserNick       = GetTextBetween(&message_info, "<userNick>",       "</userNick>"); 
     534                info.Message        = GetTextBetween(&message_info, "<message>",        "</message>"); 
     535                info.IDArticle      = GetTextBetween(&message_info, "<articleId>",      "</articleId>").toInt(); 
     536                info.MessageDate    = DateTimeFromString(GetTextBetween(&message_info, "<messageDate>", "</messageDate>")); 
     537                info.UpdateDate     = DateTimeFromString(GetTextBetween(&message_info, "<updateDate>", "</updateDate>")); 
     538                info.UserRole       = GetTextBetween(&message_info, "<userRole>",       "</userRole>"); 
     539                info.UserTitle      = GetTextBetween(&message_info, "<userTitle>",      "</userTitle>"); 
     540                info.UserTitleColor = GetTextBetween(&message_info, "<userTitleColor>", "</userTitleColor>").toInt(); 
     541                info.LastModerated  = DateTimeFromString(GetTextBetween(&message_info, "<lastModerated>", "</lastModerated>")); 
     542 
     543                if (info.MessageDate.isValid() == false) 
     544                        return QString::fromUtf8("Некорректное значение даты <messageDate>: ") + GetTextBetween(&message_info, "<messageDate>", "</messageDate>"); 
     545 
     546                if (info.UpdateDate.isValid() == false) 
     547                        return QString::fromUtf8("Некорректное значение даты <updateDate>: ") + GetTextBetween(&message_info, "<updateDate>", "</updateDate>"); 
     548 
     549                if (info.LastModerated.isValid() == false) 
     550                        return QString::fromUtf8("Некорректное значение даты <lastModerated>: ") + GetTextBetween(&message_info, "<lastModerated>", "</lastModerated>"); 
     551 
     552                list.Message.append(info); 
     553 
     554                message_info = GetNextBlock(&data, "<JanusMessageInfo>", "</JanusMessageInfo>", seed); 
     555        } 
     556 
     557        seed = 0; 
     558 
     559        QString rating_info = GetNextBlock(&data, "<JanusRatingInfo>", "</JanusRatingInfo>", seed); 
     560 
     561        while (rating_info.length()) 
     562        { 
     563                ARatingInfo info; 
     564 
     565                info.IDMessage  = GetTextBetween(&rating_info, "<messageId>",  "</messageId>").toInt(); 
     566                info.IDTopic    = GetTextBetween(&rating_info, "<topicId>",    "</topicId>").toInt(); 
     567                info.IDUser     = GetTextBetween(&rating_info, "<userId>",     "</userId>").toInt(); 
     568                info.UserRating = GetTextBetween(&rating_info, "<userRating>", "</userRating>").toInt(); 
     569                info.Rate       = GetTextBetween(&rating_info, "<rate>",       "</rate>").toInt(); 
     570                info.RateDate   = DateTimeFromString(GetTextBetween(&rating_info, "<rateDate>", "</rateDate>")); 
     571 
     572                if (info.RateDate.isValid() == false) 
     573                        return QString::fromUtf8("Некорректное значение даты <rateDate>: ") + GetTextBetween(&rating_info, "<rateDate>", "</rateDate>"); 
     574 
     575                list.Rating.append(info); 
     576 
     577                rating_info = GetNextBlock(&data, "<JanusRatingInfo>", "</JanusRatingInfo>", seed); 
     578        } 
     579 
     580        seed = 0; 
     581 
     582        QString moderate_info = GetNextBlock(&data, "<JanusModerateInfo>", "</JanusModerateInfo>", seed); 
     583 
     584        while (moderate_info.length()) 
     585        { 
     586                AModerateInfo info; 
     587 
     588                info.IDMessage = GetTextBetween(&moderate_info, "<messageId>", "</messageId>").toInt(); 
     589                info.IDUser    = GetTextBetween(&moderate_info, "<userId>",    "</userId>").toInt(); 
     590                info.IDForum   = GetTextBetween(&moderate_info, "<forumId>",   "</forumId>").toInt(); 
     591                info.Created   = DateTimeFromString(GetTextBetween(&moderate_info, "<create>", "</create>")); 
     592 
     593                if (info.Created.isValid() == false) 
     594                        return QString::fromUtf8("Некорректное значение даты <create>: ") + GetTextBetween(&moderate_info, "<create>", "</create>"); 
     595 
     596                list.Moderate.append(info); 
     597 
     598                moderate_info = GetNextBlock(&data, "<JanusModerateInfo>", "</JanusModerateInfo>", seed); 
     599        } 
     600 
     601        return ""; 
     602} 
     603//---------------------------------------------------------------------------------------------- 
  • trunk/webservice.h

    r21 r37  
    3434                // парсит ответ со списком сообщений и заносит результат в список 
    3535                static QString GetMessageList_WebserviceParse (const QString& data, ADataList& list, ARowVersion& row_version, IProgress* progress = NULL); 
     36 
     37                // возвращает заголовок и данные для POST запроса получения сообщений по их id 
     38                static void GetMessageListByID_WebserviceQuery (QString& header, QString& data, const QList<int> ids, IProgress* progress = NULL); 
     39 
     40                // парсит ответ со списком сообщений и заносит результат в список 
     41                static QString GetMessageListByID_WebserviceParse (const QString& data, ADataList& list, IProgress* progress = NULL); 
     42 
    3643}; 
    3744//---------------------------------------------------------------------------------------------- 
Note: See TracChangeset for help on using the changeset viewer.