Branch data Line data Source code
1 : : #include "precizer.h"
2 : :
3 : : /**
4 : : *
5 : : * @brief Store a formatted log line in the TEMP remember_history table.
6 : : *
7 : : * @details The table is created in db_init(). If the database is unavailable,
8 : : * the function returns without inserting anything.
9 : : *
10 : : * @note The message buffer may be non-null-terminated; line_len is used
11 : : * to bound the insert.
12 : : *
13 : : */
14 : 99 : void rational_remember(
15 : : const char *message,
16 : : const int line_len)
17 : : {
18 [ - + ]: 99 : if(message == NULL)
19 : : {
20 : 0 : return;
21 : : }
22 : :
23 [ - + ]: 99 : if(line_len <= 0)
24 : : {
25 : 0 : return;
26 : : }
27 : :
28 : 99 : sqlite3_stmt *stmt = NULL;
29 : 99 : sqlite3_int64 last_id = 0;
30 : 99 : bool append_to_last = false;
31 : :
32 : 99 : const char *select_sql =
33 : : "SELECT id, message FROM temp.remember_history "
34 : : "ORDER BY id DESC LIMIT 1;";
35 : :
36 : 99 : int rc = sqlite3_prepare_v2(config->db,select_sql,-1,&stmt,NULL);
37 : :
38 [ - + ]: 99 : if(rc != SQLITE_OK)
39 : : {
40 : 0 : log_sqlite_error(config->db,rc,NULL,
41 : : "Failed to prepare remember_history lookup");
42 : : } else {
43 : 99 : rc = sqlite3_step(stmt);
44 : :
45 [ + + ]: 99 : if(rc == SQLITE_ROW)
46 : : {
47 : 74 : const unsigned char *text = sqlite3_column_text(stmt,1);
48 : 74 : const int text_len = sqlite3_column_bytes(stmt,1);
49 : :
50 [ + - + - : 74 : if(text != NULL && text_len > 0 && text[text_len - 1] != '\n')
+ + ]
51 : : {
52 : 28 : last_id = sqlite3_column_int64(stmt,0);
53 : 28 : append_to_last = true;
54 : : }
55 : : }
56 : :
57 : 99 : sqlite3_finalize(stmt);
58 : 99 : stmt = NULL;
59 : : }
60 : :
61 [ + + ]: 99 : if(append_to_last)
62 : : {
63 : 28 : const char *update_sql =
64 : : "UPDATE temp.remember_history "
65 : : "SET message = message || ?1 WHERE id = ?2;";
66 : :
67 : 28 : rc = sqlite3_prepare_v2(config->db,update_sql,-1,&stmt,NULL);
68 : :
69 [ - + ]: 28 : if(rc != SQLITE_OK)
70 : : {
71 : 0 : log_sqlite_error(config->db,rc,NULL,
72 : : "Failed to prepare remember_history update");
73 : 0 : return;
74 : : }
75 : :
76 : 28 : rc = sqlite3_bind_text(stmt,1,message,line_len,SQLITE_TRANSIENT);
77 : :
78 [ - + ]: 28 : if(rc != SQLITE_OK)
79 : : {
80 : 0 : log_sqlite_error(config->db,rc,NULL,
81 : : "Failed to bind remember_history update");
82 : 0 : sqlite3_finalize(stmt);
83 : 0 : return;
84 : : }
85 : :
86 : 28 : rc = sqlite3_bind_int64(stmt,2,last_id);
87 : :
88 [ - + ]: 28 : if(rc != SQLITE_OK)
89 : : {
90 : 0 : log_sqlite_error(config->db,rc,NULL,
91 : : "Failed to bind remember_history id");
92 : 0 : sqlite3_finalize(stmt);
93 : 0 : return;
94 : : }
95 : : } else {
96 : 71 : const char *insert_sql =
97 : : "INSERT INTO temp.remember_history (message) VALUES (?1);";
98 : :
99 : 71 : rc = sqlite3_prepare_v2(config->db,insert_sql,-1,&stmt,NULL);
100 : :
101 [ - + ]: 71 : if(rc != SQLITE_OK)
102 : : {
103 : 0 : log_sqlite_error(config->db,rc,NULL,
104 : : "Failed to prepare remember_history insert");
105 : 0 : return;
106 : : }
107 : :
108 : 71 : rc = sqlite3_bind_text(stmt,1,message,line_len,SQLITE_TRANSIENT);
109 : : }
110 : :
111 [ - + ]: 99 : if(rc != SQLITE_OK)
112 : : {
113 : 0 : log_sqlite_error(config->db,rc,NULL,
114 : : "Failed to bind remember_history message");
115 : 0 : sqlite3_finalize(stmt);
116 : 0 : return;
117 : : }
118 : :
119 : 99 : rc = sqlite3_step(stmt);
120 : :
121 [ - + ]: 99 : if(rc != SQLITE_DONE)
122 : : {
123 [ # # ]: 0 : if(append_to_last)
124 : : {
125 : 0 : log_sqlite_error(config->db,rc,NULL,
126 : : "Failed to update remember_history record");
127 : : } else {
128 : 0 : log_sqlite_error(config->db,rc,NULL,
129 : : "Failed to insert remember_history record");
130 : : }
131 : : }
132 : :
133 : 99 : sqlite3_finalize(stmt);
134 : :
135 [ - + ]: 99 : if(rc != SQLITE_DONE)
136 : : {
137 : 0 : return;
138 : : }
139 : : }
|