Coverage Report

Created: 2026-11-12 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/plugins/in_blob/blob_db.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  Fluent Bit
4
 *  ==========
5
 *  Copyright (C) 2015-2026 The Fluent Bit Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#include <fluent-bit/flb_input_plugin.h>
21
22
#ifdef FLB_HAVE_SQLDB
23
24
#include <fluent-bit/flb_sqldb.h>
25
26
#include "blob.h"
27
#include "blob_db.h"
28
29
static int prepare_stmts(struct flb_sqldb *db, struct blob_ctx *ctx)
30
0
{
31
0
    int ret;
32
33
    /* insert */
34
0
    ret = sqlite3_prepare_v2(db->handler, SQL_INSERT_FILE, -1,
35
0
                             &ctx->stmt_insert_file, NULL);
36
0
    if (ret != SQLITE_OK) {
37
0
        flb_plg_error(ctx->ins, "cannot prepare SQL statement: %s",
38
0
                      SQL_INSERT_FILE);
39
0
        return -1;
40
0
    }
41
42
    /* delete */
43
0
    ret = sqlite3_prepare_v2(db->handler, SQL_DELETE_FILE, -1,
44
0
                             &ctx->stmt_delete_file, NULL);
45
0
    if (ret != SQLITE_OK) {
46
0
        flb_plg_error(ctx->ins, "cannot prepare SQL statement: %s",
47
0
                      SQL_DELETE_FILE);
48
0
        return -1;
49
0
    }
50
51
    /* get */
52
0
    ret = sqlite3_prepare_v2(db->handler, SQL_GET_FILE, -1,
53
0
                             &ctx->stmt_get_file, NULL);
54
0
    if (ret != SQLITE_OK) {
55
0
        flb_plg_error(ctx->ins, "cannot prepare SQL statement: %s",
56
0
                      SQL_GET_FILE);
57
0
        return -1;
58
0
    }
59
60
0
    return 0;
61
0
}
62
// static int my_special_callback(void *unused, int count, char **data, char **columns)
63
// {
64
//     int idx;
65
66
//     printf("There are %d column(s)\n", count);
67
68
//     for (idx = 0; idx < count; idx++) {
69
//         printf("The data in column \"%s\" is: %s\n", columns[idx], data[idx]);
70
//     }
71
72
//     printf("\n");
73
74
//     return 0;
75
// }
76
77
struct flb_sqldb *blob_db_open(struct blob_ctx *ctx, char *db_path)
78
0
{
79
0
    int ret;
80
0
    struct flb_sqldb *db;
81
0
    struct flb_input_instance *ins;
82
83
0
    ins = ctx->ins;
84
85
0
    db = flb_sqldb_open(db_path, ins->name, ctx->config);
86
0
    if (!db) {
87
0
        flb_plg_error(ctx->ins, "cannot open database %s", db_path);
88
0
        return NULL;
89
0
    }
90
91
0
    ret = flb_sqldb_query(db, SQL_CREATE_BLOB_FILES, NULL, NULL);
92
0
    if (ret != FLB_OK) {
93
0
        flb_plg_error(ctx->ins, "cannot create table 'in_blob_files'");
94
0
        flb_sqldb_close(db);
95
0
        return NULL;
96
0
    }
97
98
0
    ret = prepare_stmts(db, ctx);
99
0
    if (ret == -1) {
100
0
        flb_sqldb_close(db);
101
0
        return NULL;
102
0
    }
103
104
0
    return db;
105
0
}
106
107
int blob_db_close(struct blob_ctx *ctx)
108
0
{
109
0
    int ret;
110
111
0
    if (ctx->db == NULL) {
112
0
        return 0;
113
0
    }
114
115
    /* finalize prepared statements */
116
0
    if (ctx->stmt_get_file != NULL) {
117
0
        sqlite3_finalize(ctx->stmt_get_file);
118
0
        ctx->stmt_get_file = NULL;
119
0
    }
120
121
0
    if (ctx->stmt_insert_file != NULL) {
122
0
        sqlite3_finalize(ctx->stmt_insert_file);
123
0
        ctx->stmt_insert_file = NULL;
124
0
    }
125
126
0
    if (ctx->stmt_delete_file != NULL) {
127
0
        sqlite3_finalize(ctx->stmt_delete_file);
128
0
        ctx->stmt_delete_file = NULL;
129
0
    }
130
131
0
    ret = flb_sqldb_close(ctx->db);
132
0
    ctx->db = NULL;
133
134
0
    return ret;
135
0
}
136
137
int blob_db_file_exists(struct blob_ctx *ctx, char *path, uint64_t *id)
138
0
{
139
0
    int ret;
140
0
    int exists = FLB_FALSE;
141
142
    /* Bind parameters */
143
0
    sqlite3_bind_text(ctx->stmt_get_file, 1, path, -1, 0);
144
0
    ret = sqlite3_step(ctx->stmt_get_file);
145
0
    if (ret == SQLITE_ROW) {
146
0
        exists = FLB_TRUE;
147
148
        /* id: column 0 */
149
0
        *id = sqlite3_column_int64(ctx->stmt_get_file, 0);
150
0
    }
151
0
    else if (ret == SQLITE_DONE) {
152
        /* all good */
153
0
    }
154
0
    else {
155
0
        exists = -1;
156
0
    }
157
158
0
    sqlite3_clear_bindings(ctx->stmt_get_file);
159
0
    sqlite3_reset(ctx->stmt_get_file);
160
161
0
    return exists;
162
0
}
163
164
int64_t blob_db_file_insert(struct blob_ctx *ctx, char *path, size_t size)
165
0
{
166
0
    int ret;
167
0
    int64_t id;
168
0
    time_t created;
169
170
    /* Register the file */
171
0
    created = time(NULL);
172
173
    /* Bind parameters */
174
0
    sqlite3_bind_text(ctx->stmt_insert_file, 1, path, -1, 0);
175
0
    sqlite3_bind_int64(ctx->stmt_insert_file, 2, size);
176
0
    sqlite3_bind_int64(ctx->stmt_insert_file, 3, created);
177
178
    /* Run the insert */
179
0
    ret = sqlite3_step(ctx->stmt_insert_file);
180
0
    if (ret != SQLITE_DONE) {
181
0
        sqlite3_clear_bindings(ctx->stmt_insert_file);
182
0
        sqlite3_reset(ctx->stmt_insert_file);
183
0
        flb_plg_error(ctx->ins, "cannot execute insert file '%s'", path);
184
0
        return -1;
185
0
    }
186
187
    /* Get the database ID for this file */
188
0
    id = flb_sqldb_last_id(ctx->db);
189
190
0
    sqlite3_clear_bindings(ctx->stmt_insert_file);
191
0
    sqlite3_reset(ctx->stmt_insert_file);
192
193
194
0
    flb_plg_trace(ctx->ins, "db: file '%s' inserted with id=%ld", path, id);
195
0
    return id;
196
0
}
197
198
int blob_db_file_delete(struct blob_ctx *ctx, uint64_t id, char *path)
199
0
{
200
0
    int ret;
201
202
    /* Bind parameters */
203
0
    sqlite3_bind_int64(ctx->stmt_delete_file, 1, id);
204
0
    ret = sqlite3_step(ctx->stmt_delete_file);
205
0
    if (ret != SQLITE_DONE) {
206
0
        return -1;
207
0
    }
208
209
0
    sqlite3_clear_bindings(ctx->stmt_delete_file);
210
0
    sqlite3_reset(ctx->stmt_delete_file);
211
212
0
    if (ret != SQLITE_DONE) {
213
0
        flb_plg_error(ctx->ins, "db: error deleting entry id=%" PRIu64
214
0
                      ", path='%s' from database", id, path);
215
0
        return -1;
216
0
    }
217
218
0
    flb_plg_debug(ctx->ins, "db: file id=%" PRIu64
219
0
                  ", path='%s' deleted from database", id, path);
220
0
    return 0;
221
0
}
222
223
#endif