NAME
sqlbox_open
,
sqlbox_open_async
—
open a database
LIBRARY
library “sqlbox”
SYNOPSIS
#include
<stdint.h>
#include <sqlbox.h>
size_t
sqlbox_open
(struct sqlbox *box,
size_t index);
int
sqlbox_open_async
(struct sqlbox
*box, size_t index);
DESCRIPTION
Open the database passed in the struct sqlbox_src array of sqlbox_alloc(3) at index. This structure has the following fields:
- fname
- The database filename, ":memory:", for an in-memory database, or
the empty string for a private on-disc database. May not be
NULL
. The latter are only available until the database is closed. Remote databases are not supported. - mode
- One of
SQLBOX_SRC_RO
for a readonly database,SQLBOX_SRC_RW
for readable and writable, andSQLBOX_SRC_RWC
to also be created. In-memory databases need not provide the creation bit.
The synchronous
sqlbox_open
()
returns the identifier while
sqlbox_open_async
()
only returns whether box was accessed. It is used for
implicit identifiers (i.e., an identifier of zero) in subsequent operations
on the database.
Both functions always enable foreign key support on the database.
If the database is not closed with sqlbox_close(3), it is automatically closed on sqlbox_free(3). This is not considered an error, as a common usage pattern is a role with permission opening the database, shedding its role, then the close being relegated to the full destruction of the box.
It's perfectly alright to open multiple databases of the same index, although it's probably not what you want.
SQLite3 Implementation
Opens the database with sqlite3_open_v2(3). Has a random back-off on return of
SQLITE_BUSY
, SQLITE_LOCKED
,
or SQLITE_PROTOCOL
. Otherwise, if not
SQLITE_OK
, considers it a failed open.
The foreign keys are enabled with a call to sqlite3_exec(3) using a similar back-off algorithm.
RETURN VALUES
sqlbox_open
() returns an identifier >0
if communication with box works, zero otherwise
(opening the database files, etc.).
sqlbox_open_async
() returns zero if communication
with box failed, non-zero otherwise.
If sqlbox_open
() or
sqlbox_open_async
() fail, box
is no longer accessible beyond sqlbox_ping(3) and sqlbox_free(3).
EXAMPLES
This opens an in-memory database then immediately exits.
struct sqlbox *p; struct sqlbox_src srcs[] = { { .fname = (char *)":memory:", .mode = SQLBOX_SRC_RWC }, }; struct sqlbox_cfg cfg; size_t id; memset(&cfg, 0, sizeof(struct sqlbox_cfg)); cfg.msg.func_short = warnx; cfg.srcs.srcsz = 1; cfg.srcs.srcs = srcs; if ((p = sqlbox_alloc(&cfg)) == NULL) errx(EXIT_FAILURE, "sqlbox_alloc"); if (!(id = sqlbox_open(p, 0))) errx(EXIT_FAILURE, "sqlbox_open"); sqlbox_free(p);
The following opens (and creates, if not found) the database db.db. The database is explicitly closed.
struct sqlbox *p; struct sqlbox_src srcs[] = { { .fname = (char *)"db.db", .mode = SQLBOX_SRC_RWC }, }; struct sqlbox_cfg cfg; size_t id; memset(&cfg, 0, sizeof(struct sqlbox_cfg)); cfg.msg.func_short = warnx; cfg.srcs.srcsz = 1; cfg.srcs.srcs = srcs; if ((p = sqlbox_alloc(&cfg)) == NULL) errx(EXIT_FAILURE, "sqlbox_alloc"); if (!(id = sqlbox_open(p, 0))) errx(EXIT_FAILURE, "sqlbox_open"); /* Perform work... */ if (!sqlbox_close(p, id)) errx(EXIT_FAILURE, "sqlbox_close"); sqlbox_free(p);
Performing the same with implicit identifiers:
struct sqlbox *p; struct sqlbox_src srcs[] = { { .fname = (char *)"db.db", .mode = SQLBOX_SRC_RWC }, }; struct sqlbox_cfg cfg; memset(&cfg, 0, sizeof(struct sqlbox_cfg)); cfg.msg.func_short = warnx; cfg.srcs.srcsz = 1; cfg.srcs.srcs = srcs; if ((p = sqlbox_alloc(&cfg)) == NULL) errx(EXIT_FAILURE, "sqlbox_alloc"); if (!sqlbox_open_async(p, 0)) errx(EXIT_FAILURE, "sqlbox_open_async"); /* Perform work... */ if (!sqlbox_close(p, 0)) errx(EXIT_FAILURE, "sqlbox_close"); sqlbox_free(p);