/[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.9 by sysadm, Thu May 29 00:52:09 2025 UTC
# Line 26  Line 26 
26  #include <strings.h>  #include <strings.h>
27  #include <unistd.h>  #include <unistd.h>
28    
29    #define _POSIX_C_SOURCE 200809L
30    #include <string.h>
31    
32  #define SECTION_LIST_LOAD_INTERVAL 10 // second  #define SECTION_LIST_LOAD_INTERVAL 10 // second
33    
34  int section_list_loader_pid;  int section_list_loader_pid;
# Line 38  int load_section_config_from_db(void) Line 41  int load_section_config_from_db(void)
41          MYSQL_ROW row, row2;          MYSQL_ROW row, row2;
42          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
43          int32_t sid;          int32_t sid;
44          char master_name[BBS_username_max_len + 1];          char master_list[(BBS_username_max_len + 1) * 3 + 1];
45          SECTION_LIST *p_section;          SECTION_LIST *p_section;
46          int ret;          int ret;
47    
# Line 76  int load_section_config_from_db(void) Line 79  int load_section_config_from_db(void)
79                                   "SELECT username FROM section_master "                                   "SELECT username FROM section_master "
80                                   "INNER JOIN user_list ON section_master.UID = user_list.UID "                                   "INNER JOIN user_list ON section_master.UID = user_list.UID "
81                                   "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) "
82                                   "ORDER BY major DESC LIMIT 1",                                   "ORDER BY major DESC, begin_dt ASC LIMIT 3",
83                                   sid);                                   sid);
84    
85                  if (mysql_query(db, sql) != 0)                  if (mysql_query(db, sql) != 0)
# Line 91  int load_section_config_from_db(void) Line 94  int load_section_config_from_db(void)
94                          ret = -3;                          ret = -3;
95                          break;                          break;
96                  }                  }
97                  if ((row2 = mysql_fetch_row(rs2)))  
98                  {                  master_list[0] = '\0';
99                          strncpy(master_name, row2[0], sizeof(master_name) - 1);                  while ((row2 = mysql_fetch_row(rs2)))
                         master_name[sizeof(master_name) - 1] = '\0';  
                 }  
                 else  
100                  {                  {
101                          master_name[0] = '\0';                          strncat(master_list, row2[0], sizeof(master_list) - 1 - strnlen(master_list, sizeof(master_list)));
102                            strncat(master_list, " ", sizeof(master_list) - 1 - strnlen(master_list, sizeof(master_list)));
103                  }                  }
104                  mysql_free_result(rs2);                  mysql_free_result(rs2);
105    
# Line 106  int load_section_config_from_db(void) Line 107  int load_section_config_from_db(void)
107    
108                  if (p_section == NULL)                  if (p_section == NULL)
109                  {                  {
110                          p_section = section_list_create(sid, row[1], row[2], "");                          p_section = section_list_create(sid, row[1], row[2], master_list);
111                          if (p_section == NULL)                          if (p_section == NULL)
112                          {                          {
113                                  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 135  int load_section_config_from_db(void)
135                          p_section->sname[sizeof(p_section->sname) - 1] = '\0';                          p_section->sname[sizeof(p_section->sname) - 1] = '\0';
136                          strncpy(p_section->stitle, row[1], sizeof(p_section->stitle) - 1);                          strncpy(p_section->stitle, row[1], sizeof(p_section->stitle) - 1);
137                          p_section->stitle[sizeof(p_section->stitle) - 1] = '\0';                          p_section->stitle[sizeof(p_section->stitle) - 1] = '\0';
138                          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);
139                          p_section->master_name[sizeof(p_section->master_name) - 1] = '\0';                          p_section->master_list[sizeof(p_section->master_list) - 1] = '\0';
140                  }                  }
141    
142                  p_section->class_id = atoi(row[3]);                  p_section->class_id = atoi(row[3]);
# Line 157  int load_section_config_from_db(void) Line 158  int load_section_config_from_db(void)
158          return ret;          return ret;
159  }  }
160    
161  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)
162  {  {
163          MYSQL *db;          MYSQL *db;
164          MYSQL_RES *rs;          MYSQL_RES *rs;
# Line 167  int append_articles_from_db(int32_t star Line 168  int append_articles_from_db(int32_t star
168          ARTICLE *p_topic;          ARTICLE *p_topic;
169          SECTION_LIST *p_section = NULL;          SECTION_LIST *p_section = NULL;
170          int32_t last_sid = 0;          int32_t last_sid = 0;
171            int article_count = 0;
172          int ret = 0;          int ret = 0;
173          int i;          int i;
174    
# Line 180  int append_articles_from_db(int32_t star Line 182  int append_articles_from_db(int32_t star
182          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
183                           "SELECT AID, TID, SID, CID, UID, visible, excerption, ontop, `lock`, "                           "SELECT AID, TID, SID, CID, UID, visible, excerption, ontop, `lock`, "
184                           "transship, username, nickname, title, UNIX_TIMESTAMP(sub_dt) AS sub_dt "                           "transship, username, nickname, title, UNIX_TIMESTAMP(sub_dt) AS sub_dt "
185                           "FROM bbs WHERE AID >= %d ORDER BY AID",                           "FROM bbs WHERE AID >= %d ORDER BY AID LIMIT %d",
186                           start_aid);                           start_aid, article_count_limit);
187    
188          if (mysql_query(db, sql) != 0)          if (mysql_query(db, sql) != 0)
189          {          {
190                  log_error("Query article list error: %s\n", mysql_error(db));                  log_error("Query article list error: %s\n", mysql_error(db));
191                  return -3;                  return -3;
192          }          }
193          if ((rs = mysql_use_result(db)) == NULL)          if ((rs = mysql_store_result(db)) == NULL)
194          {          {
195                  log_error("Get article list data failed\n");                  log_error("Get article list data failed\n");
196                  return -3;                  return -3;
# Line 280  int append_articles_from_db(int32_t star Line 282  int append_articles_from_db(int32_t star
282                          ret = -3;                          ret = -3;
283                          break;                          break;
284                  }                  }
285    
286                    article_count++;
287    
288                    // TODO: generate content cache
289          }          }
290    
291          // release lock of last section          // release lock of last section
# Line 305  cleanup: Line 311  cleanup:
311    
312          mysql_close(db);          mysql_close(db);
313    
314          return ret;          return (ret < 0 ? ret : article_count);
315  }  }
316    
317  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 354  int set_last_article_op_log_from_db(void
354          return last_article_op_log_mid;          return last_article_op_log_mid;
355  }  }
356    
357  int apply_article_op_log_from_db(void)  int apply_article_op_log_from_db(int op_count_limit)
358  {  {
359          MYSQL *db;          MYSQL *db;
360          MYSQL_RES *rs, *rs2;          MYSQL_RES *rs, *rs2;
# Line 359  int apply_article_op_log_from_db(void) Line 365  int apply_article_op_log_from_db(void)
365          SECTION_LIST *p_section_dest;          SECTION_LIST *p_section_dest;
366          int32_t last_sid = 0;          int32_t last_sid = 0;
367          int32_t sid_dest;          int32_t sid_dest;
368            int op_count = 0;
369          int ret = 0;          int ret = 0;
370    
371          db = db_open();          db = db_open();
# Line 370  int apply_article_op_log_from_db(void) Line 377  int apply_article_op_log_from_db(void)
377    
378          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
379                           "SELECT MID, AID, type FROM bbs_article_op "                           "SELECT MID, AID, type FROM bbs_article_op "
380                           "WHERE MID > %d AND type NOT IN ('A', 'M') ORDER BY MID",                           "WHERE MID > %d AND type NOT IN ('A') "
381                           last_article_op_log_mid);                           "ORDER BY MID LIMIT %d",
382                             last_article_op_log_mid, op_count_limit);
383    
384          if (mysql_query(db, sql) != 0)          if (mysql_query(db, sql) != 0)
385          {          {
# Line 450  int apply_article_op_log_from_db(void) Line 458  int apply_article_op_log_from_db(void)
458                          p_article->lock = 0;                          p_article->lock = 0;
459                          break;                          break;
460                  case 'M': // Modify article                  case 'M': // Modify article
461                          log_error("Operation type=M should not be found\n");                          snprintf(sql, sizeof(sql),
462                                             "SELECT CID FROM bbs WHERE AID = %d",
463                                             p_article->aid);
464    
465                            if (mysql_query(db, sql) != 0)
466                            {
467                                    log_error("Query article error: %s\n", mysql_error(db));
468                                    ret = -3;
469                                    break;
470                            }
471                            if ((rs2 = mysql_store_result(db)) == NULL)
472                            {
473                                    log_error("Get article data failed\n");
474                                    ret = -3;
475                                    break;
476                            }
477                            if ((row2 = mysql_fetch_row(rs2)))
478                            {
479                                    p_article->cid = atoi(row2[0]);
480                            }
481                            else
482                            {
483                                    p_article->cid = 0;
484                                    ret = -4;
485                            }
486                            mysql_free_result(rs2);
487    
488                            if (p_article->cid > 0)
489                            {
490                                    // TODO: generate content cache
491                            }
492    
493                          break;                          break;
494                  case 'T': // Move article                  case 'T': // Move article
495                          snprintf(sql, sizeof(sql),                          snprintf(sql, sizeof(sql),
# Line 535  int apply_article_op_log_from_db(void) Line 574  int apply_article_op_log_from_db(void)
574    
575                  // Update MID with last successfully proceeded article_op_log                  // Update MID with last successfully proceeded article_op_log
576                  last_article_op_log_mid = atoi(row[0]);                  last_article_op_log_mid = atoi(row[0]);
577    
578                    op_count++;
579          }          }
580    
581          // release lock of last section          // release lock of last section
# Line 550  int apply_article_op_log_from_db(void) Line 591  int apply_article_op_log_from_db(void)
591    
592          mysql_close(db);          mysql_close(db);
593    
594          return ret;          return (ret < 0 ? ret : op_count);
595  }  }
596    
597  int section_list_loader_launch(void)  int section_list_loader_launch(void)
# Line 611  int section_list_loader_launch(void) Line 652  int section_list_loader_launch(void)
652                  }                  }
653    
654                  // Load section articles                  // Load section articles
                 last_aid = article_block_last_aid();  
655                  article_count = article_block_article_count();                  article_count = article_block_article_count();
656    
657                  if ((ret = append_articles_from_db(last_aid + 1, 0)) < 0)                  do
658                  {                  {
659                          log_error("append_articles_from_db(%d, 0) error\n", last_aid + 1);                          last_aid = article_block_last_aid();
660    
661                          if (ret == ERR_UNKNOWN_SECTION)                          if ((ret = append_articles_from_db(last_aid + 1, 0, LOAD_ARTICLE_COUNT_LIMIT)) < 0)
662                          {                          {
663                                  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);
664    
665                                    if (ret == ERR_UNKNOWN_SECTION)
666                                    {
667                                            SYS_section_list_reload = 1; // Force reload section_list
668                                    }
669                          }                          }
670                  }                  } while (ret == LOAD_ARTICLE_COUNT_LIMIT);
671    
672                  load_count = article_block_article_count() - article_count;                  load_count = article_block_article_count() - article_count;
   
673                  if (load_count > 0)                  if (load_count > 0)
674                  {                  {
675                          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 683  int section_list_loader_launch(void)
683                  // Load article_op log                  // Load article_op log
684                  last_mid = last_article_op_log_mid;                  last_mid = last_article_op_log_mid;
685    
686                  if ((ret = apply_article_op_log_from_db()) < 0)                  do
687                  {                  {
688                          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)  
689                          {                          {
690                                  SYS_section_list_reload = 1; // Force reload section_list                                  log_error("apply_article_op_log_from_db() error\n");
691    
692                                    if (ret == ERR_UNKNOWN_SECTION)
693                                    {
694                                            SYS_section_list_reload = 1; // Force reload section_list
695                                    }
696                          }                          }
697                  }                  } while (ret == LOAD_ARTICLE_COUNT_LIMIT);
698    
699                  if (last_article_op_log_mid > last_mid)                  if (last_article_op_log_mid > last_mid)
700                  {                  {
# Line 698  int section_list_loader_reload(void) Line 745  int section_list_loader_reload(void)
745    
746          return 0;          return 0;
747  }  }
748    
749    int query_section_articles(SECTION_LIST *p_section, int32_t page_id, ARTICLE *p_articles[], int32_t *p_article_count)
750    {
751            ARTICLE *p_article;
752            ARTICLE *p_next_page_first_article;
753            int ret = 0;
754    
755            if (p_section == NULL || p_articles == NULL || p_article_count == NULL)
756            {
757                    log_error("query_section_articles() NULL pointer error\n");
758                    return -1;
759            }
760    
761            // acquire lock of section
762            if ((ret = section_list_rd_lock(p_section)) < 0)
763            {
764                    log_error("section_list_rd_lock(sid = %d) error\n", p_section->sid);
765                    return -2;
766            }
767    
768            if (p_section->visible_article_count == 0)
769            {
770                    *p_article_count = 0;
771            }
772            else if (page_id < 0 || page_id >= p_section->page_count)
773            {
774                    log_error("Invalid page_id=%d, not in range [0, %d)\n", page_id, p_section->page_count);
775                    ret = -3;
776            }
777            else
778            {
779                    ret = page_id;
780                    p_article = p_section->p_page_first_article[page_id];
781                    p_next_page_first_article =
782                            (page_id == p_section->page_count - 1 ? p_section->p_article_head : p_section->p_page_first_article[page_id + 1]);
783                    *p_article_count = 0;
784    
785                    do
786                    {
787                            if (p_article->visible)
788                            {
789                                    p_articles[*p_article_count] = p_article;
790                                    (*p_article_count)++;
791                            }
792                            p_article = p_article->p_next;
793                    } while (p_article != p_next_page_first_article && (*p_article_count) <= BBS_article_limit_per_page);
794    
795                    if (*p_article_count != (page_id < p_section->page_count - 1 ? BBS_article_limit_per_page : p_section->last_page_visible_article_count))
796                    {
797                            log_error("Inconsistent visible article count %d detected in section %d page %d\n", *p_article_count, p_section->sid, page_id);
798                    }
799            }
800    
801            // release lock of section
802            if (section_list_rd_unlock(p_section) < 0)
803            {
804                    log_error("section_list_rd_unlock(sid = %d) error\n", p_section->sid);
805                    ret = -2;
806            }
807    
808            return ret;
809    }


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

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