]>
git.proxmox.com Git - mirror_frr.git/blob - lib/db.c
1 // SPDX-License-Identifier: ISC AND GPL-2.0-or-later
3 * Copyright (c) 2018 Rafael Zalamena <rzalamena@gmail.com>
7 * Copyright (c) 2016 Rafael Zalamena <rzalamena@gmail.com>
15 static struct sqlite3
*dbp
;
18 * Initialize the database in path.
20 * It's possible to use in memory database with ':memory:' path.
22 int db_init(const char *path_fmt
, ...)
30 va_start(ap
, path_fmt
);
31 vsnprintf(path
, sizeof(path
), path_fmt
, ap
);
34 if (sqlite3_open_v2(path
, &dbp
,
35 (SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE
), NULL
)
38 zlog_warn("%s: failed to open database '%s'", __func__
,
43 zlog_warn("%s: failed to open database '%s': %s", __func__
,
44 path
, sqlite3_errmsg(dbp
));
45 if (sqlite3_close_v2(dbp
) != SQLITE_OK
)
46 zlog_warn("%s: failed to terminate database", __func__
);
54 /* Closes the database if open. */
60 if (sqlite3_close_v2(dbp
) != SQLITE_OK
) {
61 zlog_warn("%s: failed to terminate database", __func__
);
67 /* Helper function to handle formating. */
68 static int db_vbindf(struct sqlite3_stmt
*ss
, const char *fmt
, va_list vl
)
70 const char *sptr
= fmt
;
83 if (sptr
++ && *sptr
== 0)
88 uinteger
= va_arg(vl
, uint32_t);
89 if (sqlite3_bind_int(ss
, column
++, uinteger
)
94 uinteger64
= va_arg(vl
, uint64_t);
95 if (sqlite3_bind_int64(ss
, column
++, uinteger64
)
100 str
= va_arg(vl
, const char *);
101 vlen
= va_arg(vl
, int);
102 if (sqlite3_bind_text(ss
, column
++, str
, vlen
,
108 blob
= va_arg(vl
, void *);
109 vlen
= va_arg(vl
, int);
110 if (sqlite3_bind_blob(ss
, column
++, blob
, vlen
,
116 if (sqlite3_bind_null(ss
, column
++) != SQLITE_OK
)
120 zlog_warn("%s: invalid format '%c'", __func__
, *sptr
);
129 * Binds values using format to the database query.
131 * Might be used to bind variables to a query, insert or update.
133 int db_bindf(struct sqlite3_stmt
*ss
, const char *fmt
, ...)
139 result
= db_vbindf(ss
, fmt
, vl
);
145 /* Prepares an statement to the database with the statement length. */
146 struct sqlite3_stmt
*db_prepare_len(const char *stmt
, int stmtlen
)
148 struct sqlite3_stmt
*ss
;
154 c
= sqlite3_prepare_v2(dbp
, stmt
, stmtlen
, &ss
, NULL
);
156 zlog_warn("%s: failed to prepare (%d:%s)", __func__
, c
,
157 sqlite3_errmsg(dbp
));
164 /* Prepares an statement to the database. */
165 struct sqlite3_stmt
*db_prepare(const char *stmt
)
167 return db_prepare_len(stmt
, strlen(stmt
));
170 /* Run a prepared statement. */
171 int db_run(struct sqlite3_stmt
*ss
)
175 result
= sqlite3_step(ss
);
178 /* TODO handle busy database. */
183 * SQLITE_DONE just causes confusion since it means the query went OK,
184 * but it has a different value.
192 /* It is expected to receive SQLITE_ROW on search queries. */
196 zlog_warn("%s: step failed (%d:%s)", __func__
, result
,
197 sqlite3_errstr(result
));
203 /* Helper function to load format to variables. */
204 static int db_vloadf(struct sqlite3_stmt
*ss
, const char *fmt
, va_list vl
)
206 const char *sptr
= fmt
;
211 uint64_t *uinteger64
;
217 columncount
= sqlite3_column_count(ss
);
218 if (columncount
== 0)
226 if (sptr
++ && *sptr
== 0)
231 uinteger
= va_arg(vl
, uint32_t *);
232 *uinteger
= sqlite3_column_int(ss
, column
);
235 uinteger64
= va_arg(vl
, uint64_t *);
236 *uinteger64
= sqlite3_column_int64(ss
, column
);
239 str
= va_arg(vl
, const char **);
240 *str
= (const char *)sqlite3_column_text(ss
, column
);
243 blob
= va_arg(vl
, void *);
244 vlen
= va_arg(vl
, int);
245 dlen
= sqlite3_column_bytes(ss
, column
);
246 blobsrc
= sqlite3_column_blob(ss
, column
);
247 memcpy(blob
, blobsrc
, MIN(vlen
, dlen
));
250 zlog_warn("%s: invalid format '%c'", __func__
, *sptr
);
260 /* Function to load format from database row. */
261 int db_loadf(struct sqlite3_stmt
*ss
, const char *fmt
, ...)
267 result
= db_vloadf(ss
, fmt
, vl
);
273 /* Finalize query and return memory. */
274 void db_finalize(struct sqlite3_stmt
**ss
)
276 sqlite3_finalize(*ss
);
280 /* Execute one or more statements. */
281 int db_execute(const char *stmt_fmt
, ...)
289 va_start(ap
, stmt_fmt
);
290 vsnprintf(stmt
, sizeof(stmt
), stmt_fmt
, ap
);
293 if (sqlite3_exec(dbp
, stmt
, NULL
, 0, NULL
) != SQLITE_OK
) {
294 zlog_warn("%s: failed to execute statement(s): %s", __func__
,
295 sqlite3_errmsg(dbp
));