/[LeafOK_CVS]/lbbs/src/section_list_loader.c
ViewVC logotype

Diff of /lbbs/src/section_list_loader.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.6 by sysadm, Tue May 27 09:33:11 2025 UTC Revision 1.13 by sysadm, Sat May 31 01:37:18 2025 UTC
# Line 15  Line 15 
15   ***************************************************************************/   ***************************************************************************/
16    
17  #include "section_list_loader.h"  #include "section_list_loader.h"
18    #include "article_cache.h"
19  #include "log.h"  #include "log.h"
20  #include "database.h"  #include "database.h"
21  #include "menu.h"  #include "menu.h"
# Line 26  Line 27 
27  #include <strings.h>  #include <strings.h>
28  #include <unistd.h>  #include <unistd.h>
29    
30    #define _POSIX_C_SOURCE 200809L
31    #include <string.h>
32    
33  #define SECTION_LIST_LOAD_INTERVAL 10 // second  #define SECTION_LIST_LOAD_INTERVAL 10 // second
34    
35  int section_list_loader_pid;  int section_list_loader_pid;
# Line 38  int load_section_config_from_db(void) Line 42  int load_section_config_from_db(void)
42          MYSQL_ROW row, row2;          MYSQL_ROW row, row2;
43          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
44          int32_t sid;          int32_t sid;
45          char master_name[BBS_username_max_len + 1];          char master_list[(BBS_username_max_len + 1) * 3 + 1];
46          SECTION_LIST *p_section;          SECTION_LIST *p_section;
47          int ret;          int ret;
48    
# Line 76  int load_section_config_from_db(void) Line 80  int load_section_config_from_db(void)
80                                   "SELECT username FROM section_master "                                   "SELECT username FROM section_master "
81                                   "INNER JOIN user_list ON section_master.UID = user_list.UID "                                   "INNER JOIN user_list ON section_master.UID = user_list.UID "
82                                   "WHERE SID = %d AND section_master.enable AND (NOW() BETWEEN begin_dt AND end_dt) "                                   "WHERE SID = %d AND section_master.enable AND (NOW() BETWEEN begin_dt AND end_dt) "
83                                   "ORDER BY major DESC LIMIT 1",                                   "ORDER BY major DESC, begin_dt ASC LIMIT 3",
84                                   sid);                                   sid);
85    
86                  if (mysql_query(db, sql) != 0)                  if (mysql_query(db, sql) != 0)
# Line 91  int load_section_config_from_db(void) Line 95  int load_section_config_from_db(void)
95                          ret = -3;                          ret = -3;
96                          break;                          break;
97                  }                  }
98                  if ((row2 = mysql_fetch_row(rs2)))  
99                  {                  master_list[0] = '\0';
100                          strncpy(master_name, row2[0], sizeof(master_name) - 1);                  while ((row2 = mysql_fetch_row(rs2)))
                         master_name[sizeof(master_name) - 1] = '\0';  
                 }  
                 else  
101                  {                  {
102                          master_name[0] = '\0';                          strncat(master_list, row2[0], sizeof(master_list) - 1 - strnlen(master_list, sizeof(master_list)));
103                            strncat(master_list, " ", sizeof(master_list) - 1 - strnlen(master_list, sizeof(master_list)));
104                  }                  }
105                  mysql_free_result(rs2);                  mysql_free_result(rs2);
106    
# Line 106  int load_section_config_from_db(void) Line 108  int load_section_config_from_db(void)
108    
109                  if (p_section == NULL)                  if (p_section == NULL)
110                  {                  {
111                          p_section = section_list_create(sid, row[1], row[2], "");                          p_section = section_list_create(sid, row[1], row[2], master_list);
112                          if (p_section == NULL)                          if (p_section == NULL)
113                          {                          {
114                                  log_error("section_list_create() error: load new section sid = %d sname = %s\n", sid, row[1]);                                  log_error("section_list_create() error: load new section sid = %d sname = %s\n", sid, row[1]);
# Line 134  int load_section_config_from_db(void) Line 136  int load_section_config_from_db(void)
136                          p_section->sname[sizeof(p_section->sname) - 1] = '\0';                          p_section->sname[sizeof(p_section->sname) - 1] = '\0';
137                          strncpy(p_section->stitle, row[1], sizeof(p_section->stitle) - 1);                          strncpy(p_section->stitle, row[1], sizeof(p_section->stitle) - 1);
138                          p_section->stitle[sizeof(p_section->stitle) - 1] = '\0';                          p_section->stitle[sizeof(p_section->stitle) - 1] = '\0';
139                          strncpy(p_section->master_name, master_name, sizeof(p_section->master_name) - 1);                          strncpy(p_section->master_list, master_list, sizeof(p_section->master_list) - 1);
140                          p_section->master_name[sizeof(p_section->master_name) - 1] = '\0';                          p_section->master_list[sizeof(p_section->master_list) - 1] = '\0';
141                  }                  }
142    
143                  p_section->class_id = atoi(row[3]);                  p_section->class_id = atoi(row[3]);
# Line 157  int load_section_config_from_db(void) Line 159  int load_section_config_from_db(void)
159          return ret;          return ret;
160  }  }
161    
162  int append_articles_from_db(int32_t start_aid, int global_lock)  int append_articles_from_db(int32_t start_aid, int global_lock, int article_count_limit)
163  {  {
164          MYSQL *db;          MYSQL *db;
165          MYSQL_RES *rs;          MYSQL_RES *rs;
# Line 167  int append_articles_from_db(int32_t star Line 169  int append_articles_from_db(int32_t star
169          ARTICLE *p_topic;          ARTICLE *p_topic;
170          SECTION_LIST *p_section = NULL;          SECTION_LIST *p_section = NULL;
171          int32_t last_sid = 0;          int32_t last_sid = 0;
172            int article_count = 0;
173          int ret = 0;          int ret = 0;
174          int i;          int i;
175    
# Line 178  int append_articles_from_db(int32_t star Line 181  int append_articles_from_db(int32_t star
181          }          }
182    
183          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
184                           "SELECT AID, TID, SID, CID, UID, visible, excerption, ontop, `lock`, "                           "SELECT bbs.AID, TID, SID, bbs.CID, UID, visible, excerption, ontop, `lock`, "
185                           "transship, username, nickname, title, UNIX_TIMESTAMP(sub_dt) AS sub_dt "                           "transship, username, nickname, title, UNIX_TIMESTAMP(sub_dt) AS sub_dt, "
186                           "FROM bbs WHERE AID >= %d ORDER BY AID",                           "bbs_content.content "
187                           start_aid);                           "FROM bbs INNER JOIN bbs_content ON bbs.CID = bbs_content.CID "
188                             "WHERE bbs.AID >= %d ORDER BY bbs.AID LIMIT %d",
189                             start_aid, article_count_limit);
190    
191          if (mysql_query(db, sql) != 0)          if (mysql_query(db, sql) != 0)
192          {          {
# Line 236  int append_articles_from_db(int32_t star Line 241  int append_articles_from_db(int32_t star
241                  {                  {
242                          if ((ret = section_list_rw_unlock(p_section)) < 0)                          if ((ret = section_list_rw_unlock(p_section)) < 0)
243                          {                          {
244                                  log_error("section_list_rw_unlock(sid = %d) error\n", p_section->sid);                                  log_error("section_list_rw_unlock(sid=%d) error\n", p_section->sid);
245                                  break;                                  break;
246                          }                          }
247                  }                  }
# Line 265  int append_articles_from_db(int32_t star Line 270  int append_articles_from_db(int32_t star
270                  {                  {
271                          if ((ret = section_list_rw_lock(p_section)) < 0)                          if ((ret = section_list_rw_lock(p_section)) < 0)
272                          {                          {
273                                  log_error("section_list_rw_lock(sid = 0) error\n");                                  log_error("section_list_rw_lock(sid=0) error\n");
274                                  break;                                  break;
275                          }                          }
276                  }                  }
# Line 275  int append_articles_from_db(int32_t star Line 280  int append_articles_from_db(int32_t star
280    
281                  if (section_list_append_article(p_section, &article) < 0)                  if (section_list_append_article(p_section, &article) < 0)
282                  {                  {
283                          log_error("section_list_append_article(sid = %d, aid = %d) error\n",                          log_error("section_list_append_article(sid=%d, aid=%d) error\n",
284                                            p_section->sid, article.aid);                                            p_section->sid, article.aid);
285                          ret = -3;                          ret = -3;
286                          break;                          break;
287                  }                  }
288    
289                    article_count++;
290    
291                    if (article_cache_generate(VAR_ARTICLE_CACHE_DIR, &article, p_section, row[i++], 0) < 0)
292                    {
293                            log_error("article_cache_generate(aid=%d, cid=%d) error\n", article.aid, article.cid);
294                            ret = -4;
295                            break;
296                    }
297          }          }
298    
299          // release lock of last section          // release lock of last section
# Line 287  int append_articles_from_db(int32_t star Line 301  int append_articles_from_db(int32_t star
301          {          {
302                  if ((ret = section_list_rw_unlock(p_section)) < 0)                  if ((ret = section_list_rw_unlock(p_section)) < 0)
303                  {                  {
304                          log_error("section_list_rw_unlock(sid = %d) error\n", p_section->sid);                          log_error("section_list_rw_unlock(sid=%d) error\n", p_section->sid);
305                  }                  }
306          }          }
307    
# Line 296  int append_articles_from_db(int32_t star Line 310  int append_articles_from_db(int32_t star
310          {          {
311                  if ((ret = section_list_rw_unlock(NULL)) < 0)                  if ((ret = section_list_rw_unlock(NULL)) < 0)
312                  {                  {
313                          log_error("section_list_rw_unlock(sid = 0) error\n");                          log_error("section_list_rw_unlock(sid=0) error\n");
314                  }                  }
315          }          }
316    
# Line 305  cleanup: Line 319  cleanup:
319    
320          mysql_close(db);          mysql_close(db);
321    
322          return ret;          return (ret < 0 ? ret : article_count);
323  }  }
324    
325  int set_last_article_op_log_from_db(void)  int set_last_article_op_log_from_db(void)
# Line 348  int set_last_article_op_log_from_db(void Line 362  int set_last_article_op_log_from_db(void
362          return last_article_op_log_mid;          return last_article_op_log_mid;
363  }  }
364    
365  int apply_article_op_log_from_db(void)  int apply_article_op_log_from_db(int op_count_limit)
366  {  {
367          MYSQL *db;          MYSQL *db;
368          MYSQL_RES *rs, *rs2;          MYSQL_RES *rs, *rs2;
# Line 359  int apply_article_op_log_from_db(void) Line 373  int apply_article_op_log_from_db(void)
373          SECTION_LIST *p_section_dest;          SECTION_LIST *p_section_dest;
374          int32_t last_sid = 0;          int32_t last_sid = 0;
375          int32_t sid_dest;          int32_t sid_dest;
376            int op_count = 0;
377          int ret = 0;          int ret = 0;
378    
379          db = db_open();          db = db_open();
# Line 370  int apply_article_op_log_from_db(void) Line 385  int apply_article_op_log_from_db(void)
385    
386          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
387                           "SELECT MID, AID, type FROM bbs_article_op "                           "SELECT MID, AID, type FROM bbs_article_op "
388                           "WHERE MID > %d AND type NOT IN ('A', 'M') ORDER BY MID",                           "WHERE MID > %d AND type NOT IN ('A') "
389                           last_article_op_log_mid);                           "ORDER BY MID LIMIT %d",
390                             last_article_op_log_mid, op_count_limit);
391    
392          if (mysql_query(db, sql) != 0)          if (mysql_query(db, sql) != 0)
393          {          {
# Line 450  int apply_article_op_log_from_db(void) Line 466  int apply_article_op_log_from_db(void)
466                          p_article->lock = 0;                          p_article->lock = 0;
467                          break;                          break;
468                  case 'M': // Modify article                  case 'M': // Modify article
469                          log_error("Operation type=M should not be found\n");                          snprintf(sql, sizeof(sql),
470                                             "SELECT bbs.CID, bbs_content.content "
471                                             "FROM bbs INNER JOIN bbs_content ON bbs.CID = bbs_content.CID "
472                                             "WHERE bbs.AID = %d",
473                                             p_article->aid);
474    
475                            if (mysql_query(db, sql) != 0)
476                            {
477                                    log_error("Query article error: %s\n", mysql_error(db));
478                                    ret = -3;
479                                    break;
480                            }
481                            if ((rs2 = mysql_use_result(db)) == NULL)
482                            {
483                                    log_error("Get article data failed\n");
484                                    ret = -3;
485                                    break;
486                            }
487                            if ((row2 = mysql_fetch_row(rs2)))
488                            {
489                                    p_article->cid = atoi(row2[0]);
490    
491                                    if (article_cache_generate(VAR_ARTICLE_CACHE_DIR, p_article, p_section, row2[1], 0) < 0)
492                                    {
493                                            log_error("article_cache_generate(aid=%d, cid=%d) error\n", p_article->aid, p_article->cid);
494                                            ret = -4;
495                                    }
496                            }
497                            else
498                            {
499                                    p_article->cid = 0;
500                                    ret = -4;
501                            }
502                            mysql_free_result(rs2);
503                          break;                          break;
504                  case 'T': // Move article                  case 'T': // Move article
505                          snprintf(sql, sizeof(sql),                          snprintf(sql, sizeof(sql),
# Line 535  int apply_article_op_log_from_db(void) Line 584  int apply_article_op_log_from_db(void)
584    
585                  // Update MID with last successfully proceeded article_op_log                  // Update MID with last successfully proceeded article_op_log
586                  last_article_op_log_mid = atoi(row[0]);                  last_article_op_log_mid = atoi(row[0]);
587    
588                    op_count++;
589          }          }
590    
591          // release lock of last section          // release lock of last section
# Line 550  int apply_article_op_log_from_db(void) Line 601  int apply_article_op_log_from_db(void)
601    
602          mysql_close(db);          mysql_close(db);
603    
604          return ret;          return (ret < 0 ? ret : op_count);
605  }  }
606    
607  int section_list_loader_launch(void)  int section_list_loader_launch(void)
# Line 611  int section_list_loader_launch(void) Line 662  int section_list_loader_launch(void)
662                  }                  }
663    
664                  // Load section articles                  // Load section articles
                 last_aid = article_block_last_aid();  
665                  article_count = article_block_article_count();                  article_count = article_block_article_count();
666    
667                  if ((ret = append_articles_from_db(last_aid + 1, 0)) < 0)                  do
668                  {                  {
669                          log_error("append_articles_from_db(%d, 0) error\n", last_aid + 1);                          last_aid = article_block_last_aid();
670    
671                          if (ret == ERR_UNKNOWN_SECTION)                          if ((ret = append_articles_from_db(last_aid + 1, 0, LOAD_ARTICLE_COUNT_LIMIT)) < 0)
672                          {                          {
673                                  SYS_section_list_reload = 1; // Force reload section_list                                  log_error("append_articles_from_db(%d, 0, %d) error\n", last_aid + 1, LOAD_ARTICLE_COUNT_LIMIT);
674    
675                                    if (ret == ERR_UNKNOWN_SECTION)
676                                    {
677                                            SYS_section_list_reload = 1; // Force reload section_list
678                                    }
679                          }                          }
680                  }                  } while (ret == LOAD_ARTICLE_COUNT_LIMIT);
681    
682                  load_count = article_block_article_count() - article_count;                  load_count = article_block_article_count() - article_count;
   
683                  if (load_count > 0)                  if (load_count > 0)
684                  {                  {
685                          log_std("Incrementally load %d articles, last_aid = %d\n", load_count, article_block_last_aid());                          log_std("Incrementally load %d articles, last_aid = %d\n", load_count, article_block_last_aid());
# Line 639  int section_list_loader_launch(void) Line 693  int section_list_loader_launch(void)
693                  // Load article_op log                  // Load article_op log
694                  last_mid = last_article_op_log_mid;                  last_mid = last_article_op_log_mid;
695    
696                  if ((ret = apply_article_op_log_from_db()) < 0)                  do
697                  {                  {
698                          log_error("apply_article_op_log_from_db() error\n");                          if ((ret = apply_article_op_log_from_db(LOAD_ARTICLE_COUNT_LIMIT)) < 0)
   
                         if (ret == ERR_UNKNOWN_SECTION)  
699                          {                          {
700                                  SYS_section_list_reload = 1; // Force reload section_list                                  log_error("apply_article_op_log_from_db() error\n");
701    
702                                    if (ret == ERR_UNKNOWN_SECTION)
703                                    {
704                                            SYS_section_list_reload = 1; // Force reload section_list
705                                    }
706                          }                          }
707                  }                  } while (ret == LOAD_ARTICLE_COUNT_LIMIT);
708    
709                  if (last_article_op_log_mid > last_mid)                  if (last_article_op_log_mid > last_mid)
710                  {                  {
# Line 698  int section_list_loader_reload(void) Line 755  int section_list_loader_reload(void)
755    
756          return 0;          return 0;
757  }  }
758    
759    int query_section_articles(SECTION_LIST *p_section, int page_id, ARTICLE *p_articles[], int *p_article_count, int *p_page_count)
760    {
761            ARTICLE *p_article;
762            ARTICLE *p_next_page_first_article;
763            int ret = 0;
764    
765            if (p_section == NULL || p_articles == NULL || p_article_count == NULL || p_page_count == NULL)
766            {
767                    log_error("query_section_articles() NULL pointer error\n");
768                    return -1;
769            }
770    
771            // acquire lock of section
772            if ((ret = section_list_rd_lock(p_section)) < 0)
773            {
774                    log_error("section_list_rd_lock(sid = %d) error\n", p_section->sid);
775                    return -2;
776            }
777    
778            *p_page_count = p_section->page_count;
779    
780            if (p_section->visible_article_count == 0)
781            {
782                    *p_article_count = 0;
783            }
784            else if (page_id < 0 || page_id >= p_section->page_count)
785            {
786                    log_error("Invalid page_id=%d, not in range [0, %d)\n", page_id, p_section->page_count);
787                    ret = -3;
788            }
789            else
790            {
791                    ret = page_id;
792                    p_article = p_section->p_page_first_article[page_id];
793                    p_next_page_first_article =
794                            (page_id == p_section->page_count - 1 ? p_section->p_article_head : p_section->p_page_first_article[page_id + 1]);
795                    *p_article_count = 0;
796    
797                    do
798                    {
799                            if (p_article->visible)
800                            {
801                                    p_articles[*p_article_count] = p_article;
802                                    (*p_article_count)++;
803                            }
804                            p_article = p_article->p_next;
805                    } while (p_article != p_next_page_first_article && (*p_article_count) <= BBS_article_limit_per_page);
806    
807                    if (*p_article_count != (page_id < p_section->page_count - 1 ? BBS_article_limit_per_page : p_section->last_page_visible_article_count))
808                    {
809                            log_error("Inconsistent visible article count %d detected in section %d page %d\n", *p_article_count, p_section->sid, page_id);
810                    }
811            }
812    
813            // release lock of section
814            if (section_list_rd_unlock(p_section) < 0)
815            {
816                    log_error("section_list_rd_unlock(sid = %d) error\n", p_section->sid);
817                    ret = -2;
818            }
819    
820            return ret;
821    }


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1