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

Annotation of /lbbs/src/article_view_log.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.19 - (hide annotations)
Fri Dec 19 06:16:26 2025 UTC (2 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.18: +17 -17 lines
Content type: text/x-csrc
Append \n to the end of logging message by log_...()
Remove ending \n from each logging message

1 sysadm 1.16 /* SPDX-License-Identifier: GPL-3.0-or-later */
2     /*
3     * article_view_log
4     * - data persistence and query of article view log
5     *
6 sysadm 1.17 * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7 sysadm 1.16 */
8 sysadm 1.1
9 sysadm 1.18 #ifdef HAVE_CONFIG_H
10     #include "config.h"
11     #endif
12    
13 sysadm 1.1 #include "article_view_log.h"
14     #include "common.h"
15     #include "database.h"
16 sysadm 1.7 #include "log.h"
17 sysadm 1.1 #include <stdlib.h>
18     #include <string.h>
19    
20 sysadm 1.3 ARTICLE_VIEW_LOG BBS_article_view_log;
21    
22 sysadm 1.1 int article_view_log_load(int uid, ARTICLE_VIEW_LOG *p_view_log, int keep_inc)
23     {
24     MYSQL *db;
25     MYSQL_RES *rs;
26     MYSQL_ROW row;
27     char sql[SQL_BUFFER_LEN];
28    
29     if (p_view_log == NULL)
30     {
31 sysadm 1.19 log_error("NULL pointer error");
32 sysadm 1.1 return -1;
33     }
34    
35 sysadm 1.3 p_view_log->uid = uid;
36    
37 sysadm 1.2 if (uid == 0)
38     {
39     p_view_log->aid_base_cnt = 0;
40     p_view_log->aid_base = NULL;
41    
42     if (!keep_inc)
43     {
44     p_view_log->aid_inc_cnt = 0;
45     }
46    
47     return 0;
48     }
49    
50 sysadm 1.1 if ((db = db_open()) == NULL)
51     {
52 sysadm 1.19 log_error("article_view_log_load() error: Unable to open DB");
53 sysadm 1.1 return -2;
54     }
55    
56     snprintf(sql, sizeof(sql),
57     "SELECT AID FROM view_article_log WHERE UID = %d "
58     "ORDER BY AID",
59     uid);
60     if (mysql_query(db, sql) != 0)
61     {
62 sysadm 1.19 log_error("Query view_article_log error: %s", mysql_error(db));
63 sysadm 1.1 return -3;
64     }
65     if ((rs = mysql_store_result(db)) == NULL)
66     {
67 sysadm 1.19 log_error("Get view_article_log data failed");
68 sysadm 1.1 return -3;
69     }
70    
71     p_view_log->aid_base_cnt = 0;
72     p_view_log->aid_base = malloc(sizeof(int32_t) * mysql_num_rows(rs));
73     if (p_view_log->aid_base == NULL)
74     {
75 sysadm 1.19 log_error("malloc(INT32 * %d) error: OOM", mysql_num_rows(rs));
76 sysadm 1.1 mysql_free_result(rs);
77     mysql_close(db);
78     return -4;
79     }
80    
81     while ((row = mysql_fetch_row(rs)))
82     {
83     p_view_log->aid_base[(p_view_log->aid_base_cnt)++] = atoi(row[0]);
84     }
85     mysql_free_result(rs);
86    
87     mysql_close(db);
88    
89 sysadm 1.19 log_common("Loaded %d view_article_log records for uid=%d", p_view_log->aid_base_cnt, uid);
90 sysadm 1.3
91 sysadm 1.1 if (!keep_inc)
92     {
93     p_view_log->aid_inc_cnt = 0;
94     }
95    
96     return 0;
97     }
98    
99 sysadm 1.2 int article_view_log_unload(ARTICLE_VIEW_LOG *p_view_log)
100 sysadm 1.1 {
101     if (p_view_log == NULL)
102     {
103 sysadm 1.19 log_error("NULL pointer error");
104 sysadm 1.1 return -1;
105     }
106    
107     if (p_view_log->aid_base != NULL)
108     {
109     free(p_view_log->aid_base);
110     p_view_log->aid_base = NULL;
111     p_view_log->aid_base_cnt = 0;
112     }
113    
114     return 0;
115     }
116    
117 sysadm 1.3 int article_view_log_save_inc(const ARTICLE_VIEW_LOG *p_view_log)
118 sysadm 1.1 {
119 sysadm 1.4 MYSQL *db = NULL;
120 sysadm 1.1 char sql[SQL_BUFFER_LEN];
121     char tuple_tmp[LINE_BUFFER_LEN];
122     int i;
123 sysadm 1.3 int affected_record = 0;
124 sysadm 1.1
125     if (p_view_log == NULL)
126     {
127 sysadm 1.19 log_error("NULL pointer error");
128 sysadm 1.1 return -1;
129     }
130    
131 sysadm 1.10 if (p_view_log->uid <= 0 || p_view_log->aid_inc_cnt == 0)
132 sysadm 1.3 {
133     return 0;
134     }
135    
136 sysadm 1.1 if ((db = db_open()) == NULL)
137     {
138 sysadm 1.19 log_error("article_view_log_load() error: Unable to open DB");
139 sysadm 1.1 return -2;
140     }
141    
142     snprintf(sql, sizeof(sql),
143 sysadm 1.3 "INSERT IGNORE INTO view_article_log(AID, UID, dt) VALUES ");
144 sysadm 1.1
145     for (i = 0; i < p_view_log->aid_inc_cnt; i++)
146     {
147     snprintf(tuple_tmp, sizeof(tuple_tmp),
148     "(%d, %d, NOW())",
149 sysadm 1.3 p_view_log->aid_inc[i], p_view_log->uid);
150 sysadm 1.1 strncat(sql, tuple_tmp, sizeof(sql) - 1 - strnlen(sql, sizeof(sql)));
151    
152 sysadm 1.3 if ((i + 1) % 100 == 0 || (i + 1) == p_view_log->aid_inc_cnt) // Insert 100 records per query
153 sysadm 1.1 {
154     if (mysql_query(db, sql) != 0)
155     {
156 sysadm 1.19 log_error("Add view_article_log error: %s", mysql_error(db));
157 sysadm 1.4 mysql_close(db);
158 sysadm 1.1 return -3;
159     }
160    
161 sysadm 1.3 affected_record += (int)mysql_affected_rows(db);
162    
163 sysadm 1.1 snprintf(sql, sizeof(sql),
164 sysadm 1.3 "INSERT IGNORE INTO view_article_log(AID, UID, dt) VALUES ");
165 sysadm 1.1 }
166     else
167     {
168     strncat(sql, ", ", sizeof(sql) - 1 - strnlen(sql, sizeof(sql)));
169     }
170     }
171    
172 sysadm 1.19 log_common("Saved %d view_article_log records for uid=%d", affected_record, p_view_log->uid);
173 sysadm 1.3
174 sysadm 1.1 mysql_close(db);
175    
176     return 0;
177     }
178    
179     int article_view_log_merge_inc(ARTICLE_VIEW_LOG *p_view_log)
180     {
181     int32_t *aid_new;
182     int aid_new_cnt;
183     int i, j, k;
184 sysadm 1.14 int len;
185 sysadm 1.1
186     if (p_view_log == NULL)
187     {
188 sysadm 1.19 log_error("NULL pointer error");
189 sysadm 1.1 return -1;
190     }
191    
192     if (p_view_log->aid_inc_cnt == 0) // Nothing to be merged
193     {
194     return 0;
195     }
196    
197     aid_new_cnt = p_view_log->aid_base_cnt + p_view_log->aid_inc_cnt;
198    
199     aid_new = malloc(sizeof(int32_t) * (size_t)aid_new_cnt);
200     if (aid_new == NULL)
201     {
202 sysadm 1.19 log_error("malloc(INT32 * %d) error: OOM", aid_new_cnt);
203 sysadm 1.1 return -2;
204     }
205    
206     for (i = 0, j = 0, k = 0; i < p_view_log->aid_base_cnt && j < p_view_log->aid_inc_cnt;)
207     {
208     if (p_view_log->aid_base[i] <= p_view_log->aid_inc[j])
209     {
210     if (p_view_log->aid_base[i] == p_view_log->aid_inc[j])
211     {
212 sysadm 1.19 log_error("Duplicate aid = %d found in both Base (offset = %d) and Inc (offset = %d)",
213 sysadm 1.1 p_view_log->aid_base[i], i, j);
214     j++; // Skip duplicate one in Inc
215     }
216    
217     aid_new[k++] = p_view_log->aid_base[i++];
218     }
219     else if (p_view_log->aid_base[i] > p_view_log->aid_inc[j])
220     {
221     aid_new[k++] = p_view_log->aid_inc[j++];
222     }
223     }
224    
225 sysadm 1.14 len = p_view_log->aid_base_cnt - i;
226     if (len > 0)
227     {
228     memcpy(aid_new + k, p_view_log->aid_base + i,
229     sizeof(int32_t) * (size_t)len);
230     k += len;
231     }
232     len = p_view_log->aid_inc_cnt - j;
233     if (len > 0)
234     {
235     memcpy(aid_new + k, p_view_log->aid_inc + j,
236     sizeof(int32_t) * (size_t)len);
237     k += len;
238     }
239 sysadm 1.1
240     free(p_view_log->aid_base);
241     p_view_log->aid_base = aid_new;
242     p_view_log->aid_base_cnt = k;
243    
244     p_view_log->aid_inc_cnt = 0;
245    
246     return 0;
247     }
248    
249     int article_view_log_is_viewed(int32_t aid, const ARTICLE_VIEW_LOG *p_view_log)
250     {
251     int left;
252     int right;
253     int mid;
254     int i;
255    
256     if (p_view_log == NULL)
257     {
258 sysadm 1.19 log_error("NULL pointer error");
259 sysadm 1.1 return -1;
260     }
261    
262     for (i = 0; i < 2; i++)
263     {
264     left = 0;
265     right = (i == 0 ? p_view_log->aid_base_cnt : p_view_log->aid_inc_cnt) - 1;
266    
267     if (right < 0)
268     {
269     continue;
270     }
271    
272     while (left < right)
273     {
274     mid = (left + right) / 2;
275     if (aid < (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
276     {
277 sysadm 1.15 right = mid - 1;
278 sysadm 1.1 }
279     else if (aid > (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
280     {
281     left = mid + 1;
282     }
283     else // if (aid == p_view_log->aid_base[mid])
284     {
285     return 1;
286     }
287     }
288    
289     if (aid == (i == 0 ? p_view_log->aid_base[left] : p_view_log->aid_inc[left])) // Found
290     {
291     return 1;
292     }
293     }
294    
295     return 0;
296     }
297    
298     int article_view_log_set_viewed(int32_t aid, ARTICLE_VIEW_LOG *p_view_log)
299     {
300     int left;
301     int right;
302     int mid;
303     int i;
304    
305     if (p_view_log == NULL)
306     {
307 sysadm 1.19 log_error("NULL pointer error");
308 sysadm 1.1 return -1;
309     }
310    
311     for (i = 0; i < 2; i++)
312     {
313     left = 0;
314     right = (i == 0 ? p_view_log->aid_base_cnt : p_view_log->aid_inc_cnt) - 1;
315    
316     if (right < 0)
317     {
318     continue;
319     }
320    
321     while (left < right)
322     {
323     mid = (left + right) / 2;
324     if (aid < (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
325     {
326 sysadm 1.15 right = mid - 1;
327 sysadm 1.1 }
328     else if (aid > (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
329     {
330     left = mid + 1;
331     }
332     else // if (aid == p_view_log->aid_base[mid])
333     {
334     return 0; // Already set
335     }
336     }
337    
338     if (aid == (i == 0 ? p_view_log->aid_base[left] : p_view_log->aid_inc[left])) // Found
339     {
340     return 0; // Already set
341     }
342     }
343    
344     // Merge if Inc is full
345 sysadm 1.8 if (p_view_log->aid_inc_cnt >= MAX_VIEWED_AID_INC_CNT)
346 sysadm 1.1 {
347 sysadm 1.3 // Save incremental article view log
348     if (article_view_log_save_inc(p_view_log) < 0)
349     {
350 sysadm 1.19 log_error("article_view_log_save_inc() error");
351 sysadm 1.3 return -2;
352     }
353    
354 sysadm 1.1 article_view_log_merge_inc(p_view_log);
355    
356     p_view_log->aid_inc[(p_view_log->aid_inc_cnt)++] = aid;
357    
358     return 1; // Set complete
359     }
360    
361     if (right < 0)
362     {
363     right = 0;
364     }
365     else if (aid > p_view_log->aid_inc[left])
366     {
367     right = left + 1;
368     }
369    
370 sysadm 1.13 if (p_view_log->aid_inc_cnt > right)
371 sysadm 1.12 {
372 sysadm 1.13 memmove(p_view_log->aid_inc + right + 1,
373     p_view_log->aid_inc + right,
374     sizeof(int32_t) * (size_t)(p_view_log->aid_inc_cnt - right));
375 sysadm 1.12 }
376 sysadm 1.1
377     p_view_log->aid_inc[right] = aid;
378     (p_view_log->aid_inc_cnt)++;
379    
380     return 1; // Set complete
381     }

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