/[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.16 - (hide annotations)
Tue Nov 4 13:49:51 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.15: +7 -15 lines
Content type: text/x-csrc
Update file header information comments

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

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