Coverage Report

Created: 2026-02-09 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/src/flb_sqldb.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_mem.h>
21
#include <fluent-bit/flb_str.h>
22
#include <fluent-bit/flb_log.h>
23
#include <fluent-bit/flb_sqldb.h>
24
25
/*
26
 * Open or create a new database. Note that this function will always try to
27
 * use an open database and share it handler in as a new context.
28
 */
29
struct flb_sqldb *flb_sqldb_open(const char *path, const char *desc,
30
                                 struct flb_config *config)
31
0
{
32
0
    int ret;
33
0
    struct mk_list *head;
34
0
    struct flb_sqldb *db_temp = NULL;
35
0
    struct flb_sqldb *db;
36
0
    sqlite3 *sdb = NULL;
37
38
0
    db = flb_calloc(1, sizeof(struct flb_sqldb));
39
40
0
    if (db == NULL) {
41
0
        flb_errno();
42
43
0
        return NULL;
44
0
    }
45
46
0
    db->parent = NULL;
47
0
    db->shared = FLB_FALSE;
48
0
    db->users  = 0;
49
50
0
    ret = flb_lock_init(&db->lock);
51
52
0
    if (ret != 0) {
53
0
        flb_free(db);
54
55
0
        return NULL;
56
0
    }
57
58
    /*
59
     * The database handler can be shared across different instances of
60
     * Fluent Bit. Before to open a new one, try to find a database that
61
     * is already open.
62
     */
63
0
    mk_list_foreach(head, &config->sqldb_list) {
64
0
        db_temp = mk_list_entry(head, struct flb_sqldb, _head);
65
66
        /* Only lookup for original database, not contexts already shared */
67
0
        if (db_temp->shared == FLB_TRUE) {
68
0
            continue;
69
0
        }
70
71
0
        if (strcmp(db_temp->path, path) == 0) {
72
0
            break;
73
0
        }
74
0
        db_temp = NULL;
75
0
    }
76
77
    /* Found a database that can be shared */
78
0
    if (db_temp) {
79
        /* Increase users counter */
80
0
        db_temp->users++;
81
82
        /* Setup the new context */
83
0
        db->handler = db_temp->handler;
84
0
        db->shared  = FLB_TRUE;
85
0
        db->parent  = db_temp;
86
0
    }
87
0
    else {
88
0
        ret = sqlite3_open(path, &sdb);
89
90
0
        if (ret) {
91
0
            flb_error("[sqldb] cannot open database %s", path);
92
93
0
            flb_lock_destroy(&db->lock);
94
0
            flb_free(db);
95
96
0
            return NULL;
97
98
0
        }
99
0
        db->handler = sdb;
100
0
    }
101
102
0
    db->path = flb_strdup(path);
103
104
0
    if (db->path == NULL) {
105
0
        flb_lock_destroy(&db->lock);
106
0
        sqlite3_close(sdb);
107
0
        flb_free(db);
108
109
0
        return NULL;
110
0
    }
111
112
113
0
    db->desc = flb_strdup(desc);
114
115
0
    if (db->desc == NULL) {
116
0
        flb_lock_destroy(&db->lock);
117
0
        flb_free(db->path);
118
0
        sqlite3_close(sdb);
119
0
        flb_free(db);
120
121
0
        return NULL;
122
0
    }
123
124
0
    mk_list_add(&db->_head, &config->sqldb_list);
125
126
0
    return db;
127
0
}
128
129
int flb_sqldb_close(struct flb_sqldb *db)
130
0
{
131
0
    struct flb_sqldb *parent;
132
133
0
    if (db->shared == FLB_TRUE) {
134
0
        parent = db->parent;
135
0
        parent->users--;
136
0
    }
137
0
    else {
138
0
        sqlite3_exec(db->handler, "COMMIT;", NULL, NULL, NULL);
139
0
        sqlite3_close(db->handler);
140
0
    }
141
142
0
    mk_list_del(&db->_head);
143
0
    flb_free(db->path);
144
0
    flb_free(db->desc);
145
0
    flb_lock_destroy(&db->lock);
146
0
    flb_free(db);
147
148
0
    return 0;
149
0
}
150
151
int flb_sqldb_query(struct flb_sqldb *db, const char *sql,
152
                    int (*callback) (void *, int, char **, char **),
153
                    void *data)
154
0
{
155
0
    int ret;
156
0
    char *err_msg = NULL;
157
158
0
    ret = sqlite3_exec(db->handler, sql, callback, data, &err_msg);
159
0
    if (ret != SQLITE_OK) {
160
0
        flb_error("[sqldb] error=%s", err_msg);
161
0
        sqlite3_free(err_msg);
162
0
        return FLB_ERROR;
163
0
    }
164
165
0
    return FLB_OK;
166
0
}
167
168
int64_t flb_sqldb_last_id(struct flb_sqldb *db)
169
0
{
170
0
    return sqlite3_last_insert_rowid(db->handler);
171
0
}
172
173
int flb_sqldb_lock(struct flb_sqldb *db)
174
0
{
175
0
    return flb_lock_acquire(&db->lock,
176
0
                            FLB_LOCK_INFINITE_RETRY_LIMIT,
177
0
                            FLB_LOCK_DEFAULT_RETRY_DELAY);
178
0
}
179
180
int flb_sqldb_unlock(struct flb_sqldb *db)
181
0
{
182
0
    return flb_lock_release(&db->lock,
183
0
                            FLB_LOCK_INFINITE_RETRY_LIMIT,
184
0
                            FLB_LOCK_DEFAULT_RETRY_DELAY);
185
0
}