/[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.2 - (hide annotations)
Sat Jun 7 08:07:07 2025 UTC (9 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.1: +14 -1 lines
Content type: text/x-csrc
Update

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

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